@multiplatform.one/backoffice 7.6.2 → 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.
- package/dist/cjs/chrome/BackofficeAwesomebar.native.js +1 -1
- package/dist/cjs/chrome/BackofficeAwesomebar.native.js.map +1 -1
- package/dist/cjs/chrome/CommandPalette.native.js +1 -1
- package/dist/cjs/chrome/CommandPalette.native.js.map +1 -1
- package/dist/cjs/chrome/HelpMenu.native.js +1 -1
- package/dist/cjs/chrome/HelpMenu.native.js.map +1 -1
- package/dist/cjs/chrome/NotificationsButton.native.js +1 -1
- package/dist/cjs/chrome/NotificationsButton.native.js.map +1 -1
- package/dist/cjs/chrome/UserMenu.native.js +1 -1
- package/dist/cjs/chrome/UserMenu.native.js.map +1 -1
- package/dist/cjs/chrome/awesomebar-data.native.js.map +1 -1
- package/dist/cjs/chrome/command-palette-model.native.js +1 -1
- package/dist/cjs/chrome/command-palette-model.native.js.map +1 -1
- package/dist/cjs/chrome/help-about-dialog.native.js +1 -1
- package/dist/cjs/chrome/help-about-dialog.native.js.map +1 -1
- package/dist/cjs/chrome/help-shortcuts-dialog.native.js +1 -1
- package/dist/cjs/chrome/help-shortcuts-dialog.native.js.map +1 -1
- package/dist/cjs/chrome/notifications-data.native.js.map +1 -1
- package/dist/cjs/chrome/notifications-panel.native.js +1 -1
- package/dist/cjs/chrome/notifications-panel.native.js.map +1 -1
- package/dist/cjs/chrome/notifications-utils.native.js.map +1 -1
- package/dist/cjs/chrome/shortcuts.native.js.map +1 -1
- package/dist/cjs/chrome/user-session.native.js.map +1 -1
- package/dist/cjs/config/BackofficeProvider.native.js +1 -1
- package/dist/cjs/config/BackofficeProvider.native.js.map +1 -1
- package/dist/cjs/config/capabilities.native.js.map +1 -1
- package/dist/cjs/config/events.native.js.map +1 -1
- package/dist/cjs/config/slots.native.js.map +1 -1
- package/dist/cjs/desk/Desk.native.js.map +1 -1
- package/dist/cjs/desk/DeskSurface.native.js.map +1 -1
- package/dist/cjs/desk/resolveDeskPath.native.js.map +1 -1
- package/dist/cjs/desk/scope.native.js.map +1 -1
- package/dist/cjs/desk/target.native.js.map +1 -1
- package/dist/cjs/form/DocFormScreen.native.js +1 -1
- package/dist/cjs/form/DocFormScreen.native.js.map +1 -1
- package/dist/cjs/form/FormConnections.native.js +1 -1
- package/dist/cjs/form/FormConnections.native.js.map +1 -1
- package/dist/cjs/form/FormDialogs.native.js +1 -1
- package/dist/cjs/form/FormDialogs.native.js.map +1 -1
- package/dist/cjs/form/FormErrorBoundary.native.js +1 -1
- package/dist/cjs/form/FormErrorBoundary.native.js.map +1 -1
- package/dist/cjs/form/FormHeaderCluster.native.js +1 -1
- package/dist/cjs/form/FormHeaderCluster.native.js.map +1 -1
- package/dist/cjs/form/FormSidebarPanel.native.js +1 -1
- package/dist/cjs/form/FormSidebarPanel.native.js.map +1 -1
- package/dist/cjs/form/FormTimeline.native.js +1 -1
- package/dist/cjs/form/FormTimeline.native.js.map +1 -1
- package/dist/cjs/form/FormToolbar.native.js +1 -1
- package/dist/cjs/form/FormToolbar.native.js.map +1 -1
- package/dist/cjs/form/connections-data.native.js.map +1 -1
- package/dist/cjs/form/createPrefill.cjs +3 -11
- package/dist/cjs/form/createPrefill.native.js +3 -11
- package/dist/cjs/form/createPrefill.native.js.map +1 -1
- package/dist/cjs/form/dependsOn.native.js.map +1 -1
- package/dist/cjs/form/dirtyTracking.cjs +4 -29
- package/dist/cjs/form/dirtyTracking.native.js +4 -48
- package/dist/cjs/form/dirtyTracking.native.js.map +1 -1
- package/dist/cjs/form/docinfo.native.js.map +1 -1
- package/dist/cjs/form/fetchFrom.cjs +4 -41
- package/dist/cjs/form/fetchFrom.native.js +4 -81
- package/dist/cjs/form/fetchFrom.native.js.map +1 -1
- package/dist/cjs/form/fieldPermissions.cjs +4 -29
- package/dist/cjs/form/fieldPermissions.native.js +4 -51
- package/dist/cjs/form/fieldPermissions.native.js.map +1 -1
- package/dist/cjs/form/formActions.cjs +2 -171
- package/dist/cjs/form/formActions.native.js +2 -178
- package/dist/cjs/form/formActions.native.js.map +1 -1
- package/dist/cjs/form/formLayout.cjs +5 -219
- package/dist/cjs/form/formLayout.native.js +5 -359
- package/dist/cjs/form/formLayout.native.js.map +1 -1
- package/dist/cjs/form/platformHooks.native.js.map +1 -1
- package/dist/cjs/form/sidebar-attachments.native.js +1 -1
- package/dist/cjs/form/sidebar-attachments.native.js.map +1 -1
- package/dist/cjs/form/sidebar-dialogs.native.js +1 -1
- package/dist/cjs/form/sidebar-dialogs.native.js.map +1 -1
- package/dist/cjs/form/sidebar-people.native.js +1 -1
- package/dist/cjs/form/sidebar-people.native.js.map +1 -1
- package/dist/cjs/form/sidebar-rpc.native.js.map +1 -1
- package/dist/cjs/form/sidebar-utils.native.js.map +1 -1
- package/dist/cjs/form/timeline-entries.native.js.map +1 -1
- package/dist/cjs/form/timeline-utils.native.js.map +1 -1
- package/dist/cjs/form/useFormEngine.cjs +2 -361
- package/dist/cjs/form/useFormEngine.native.js +2 -447
- package/dist/cjs/form/useFormEngine.native.js.map +1 -1
- package/dist/cjs/i18n/en.native.js.map +1 -1
- package/dist/cjs/i18n/index.native.js.map +1 -1
- package/dist/cjs/index.native.js +1 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/list/AddTagsDialog.native.js +1 -1
- package/dist/cjs/list/AddTagsDialog.native.js.map +1 -1
- package/dist/cjs/list/AssignToDialog.native.js +1 -1
- package/dist/cjs/list/AssignToDialog.native.js.map +1 -1
- package/dist/cjs/list/DoctypeListScreen.native.js +1 -1
- package/dist/cjs/list/DoctypeListScreen.native.js.map +1 -1
- package/dist/cjs/list/ListBulkActionsBar.native.js +1 -1
- package/dist/cjs/list/ListBulkActionsBar.native.js.map +1 -1
- package/dist/cjs/list/ListFilterBar.native.js +1 -1
- package/dist/cjs/list/ListFilterBar.native.js.map +1 -1
- package/dist/cjs/list/ListSidebar.native.js +1 -1
- package/dist/cjs/list/ListSidebar.native.js.map +1 -1
- package/dist/cjs/list/bulk-edit-dialog.native.js +1 -1
- package/dist/cjs/list/bulk-edit-dialog.native.js.map +1 -1
- package/dist/cjs/list/bulk-export.native.js.map +1 -1
- package/dist/cjs/list/bulk-submit-cancel.native.js.map +1 -1
- package/dist/cjs/list/bulkActions.native.js.map +1 -1
- package/dist/cjs/list/filter-chips.native.js +1 -1
- package/dist/cjs/list/filter-chips.native.js.map +1 -1
- package/dist/cjs/list/filter-editor.native.js +1 -1
- package/dist/cjs/list/filter-editor.native.js.map +1 -1
- package/dist/cjs/list/filter-fields.native.js.map +1 -1
- package/dist/cjs/list/filter-saved.native.js +1 -1
- package/dist/cjs/list/filter-saved.native.js.map +1 -1
- package/dist/cjs/list/filter-sort.native.js +1 -1
- package/dist/cjs/list/filter-sort.native.js.map +1 -1
- package/dist/cjs/list/filter-standard.native.js.map +1 -1
- package/dist/cjs/list/filterConversion.native.js.map +1 -1
- package/dist/cjs/list/list-tools-sheet.native.js +1 -1
- package/dist/cjs/list/list-tools-sheet.native.js.map +1 -1
- package/dist/cjs/list/listColumns.native.js.map +1 -1
- package/dist/cjs/list/listFields.native.js.map +1 -1
- package/dist/cjs/list/listFormat.native.js.map +1 -1
- package/dist/cjs/list/listUrlState.native.js.map +1 -1
- package/dist/cjs/list/sidebar-section.native.js +1 -1
- package/dist/cjs/list/sidebar-section.native.js.map +1 -1
- package/dist/cjs/list/sidebar-stats.native.js.map +1 -1
- package/dist/cjs/list/statusColors.native.js.map +1 -1
- package/dist/cjs/navigation/navigator.native.js.map +1 -1
- package/dist/cjs/navigation/paths.native.js.map +1 -1
- package/dist/cjs/oneAdapter/index.native.js.map +1 -1
- package/dist/cjs/quickEntry/QuickEntryDialog.native.js +1 -1
- package/dist/cjs/quickEntry/QuickEntryDialog.native.js.map +1 -1
- package/dist/cjs/quickEntry/quickEntryPlan.native.js.map +1 -1
- package/dist/cjs/report/DoctypeReportView.native.js +1 -1
- package/dist/cjs/report/DoctypeReportView.native.js.map +1 -1
- package/dist/cjs/report/QueryReportScreen.native.js +1 -1
- package/dist/cjs/report/QueryReportScreen.native.js.map +1 -1
- package/dist/cjs/report/queryReportColumns.native.js.map +1 -1
- package/dist/cjs/report/queryReportFilterBar.native.js +1 -1
- package/dist/cjs/report/queryReportFilterBar.native.js.map +1 -1
- package/dist/cjs/report/queryReportUrlState.native.js.map +1 -1
- package/dist/cjs/report/report-grid.native.js +1 -1
- package/dist/cjs/report/report-grid.native.js.map +1 -1
- package/dist/cjs/report/report-toolbar.native.js +1 -1
- package/dist/cjs/report/report-toolbar.native.js.map +1 -1
- package/dist/cjs/report/reportShapes.native.js.map +1 -1
- package/dist/cjs/report/reportViewModel.native.js.map +1 -1
- package/dist/cjs/report/savedReports.native.js.map +1 -1
- package/dist/cjs/report/useQueryReport.native.js.map +1 -1
- package/dist/cjs/shared/deskLinks.native.js.map +1 -1
- package/dist/cjs/shared/listNavContext.native.js.map +1 -1
- package/dist/cjs/shared/types.native.js.map +1 -1
- package/dist/cjs/shared/useDocinfo.native.js.map +1 -1
- package/dist/cjs/shared/useDoctypeMeta.native.js.map +1 -1
- package/dist/cjs/shared/useFrappeApp.native.js.map +1 -1
- package/dist/cjs/shared/useRecentVisit.native.js.map +1 -1
- package/dist/cjs/shared/useSessionUserId.native.js.map +1 -1
- package/dist/cjs/shared/useSlugTarget.native.js.map +1 -1
- package/dist/cjs/shared/useUserRoles.native.js.map +1 -1
- package/dist/cjs/shell/BackofficeShell.native.js +1 -1
- package/dist/cjs/shell/BackofficeShell.native.js.map +1 -1
- package/dist/cjs/shell/HomeRedirect.native.js +1 -1
- package/dist/cjs/shell/HomeRedirect.native.js.map +1 -1
- package/dist/cjs/shell/NotFoundScreen.native.js +1 -1
- package/dist/cjs/shell/NotFoundScreen.native.js.map +1 -1
- package/dist/cjs/shell/SlugScreen.native.js +1 -1
- package/dist/cjs/shell/SlugScreen.native.js.map +1 -1
- package/dist/cjs/shell/WorkspaceSidebar.native.js +1 -1
- package/dist/cjs/shell/WorkspaceSidebar.native.js.map +1 -1
- package/dist/cjs/shell/useWorkspaces.native.js.map +1 -1
- package/dist/cjs/shell/workspaceIcons.native.js.map +1 -1
- package/dist/cjs/views/CalendarView.native.js +1 -1
- package/dist/cjs/views/CalendarView.native.js.map +1 -1
- package/dist/cjs/views/DashboardView.native.js +1 -1
- package/dist/cjs/views/DashboardView.native.js.map +1 -1
- package/dist/cjs/views/DoctypeViewScreen.native.js.map +1 -1
- package/dist/cjs/views/ImageView.native.js +1 -1
- package/dist/cjs/views/ImageView.native.js.map +1 -1
- package/dist/cjs/views/KanbanView.native.js +1 -1
- package/dist/cjs/views/KanbanView.native.js.map +1 -1
- package/dist/cjs/views/ReportView.native.js +1 -1
- package/dist/cjs/views/ReportView.native.js.map +1 -1
- package/dist/cjs/views/TreeView.native.js +1 -1
- package/dist/cjs/views/TreeView.native.js.map +1 -1
- package/dist/cjs/views/ViewHeader.native.js +1 -1
- package/dist/cjs/views/ViewHeader.native.js.map +1 -1
- package/dist/cjs/views/ViewStates.native.js +1 -1
- package/dist/cjs/views/ViewStates.native.js.map +1 -1
- package/dist/cjs/views/ViewSwitcherMenu.native.js +1 -1
- package/dist/cjs/views/ViewSwitcherMenu.native.js.map +1 -1
- package/dist/cjs/views/calendar-field-selector.native.js +1 -1
- package/dist/cjs/views/calendar-field-selector.native.js.map +1 -1
- package/dist/cjs/views/connection.native.js.map +1 -1
- package/dist/cjs/views/dashboard-data.native.js.map +1 -1
- package/dist/cjs/views/deskViewConfigs.native.js.map +1 -1
- package/dist/cjs/views/kanban-board-controls.native.js +1 -1
- package/dist/cjs/views/kanban-board-controls.native.js.map +1 -1
- package/dist/cjs/views/kanban-field-picker.native.js +1 -1
- package/dist/cjs/views/kanban-field-picker.native.js.map +1 -1
- package/dist/cjs/views/kanbanBoardOps.native.js.map +1 -1
- package/dist/cjs/views/report-controls.native.js +1 -1
- package/dist/cjs/views/report-controls.native.js.map +1 -1
- package/dist/cjs/views/viewAvailability.native.js.map +1 -1
- package/dist/cjs/views/viewMeta.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceChartBlock.native.js +1 -1
- package/dist/cjs/workspace/WorkspaceChartBlock.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceGrid.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceLinkCard.native.js +1 -1
- package/dist/cjs/workspace/WorkspaceLinkCard.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceLinkDirectory.native.js +1 -1
- package/dist/cjs/workspace/WorkspaceLinkDirectory.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceNumberCard.native.js +1 -1
- package/dist/cjs/workspace/WorkspaceNumberCard.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceQuickList.cjs +1 -1
- package/dist/cjs/workspace/WorkspaceQuickList.native.js +4 -2
- package/dist/cjs/workspace/WorkspaceQuickList.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceRecents.cjs +1 -3
- package/dist/cjs/workspace/WorkspaceRecents.native.js +4 -4
- package/dist/cjs/workspace/WorkspaceRecents.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceScreen.native.js +1 -1
- package/dist/cjs/workspace/WorkspaceScreen.native.js.map +1 -1
- package/dist/cjs/workspace/WorkspaceShortcut.cjs +1 -3
- package/dist/cjs/workspace/WorkspaceShortcut.native.js +5 -4
- package/dist/cjs/workspace/WorkspaceShortcut.native.js.map +1 -1
- package/dist/cjs/workspace/parseContent.native.js.map +1 -1
- package/dist/cjs/workspace/types.native.js.map +1 -1
- package/dist/cjs/workspace/useDashboardChart.native.js.map +1 -1
- package/dist/cjs/workspace/useWorkspaceDoc.native.js.map +1 -1
- package/dist/esm/desk/DeskSurface.mjs.map +1 -1
- package/dist/esm/desk/DeskSurface.native.js.map +1 -1
- package/dist/esm/form/createPrefill.mjs +1 -9
- package/dist/esm/form/createPrefill.mjs.map +1 -1
- package/dist/esm/form/createPrefill.native.js +1 -9
- package/dist/esm/form/createPrefill.native.js.map +1 -1
- package/dist/esm/form/dirtyTracking.mjs +1 -26
- package/dist/esm/form/dirtyTracking.mjs.map +1 -1
- package/dist/esm/form/dirtyTracking.native.js +1 -45
- package/dist/esm/form/dirtyTracking.native.js.map +1 -1
- package/dist/esm/form/fetchFrom.mjs +1 -38
- package/dist/esm/form/fetchFrom.mjs.map +1 -1
- package/dist/esm/form/fetchFrom.native.js +1 -78
- package/dist/esm/form/fetchFrom.native.js.map +1 -1
- package/dist/esm/form/fieldPermissions.mjs +1 -26
- package/dist/esm/form/fieldPermissions.mjs.map +1 -1
- package/dist/esm/form/fieldPermissions.native.js +1 -48
- package/dist/esm/form/fieldPermissions.native.js.map +1 -1
- package/dist/esm/form/formActions.mjs +1 -145
- package/dist/esm/form/formActions.mjs.map +1 -1
- package/dist/esm/form/formActions.native.js +1 -152
- package/dist/esm/form/formActions.native.js.map +1 -1
- package/dist/esm/form/formLayout.mjs +1 -215
- package/dist/esm/form/formLayout.mjs.map +1 -1
- package/dist/esm/form/formLayout.native.js +1 -355
- package/dist/esm/form/formLayout.native.js.map +1 -1
- package/dist/esm/form/useFormEngine.mjs +1 -360
- package/dist/esm/form/useFormEngine.mjs.map +1 -1
- package/dist/esm/form/useFormEngine.native.js +1 -446
- package/dist/esm/form/useFormEngine.native.js.map +1 -1
- package/dist/esm/shared/useDoctypeMeta.mjs.map +1 -1
- package/dist/esm/shared/useDoctypeMeta.native.js.map +1 -1
- package/dist/esm/workspace/WorkspaceQuickList.mjs +2 -2
- package/dist/esm/workspace/WorkspaceQuickList.mjs.map +1 -1
- package/dist/esm/workspace/WorkspaceQuickList.native.js +4 -2
- package/dist/esm/workspace/WorkspaceQuickList.native.js.map +1 -1
- package/dist/esm/workspace/WorkspaceRecents.mjs +1 -3
- package/dist/esm/workspace/WorkspaceRecents.mjs.map +1 -1
- package/dist/esm/workspace/WorkspaceRecents.native.js +3 -3
- package/dist/esm/workspace/WorkspaceRecents.native.js.map +1 -1
- package/dist/esm/workspace/WorkspaceShortcut.mjs +1 -3
- package/dist/esm/workspace/WorkspaceShortcut.mjs.map +1 -1
- package/dist/esm/workspace/WorkspaceShortcut.native.js +4 -3
- package/dist/esm/workspace/WorkspaceShortcut.native.js.map +1 -1
- package/dist/jsx/desk/DeskSurface.mjs.map +1 -1
- package/dist/jsx/desk/DeskSurface.native.js.map +1 -1
- package/dist/jsx/form/createPrefill.mjs +1 -9
- package/dist/jsx/form/createPrefill.mjs.map +1 -1
- package/dist/jsx/form/createPrefill.native.js +3 -11
- package/dist/jsx/form/createPrefill.native.js.map +1 -1
- package/dist/jsx/form/dirtyTracking.mjs +1 -26
- package/dist/jsx/form/dirtyTracking.mjs.map +1 -1
- package/dist/jsx/form/dirtyTracking.native.js +4 -48
- package/dist/jsx/form/dirtyTracking.native.js.map +1 -1
- package/dist/jsx/form/fetchFrom.mjs +1 -38
- package/dist/jsx/form/fetchFrom.mjs.map +1 -1
- package/dist/jsx/form/fetchFrom.native.js +4 -81
- package/dist/jsx/form/fetchFrom.native.js.map +1 -1
- package/dist/jsx/form/fieldPermissions.mjs +1 -26
- package/dist/jsx/form/fieldPermissions.mjs.map +1 -1
- package/dist/jsx/form/fieldPermissions.native.js +4 -51
- package/dist/jsx/form/fieldPermissions.native.js.map +1 -1
- package/dist/jsx/form/formActions.mjs +1 -145
- package/dist/jsx/form/formActions.mjs.map +1 -1
- package/dist/jsx/form/formActions.native.js +2 -178
- package/dist/jsx/form/formActions.native.js.map +1 -1
- package/dist/jsx/form/formLayout.mjs +1 -215
- package/dist/jsx/form/formLayout.mjs.map +1 -1
- package/dist/jsx/form/formLayout.native.js +5 -359
- package/dist/jsx/form/formLayout.native.js.map +1 -1
- package/dist/jsx/form/useFormEngine.mjs +1 -360
- package/dist/jsx/form/useFormEngine.mjs.map +1 -1
- package/dist/jsx/form/useFormEngine.native.js +2 -447
- package/dist/jsx/form/useFormEngine.native.js.map +1 -1
- package/dist/jsx/shared/useDoctypeMeta.mjs.map +1 -1
- package/dist/jsx/shared/useDoctypeMeta.native.js.map +1 -1
- package/dist/jsx/workspace/WorkspaceQuickList.mjs +2 -2
- package/dist/jsx/workspace/WorkspaceQuickList.mjs.map +1 -1
- package/dist/jsx/workspace/WorkspaceQuickList.native.js +3 -1
- package/dist/jsx/workspace/WorkspaceQuickList.native.js.map +1 -1
- package/dist/jsx/workspace/WorkspaceRecents.mjs +1 -3
- package/dist/jsx/workspace/WorkspaceRecents.mjs.map +1 -1
- package/dist/jsx/workspace/WorkspaceRecents.native.js +3 -3
- package/dist/jsx/workspace/WorkspaceRecents.native.js.map +1 -1
- package/dist/jsx/workspace/WorkspaceShortcut.mjs +1 -3
- package/dist/jsx/workspace/WorkspaceShortcut.mjs.map +1 -1
- package/dist/jsx/workspace/WorkspaceShortcut.native.js +4 -3
- package/dist/jsx/workspace/WorkspaceShortcut.native.js.map +1 -1
- package/package.json +12 -13
- package/src/desk/DeskSurface.tsx +8 -4
- package/src/form/createPrefill.ts +5 -25
- package/src/form/dirtyTracking.ts +4 -61
- package/src/form/fetchFrom.ts +5 -108
- package/src/form/fieldPermissions.ts +7 -65
- package/src/form/formActions.ts +10 -281
- package/src/form/formEngineShim.spec.ts +122 -0
- package/src/form/formLayout.ts +15 -387
- package/src/form/useFormEngine.ts +5 -493
- package/src/shared/useDoctypeMeta.ts +12 -100
- package/src/workspace/WorkspaceQuickList.tsx +10 -2
- package/src/workspace/WorkspaceRecents.tsx +3 -1
- package/src/workspace/WorkspaceShortcut.tsx +4 -1
- package/types/desk/DeskSurface.d.ts.map +1 -1
- package/types/form/createPrefill.d.ts +5 -16
- package/types/form/createPrefill.d.ts.map +1 -1
- package/types/form/dirtyTracking.d.ts +4 -33
- package/types/form/dirtyTracking.d.ts.map +1 -1
- package/types/form/fetchFrom.d.ts +5 -40
- package/types/form/fetchFrom.d.ts.map +1 -1
- package/types/form/fieldPermissions.d.ts +7 -35
- package/types/form/fieldPermissions.d.ts.map +1 -1
- package/types/form/formActions.d.ts +6 -91
- package/types/form/formActions.d.ts.map +1 -1
- package/types/form/formLayout.d.ts +12 -89
- package/types/form/formLayout.d.ts.map +1 -1
- package/types/form/useFormEngine.d.ts +5 -58
- package/types/form/useFormEngine.d.ts.map +1 -1
- package/types/shared/useDoctypeMeta.d.ts +2 -100
- package/types/shared/useDoctypeMeta.d.ts.map +1 -1
- package/types/workspace/WorkspaceQuickList.d.ts.map +1 -1
- package/types/workspace/WorkspaceRecents.d.ts.map +1 -1
- package/types/workspace/WorkspaceShortcut.d.ts.map +1 -1
- package/src/form/dirtyTracking.spec.ts +0 -91
- package/src/form/fetchFrom.spec.ts +0 -92
- package/src/form/fieldPermissions.spec.ts +0 -61
- package/src/form/formLayout.spec.ts +0 -373
package/src/form/formLayout.ts
CHANGED
|
@@ -1,391 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Desk form layout engine
|
|
2
|
+
* Desk form layout engine — moved to
|
|
3
|
+
* `@multiplatform.one/frappe-ui/src/formEngine/formLayout` (MPO-15).
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* FieldSchema handed to SchemaForm so its string-eval-based evaluator
|
|
11
|
-
* (which cannot run on Hermes/GJS) never engages:
|
|
12
|
-
*
|
|
13
|
-
* - depends_on → field omitted from the built schema
|
|
14
|
-
* - mandatory_depends_on → `required: true` on the built FieldSchema
|
|
15
|
-
* - read_only_depends_on → `readOnly: true` on the built FieldSchema
|
|
16
|
-
* - permlevel → hidden without level read, read-only without
|
|
17
|
-
* level write (role matrix via fieldPermissions.ts; coarse read-only
|
|
18
|
-
* fallback when roles are unavailable)
|
|
19
|
-
* - set_only_once → read-only on saved docs
|
|
20
|
-
* - fetch_from → read-only while the source link holds a value
|
|
21
|
-
* (unless fetch_if_empty)
|
|
22
|
-
* - docstatus > 0 → everything read-only except allow_on_submit
|
|
23
|
-
* fields on a submitted (1) doc
|
|
24
|
-
* - collapsible / collapsible_depends_on / missing-mandatory → per-section
|
|
25
|
-
* computed collapse state (desk refresh_section_collapse)
|
|
26
|
-
*
|
|
27
|
-
* Sections whose Section Break has a false depends_on hide wholesale; a
|
|
28
|
-
* section with no visible fields is dropped so SchemaForm never renders an
|
|
29
|
-
* empty card.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
import { formatCalendarDate } from "@multiplatform.one/theme";
|
|
33
|
-
import type { FieldSchema, FormSchema, FormSection } from "@multiplatform.one/frappe-ui";
|
|
34
|
-
import { evaluateDependsOn } from "./dependsOn";
|
|
35
|
-
import { canReadLevel, canWriteLevel, type PermLevelMatrix } from "./fieldPermissions";
|
|
36
|
-
import { isFetchLocked } from "./fetchFrom";
|
|
37
|
-
import type { DocFieldMeta } from "../shared/useDoctypeMeta";
|
|
38
|
-
|
|
39
|
-
// ---------------------------------------------------------------------------
|
|
40
|
-
// Types
|
|
41
|
-
// ---------------------------------------------------------------------------
|
|
42
|
-
|
|
43
|
-
export interface FormTab {
|
|
44
|
-
/** Stable key (fieldname of the Tab Break or "__details") */
|
|
45
|
-
key: string;
|
|
46
|
-
label: string;
|
|
47
|
-
schema: FormSchema;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface LayoutColumn {
|
|
51
|
-
fields: DocFieldMeta[];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
interface LayoutSection {
|
|
55
|
-
breakField?: DocFieldMeta;
|
|
56
|
-
columns: LayoutColumn[];
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
interface LayoutTab {
|
|
60
|
-
key: string;
|
|
61
|
-
label?: string;
|
|
62
|
-
sections: LayoutSection[];
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
|
-
// Static structure (from meta, doc-independent)
|
|
67
|
-
// ---------------------------------------------------------------------------
|
|
68
|
-
|
|
69
|
-
function splitIntoTabs(fields: DocFieldMeta[]): LayoutTab[] {
|
|
70
|
-
const tabs: LayoutTab[] = [];
|
|
71
|
-
let currentTab: LayoutTab = { key: "__details", sections: [] };
|
|
72
|
-
let currentSection: LayoutSection = { columns: [{ fields: [] }] };
|
|
73
|
-
currentTab.sections.push(currentSection);
|
|
74
|
-
tabs.push(currentTab);
|
|
75
|
-
|
|
76
|
-
for (const field of fields) {
|
|
77
|
-
switch (field.fieldtype) {
|
|
78
|
-
case "Tab Break":
|
|
79
|
-
currentTab = { key: field.fieldname, label: field.label, sections: [] };
|
|
80
|
-
currentSection = { columns: [{ fields: [] }] };
|
|
81
|
-
currentTab.sections.push(currentSection);
|
|
82
|
-
tabs.push(currentTab);
|
|
83
|
-
break;
|
|
84
|
-
case "Section Break":
|
|
85
|
-
currentSection = { breakField: field, columns: [{ fields: [] }] };
|
|
86
|
-
currentTab.sections.push(currentSection);
|
|
87
|
-
break;
|
|
88
|
-
case "Column Break":
|
|
89
|
-
currentSection.columns.push({ fields: [] });
|
|
90
|
-
break;
|
|
91
|
-
default:
|
|
92
|
-
currentSection.columns[currentSection.columns.length - 1].fields.push(field);
|
|
93
|
-
break;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return tabs;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// ---------------------------------------------------------------------------
|
|
100
|
-
// Doc-dependent resolution
|
|
101
|
-
// ---------------------------------------------------------------------------
|
|
102
|
-
|
|
103
|
-
export interface BuildTabsOptions {
|
|
104
|
-
fields: DocFieldMeta[];
|
|
105
|
-
doc: Record<string, unknown>;
|
|
106
|
-
/** docstatus of the loaded doc (0 draft / 1 submitted / 2 cancelled). */
|
|
107
|
-
docstatus: number;
|
|
108
|
-
/** Meta-level read_only or missing write permission. */
|
|
109
|
-
formReadOnly: boolean;
|
|
110
|
-
/** Create mode relaxes read_only_depends_on on unsaved values. */
|
|
111
|
-
isCreate: boolean;
|
|
112
|
-
/** Default label for the implicit first tab. */
|
|
113
|
-
detailsLabel: string;
|
|
114
|
-
/**
|
|
115
|
-
* Role-derived permlevel matrix (fieldPermissions.ts). Desk semantics:
|
|
116
|
-
* fields at a level without read HIDE; read without write → read-only.
|
|
117
|
-
* Undefined (fixtures / roles unavailable) → coarse fallback: any
|
|
118
|
-
* permlevel > 0 renders read-only, never hidden.
|
|
119
|
-
*/
|
|
120
|
-
permLevels?: PermLevelMatrix;
|
|
121
|
-
/** Host-hidden fields (fieldnames) — dropped before layout resolution. */
|
|
122
|
-
hiddenFields?: readonly string[];
|
|
123
|
-
/**
|
|
124
|
-
* Host-hidden sections/tabs. Matches a Section Break's or Tab Break's
|
|
125
|
-
* fieldname OR label; the whole section (or tab) is dropped.
|
|
126
|
-
*/
|
|
127
|
-
hiddenSections?: readonly string[];
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function isFieldVisible(
|
|
131
|
-
field: DocFieldMeta,
|
|
132
|
-
doc: Record<string, unknown>,
|
|
133
|
-
permLevels?: PermLevelMatrix,
|
|
134
|
-
): boolean {
|
|
135
|
-
if (field.hidden) return false;
|
|
136
|
-
// Desk hides fields whose permlevel the user cannot read (perm.js:209-215).
|
|
137
|
-
if (!canReadLevel(permLevels, field.permlevel ?? 0)) return false;
|
|
138
|
-
// Visibility fallback = true: an unparseable expression shows the field.
|
|
139
|
-
return evaluateDependsOn(field.depends_on, doc, true);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function toFieldSchema(
|
|
143
|
-
field: DocFieldMeta,
|
|
144
|
-
doc: Record<string, unknown>,
|
|
145
|
-
options: BuildTabsOptions,
|
|
146
|
-
): FieldSchema {
|
|
147
|
-
const required =
|
|
148
|
-
!!field.reqd ||
|
|
149
|
-
(!!field.mandatory_depends_on && evaluateDependsOn(field.mandatory_depends_on, doc, false));
|
|
150
|
-
|
|
151
|
-
let readOnly =
|
|
152
|
-
!!field.read_only ||
|
|
153
|
-
(!!field.read_only_depends_on && evaluateDependsOn(field.read_only_depends_on, doc, false)) ||
|
|
154
|
-
!canWriteLevel(options.permLevels, field.permlevel ?? 0);
|
|
155
|
-
// set_only_once: editable only while the doc is unsaved (perm.js:261-263).
|
|
156
|
-
if (field.set_only_once && !options.isCreate) readOnly = true;
|
|
157
|
-
// fetch_from without fetch_if_empty locks the target while its source link
|
|
158
|
-
// holds a value (desk read_only_because_of_fetch_from).
|
|
159
|
-
if (!readOnly && isFetchLocked(field, doc)) readOnly = true;
|
|
160
|
-
if (options.docstatus === 1 && !field.allow_on_submit) readOnly = true;
|
|
161
|
-
if (options.docstatus === 2) readOnly = true;
|
|
162
|
-
if (options.formReadOnly) readOnly = true;
|
|
163
|
-
|
|
164
|
-
return {
|
|
165
|
-
type: field.fieldtype,
|
|
166
|
-
name: field.fieldname,
|
|
167
|
-
label: field.label,
|
|
168
|
-
options: field.options,
|
|
169
|
-
description: field.description,
|
|
170
|
-
required,
|
|
171
|
-
readOnly,
|
|
172
|
-
precision:
|
|
173
|
-
field.precision !== undefined && field.precision !== null && field.precision !== ""
|
|
174
|
-
? Number(field.precision)
|
|
175
|
-
: undefined,
|
|
176
|
-
maxLength:
|
|
177
|
-
field.length !== undefined && field.length !== null && Number(field.length) > 0
|
|
178
|
-
? Number(field.length)
|
|
179
|
-
: undefined,
|
|
180
|
-
// depends_on intentionally NOT forwarded — visibility resolved here.
|
|
181
|
-
fieldtype: field.fieldtype,
|
|
182
|
-
fieldname: field.fieldname,
|
|
183
|
-
in_list_view: field.in_list_view,
|
|
184
|
-
in_standard_filter: field.in_standard_filter,
|
|
185
|
-
};
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Desk's refresh_section_collapse (layout.js:463-483): a collapsible section
|
|
190
|
-
* starts collapsed unless its `collapsible_depends_on` evaluates truthy, and
|
|
191
|
-
* a section with a missing mandatory value is forced open. Recomputed per
|
|
192
|
-
* doc change — SchemaForm treats it as the live default while manual toggles
|
|
193
|
-
* survive between recomputes.
|
|
194
|
-
*/
|
|
195
|
-
function resolveSectionCollapsed(
|
|
196
|
-
breakField: DocFieldMeta | undefined,
|
|
197
|
-
sectionFields: DocFieldMeta[],
|
|
198
|
-
doc: Record<string, unknown>,
|
|
199
|
-
): boolean | undefined {
|
|
200
|
-
if (!breakField?.collapsible) return undefined;
|
|
201
|
-
let collapsed = true;
|
|
202
|
-
if (breakField.collapsible_depends_on) {
|
|
203
|
-
// Unparseable expression → expanded (never hide content silently).
|
|
204
|
-
collapsed = !evaluateDependsOn(breakField.collapsible_depends_on, doc, true);
|
|
205
|
-
}
|
|
206
|
-
if (collapsed && sectionHasMissingMandatory(sectionFields, doc)) collapsed = false;
|
|
207
|
-
return collapsed;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/** Desk section.has_missing_mandatory: `reqd && value == null` (section.js:146-156). */
|
|
211
|
-
function sectionHasMissingMandatory(fields: DocFieldMeta[], doc: Record<string, unknown>): boolean {
|
|
212
|
-
return fields.some((field) => !!field.reqd && doc[field.fieldname] == null);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Build the desk tab list for the current doc state. Recomputed whenever
|
|
217
|
-
* the doc changes so depends_on chains re-resolve; the work is O(fields).
|
|
218
|
-
*/
|
|
219
|
-
export function buildFormTabs(options: BuildTabsOptions): FormTab[] {
|
|
220
|
-
const { fields, doc, detailsLabel, permLevels } = options;
|
|
221
|
-
const hiddenFieldSet = new Set(options.hiddenFields ?? []);
|
|
222
|
-
const hiddenSectionSet = new Set(options.hiddenSections ?? []);
|
|
223
|
-
const sectionHidden = (breakField: DocFieldMeta | undefined, label?: string): boolean => {
|
|
224
|
-
if (hiddenSectionSet.size === 0) return false;
|
|
225
|
-
if (breakField && hiddenSectionSet.has(breakField.fieldname)) return true;
|
|
226
|
-
const resolvedLabel = breakField?.label ?? label;
|
|
227
|
-
return !!resolvedLabel && hiddenSectionSet.has(resolvedLabel);
|
|
228
|
-
};
|
|
229
|
-
const layoutTabs = splitIntoTabs(fields);
|
|
230
|
-
const tabs: FormTab[] = [];
|
|
231
|
-
|
|
232
|
-
for (const layoutTab of layoutTabs) {
|
|
233
|
-
// Tab Break fields support depends_on + permlevel gating too (tab.js:38-43).
|
|
234
|
-
const tabBreak = fields.find(
|
|
235
|
-
(field) => field.fieldtype === "Tab Break" && field.fieldname === layoutTab.key,
|
|
236
|
-
);
|
|
237
|
-
if (tabBreak && !isFieldVisible(tabBreak, doc, permLevels)) continue;
|
|
238
|
-
// Host hiddenSections also match tabs (fieldname or label).
|
|
239
|
-
if (sectionHidden(tabBreak, layoutTab.label)) continue;
|
|
240
|
-
|
|
241
|
-
const sections: FormSection[] = [];
|
|
242
|
-
const flatFields: FieldSchema[] = [];
|
|
243
|
-
|
|
244
|
-
for (const section of layoutTab.sections) {
|
|
245
|
-
// Section Breaks are not permlevel-gated in desk (sections aren't
|
|
246
|
-
// controls; they only auto-hide when all their fields hide) — so the
|
|
247
|
-
// permlevel matrix is deliberately not passed here.
|
|
248
|
-
if (section.breakField && !isFieldVisible(section.breakField, doc)) continue;
|
|
249
|
-
if (sectionHidden(section.breakField)) continue;
|
|
250
|
-
|
|
251
|
-
const columns = section.columns
|
|
252
|
-
.map((column) => ({
|
|
253
|
-
fields: column.fields
|
|
254
|
-
.filter(
|
|
255
|
-
(field) =>
|
|
256
|
-
!hiddenFieldSet.has(field.fieldname) && isFieldVisible(field, doc, permLevels),
|
|
257
|
-
)
|
|
258
|
-
.map((field) => toFieldSchema(field, doc, options)),
|
|
259
|
-
}))
|
|
260
|
-
.filter((column) => column.fields.length > 0);
|
|
261
|
-
if (columns.length === 0) continue;
|
|
262
|
-
|
|
263
|
-
for (const column of columns) flatFields.push(...column.fields);
|
|
264
|
-
const sectionFields = section.columns.flatMap((column) => column.fields);
|
|
265
|
-
sections.push({
|
|
266
|
-
label: section.breakField?.label,
|
|
267
|
-
description: section.breakField?.description,
|
|
268
|
-
collapsible: !!section.breakField?.collapsible,
|
|
269
|
-
collapsed: resolveSectionCollapsed(section.breakField, sectionFields, doc),
|
|
270
|
-
hideBorder: !!section.breakField?.hide_border,
|
|
271
|
-
columns,
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
if (sections.length === 0) continue;
|
|
276
|
-
tabs.push({
|
|
277
|
-
key: layoutTab.key,
|
|
278
|
-
label: layoutTab.label || detailsLabel,
|
|
279
|
-
schema: { sections, fields: flatFields },
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
return tabs;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// ---------------------------------------------------------------------------
|
|
287
|
-
// Create-mode defaults
|
|
288
|
-
// ---------------------------------------------------------------------------
|
|
289
|
-
|
|
290
|
-
const LAYOUT_TYPES = new Set(["Section Break", "Column Break", "Tab Break", "Fold"]);
|
|
291
|
-
const NUMERIC_TYPES = new Set(["Int", "Float", "Currency", "Percent", "Check", "Rating"]);
|
|
292
|
-
|
|
293
|
-
const todayISO = () => formatCalendarDate(new Date());
|
|
294
|
-
const nowTime = () => formatCalendarDate(new Date(), "time");
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Seed a create-mode doc from meta field defaults — desk parity with
|
|
298
|
-
* create_new.js get_default_value / set_default_values:
|
|
299
|
-
*
|
|
300
|
-
* - `Today` → today's date; `now` → time (Time) / local datetime (else)
|
|
301
|
-
* - `__user` / `user` (Link/Data only, avoiding Select option collisions)
|
|
302
|
-
* → session user
|
|
303
|
-
* - Select fields with no default seed their first option
|
|
304
|
-
* (create_new.js:107-114)
|
|
305
|
-
* - `:fieldname` boot sysdefaults, `frappe.*`, `user_fullname` stay unset —
|
|
306
|
-
* server-resolved on insert (documented gap)
|
|
307
|
-
*/
|
|
308
|
-
export function buildCreateDefaults(
|
|
309
|
-
fields: DocFieldMeta[],
|
|
310
|
-
currentUser?: string,
|
|
311
|
-
): Record<string, unknown> {
|
|
312
|
-
const doc: Record<string, unknown> = {};
|
|
313
|
-
for (const field of fields) {
|
|
314
|
-
if (LAYOUT_TYPES.has(field.fieldtype)) continue;
|
|
315
|
-
const raw = field.default;
|
|
316
|
-
if (raw === undefined || raw === null || raw === "") {
|
|
317
|
-
// Desk seeds the first Select option when no default resolves.
|
|
318
|
-
if (
|
|
319
|
-
field.fieldtype === "Select" &&
|
|
320
|
-
typeof field.options === "string" &&
|
|
321
|
-
field.options &&
|
|
322
|
-
!["[Select]", "Loading..."].includes(field.options)
|
|
323
|
-
) {
|
|
324
|
-
doc[field.fieldname] = field.options.split("\n")[0];
|
|
325
|
-
}
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
if (raw === "Today") {
|
|
329
|
-
doc[field.fieldname] = todayISO();
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
if (raw.toLowerCase() === "now") {
|
|
333
|
-
doc[field.fieldname] = field.fieldtype === "Time" ? nowTime() : `${todayISO()} ${nowTime()}`;
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
if (
|
|
337
|
-
raw === "__user" ||
|
|
338
|
-
(raw.toLowerCase() === "user" && (field.fieldtype === "Link" || field.fieldtype === "Data"))
|
|
339
|
-
) {
|
|
340
|
-
if (currentUser) doc[field.fieldname] = currentUser;
|
|
341
|
-
continue;
|
|
342
|
-
}
|
|
343
|
-
if (raw === "user_fullname") continue; // session fullname not mirrored client-side
|
|
344
|
-
if (raw.startsWith(":") || raw.startsWith("frappe.")) continue; // server-resolved
|
|
345
|
-
doc[field.fieldname] = NUMERIC_TYPES.has(field.fieldtype) ? Number(raw) || 0 : raw;
|
|
346
|
-
}
|
|
347
|
-
return doc;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Copyable field values for Duplicate / Amend: strips standard bookkeeping
|
|
352
|
-
* fields, `no_copy` fields, layout breaks, and empty values.
|
|
5
|
+
* The exported `FrappeForm` needed the same tab / section / depends_on /
|
|
6
|
+
* permlevel / fetch_from resolution the desk uses, and backoffice sits a
|
|
7
|
+
* tier ABOVE frappe-ui, so the engine could not be reached from there. It
|
|
8
|
+
* lives in frappe-ui now. This module re-exports it so the barrel and the
|
|
9
|
+
* `@multiplatform.one/backoffice/src/form/formLayout` deep import keep
|
|
10
|
+
* resolving unchanged; the specs moved with the implementation.
|
|
353
11
|
*/
|
|
354
|
-
export function buildCopyValues(
|
|
355
|
-
fields: DocFieldMeta[],
|
|
356
|
-
doc: Record<string, unknown>,
|
|
357
|
-
): Record<string, unknown> {
|
|
358
|
-
const copy: Record<string, unknown> = {};
|
|
359
|
-
for (const field of fields) {
|
|
360
|
-
if (LAYOUT_TYPES.has(field.fieldtype)) continue;
|
|
361
|
-
if (field.no_copy) continue;
|
|
362
|
-
if (field.fieldtype === "Attach" || field.fieldtype === "Attach Image") continue;
|
|
363
|
-
const value = doc[field.fieldname];
|
|
364
|
-
if (value === undefined || value === null || value === "") continue;
|
|
365
|
-
if (field.fieldtype === "Table" || field.fieldtype === "Table MultiSelect") {
|
|
366
|
-
if (Array.isArray(value)) {
|
|
367
|
-
copy[field.fieldname] = value.map((row) => {
|
|
368
|
-
const {
|
|
369
|
-
name: _name,
|
|
370
|
-
parent: _parent,
|
|
371
|
-
parentfield: _parentfield,
|
|
372
|
-
parenttype: _parenttype,
|
|
373
|
-
creation: _creation,
|
|
374
|
-
modified: _modified,
|
|
375
|
-
...rest
|
|
376
|
-
} = (row ?? {}) as Record<string, unknown>;
|
|
377
|
-
return rest;
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
continue;
|
|
381
|
-
}
|
|
382
|
-
copy[field.fieldname] = value;
|
|
383
|
-
}
|
|
384
|
-
return copy;
|
|
385
|
-
}
|
|
386
12
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
13
|
+
export {
|
|
14
|
+
buildCopyValues,
|
|
15
|
+
buildCreateDefaults,
|
|
16
|
+
buildFormTabs,
|
|
17
|
+
isPromptNamed,
|
|
18
|
+
} from "@multiplatform.one/frappe-ui";
|
|
19
|
+
export type { BuildTabsOptions, FormTab } from "@multiplatform.one/frappe-ui";
|