@multiplatform.one/frappe-ui 7.10.0 → 7.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cjs/FrappeDashboard.cjs +8 -10
- package/dist/cjs/FrappeDashboard.native.js +8 -14
- package/dist/cjs/FrappeDashboard.native.js.map +1 -1
- package/dist/cjs/FrappeForm.cjs +465 -175
- package/dist/cjs/FrappeForm.native.js +611 -207
- package/dist/cjs/FrappeForm.native.js.map +1 -1
- package/dist/cjs/FrappeFormConnections.cjs +125 -0
- package/dist/cjs/FrappeFormConnections.native.js +149 -0
- package/dist/cjs/FrappeFormConnections.native.js.map +1 -0
- package/dist/cjs/FrappeImageView.cjs +7 -9
- package/dist/cjs/FrappeImageView.native.js +7 -13
- package/dist/cjs/FrappeImageView.native.js.map +1 -1
- package/dist/cjs/FrappeList.cjs +29 -4
- package/dist/cjs/FrappeList.native.js +37 -5
- package/dist/cjs/FrappeList.native.js.map +1 -1
- package/dist/cjs/FrappeListView.cjs +102 -29
- package/dist/cjs/FrappeListView.native.js +109 -29
- package/dist/cjs/FrappeListView.native.js.map +1 -1
- package/dist/cjs/FrappeProvider.cjs +7 -2
- package/dist/cjs/FrappeProvider.native.js +7 -2
- package/dist/cjs/FrappeProvider.native.js.map +1 -1
- package/dist/cjs/FrappeReportBuilder.cjs +10 -11
- package/dist/cjs/FrappeReportBuilder.native.js +10 -16
- package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
- package/dist/cjs/FrappeRowsReader.cjs +49 -0
- package/dist/cjs/FrappeRowsReader.native.js +53 -0
- package/dist/cjs/FrappeRowsReader.native.js.map +1 -0
- package/dist/cjs/FrappeTable.cjs +18 -6
- package/dist/cjs/FrappeTable.native.js +24 -6
- package/dist/cjs/FrappeTable.native.js.map +1 -1
- package/dist/cjs/fieldRegistry.cjs +36 -11
- package/dist/cjs/fieldRegistry.native.js +59 -11
- package/dist/cjs/fieldRegistry.native.js.map +1 -1
- package/dist/cjs/fields/Date/index.native.js +5 -2
- package/dist/cjs/fields/Date/index.native.js.map +1 -1
- package/dist/cjs/fields/Date/sheetKeyboard.cjs +2 -2
- package/dist/cjs/fields/Date/sheetKeyboard.native.js +2 -2
- package/dist/cjs/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/cjs/fields/DateRange/index.cjs +2 -1
- package/dist/cjs/fields/DateRange/index.native.js +4 -1
- package/dist/cjs/fields/DateRange/index.native.js.map +1 -1
- package/dist/cjs/formEngine/index.cjs +4 -2
- package/dist/cjs/formEngine/index.native.js +3 -1
- package/dist/cjs/formEngine/index.native.js.map +1 -1
- package/dist/cjs/formEngine/useSessionRoles.cjs +77 -0
- package/dist/cjs/formEngine/useSessionRoles.native.js +84 -0
- package/dist/cjs/formEngine/useSessionRoles.native.js.map +1 -0
- package/dist/cjs/frappeConnections.cjs +41 -0
- package/dist/cjs/frappeConnections.native.js +50 -0
- package/dist/cjs/frappeConnections.native.js.map +1 -0
- package/dist/cjs/frappeNavigation.cjs +107 -0
- package/dist/cjs/frappeNavigation.native.js +112 -0
- package/dist/cjs/frappeNavigation.native.js.map +1 -0
- package/dist/cjs/index.cjs +18 -1
- package/dist/cjs/index.native.js +18 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/schemaForm/index.cjs +4 -1
- package/dist/cjs/schemaForm/index.native.js +4 -1
- package/dist/cjs/schemaForm/index.native.js.map +1 -1
- package/dist/cjs/useConnectionFilters.cjs +146 -0
- package/dist/cjs/useConnectionFilters.native.js +213 -0
- package/dist/cjs/useConnectionFilters.native.js.map +1 -0
- package/dist/cjs/useFrappePagination.cjs +37 -18
- package/dist/cjs/useFrappePagination.native.js +59 -23
- package/dist/cjs/useFrappePagination.native.js.map +1 -1
- package/dist/cjs/useFrappeRows.native.js.map +1 -1
- package/dist/esm/FrappeDashboard.mjs +9 -11
- package/dist/esm/FrappeDashboard.mjs.map +1 -1
- package/dist/esm/FrappeDashboard.native.js +9 -15
- package/dist/esm/FrappeDashboard.native.js.map +1 -1
- package/dist/esm/FrappeForm.mjs +471 -181
- package/dist/esm/FrappeForm.mjs.map +1 -1
- package/dist/esm/FrappeForm.native.js +599 -195
- package/dist/esm/FrappeForm.native.js.map +1 -1
- package/dist/esm/FrappeFormConnections.mjs +99 -0
- package/dist/esm/FrappeFormConnections.mjs.map +1 -0
- package/dist/esm/FrappeFormConnections.native.js +120 -0
- package/dist/esm/FrappeFormConnections.native.js.map +1 -0
- package/dist/esm/FrappeImageView.mjs +8 -10
- package/dist/esm/FrappeImageView.mjs.map +1 -1
- package/dist/esm/FrappeImageView.native.js +8 -14
- package/dist/esm/FrappeImageView.native.js.map +1 -1
- package/dist/esm/FrappeList.mjs +31 -6
- package/dist/esm/FrappeList.mjs.map +1 -1
- package/dist/esm/FrappeList.native.js +39 -7
- package/dist/esm/FrappeList.native.js.map +1 -1
- package/dist/esm/FrappeListView.mjs +103 -30
- package/dist/esm/FrappeListView.mjs.map +1 -1
- package/dist/esm/FrappeListView.native.js +110 -30
- package/dist/esm/FrappeListView.native.js.map +1 -1
- package/dist/esm/FrappeProvider.mjs +7 -2
- package/dist/esm/FrappeProvider.mjs.map +1 -1
- package/dist/esm/FrappeProvider.native.js +7 -2
- package/dist/esm/FrappeProvider.native.js.map +1 -1
- package/dist/esm/FrappeReportBuilder.mjs +11 -12
- package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
- package/dist/esm/FrappeReportBuilder.native.js +11 -17
- package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
- package/dist/esm/FrappeRowsReader.mjs +24 -0
- package/dist/esm/FrappeRowsReader.mjs.map +1 -0
- package/dist/esm/FrappeRowsReader.native.js +25 -0
- package/dist/esm/FrappeRowsReader.native.js.map +1 -0
- package/dist/esm/FrappeTable.mjs +18 -6
- package/dist/esm/FrappeTable.mjs.map +1 -1
- package/dist/esm/FrappeTable.native.js +24 -6
- package/dist/esm/FrappeTable.native.js.map +1 -1
- package/dist/esm/fieldRegistry.mjs +35 -12
- package/dist/esm/fieldRegistry.mjs.map +1 -1
- package/dist/esm/fieldRegistry.native.js +58 -12
- package/dist/esm/fieldRegistry.native.js.map +1 -1
- package/dist/esm/fields/Date/index.native.js +6 -3
- package/dist/esm/fields/Date/index.native.js.map +1 -1
- package/dist/esm/fields/Date/sheetKeyboard.mjs +2 -2
- package/dist/esm/fields/Date/sheetKeyboard.mjs.map +1 -1
- package/dist/esm/fields/Date/sheetKeyboard.native.js +2 -2
- package/dist/esm/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/esm/fields/DateRange/index.mjs +2 -1
- package/dist/esm/fields/DateRange/index.mjs.map +1 -1
- package/dist/esm/fields/DateRange/index.native.js +4 -1
- package/dist/esm/fields/DateRange/index.native.js.map +1 -1
- package/dist/esm/formEngine/index.mjs +2 -1
- package/dist/esm/formEngine/index.mjs.map +1 -1
- package/dist/esm/formEngine/index.native.js +2 -1
- package/dist/esm/formEngine/index.native.js.map +1 -1
- package/dist/esm/formEngine/useSessionRoles.mjs +52 -0
- package/dist/esm/formEngine/useSessionRoles.mjs.map +1 -0
- package/dist/esm/formEngine/useSessionRoles.native.js +56 -0
- package/dist/esm/formEngine/useSessionRoles.native.js.map +1 -0
- package/dist/esm/frappeConnections.mjs +15 -0
- package/dist/esm/frappeConnections.mjs.map +1 -0
- package/dist/esm/frappeConnections.native.js +21 -0
- package/dist/esm/frappeConnections.native.js.map +1 -0
- package/dist/esm/frappeNavigation.mjs +78 -0
- package/dist/esm/frappeNavigation.mjs.map +1 -0
- package/dist/esm/frappeNavigation.native.js +80 -0
- package/dist/esm/frappeNavigation.native.js.map +1 -0
- package/dist/esm/index.mjs +7 -3
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +7 -3
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/schemaForm/index.mjs +4 -1
- package/dist/esm/schemaForm/index.mjs.map +1 -1
- package/dist/esm/schemaForm/index.native.js +4 -1
- package/dist/esm/schemaForm/index.native.js.map +1 -1
- package/dist/esm/useConnectionFilters.mjs +121 -0
- package/dist/esm/useConnectionFilters.mjs.map +1 -0
- package/dist/esm/useConnectionFilters.native.js +185 -0
- package/dist/esm/useConnectionFilters.native.js.map +1 -0
- package/dist/esm/useFrappePagination.mjs +38 -19
- package/dist/esm/useFrappePagination.mjs.map +1 -1
- package/dist/esm/useFrappePagination.native.js +60 -24
- package/dist/esm/useFrappePagination.native.js.map +1 -1
- package/dist/esm/useFrappeRows.mjs.map +1 -1
- package/dist/esm/useFrappeRows.native.js.map +1 -1
- package/dist/jsx/FrappeDashboard.mjs +9 -11
- package/dist/jsx/FrappeDashboard.mjs.map +1 -1
- package/dist/jsx/FrappeDashboard.native.js +8 -14
- package/dist/jsx/FrappeDashboard.native.js.map +1 -1
- package/dist/jsx/FrappeForm.mjs +471 -181
- package/dist/jsx/FrappeForm.mjs.map +1 -1
- package/dist/jsx/FrappeForm.native.js +611 -207
- package/dist/jsx/FrappeForm.native.js.map +1 -1
- package/dist/jsx/FrappeFormConnections.mjs +99 -0
- package/dist/jsx/FrappeFormConnections.mjs.map +1 -0
- package/dist/jsx/FrappeFormConnections.native.js +149 -0
- package/dist/jsx/FrappeFormConnections.native.js.map +1 -0
- package/dist/jsx/FrappeImageView.mjs +8 -10
- package/dist/jsx/FrappeImageView.mjs.map +1 -1
- package/dist/jsx/FrappeImageView.native.js +7 -13
- package/dist/jsx/FrappeImageView.native.js.map +1 -1
- package/dist/jsx/FrappeList.mjs +31 -6
- package/dist/jsx/FrappeList.mjs.map +1 -1
- package/dist/jsx/FrappeList.native.js +37 -5
- package/dist/jsx/FrappeList.native.js.map +1 -1
- package/dist/jsx/FrappeListView.mjs +103 -30
- package/dist/jsx/FrappeListView.mjs.map +1 -1
- package/dist/jsx/FrappeListView.native.js +109 -29
- package/dist/jsx/FrappeListView.native.js.map +1 -1
- package/dist/jsx/FrappeProvider.mjs +7 -2
- package/dist/jsx/FrappeProvider.mjs.map +1 -1
- package/dist/jsx/FrappeProvider.native.js +7 -2
- package/dist/jsx/FrappeProvider.native.js.map +1 -1
- package/dist/jsx/FrappeReportBuilder.mjs +11 -12
- package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
- package/dist/jsx/FrappeReportBuilder.native.js +10 -16
- package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
- package/dist/jsx/FrappeRowsReader.mjs +24 -0
- package/dist/jsx/FrappeRowsReader.mjs.map +1 -0
- package/dist/jsx/FrappeRowsReader.native.js +53 -0
- package/dist/jsx/FrappeRowsReader.native.js.map +1 -0
- package/dist/jsx/FrappeTable.mjs +18 -6
- package/dist/jsx/FrappeTable.mjs.map +1 -1
- package/dist/jsx/FrappeTable.native.js +24 -6
- package/dist/jsx/FrappeTable.native.js.map +1 -1
- package/dist/jsx/fieldRegistry.mjs +35 -12
- package/dist/jsx/fieldRegistry.mjs.map +1 -1
- package/dist/jsx/fieldRegistry.native.js +59 -11
- package/dist/jsx/fieldRegistry.native.js.map +1 -1
- package/dist/jsx/fields/Date/index.native.js +5 -2
- package/dist/jsx/fields/Date/index.native.js.map +1 -1
- package/dist/jsx/fields/Date/sheetKeyboard.mjs +2 -2
- package/dist/jsx/fields/Date/sheetKeyboard.mjs.map +1 -1
- package/dist/jsx/fields/Date/sheetKeyboard.native.js +2 -2
- package/dist/jsx/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/jsx/fields/DateRange/index.mjs +2 -1
- package/dist/jsx/fields/DateRange/index.mjs.map +1 -1
- package/dist/jsx/fields/DateRange/index.native.js +4 -1
- package/dist/jsx/fields/DateRange/index.native.js.map +1 -1
- package/dist/jsx/formEngine/index.mjs +2 -1
- package/dist/jsx/formEngine/index.mjs.map +1 -1
- package/dist/jsx/formEngine/index.native.js +3 -1
- package/dist/jsx/formEngine/index.native.js.map +1 -1
- package/dist/jsx/formEngine/useSessionRoles.mjs +52 -0
- package/dist/jsx/formEngine/useSessionRoles.mjs.map +1 -0
- package/dist/jsx/formEngine/useSessionRoles.native.js +84 -0
- package/dist/jsx/formEngine/useSessionRoles.native.js.map +1 -0
- package/dist/jsx/frappeConnections.mjs +15 -0
- package/dist/jsx/frappeConnections.mjs.map +1 -0
- package/dist/jsx/frappeConnections.native.js +50 -0
- package/dist/jsx/frappeConnections.native.js.map +1 -0
- package/dist/jsx/frappeNavigation.mjs +78 -0
- package/dist/jsx/frappeNavigation.mjs.map +1 -0
- package/dist/jsx/frappeNavigation.native.js +112 -0
- package/dist/jsx/frappeNavigation.native.js.map +1 -0
- package/dist/jsx/index.js +7 -3
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +7 -3
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +18 -1
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/schemaForm/index.mjs +4 -1
- package/dist/jsx/schemaForm/index.mjs.map +1 -1
- package/dist/jsx/schemaForm/index.native.js +4 -1
- package/dist/jsx/schemaForm/index.native.js.map +1 -1
- package/dist/jsx/useConnectionFilters.mjs +121 -0
- package/dist/jsx/useConnectionFilters.mjs.map +1 -0
- package/dist/jsx/useConnectionFilters.native.js +213 -0
- package/dist/jsx/useConnectionFilters.native.js.map +1 -0
- package/dist/jsx/useFrappePagination.mjs +38 -19
- package/dist/jsx/useFrappePagination.mjs.map +1 -1
- package/dist/jsx/useFrappePagination.native.js +59 -23
- package/dist/jsx/useFrappePagination.native.js.map +1 -1
- package/dist/jsx/useFrappeRows.mjs.map +1 -1
- package/dist/jsx/useFrappeRows.native.js.map +1 -1
- package/package.json +26 -22
- package/src/FileBrowser/AttachLibrary.stories.tsx +23 -0
- package/src/FrappeDashboard.tsx +11 -16
- package/src/FrappeForm.connections.spec.tsx +280 -0
- package/src/FrappeForm.connections.stories.tsx +93 -0
- package/src/FrappeForm.deskSemantics.spec.tsx +284 -0
- package/src/FrappeForm.tsx +560 -145
- package/src/FrappeFormConnections.tsx +148 -0
- package/src/FrappeGuestMeta.spec.tsx +143 -0
- package/src/FrappeImageView.tsx +8 -12
- package/src/FrappeList.tsx +71 -15
- package/src/FrappeListView.cards.spec.tsx +175 -0
- package/src/FrappeListView.cards.stories.tsx +131 -0
- package/src/FrappeListView.connections.spec.tsx +192 -0
- package/src/FrappeListView.connections.stories.tsx +99 -0
- package/src/FrappeListView.seed.spec.tsx +228 -0
- package/src/FrappeListView.tsx +177 -31
- package/src/FrappeProvider.catchUp.spec.tsx +502 -0
- package/src/FrappeProvider.tsx +15 -3
- package/src/FrappeReportBuilder.tsx +11 -19
- package/src/FrappeRowsReader.tsx +38 -0
- package/src/FrappeTable.optionalProps.spec.tsx +249 -0
- package/src/FrappeTable.spec.tsx +32 -42
- package/src/FrappeTable.stories.spec.tsx +55 -0
- package/src/FrappeTable.stories.tsx +28 -37
- package/src/FrappeTable.tsx +108 -45
- package/src/childTableDependsOn.spec.tsx +85 -0
- package/src/desk/DeskFormSidebar.spec.tsx +20 -0
- package/src/desk/DeskFormSidebar.stories.tsx +42 -0
- package/src/fieldRegistry.spec.tsx +27 -64
- package/src/fieldRegistry.ts +71 -14
- package/src/fields/Date/index.native.tsx +4 -2
- package/src/fields/Date/sheetKeyboard.spec.ts +14 -5
- package/src/fields/Date/sheetKeyboard.ts +12 -4
- package/src/fields/DateRange/DateRange.spec.tsx +67 -0
- package/src/fields/DateRange/index.tsx +5 -1
- package/src/fields/LinkTree.spec.tsx +8 -0
- package/src/fields/LinkTree.stories.tsx +28 -5
- package/src/fields/Select/Select.hydration.spec.tsx +177 -0
- package/src/formEngine/doctypeMeta.ts +15 -114
- package/src/formEngine/index.ts +2 -0
- package/src/formEngine/seam.spec.ts +23 -4
- package/src/formEngine/useSessionRoles.ts +73 -0
- package/src/frappeConnections.ts +50 -0
- package/src/frappeNavigation.tsx +112 -0
- package/src/frappeRoutes.spec.tsx +335 -0
- package/src/index.ts +28 -1
- package/src/schemaForm/index.tsx +1 -0
- package/src/useConnectionFilters.tsx +157 -0
- package/src/useFrappePagination.ts +70 -26
- package/src/useFrappeRows.sharedPath.spec.tsx +206 -0
- package/src/useFrappeRows.ts +5 -4
- package/types/FrappeDashboard.d.ts +3 -4
- package/types/FrappeDashboard.d.ts.map +1 -1
- package/types/FrappeForm.d.ts +57 -5
- package/types/FrappeForm.d.ts.map +1 -1
- package/types/FrappeFormConnections.d.ts +18 -0
- package/types/FrappeFormConnections.d.ts.map +1 -0
- package/types/FrappeImageView.d.ts +2 -3
- package/types/FrappeImageView.d.ts.map +1 -1
- package/types/FrappeList.d.ts +20 -2
- package/types/FrappeList.d.ts.map +1 -1
- package/types/FrappeListView.d.ts +53 -3
- package/types/FrappeListView.d.ts.map +1 -1
- package/types/FrappeProvider.d.ts +10 -3
- package/types/FrappeProvider.d.ts.map +1 -1
- package/types/FrappeReportBuilder.d.ts.map +1 -1
- package/types/FrappeRowsReader.d.ts +26 -0
- package/types/FrappeRowsReader.d.ts.map +1 -0
- package/types/FrappeTable.d.ts +39 -8
- package/types/FrappeTable.d.ts.map +1 -1
- package/types/fieldRegistry.d.ts +17 -3
- package/types/fieldRegistry.d.ts.map +1 -1
- package/types/fields/Date/index.native.d.ts.map +1 -1
- package/types/fields/Date/sheetKeyboard.d.ts +4 -3
- package/types/fields/Date/sheetKeyboard.d.ts.map +1 -1
- package/types/fields/DateRange/index.d.ts.map +1 -1
- package/types/formEngine/doctypeMeta.d.ts +10 -114
- package/types/formEngine/doctypeMeta.d.ts.map +1 -1
- package/types/formEngine/index.d.ts +1 -0
- package/types/formEngine/index.d.ts.map +1 -1
- package/types/formEngine/useSessionRoles.d.ts +19 -0
- package/types/formEngine/useSessionRoles.d.ts.map +1 -0
- package/types/frappeConnections.d.ts +33 -0
- package/types/frappeConnections.d.ts.map +1 -0
- package/types/frappeNavigation.d.ts +49 -0
- package/types/frappeNavigation.d.ts.map +1 -0
- package/types/index.d.ts +7 -3
- package/types/index.d.ts.map +1 -1
- package/types/schemaForm/index.d.ts.map +1 -1
- package/types/useConnectionFilters.d.ts +34 -0
- package/types/useConnectionFilters.d.ts.map +1 -0
- package/types/useFrappePagination.d.ts +18 -5
- package/types/useFrappePagination.d.ts.map +1 -1
- package/types/useFrappeRows.d.ts +5 -4
- package/types/useFrappeRows.d.ts.map +1 -1
- package/src/FileBrowser/AttachLibrary.spec.tsx +0 -74
package/dist/cjs/FrappeForm.cjs
CHANGED
|
@@ -43,46 +43,55 @@ var import_FrappeProvider = require("./FrappeProvider.cjs");
|
|
|
43
43
|
var import_FrappeReconnectIndicator = require("./FrappeReconnectIndicator.cjs");
|
|
44
44
|
var import_timeline = require("./components/timeline.cjs");
|
|
45
45
|
var import_desktop = require("@multiplatform.one/desktop");
|
|
46
|
+
var import_fetchFrom = require("./formEngine/fetchFrom.cjs");
|
|
47
|
+
var import_fieldPermissions = require("./formEngine/fieldPermissions.cjs");
|
|
48
|
+
var import_formActions = require("./formEngine/formActions.cjs");
|
|
49
|
+
var import_formLayout = require("./formEngine/formLayout.cjs");
|
|
50
|
+
var import_useSessionRoles = require("./formEngine/useSessionRoles.cjs");
|
|
51
|
+
var import_frappeConnections = require("./frappeConnections.cjs");
|
|
52
|
+
var import_FrappeFormConnections = require("./FrappeFormConnections.cjs");
|
|
53
|
+
var import_FrappeRowsReader = require("./FrappeRowsReader.cjs");
|
|
54
|
+
var import_frappeNavigation = require("./frappeNavigation.cjs");
|
|
46
55
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
47
|
-
|
|
56
|
+
var import_react3 = require("react");
|
|
48
57
|
function isEmptyFieldValue(value) {
|
|
49
58
|
if (value === void 0 || value === null) return true;
|
|
50
59
|
if (typeof value === "string" && value.trim() === "") return true;
|
|
51
60
|
if (Array.isArray(value) && value.length === 0) return true;
|
|
52
61
|
return false;
|
|
53
62
|
}
|
|
54
|
-
function
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
function sectionsToLayoutFields(sections) {
|
|
64
|
+
const fields = [];
|
|
65
|
+
sections.forEach((section, sectionIndex) => {
|
|
66
|
+
fields.push({
|
|
67
|
+
fieldname: `__section_${sectionIndex}`,
|
|
68
|
+
fieldtype: section.tab ? "Tab Break" : "Section Break",
|
|
69
|
+
label: section.label,
|
|
70
|
+
collapsible: section.collapsible ? 1 : 0
|
|
71
|
+
});
|
|
72
|
+
section.columns.forEach((column, columnIndex) => {
|
|
73
|
+
if (columnIndex > 0) {
|
|
74
|
+
fields.push({
|
|
75
|
+
fieldname: `__column_${sectionIndex}_${columnIndex}`,
|
|
76
|
+
fieldtype: "Column Break"
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
fields.push(...column.fields);
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
return fields;
|
|
71
83
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
}))
|
|
84
|
+
const documentBookkeeping = /* @__PURE__ */new Set(["name", "owner", "creation", "modified", "modified_by", "docstatus", "idx", "doctype", "_user_tags", "_comments", "_assign", "_liked_by", "_seen"]);
|
|
85
|
+
function fieldsFromDocument(doc) {
|
|
86
|
+
return Object.entries(doc).filter(([key, value]) => !key.startsWith("$") && !documentBookkeeping.has(key) && (value === null || typeof value === "string" || typeof value === "number")).map(([key, value]) => ({
|
|
87
|
+
name: key,
|
|
88
|
+
label: key.replace(/_/g, " ").replace(/(^|\s)\S/g, c => c.toUpperCase()),
|
|
89
|
+
type: typeof value === "number" ? Number.isInteger(value) ? "Int" : "Float" : "Data",
|
|
90
|
+
readOnly: true
|
|
80
91
|
}));
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
fields: allFields
|
|
85
|
-
};
|
|
92
|
+
}
|
|
93
|
+
function hasRestrictedPermLevel(meta) {
|
|
94
|
+
return !!meta?.fields.some(field => Number(field.permlevel ?? 0) > 0);
|
|
86
95
|
}
|
|
87
96
|
function resolveFileUrl(value, baseURL) {
|
|
88
97
|
if (!value || typeof value !== "string") return void 0;
|
|
@@ -148,7 +157,72 @@ function mapDocToSidebarMetadata(doc, t) {
|
|
|
148
157
|
}
|
|
149
158
|
return metadata;
|
|
150
159
|
}
|
|
151
|
-
function FrappeForm({
|
|
160
|
+
function FrappeForm(props) {
|
|
161
|
+
const {
|
|
162
|
+
route,
|
|
163
|
+
...formProps
|
|
164
|
+
} = props;
|
|
165
|
+
if (route === void 0) return /* @__PURE__ */(0, import_jsx_runtime.jsx)(FrappeFormBody, {
|
|
166
|
+
...formProps
|
|
167
|
+
});
|
|
168
|
+
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(FrappeFormRoute, {
|
|
169
|
+
...formProps,
|
|
170
|
+
route
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function FrappeFormRoute({
|
|
174
|
+
route,
|
|
175
|
+
name: nameProp,
|
|
176
|
+
onSave,
|
|
177
|
+
onCancel,
|
|
178
|
+
onDelete,
|
|
179
|
+
onEdit,
|
|
180
|
+
...props
|
|
181
|
+
}) {
|
|
182
|
+
const router = (0, import_frappeNavigation.useFrappeRouter)();
|
|
183
|
+
const fromPath = router ? (0, import_frappeNavigation.frappeRouteTarget)(route, router.pathname) : void 0;
|
|
184
|
+
const target = nameProp ? {
|
|
185
|
+
mode: fromPath?.mode === "view" ? "view" : "edit",
|
|
186
|
+
name: nameProp
|
|
187
|
+
} : fromPath?.mode === "view" || fromPath?.mode === "edit" ? fromPath : {
|
|
188
|
+
mode: "create"
|
|
189
|
+
};
|
|
190
|
+
const go = next => router?.navigate((0, import_frappeNavigation.frappeRouteHref)(route, next));
|
|
191
|
+
const name = target.mode === "view" || target.mode === "edit" ? target.name : void 0;
|
|
192
|
+
return /* @__PURE__ */(0, import_react3.createElement)(FrappeFormBody, {
|
|
193
|
+
...props,
|
|
194
|
+
key: `${target.mode}:${name ?? ""}`,
|
|
195
|
+
name,
|
|
196
|
+
routePage: {
|
|
197
|
+
onBack: () => go({
|
|
198
|
+
mode: "list"
|
|
199
|
+
})
|
|
200
|
+
},
|
|
201
|
+
onEdit: target.mode === "view" ? onEdit ?? (() => go({
|
|
202
|
+
mode: "edit",
|
|
203
|
+
name: target.name
|
|
204
|
+
})) : void 0,
|
|
205
|
+
onSave: onSave ?? (doc => {
|
|
206
|
+
const saved = doc.name ?? name;
|
|
207
|
+
go(saved ? {
|
|
208
|
+
mode: "view",
|
|
209
|
+
name: saved
|
|
210
|
+
} : {
|
|
211
|
+
mode: "list"
|
|
212
|
+
});
|
|
213
|
+
}),
|
|
214
|
+
onCancel: onCancel ?? (() => go(name ? {
|
|
215
|
+
mode: "view",
|
|
216
|
+
name
|
|
217
|
+
} : {
|
|
218
|
+
mode: "list"
|
|
219
|
+
})),
|
|
220
|
+
onDelete: onDelete ?? (() => go({
|
|
221
|
+
mode: "list"
|
|
222
|
+
}))
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
function FrappeFormBody({
|
|
152
226
|
baseURL,
|
|
153
227
|
auth,
|
|
154
228
|
syncOptions,
|
|
@@ -161,14 +235,23 @@ function FrappeForm({
|
|
|
161
235
|
readOnlyFields,
|
|
162
236
|
sections,
|
|
163
237
|
order,
|
|
238
|
+
roles,
|
|
164
239
|
onSave,
|
|
165
240
|
onCancel,
|
|
166
241
|
onDelete,
|
|
242
|
+
onEdit,
|
|
167
243
|
showToolbar = true,
|
|
168
244
|
showSidebar = true,
|
|
169
245
|
showTimeline = true,
|
|
170
246
|
disabled = false,
|
|
171
|
-
sectionHeadingLevel
|
|
247
|
+
sectionHeadingLevel,
|
|
248
|
+
connections,
|
|
249
|
+
showConnections = true,
|
|
250
|
+
initialDoc,
|
|
251
|
+
loadingFallback,
|
|
252
|
+
notFoundFallback,
|
|
253
|
+
errorFallback,
|
|
254
|
+
routePage
|
|
172
255
|
}) {
|
|
173
256
|
const config = (0, import_FrappeProvider.useFrappeConfig)();
|
|
174
257
|
const {
|
|
@@ -177,12 +260,17 @@ function FrappeForm({
|
|
|
177
260
|
const {
|
|
178
261
|
t
|
|
179
262
|
} = (0, import_react_i18next.useTranslation)();
|
|
180
|
-
const
|
|
181
|
-
const
|
|
263
|
+
const seedDoc = name && initialDoc && initialDoc.name === name ? initialDoc : void 0;
|
|
264
|
+
const seedRef = (0, import_react2.useRef)(seedDoc);
|
|
265
|
+
seedRef.current = seedDoc;
|
|
266
|
+
const [localDoc, setLocalDoc] = (0, import_react2.useState)(() => seedDoc ?? {});
|
|
267
|
+
const [baselineDoc, setBaselineDoc] = (0, import_react2.useState)(() => seedDoc);
|
|
268
|
+
const [docError, setDocError] = (0, import_react2.useState)(null);
|
|
182
269
|
const [conflictFields, setConflictFields] = (0, import_react2.useState)([]);
|
|
183
270
|
const [wasDeleted, setWasDeleted] = (0, import_react2.useState)(false);
|
|
184
271
|
const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
|
|
185
272
|
const [errors, setErrors] = (0, import_react2.useState)({});
|
|
273
|
+
const [activeTab, setActiveTab] = (0, import_react2.useState)(void 0);
|
|
186
274
|
const everLoadedRef = (0, import_react2.useRef)(false);
|
|
187
275
|
const localDocRef = (0, import_react2.useRef)(localDoc);
|
|
188
276
|
localDocRef.current = localDoc;
|
|
@@ -209,16 +297,59 @@ function FrappeForm({
|
|
|
209
297
|
isLoading: isMetaLoading,
|
|
210
298
|
error: metaError
|
|
211
299
|
} = (0, import_frappe.useDocTypeMeta)(frappeConfig, doctype);
|
|
212
|
-
const
|
|
300
|
+
const sessionRoles = (0, import_useSessionRoles.useSessionRoles)(!roles && hasRestrictedPermLevel(meta) ? frappeConfig : void 0);
|
|
301
|
+
const effectiveRoles = roles ?? sessionRoles;
|
|
302
|
+
const permLevels = (0, import_react2.useMemo)(() => (0, import_fieldPermissions.buildPermLevelMatrix)(meta?.permissions, effectiveRoles), [meta?.permissions, effectiveRoles]);
|
|
303
|
+
const isCreate = !name;
|
|
304
|
+
const docstatus = Number(baselineDoc?.docstatus ?? 0);
|
|
305
|
+
const layoutFields = (0, import_react2.useMemo)(() => {
|
|
213
306
|
if (!meta) return void 0;
|
|
214
|
-
return
|
|
307
|
+
return sections ? sectionsToLayoutFields(sections) : meta.fields;
|
|
215
308
|
}, [meta, sections]);
|
|
216
|
-
const
|
|
309
|
+
const formTabs = (0, import_react2.useMemo)(() => {
|
|
310
|
+
if (!layoutFields) return void 0;
|
|
311
|
+
return (0, import_formLayout.buildFormTabs)({
|
|
312
|
+
fields: layoutFields,
|
|
313
|
+
doc: {
|
|
314
|
+
...localDoc,
|
|
315
|
+
__islocal: isCreate ? 1 : 0
|
|
316
|
+
},
|
|
317
|
+
docstatus,
|
|
318
|
+
formReadOnly: !!meta?.read_only,
|
|
319
|
+
isCreate,
|
|
320
|
+
detailsLabel: t("Details"),
|
|
321
|
+
permLevels,
|
|
322
|
+
hiddenFields: hideFields
|
|
323
|
+
});
|
|
324
|
+
}, [layoutFields, localDoc, docstatus, meta?.read_only, isCreate, permLevels, hideFields, t]);
|
|
325
|
+
const readsWithoutMeta = !children && !meta && Boolean(metaError) && Boolean(name);
|
|
326
|
+
const recordTabs = (0, import_react2.useMemo)(() => {
|
|
327
|
+
if (!readsWithoutMeta || !baselineDoc) return void 0;
|
|
328
|
+
const recordFields = fieldsFromDocument(baselineDoc);
|
|
329
|
+
return [{
|
|
330
|
+
key: "__details",
|
|
331
|
+
label: t("Details"),
|
|
332
|
+
schema: {
|
|
333
|
+
sections: [{
|
|
334
|
+
columns: [{
|
|
335
|
+
fields: recordFields
|
|
336
|
+
}]
|
|
337
|
+
}],
|
|
338
|
+
fields: recordFields
|
|
339
|
+
}
|
|
340
|
+
}];
|
|
341
|
+
}, [readsWithoutMeta, baselineDoc, t]);
|
|
342
|
+
const promptNamed = isCreate && !!meta && (0, import_formLayout.isPromptNamed)(meta.autoname, meta.naming_rule);
|
|
343
|
+
const fetchMap = (0, import_react2.useMemo)(() => meta ? (0, import_fetchFrom.buildFetchMap)(meta.fields) : void 0, [meta]);
|
|
344
|
+
const handleDocSyncError = (0, import_react2.useCallback)(err => {
|
|
345
|
+
setDocError(err instanceof Error ? err : new Error(String(err)));
|
|
346
|
+
}, []);
|
|
217
347
|
const docCollection = (0, import_frappe.useFrappeCollection)(name ? frappeConfig : void 0, doctype, {
|
|
218
348
|
fields,
|
|
219
349
|
filters: name ? {
|
|
220
350
|
name
|
|
221
|
-
} : void 0
|
|
351
|
+
} : void 0,
|
|
352
|
+
onSyncError: handleDocSyncError
|
|
222
353
|
});
|
|
223
354
|
const {
|
|
224
355
|
data: rawDocData,
|
|
@@ -279,8 +410,41 @@ function FrappeForm({
|
|
|
279
410
|
everLoadedRef.current = false;
|
|
280
411
|
setWasDeleted(false);
|
|
281
412
|
setConflictFields([]);
|
|
282
|
-
|
|
413
|
+
setDocError(null);
|
|
414
|
+
const seed = seedRef.current;
|
|
415
|
+
setBaselineDoc(seed);
|
|
416
|
+
if (seed) setLocalDoc(seed);
|
|
283
417
|
}, [doctype, name]);
|
|
418
|
+
const effectiveConnections = (0, import_react2.useMemo)(() => connections ?? (0, import_frappeConnections.connectionsFromMeta)(meta), [connections, meta]);
|
|
419
|
+
const readsConnections = Boolean(children) && Boolean(name) && effectiveConnections.length > 0;
|
|
420
|
+
const [connectionSnapshots, setConnectionSnapshots] = (0, import_react2.useState)({});
|
|
421
|
+
(0, import_react2.useEffect)(() => {
|
|
422
|
+
setConnectionSnapshots({});
|
|
423
|
+
}, [doctype, name]);
|
|
424
|
+
const connectionReads = (0, import_react2.useMemo)(() => readsConnections && name ? effectiveConnections.map(link => ({
|
|
425
|
+
link,
|
|
426
|
+
options: {
|
|
427
|
+
fields: (0, import_frappeConnections.connectionFields)(link),
|
|
428
|
+
filters: [[link.fieldname, "=", name]],
|
|
429
|
+
limit: link.limit ?? 0
|
|
430
|
+
},
|
|
431
|
+
onChange: snapshot => setConnectionSnapshots(prev => ({
|
|
432
|
+
...prev,
|
|
433
|
+
[link.doctype]: snapshot
|
|
434
|
+
}))
|
|
435
|
+
})) : [], [readsConnections, effectiveConnections, name]);
|
|
436
|
+
const connectionRows = (0, import_react2.useMemo)(() => {
|
|
437
|
+
const rows = {};
|
|
438
|
+
for (const {
|
|
439
|
+
link
|
|
440
|
+
} of connectionReads) {
|
|
441
|
+
rows[link.doctype] = connectionSnapshots[link.doctype]?.rows ?? [];
|
|
442
|
+
}
|
|
443
|
+
return rows;
|
|
444
|
+
}, [connectionReads, connectionSnapshots]);
|
|
445
|
+
const connectionsLoading = connectionReads.some(({
|
|
446
|
+
link
|
|
447
|
+
}) => connectionSnapshots[link.doctype]?.isLoading ?? true);
|
|
284
448
|
(0, import_frappe.useFrappeDoctypeEvents)(name ? frappeConfig : void 0, doctype, event => {
|
|
285
449
|
if (event.type !== "doc_deleted") return;
|
|
286
450
|
const payload = event.payload;
|
|
@@ -333,6 +497,32 @@ function FrappeForm({
|
|
|
333
497
|
return dirty;
|
|
334
498
|
}, [localDoc, baselineDoc]);
|
|
335
499
|
const hasUnsavedChanges = dirtyFieldNames.length > 0;
|
|
500
|
+
const runFetchFrom = (field, value) => {
|
|
501
|
+
const rules = fetchMap?.get(field);
|
|
502
|
+
if (!rules || rules.length === 0) return;
|
|
503
|
+
const applyPatch = fetched2 => {
|
|
504
|
+
setLocalDoc(prev => {
|
|
505
|
+
const current = prev;
|
|
506
|
+
if (current[field] !== value) return prev;
|
|
507
|
+
const patch = (0, import_fetchFrom.applyFetchedValues)(rules, fetched2, current);
|
|
508
|
+
return Object.keys(patch).length > 0 ? {
|
|
509
|
+
...current,
|
|
510
|
+
...patch
|
|
511
|
+
} : prev;
|
|
512
|
+
});
|
|
513
|
+
};
|
|
514
|
+
if (isEmptyFieldValue(value)) {
|
|
515
|
+
applyPatch({});
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
518
|
+
const linkField = meta?.fields.find(metaField => metaField.fieldname === field);
|
|
519
|
+
const targetDoctype = typeof linkField?.options === "string" ? linkField.options : "";
|
|
520
|
+
if (!targetDoctype) return;
|
|
521
|
+
const sources = Array.from(new Set(rules.map(rule => rule.source)));
|
|
522
|
+
const fixtures = frappeConfig.fixtures;
|
|
523
|
+
const fetched = fixtures ? fixtures.getDoc(targetDoctype, String(value), sources).then(doc => doc ?? {}) : (0, import_formActions.validateLink)((0, import_formActions.createHttpClient)(frappeConfig), targetDoctype, String(value), sources);
|
|
524
|
+
fetched.then(applyPatch).catch(() => void 0);
|
|
525
|
+
};
|
|
336
526
|
const setValue = (field, value) => {
|
|
337
527
|
setLocalDoc(prev => ({
|
|
338
528
|
...prev,
|
|
@@ -345,19 +535,23 @@ function FrappeForm({
|
|
|
345
535
|
delete newErrors[String(field)];
|
|
346
536
|
return newErrors;
|
|
347
537
|
});
|
|
538
|
+
runFetchFrom(String(field), value);
|
|
348
539
|
};
|
|
349
540
|
const validateRequiredFields = () => {
|
|
350
|
-
if (!
|
|
541
|
+
if (!formTabs) return {};
|
|
351
542
|
const validationErrors = {};
|
|
352
543
|
const doc = localDoc;
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
544
|
+
if (promptNamed && isEmptyFieldValue(doc.name)) {
|
|
545
|
+
validationErrors.name = t("Name is required");
|
|
546
|
+
}
|
|
547
|
+
for (const tab of formTabs) {
|
|
548
|
+
for (const field of tab.schema.fields) {
|
|
549
|
+
if (!field.required) continue;
|
|
550
|
+
if (isEmptyFieldValue(doc[field.name])) {
|
|
551
|
+
validationErrors[field.name] = t("{{label}} is required", {
|
|
552
|
+
label: field.label || field.name
|
|
553
|
+
});
|
|
554
|
+
}
|
|
361
555
|
}
|
|
362
556
|
}
|
|
363
557
|
return validationErrors;
|
|
@@ -387,13 +581,20 @@ function FrappeForm({
|
|
|
387
581
|
setConflictFields([]);
|
|
388
582
|
} else {
|
|
389
583
|
if (!collection) return;
|
|
584
|
+
const temporaryName = localDoc.name ?? `new-${Date.now()}`;
|
|
390
585
|
const docToInsert = {
|
|
391
586
|
...localDoc,
|
|
392
587
|
doctype,
|
|
393
|
-
name:
|
|
588
|
+
name: temporaryName
|
|
394
589
|
};
|
|
395
590
|
const tx = collection.insert(docToInsert);
|
|
396
591
|
await tx.isPersisted.promise;
|
|
592
|
+
const createdName = (0, import_frappe.getFrappeSyncModule)(frappeConfig)?.createdName(temporaryName) ?? temporaryName;
|
|
593
|
+
onSave?.({
|
|
594
|
+
...localDoc,
|
|
595
|
+
name: createdName
|
|
596
|
+
});
|
|
597
|
+
return;
|
|
397
598
|
}
|
|
398
599
|
onSave?.(localDoc);
|
|
399
600
|
} catch (err) {
|
|
@@ -456,17 +657,45 @@ function FrappeForm({
|
|
|
456
657
|
setIsSubmitting(false);
|
|
457
658
|
}
|
|
458
659
|
};
|
|
660
|
+
const titleField = meta?.title_field;
|
|
661
|
+
const titleValue = titleField ? localDoc[titleField] : void 0;
|
|
662
|
+
const pageTitle = isCreate ? t("New {{doctype}}", {
|
|
663
|
+
doctype
|
|
664
|
+
}) : String(titleValue || name);
|
|
665
|
+
const frame = (content, aside) => routePage ?
|
|
666
|
+
// flexBasis auto: see DeskFormPage (react-native-web's min-height:0
|
|
667
|
+
// reset would cap the scroll page at viewport height).
|
|
668
|
+
/* @__PURE__ */
|
|
669
|
+
(0, import_jsx_runtime.jsx)(import_components.DetailPageLayout, {
|
|
670
|
+
flexBasis: "auto",
|
|
671
|
+
toolbarLeading: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_forms.Button, {
|
|
672
|
+
size: "$3",
|
|
673
|
+
chromeless: true,
|
|
674
|
+
icon: import_react.ArrowLeftIcon,
|
|
675
|
+
onPress: routePage.onBack,
|
|
676
|
+
"aria-label": t("Back to {{doctype}} list", {
|
|
677
|
+
doctype
|
|
678
|
+
}),
|
|
679
|
+
children: doctype
|
|
680
|
+
}),
|
|
681
|
+
header: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.PageHeader, {
|
|
682
|
+
title: pageTitle,
|
|
683
|
+
divider: false
|
|
684
|
+
}),
|
|
685
|
+
aside,
|
|
686
|
+
children: content
|
|
687
|
+
}) : content;
|
|
459
688
|
if (!children && isMetaLoading && !meta) {
|
|
460
|
-
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.YStack, {
|
|
689
|
+
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.YStack, {
|
|
461
690
|
...knobProps.panelPadding,
|
|
462
691
|
testID: "frappe-form-skeleton",
|
|
463
692
|
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.AsyncSkeleton, {
|
|
464
693
|
layout: "generic"
|
|
465
694
|
})
|
|
466
|
-
});
|
|
695
|
+
}));
|
|
467
696
|
}
|
|
468
|
-
if (!children && metaError && !meta) {
|
|
469
|
-
return /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.YStack, {
|
|
697
|
+
if (!children && metaError && !meta && !name) {
|
|
698
|
+
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.YStack, {
|
|
470
699
|
...knobProps.panelPadding,
|
|
471
700
|
alignItems: "center",
|
|
472
701
|
...knobProps.gap,
|
|
@@ -481,19 +710,33 @@ function FrappeForm({
|
|
|
481
710
|
...knobProps.body,
|
|
482
711
|
children: metaError.message
|
|
483
712
|
})]
|
|
484
|
-
});
|
|
713
|
+
}));
|
|
485
714
|
}
|
|
486
|
-
|
|
487
|
-
|
|
715
|
+
const isDocReading = Boolean(name) && (!docCollection || Boolean(liveDoc?.isLoading));
|
|
716
|
+
const showsSeed = Boolean(seedDoc) && isDocReading;
|
|
717
|
+
if (name && docError && !liveDoc?.data && !wasDeleted) {
|
|
718
|
+
if (errorFallback !== void 0) return frame(errorFallback);
|
|
719
|
+
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.AsyncBoundary, {
|
|
720
|
+
...knobProps.panelPadding,
|
|
721
|
+
error: docError,
|
|
722
|
+
errorTitle: t("Failed to load {{doctype}}", {
|
|
723
|
+
doctype
|
|
724
|
+
})
|
|
725
|
+
}));
|
|
726
|
+
}
|
|
727
|
+
if (name && isDocReading && !showsSeed && !wasDeleted) {
|
|
728
|
+
if (loadingFallback !== void 0) return frame(loadingFallback);
|
|
729
|
+
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.YStack, {
|
|
488
730
|
...knobProps.panelPadding,
|
|
489
731
|
testID: "frappe-form-skeleton",
|
|
490
732
|
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.AsyncSkeleton, {
|
|
491
733
|
layout: "generic"
|
|
492
734
|
})
|
|
493
|
-
});
|
|
735
|
+
}));
|
|
494
736
|
}
|
|
495
|
-
if (name && !
|
|
496
|
-
|
|
737
|
+
if (name && !isDocReading && !liveDoc?.data && !wasDeleted) {
|
|
738
|
+
if (notFoundFallback !== void 0) return frame(notFoundFallback);
|
|
739
|
+
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.YStack, {
|
|
497
740
|
...knobProps.panelPadding,
|
|
498
741
|
alignItems: "center",
|
|
499
742
|
...knobProps.gap,
|
|
@@ -510,132 +753,179 @@ function FrappeForm({
|
|
|
510
753
|
name
|
|
511
754
|
})
|
|
512
755
|
})]
|
|
513
|
-
});
|
|
756
|
+
}));
|
|
514
757
|
}
|
|
515
758
|
const effectiveDisabled = disabled || wasDeleted;
|
|
759
|
+
const readOnlyView = Boolean(onEdit) || readsWithoutMeta;
|
|
760
|
+
const fieldsDisabled = effectiveDisabled || readOnlyView;
|
|
761
|
+
const shownTabs = formTabs ?? recordTabs;
|
|
516
762
|
const imageFieldName = meta?.image_field;
|
|
517
763
|
const sidebarImageUrl = imageFieldName ? resolveFileUrl(localDoc[imageFieldName], finalBaseURL) : void 0;
|
|
518
764
|
const conflictLabels = conflictFields.map(fieldname => {
|
|
519
765
|
const field = meta?.fields.find(metaField => metaField.fieldname === fieldname);
|
|
520
766
|
return field?.label || fieldname;
|
|
521
767
|
}).join(", ");
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
768
|
+
const formTabItems = (shownTabs ?? []).map(tab => ({
|
|
769
|
+
value: tab.key,
|
|
770
|
+
label: tab.label,
|
|
771
|
+
content: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_schemaForm.SchemaForm, {
|
|
772
|
+
schema: tab.schema,
|
|
773
|
+
doc: localDoc,
|
|
774
|
+
setValue: (field, value) => setValue(field, value),
|
|
775
|
+
errors,
|
|
776
|
+
disabled: fieldsDisabled,
|
|
777
|
+
overrides,
|
|
778
|
+
readOnlyFields,
|
|
779
|
+
sectionHeadingLevel,
|
|
780
|
+
order
|
|
781
|
+
})
|
|
782
|
+
}));
|
|
783
|
+
const tabItems = showConnections && name && effectiveConnections.length > 0 ? [...formTabItems, {
|
|
784
|
+
value: "__connections",
|
|
785
|
+
label: t("Connections"),
|
|
786
|
+
content: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeFormConnections.FrappeFormConnections, {
|
|
787
|
+
connection: frappeConfig,
|
|
788
|
+
connections: effectiveConnections,
|
|
789
|
+
name
|
|
790
|
+
})
|
|
791
|
+
}] : formTabItems;
|
|
792
|
+
const effectiveTab = activeTab && tabItems.some(tab => tab.value === activeTab) ? activeTab : tabItems[0]?.value;
|
|
793
|
+
const localName = localDoc.name;
|
|
794
|
+
const sidebar = showSidebar && name && meta ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FormSidebar.FormSidebar, {
|
|
795
|
+
imageUrl: sidebarImageUrl,
|
|
796
|
+
sections: buildSidebarSections(localDoc, shareRows, t, assignmentRows),
|
|
797
|
+
metadata: mapDocToSidebarMetadata(localDoc, t)
|
|
798
|
+
}) : void 0;
|
|
799
|
+
return frame(
|
|
800
|
+
// flexBasis auto (not the flex:1 shorthand's 0%): inside scroll-flow page
|
|
801
|
+
// scaffolds (LC-29 templates) the parent is auto-height, and a 0% basis
|
|
802
|
+
// collapses this stack to zero height on web — content then paints over
|
|
803
|
+
// whatever follows. Bounded parents still fill (grow 1) exactly as before.
|
|
804
|
+
/* @__PURE__ */
|
|
805
|
+
(0, import_jsx_runtime.jsxs)(import_tamagui.YStack, {
|
|
806
|
+
...knobProps.gapLg,
|
|
807
|
+
flexGrow: 1,
|
|
808
|
+
flexShrink: 1,
|
|
809
|
+
flexBasis: "auto",
|
|
810
|
+
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeReconnectIndicator.FrappeReconnectIndicator, {
|
|
811
|
+
config: frappeConfig
|
|
812
|
+
}), connectionReads.map(read => /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeRowsReader.FrappeRowsReader, {
|
|
813
|
+
connection: frappeConfig,
|
|
814
|
+
doctype: read.link.doctype,
|
|
815
|
+
options: read.options,
|
|
816
|
+
onChange: read.onChange
|
|
817
|
+
}, read.link.doctype)), wasDeleted && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.XStack, {
|
|
818
|
+
role: "alert",
|
|
819
|
+
alignItems: "center",
|
|
820
|
+
...knobProps.containerRadius,
|
|
821
|
+
...knobProps.panelPadding,
|
|
822
|
+
backgroundColor: "$red3",
|
|
823
|
+
testID: "frappe-form-deleted-banner",
|
|
824
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
825
|
+
color: import_forms.formCommonColors.error,
|
|
826
|
+
...knobProps.body,
|
|
827
|
+
children: hasUnsavedChanges ? t("This {{doctype}} was deleted on the server. Fields are read-only and your unsaved edits can no longer be saved.", {
|
|
828
|
+
doctype
|
|
829
|
+
}) : t("This {{doctype}} was deleted on the server. Fields are read-only.", {
|
|
830
|
+
doctype
|
|
831
|
+
})
|
|
832
|
+
})
|
|
833
|
+
}), !wasDeleted && conflictFields.length > 0 && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.XStack, {
|
|
834
|
+
role: "status",
|
|
835
|
+
alignItems: "center",
|
|
836
|
+
...knobProps.containerRadius,
|
|
837
|
+
...knobProps.panelPadding,
|
|
838
|
+
backgroundColor: "$orange3",
|
|
839
|
+
testID: "frappe-form-conflict-banner",
|
|
840
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
841
|
+
color: "$orange11",
|
|
842
|
+
...knobProps.body,
|
|
843
|
+
children: t("Changed elsewhere while you were editing: {{fields}}. Your edits are kept \u2014 saving will overwrite the newer server values.", {
|
|
844
|
+
fields: conflictLabels
|
|
845
|
+
})
|
|
846
|
+
})
|
|
847
|
+
}), /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.XStack, {
|
|
530
848
|
flexGrow: 1,
|
|
531
849
|
flexShrink: 1,
|
|
532
850
|
flexBasis: "auto",
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
role: "alert",
|
|
537
|
-
alignItems: "center",
|
|
538
|
-
...knobProps.containerRadius,
|
|
539
|
-
...knobProps.panelPadding,
|
|
540
|
-
backgroundColor: "$red3",
|
|
541
|
-
testID: "frappe-form-deleted-banner",
|
|
542
|
-
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
543
|
-
color: import_forms.formCommonColors.error,
|
|
544
|
-
...knobProps.body,
|
|
545
|
-
children: hasUnsavedChanges ? t("This {{doctype}} was deleted on the server. Fields are read-only and your unsaved edits can no longer be saved.", {
|
|
546
|
-
doctype
|
|
547
|
-
}) : t("This {{doctype}} was deleted on the server. Fields are read-only.", {
|
|
548
|
-
doctype
|
|
549
|
-
})
|
|
550
|
-
})
|
|
551
|
-
}), !wasDeleted && conflictFields.length > 0 && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.XStack, {
|
|
552
|
-
role: "status",
|
|
553
|
-
alignItems: "center",
|
|
554
|
-
...knobProps.containerRadius,
|
|
555
|
-
...knobProps.panelPadding,
|
|
556
|
-
backgroundColor: "$orange3",
|
|
557
|
-
testID: "frappe-form-conflict-banner",
|
|
558
|
-
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
559
|
-
color: "$orange11",
|
|
560
|
-
...knobProps.body,
|
|
561
|
-
children: t("Changed elsewhere while you were editing: {{fields}}. Your edits are kept \u2014 saving will overwrite the newer server values.", {
|
|
562
|
-
fields: conflictLabels
|
|
563
|
-
})
|
|
564
|
-
})
|
|
565
|
-
}), /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.XStack, {
|
|
566
|
-
flexGrow: 1,
|
|
567
|
-
flexShrink: 1,
|
|
568
|
-
flexBasis: "auto",
|
|
851
|
+
...knobProps.gapLg,
|
|
852
|
+
children: [routePage ? null : sidebar, /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.YStack, {
|
|
853
|
+
flex: 1,
|
|
569
854
|
...knobProps.gapLg,
|
|
570
|
-
children: [
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
855
|
+
children: [children ?
|
|
856
|
+
// Render-prop mode
|
|
857
|
+
children({
|
|
858
|
+
doc: localDoc,
|
|
859
|
+
setValue,
|
|
860
|
+
isSubmitting,
|
|
861
|
+
errors,
|
|
862
|
+
meta,
|
|
863
|
+
disabled: fieldsDisabled,
|
|
864
|
+
connections: connectionRows,
|
|
865
|
+
connectionsLoading
|
|
866
|
+
}) : shownTabs ? /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.YStack, {
|
|
576
867
|
...knobProps.gapLg,
|
|
577
|
-
children: [
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
errors,
|
|
584
|
-
meta,
|
|
868
|
+
children: [promptNamed && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_forms.Input, {
|
|
869
|
+
label: t("Name"),
|
|
870
|
+
value: typeof localName === "string" ? localName : "",
|
|
871
|
+
onChangeText: value => setValue("name", value),
|
|
872
|
+
placeholder: t("New document name"),
|
|
873
|
+
error: errors.name,
|
|
585
874
|
disabled: effectiveDisabled
|
|
586
|
-
})
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
}) :
|
|
601
|
-
// Metadata unavailable (should be covered by metaError branch above)
|
|
602
|
-
/* @__PURE__ */
|
|
603
|
-
(0, import_jsx_runtime.jsx)(import_tamagui.YStack, {
|
|
604
|
-
...knobProps.panelPadding,
|
|
605
|
-
alignItems: "center",
|
|
606
|
-
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
607
|
-
color: import_forms.formCommonColors.muted,
|
|
608
|
-
...knobProps.body,
|
|
609
|
-
children: t("Form schema unavailable")
|
|
610
|
-
})
|
|
611
|
-
}), errors.general && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
612
|
-
color: import_forms.formCommonColors.error,
|
|
875
|
+
}), tabItems.length > 1 ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.Tabs, {
|
|
876
|
+
items: tabItems,
|
|
877
|
+
value: effectiveTab,
|
|
878
|
+
onChange: setActiveTab,
|
|
879
|
+
lazyMount: true
|
|
880
|
+
}) : tabItems[0]?.content ?? null]
|
|
881
|
+
}) :
|
|
882
|
+
// Metadata unavailable (should be covered by metaError branch above)
|
|
883
|
+
/* @__PURE__ */
|
|
884
|
+
(0, import_jsx_runtime.jsx)(import_tamagui.YStack, {
|
|
885
|
+
...knobProps.panelPadding,
|
|
886
|
+
alignItems: "center",
|
|
887
|
+
children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
888
|
+
color: import_forms.formCommonColors.muted,
|
|
613
889
|
...knobProps.body,
|
|
614
|
-
children:
|
|
615
|
-
})
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
890
|
+
children: t("Form schema unavailable")
|
|
891
|
+
})
|
|
892
|
+
}), errors.general && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
893
|
+
color: import_forms.formCommonColors.error,
|
|
894
|
+
...knobProps.body,
|
|
895
|
+
children: errors.general
|
|
896
|
+
}), showToolbar && !readsWithoutMeta && /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.XStack, {
|
|
897
|
+
...knobProps.gap,
|
|
898
|
+
justifyContent: "flex-end",
|
|
899
|
+
alignItems: "center",
|
|
900
|
+
paddingTop: "$3",
|
|
901
|
+
children: [hasUnsavedChanges && !onEdit && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
902
|
+
color: "$orange11",
|
|
903
|
+
marginInlineEnd: "auto",
|
|
904
|
+
...knobProps.body,
|
|
905
|
+
children: t("Not Saved")
|
|
906
|
+
}), name && onDelete && !wasDeleted && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_forms.Button, {
|
|
907
|
+
outlined: true,
|
|
908
|
+
error: true,
|
|
909
|
+
icon: import_react.TrashIcon,
|
|
910
|
+
loading: isSubmitting,
|
|
911
|
+
disabled: effectiveDisabled,
|
|
912
|
+
disabledReason: t("Form is read-only"),
|
|
913
|
+
disabledReasonPlacement: "inline",
|
|
914
|
+
onPress: handleDelete,
|
|
915
|
+
children: t("Delete")
|
|
916
|
+
}), onEdit ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_forms.Button, {
|
|
917
|
+
accent: true,
|
|
918
|
+
icon: import_react.PencilSimpleIcon,
|
|
919
|
+
disabled: effectiveDisabled,
|
|
920
|
+
disabledReason: t("Form is read-only"),
|
|
921
|
+
disabledReasonPlacement: "inline",
|
|
922
|
+
onPress: onEdit,
|
|
923
|
+
children: t("Edit")
|
|
924
|
+
}) : /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
|
|
925
|
+
children: [onCancel && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_forms.Button, {
|
|
636
926
|
outlined: true,
|
|
637
927
|
icon: import_react.XIcon,
|
|
638
|
-
disabled
|
|
928
|
+
disabled,
|
|
639
929
|
disabledReason: t("Form is read-only"),
|
|
640
930
|
disabledReasonPlacement: "inline",
|
|
641
931
|
onPress: handleCancel,
|
|
@@ -652,11 +942,11 @@ function FrappeForm({
|
|
|
652
942
|
})]
|
|
653
943
|
})]
|
|
654
944
|
})]
|
|
655
|
-
}), showTimeline && name && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_timeline.Timeline, {
|
|
656
|
-
doctype,
|
|
657
|
-
docname: name,
|
|
658
|
-
label: t("Activity")
|
|
659
945
|
})]
|
|
660
|
-
})
|
|
661
|
-
|
|
946
|
+
}), showTimeline && name && !readsWithoutMeta && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_timeline.Timeline, {
|
|
947
|
+
doctype,
|
|
948
|
+
docname: name,
|
|
949
|
+
label: t("Activity")
|
|
950
|
+
})]
|
|
951
|
+
}), routePage ? sidebar : void 0);
|
|
662
952
|
}
|