@multiplatform.one/frappe-ui 7.28.1 → 7.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/FrappeCalendar.cjs +3 -2
- package/dist/cjs/FrappeCalendar.native.js +3 -2
- package/dist/cjs/FrappeCalendar.native.js.map +1 -1
- package/dist/cjs/FrappeForm.cjs +148 -464
- package/dist/cjs/FrappeForm.native.js +152 -633
- package/dist/cjs/FrappeForm.native.js.map +1 -1
- package/dist/cjs/FrappeListView.cjs +5 -27
- package/dist/cjs/FrappeListView.native.js +11 -32
- package/dist/cjs/FrappeListView.native.js.map +1 -1
- package/dist/cjs/FrappeReportBuilder.cjs +523 -309
- package/dist/cjs/FrappeReportBuilder.native.js +658 -353
- package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
- package/dist/cjs/FrappeReportView.cjs +35 -234
- package/dist/cjs/FrappeReportView.native.js +39 -283
- package/dist/cjs/FrappeReportView.native.js.map +1 -1
- package/dist/cjs/dependsOn.cjs +2 -2
- package/dist/cjs/dependsOn.native.js +1 -2
- package/dist/cjs/dependsOn.native.js.map +1 -1
- package/dist/cjs/fields/shared/EditorPreviewPanes.cjs +2 -2
- package/dist/cjs/fields/shared/EditorPreviewPanes.native.js +2 -2
- package/dist/cjs/fields/shared/EditorPreviewPanes.native.js.map +1 -1
- package/dist/cjs/formEngine/docPermissions.cjs +20 -0
- package/dist/cjs/formEngine/docPermissions.native.js +69 -0
- package/dist/cjs/formEngine/docPermissions.native.js.map +1 -1
- package/dist/cjs/formEngine/index.cjs +2 -0
- package/dist/cjs/formEngine/index.native.js +2 -0
- package/dist/cjs/formEngine/index.native.js.map +1 -1
- package/dist/cjs/index.cjs +67 -7
- package/dist/cjs/index.native.js +67 -7
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/liveErrors.cjs +8 -2
- package/dist/cjs/liveErrors.native.js +8 -2
- package/dist/cjs/liveErrors.native.js.map +1 -1
- package/dist/cjs/measures.cjs +31 -0
- package/dist/cjs/measures.native.js +34 -0
- package/dist/cjs/measures.native.js.map +1 -0
- package/dist/cjs/recordShape.cjs +103 -0
- package/dist/cjs/recordShape.native.js +115 -0
- package/dist/cjs/recordShape.native.js.map +1 -0
- package/dist/cjs/report/ReportGrid.cjs +453 -0
- package/dist/cjs/report/ReportGrid.native.js +510 -0
- package/dist/cjs/report/ReportGrid.native.js.map +1 -0
- package/dist/cjs/report/ReportViewToolbar.cjs +253 -0
- package/dist/cjs/report/ReportViewToolbar.native.js +303 -0
- package/dist/cjs/report/ReportViewToolbar.native.js.map +1 -0
- package/dist/cjs/report/queryReport.cjs +444 -0
- package/dist/cjs/report/queryReport.native.js +588 -0
- package/dist/cjs/report/queryReport.native.js.map +1 -0
- package/dist/cjs/report/queryReportColumns.cjs +131 -0
- package/dist/cjs/report/queryReportColumns.native.js +159 -0
- package/dist/cjs/report/queryReportColumns.native.js.map +1 -0
- package/dist/cjs/report/reportViewModel.cjs +386 -0
- package/dist/cjs/report/reportViewModel.native.js +657 -0
- package/dist/cjs/report/reportViewModel.native.js.map +1 -0
- package/dist/cjs/report/savedReports.cjs +137 -0
- package/dist/cjs/report/savedReports.native.js +169 -0
- package/dist/cjs/report/savedReports.native.js.map +1 -0
- package/dist/cjs/report/useFrappeReport.cjs +184 -0
- package/dist/cjs/report/useFrappeReport.native.js +214 -0
- package/dist/cjs/report/useFrappeReport.native.js.map +1 -0
- package/dist/cjs/report/useQueryReport.cjs +201 -0
- package/dist/cjs/report/useQueryReport.native.js +233 -0
- package/dist/cjs/report/useQueryReport.native.js.map +1 -0
- package/dist/cjs/useFrappeForm.cjs +558 -0
- package/dist/cjs/useFrappeForm.native.js +714 -0
- package/dist/cjs/useFrappeForm.native.js.map +1 -0
- package/dist/esm/FrappeCalendar.mjs +4 -3
- package/dist/esm/FrappeCalendar.mjs.map +1 -1
- package/dist/esm/FrappeCalendar.native.js +4 -3
- package/dist/esm/FrappeCalendar.native.js.map +1 -1
- package/dist/esm/FrappeForm.mjs +151 -467
- package/dist/esm/FrappeForm.mjs.map +1 -1
- package/dist/esm/FrappeForm.native.js +155 -636
- package/dist/esm/FrappeForm.native.js.map +1 -1
- package/dist/esm/FrappeListView.mjs +6 -28
- package/dist/esm/FrappeListView.mjs.map +1 -1
- package/dist/esm/FrappeListView.native.js +12 -33
- package/dist/esm/FrappeListView.native.js.map +1 -1
- package/dist/esm/FrappeReportBuilder.mjs +526 -312
- package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
- package/dist/esm/FrappeReportBuilder.native.js +661 -356
- package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
- package/dist/esm/FrappeReportView.mjs +30 -229
- package/dist/esm/FrappeReportView.mjs.map +1 -1
- package/dist/esm/FrappeReportView.native.js +34 -278
- package/dist/esm/FrappeReportView.native.js.map +1 -1
- package/dist/esm/dependsOn.mjs +2 -2
- package/dist/esm/dependsOn.mjs.map +1 -1
- package/dist/esm/dependsOn.native.js +1 -2
- package/dist/esm/dependsOn.native.js.map +1 -1
- package/dist/esm/fields/shared/EditorPreviewPanes.mjs +2 -2
- package/dist/esm/fields/shared/EditorPreviewPanes.mjs.map +1 -1
- package/dist/esm/fields/shared/EditorPreviewPanes.native.js +2 -2
- package/dist/esm/fields/shared/EditorPreviewPanes.native.js.map +1 -1
- package/dist/esm/formEngine/docPermissions.mjs +19 -1
- package/dist/esm/formEngine/docPermissions.mjs.map +1 -1
- package/dist/esm/formEngine/docPermissions.native.js +68 -1
- package/dist/esm/formEngine/docPermissions.native.js.map +1 -1
- package/dist/esm/formEngine/index.mjs +2 -2
- package/dist/esm/formEngine/index.mjs.map +1 -1
- package/dist/esm/formEngine/index.native.js +2 -2
- package/dist/esm/formEngine/index.native.js.map +1 -1
- package/dist/esm/index.mjs +16 -4
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +16 -4
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/liveErrors.mjs +8 -3
- package/dist/esm/liveErrors.mjs.map +1 -1
- package/dist/esm/liveErrors.native.js +8 -3
- package/dist/esm/liveErrors.native.js.map +1 -1
- package/dist/esm/measures.mjs +5 -0
- package/dist/esm/measures.mjs.map +1 -0
- package/dist/esm/measures.native.js +5 -0
- package/dist/esm/measures.native.js.map +1 -0
- package/dist/esm/recordShape.mjs +74 -0
- package/dist/esm/recordShape.mjs.map +1 -0
- package/dist/esm/recordShape.native.js +83 -0
- package/dist/esm/recordShape.native.js.map +1 -0
- package/dist/esm/report/ReportGrid.mjs +428 -0
- package/dist/esm/report/ReportGrid.mjs.map +1 -0
- package/dist/esm/report/ReportGrid.native.js +471 -0
- package/dist/esm/report/ReportGrid.native.js.map +1 -0
- package/dist/esm/report/ReportViewToolbar.mjs +228 -0
- package/dist/esm/report/ReportViewToolbar.mjs.map +1 -0
- package/dist/esm/report/ReportViewToolbar.native.js +264 -0
- package/dist/esm/report/ReportViewToolbar.native.js.map +1 -0
- package/dist/esm/report/queryReport.mjs +404 -0
- package/dist/esm/report/queryReport.mjs.map +1 -0
- package/dist/esm/report/queryReport.native.js +545 -0
- package/dist/esm/report/queryReport.native.js.map +1 -0
- package/dist/esm/report/queryReportColumns.mjs +105 -0
- package/dist/esm/report/queryReportColumns.mjs.map +1 -0
- package/dist/esm/report/queryReportColumns.native.js +119 -0
- package/dist/esm/report/queryReportColumns.native.js.map +1 -0
- package/dist/esm/report/reportViewModel.mjs +343 -0
- package/dist/esm/report/reportViewModel.mjs.map +1 -0
- package/dist/esm/report/reportViewModel.native.js +611 -0
- package/dist/esm/report/reportViewModel.native.js.map +1 -0
- package/dist/esm/report/savedReports.mjs +112 -0
- package/dist/esm/report/savedReports.mjs.map +1 -0
- package/dist/esm/report/savedReports.native.js +141 -0
- package/dist/esm/report/savedReports.native.js.map +1 -0
- package/dist/esm/report/useFrappeReport.mjs +158 -0
- package/dist/esm/report/useFrappeReport.mjs.map +1 -0
- package/dist/esm/report/useFrappeReport.native.js +185 -0
- package/dist/esm/report/useFrappeReport.native.js.map +1 -0
- package/dist/esm/report/useQueryReport.mjs +176 -0
- package/dist/esm/report/useQueryReport.mjs.map +1 -0
- package/dist/esm/report/useQueryReport.native.js +205 -0
- package/dist/esm/report/useQueryReport.native.js.map +1 -0
- package/dist/esm/useFrappeForm.mjs +533 -0
- package/dist/esm/useFrappeForm.mjs.map +1 -0
- package/dist/esm/useFrappeForm.native.js +686 -0
- package/dist/esm/useFrappeForm.native.js.map +1 -0
- package/dist/jsx/FrappeCalendar.mjs +4 -3
- package/dist/jsx/FrappeCalendar.mjs.map +1 -1
- package/dist/jsx/FrappeCalendar.native.js +3 -2
- package/dist/jsx/FrappeCalendar.native.js.map +1 -1
- package/dist/jsx/FrappeForm.mjs +151 -467
- package/dist/jsx/FrappeForm.mjs.map +1 -1
- package/dist/jsx/FrappeForm.native.js +152 -633
- package/dist/jsx/FrappeForm.native.js.map +1 -1
- package/dist/jsx/FrappeListView.mjs +6 -28
- package/dist/jsx/FrappeListView.mjs.map +1 -1
- package/dist/jsx/FrappeListView.native.js +11 -32
- package/dist/jsx/FrappeListView.native.js.map +1 -1
- package/dist/jsx/FrappeReportBuilder.mjs +526 -312
- package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
- package/dist/jsx/FrappeReportBuilder.native.js +658 -353
- package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
- package/dist/jsx/FrappeReportView.mjs +30 -229
- package/dist/jsx/FrappeReportView.mjs.map +1 -1
- package/dist/jsx/FrappeReportView.native.js +39 -283
- package/dist/jsx/FrappeReportView.native.js.map +1 -1
- package/dist/jsx/dependsOn.mjs +2 -2
- package/dist/jsx/dependsOn.mjs.map +1 -1
- package/dist/jsx/dependsOn.native.js +1 -2
- package/dist/jsx/dependsOn.native.js.map +1 -1
- package/dist/jsx/fields/shared/EditorPreviewPanes.mjs +2 -2
- package/dist/jsx/fields/shared/EditorPreviewPanes.mjs.map +1 -1
- package/dist/jsx/fields/shared/EditorPreviewPanes.native.js +2 -2
- package/dist/jsx/fields/shared/EditorPreviewPanes.native.js.map +1 -1
- package/dist/jsx/formEngine/docPermissions.mjs +19 -1
- package/dist/jsx/formEngine/docPermissions.mjs.map +1 -1
- package/dist/jsx/formEngine/docPermissions.native.js +69 -0
- package/dist/jsx/formEngine/docPermissions.native.js.map +1 -1
- package/dist/jsx/formEngine/index.mjs +2 -2
- package/dist/jsx/formEngine/index.mjs.map +1 -1
- package/dist/jsx/formEngine/index.native.js +2 -0
- package/dist/jsx/formEngine/index.native.js.map +1 -1
- package/dist/jsx/index.js +16 -4
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +16 -4
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +67 -7
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/liveErrors.mjs +8 -3
- package/dist/jsx/liveErrors.mjs.map +1 -1
- package/dist/jsx/liveErrors.native.js +8 -2
- package/dist/jsx/liveErrors.native.js.map +1 -1
- package/dist/jsx/measures.mjs +5 -0
- package/dist/jsx/measures.mjs.map +1 -0
- package/dist/jsx/measures.native.js +34 -0
- package/dist/jsx/measures.native.js.map +1 -0
- package/dist/jsx/recordShape.mjs +74 -0
- package/dist/jsx/recordShape.mjs.map +1 -0
- package/dist/jsx/recordShape.native.js +115 -0
- package/dist/jsx/recordShape.native.js.map +1 -0
- package/dist/jsx/report/ReportGrid.mjs +428 -0
- package/dist/jsx/report/ReportGrid.mjs.map +1 -0
- package/dist/jsx/report/ReportGrid.native.js +510 -0
- package/dist/jsx/report/ReportGrid.native.js.map +1 -0
- package/dist/jsx/report/ReportViewToolbar.mjs +228 -0
- package/dist/jsx/report/ReportViewToolbar.mjs.map +1 -0
- package/dist/jsx/report/ReportViewToolbar.native.js +303 -0
- package/dist/jsx/report/ReportViewToolbar.native.js.map +1 -0
- package/dist/jsx/report/queryReport.mjs +404 -0
- package/dist/jsx/report/queryReport.mjs.map +1 -0
- package/dist/jsx/report/queryReport.native.js +588 -0
- package/dist/jsx/report/queryReport.native.js.map +1 -0
- package/dist/jsx/report/queryReportColumns.mjs +105 -0
- package/dist/jsx/report/queryReportColumns.mjs.map +1 -0
- package/dist/jsx/report/queryReportColumns.native.js +159 -0
- package/dist/jsx/report/queryReportColumns.native.js.map +1 -0
- package/dist/jsx/report/reportViewModel.mjs +343 -0
- package/dist/jsx/report/reportViewModel.mjs.map +1 -0
- package/dist/jsx/report/reportViewModel.native.js +657 -0
- package/dist/jsx/report/reportViewModel.native.js.map +1 -0
- package/dist/jsx/report/savedReports.mjs +112 -0
- package/dist/jsx/report/savedReports.mjs.map +1 -0
- package/dist/jsx/report/savedReports.native.js +169 -0
- package/dist/jsx/report/savedReports.native.js.map +1 -0
- package/dist/jsx/report/useFrappeReport.mjs +158 -0
- package/dist/jsx/report/useFrappeReport.mjs.map +1 -0
- package/dist/jsx/report/useFrappeReport.native.js +214 -0
- package/dist/jsx/report/useFrappeReport.native.js.map +1 -0
- package/dist/jsx/report/useQueryReport.mjs +176 -0
- package/dist/jsx/report/useQueryReport.mjs.map +1 -0
- package/dist/jsx/report/useQueryReport.native.js +233 -0
- package/dist/jsx/report/useQueryReport.native.js.map +1 -0
- package/dist/jsx/useFrappeForm.mjs +533 -0
- package/dist/jsx/useFrappeForm.mjs.map +1 -0
- package/dist/jsx/useFrappeForm.native.js +714 -0
- package/dist/jsx/useFrappeForm.native.js.map +1 -0
- package/package.json +16 -16
- package/src/FrappeCalendar.tsx +8 -2
- package/src/FrappeForm.stories.tsx +52 -0
- package/src/FrappeForm.tsx +176 -565
- package/src/FrappeListView.cards.stories.tsx +3 -6
- package/src/FrappeListView.tsx +15 -55
- package/src/FrappeReportBuilder.stories.tsx +34 -7
- package/src/FrappeReportBuilder.tsx +790 -380
- package/src/FrappeReportView.spec.tsx +10 -6
- package/src/FrappeReportView.stories.tsx +20 -1
- package/src/FrappeReportView.tsx +89 -415
- package/src/dependsOn.ts +4 -1
- package/src/fields/shared/EditorPreviewPanes.tsx +2 -2
- package/src/formEngine/docPermissions.spec.ts +36 -1
- package/src/formEngine/docPermissions.ts +34 -0
- package/src/formEngine/index.ts +8 -1
- package/src/frappeRemainder.designLaw.spec.ts +9 -1
- package/src/frappeRoutes.spec.tsx +9 -0
- package/src/frappeViews.designLaw.spec.ts +15 -2
- package/src/guestFallback.spec.tsx +236 -0
- package/src/index.ts +117 -16
- package/src/liveErrors.spec.ts +10 -0
- package/src/liveErrors.ts +16 -3
- package/src/measures.ts +11 -0
- package/src/recordShape.spec.ts +100 -0
- package/src/recordShape.ts +133 -0
- package/src/report/ReportGrid.spec.tsx +175 -0
- package/src/report/ReportGrid.tsx +530 -0
- package/src/report/ReportViewToolbar.spec.tsx +90 -0
- package/src/report/ReportViewToolbar.tsx +314 -0
- package/src/report/queryReport.spec.ts +483 -0
- package/src/report/queryReport.ts +722 -0
- package/src/report/queryReportColumns.tsx +123 -0
- package/src/report/reportViewModel.spec.ts +393 -0
- package/src/report/reportViewModel.ts +617 -0
- package/src/report/savedReports.ts +172 -0
- package/src/report/seam.spec.ts +216 -0
- package/src/report/useFrappeReport.ts +241 -0
- package/src/report/useQueryReport.spec.tsx +131 -0
- package/src/report/useQueryReport.ts +309 -0
- package/src/useFrappeForm.spec.tsx +209 -0
- package/src/useFrappeForm.ts +778 -0
- package/types/FrappeCalendar.d.ts.map +1 -1
- package/types/FrappeForm.d.ts +21 -1
- package/types/FrappeForm.d.ts.map +1 -1
- package/types/FrappeListView.d.ts.map +1 -1
- package/types/FrappeReportBuilder.d.ts +66 -16
- package/types/FrappeReportBuilder.d.ts.map +1 -1
- package/types/FrappeReportView.d.ts +9 -127
- package/types/FrappeReportView.d.ts.map +1 -1
- package/types/dependsOn.d.ts.map +1 -1
- package/types/formEngine/docPermissions.d.ts +14 -0
- package/types/formEngine/docPermissions.d.ts.map +1 -1
- package/types/formEngine/index.d.ts +1 -1
- package/types/formEngine/index.d.ts.map +1 -1
- package/types/index.d.ts +15 -3
- package/types/index.d.ts.map +1 -1
- package/types/liveErrors.d.ts +9 -1
- package/types/liveErrors.d.ts.map +1 -1
- package/types/measures.d.ts +3 -0
- package/types/measures.d.ts.map +1 -0
- package/types/recordShape.d.ts +45 -0
- package/types/recordShape.d.ts.map +1 -0
- package/types/report/ReportGrid.d.ts +20 -0
- package/types/report/ReportGrid.d.ts.map +1 -0
- package/types/report/ReportViewToolbar.d.ts +31 -0
- package/types/report/ReportViewToolbar.d.ts.map +1 -0
- package/types/report/queryReport.d.ts +181 -0
- package/types/report/queryReport.d.ts.map +1 -0
- package/types/report/queryReportColumns.d.ts +12 -0
- package/types/report/queryReportColumns.d.ts.map +1 -0
- package/types/report/reportViewModel.d.ts +146 -0
- package/types/report/reportViewModel.d.ts.map +1 -0
- package/types/report/savedReports.d.ts +27 -0
- package/types/report/savedReports.d.ts.map +1 -0
- package/types/report/useFrappeReport.d.ts +60 -0
- package/types/report/useFrappeReport.d.ts.map +1 -0
- package/types/report/useQueryReport.d.ts +37 -0
- package/types/report/useQueryReport.d.ts.map +1 -0
- package/types/useFrappeForm.d.ts +142 -0
- package/types/useFrappeForm.d.ts.map +1 -0
package/dist/cjs/FrappeForm.cjs
CHANGED
|
@@ -32,7 +32,6 @@ var import_frappe = require("@multiplatform.one/frappe");
|
|
|
32
32
|
var import_components = require("@multiplatform.one/components");
|
|
33
33
|
var import_schemaForm = require("./schemaForm/index.cjs");
|
|
34
34
|
var import_FormSidebar = require("./FormSidebar.cjs");
|
|
35
|
-
var import_db = require("@tanstack/db");
|
|
36
35
|
var import_react = require("@phosphor-icons/react");
|
|
37
36
|
var import_react2 = require("react");
|
|
38
37
|
var import_react_i18next = require("react-i18next");
|
|
@@ -43,56 +42,23 @@ var import_FrappeProvider = require("./FrappeProvider.cjs");
|
|
|
43
42
|
var import_FrappeReconnectIndicator = require("./FrappeReconnectIndicator.cjs");
|
|
44
43
|
var import_timeline = require("./components/timeline.cjs");
|
|
45
44
|
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_createPrefill = require("./formEngine/createPrefill.cjs");
|
|
51
45
|
var import_docLifecycle = require("./formEngine/docLifecycle.cjs");
|
|
52
|
-
var import_useAmendedAs = require("./formEngine/useAmendedAs.cjs");
|
|
53
|
-
var import_useDocRights = require("./formEngine/useDocRights.cjs");
|
|
54
|
-
var import_useFormEngine = require("./formEngine/useFormEngine.cjs");
|
|
55
46
|
var import_FrappeFormActions = require("./FrappeFormActions.cjs");
|
|
56
47
|
var import_frappeConnections = require("./frappeConnections.cjs");
|
|
57
48
|
var import_FrappeFormConnections = require("./FrappeFormConnections.cjs");
|
|
58
49
|
var import_FrappeNotConfigured = require("./FrappeNotConfigured.cjs");
|
|
59
50
|
var import_FrappeRowsReader = require("./FrappeRowsReader.cjs");
|
|
51
|
+
var import_liveErrors = require("./liveErrors.cjs");
|
|
52
|
+
var import_recordShape = require("./recordShape.cjs");
|
|
60
53
|
var import_frappeNavigation = require("./frappeNavigation.cjs");
|
|
54
|
+
var import_useFrappeForm = require("./useFrappeForm.cjs");
|
|
61
55
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
62
56
|
var import_react3 = require("react");
|
|
63
|
-
function
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
}
|
|
69
|
-
function sectionsToLayoutFields(sections) {
|
|
70
|
-
const fields = [];
|
|
71
|
-
sections.forEach((section, sectionIndex) => {
|
|
72
|
-
fields.push({
|
|
73
|
-
fieldname: `__section_${sectionIndex}`,
|
|
74
|
-
fieldtype: section.tab ? "Tab Break" : "Section Break",
|
|
75
|
-
label: section.label,
|
|
76
|
-
collapsible: section.collapsible ? 1 : 0
|
|
77
|
-
});
|
|
78
|
-
section.columns.forEach((column, columnIndex) => {
|
|
79
|
-
if (columnIndex > 0) {
|
|
80
|
-
fields.push({
|
|
81
|
-
fieldname: `__column_${sectionIndex}_${columnIndex}`,
|
|
82
|
-
fieldtype: "Column Break"
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
fields.push(...column.fields);
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
return fields;
|
|
89
|
-
}
|
|
90
|
-
const documentBookkeeping = /* @__PURE__ */new Set(["name", "owner", "creation", "modified", "modified_by", "docstatus", "idx", "doctype", "_user_tags", "_comments", "_assign", "_liked_by", "_seen"]);
|
|
91
|
-
function fieldsFromDocument(doc) {
|
|
92
|
-
return Object.entries(doc).filter(([key, value]) => !key.startsWith("$") && !documentBookkeeping.has(key) && (value === null || typeof value === "string" || typeof value === "number")).map(([key, value]) => ({
|
|
93
|
-
name: key,
|
|
94
|
-
label: key.replace(/_/g, " ").replace(/(^|\s)\S/g, c => c.toUpperCase()),
|
|
95
|
-
type: typeof value === "number" ? Number.isInteger(value) ? "Int" : "Float" : "Data",
|
|
57
|
+
function schemaFieldsFromRecord(doc) {
|
|
58
|
+
return (0, import_recordShape.fieldsFromRecord)(doc).map(field => ({
|
|
59
|
+
name: field.fieldname,
|
|
60
|
+
label: field.label,
|
|
61
|
+
type: field.fieldtype,
|
|
96
62
|
readOnly: true
|
|
97
63
|
}));
|
|
98
64
|
}
|
|
@@ -236,20 +202,48 @@ function FrappeFormRoute({
|
|
|
236
202
|
}))
|
|
237
203
|
});
|
|
238
204
|
}
|
|
239
|
-
function FrappeFormBody({
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
205
|
+
function FrappeFormBody(props) {
|
|
206
|
+
if (props.form) return /* @__PURE__ */(0, import_jsx_runtime.jsx)(FrappeFormView, {
|
|
207
|
+
...props,
|
|
208
|
+
form: props.form
|
|
209
|
+
});
|
|
210
|
+
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(FrappeFormOwned, {
|
|
211
|
+
...props
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
function FrappeFormOwned(props) {
|
|
215
|
+
const config = (0, import_FrappeProvider.useFrappeConfig)();
|
|
216
|
+
if (!(props.baseURL ?? config?.baseURL)) {
|
|
217
|
+
throw new Error("FrappeForm requires baseURL prop or FrappeProvider with baseURL");
|
|
218
|
+
}
|
|
219
|
+
const form = (0, import_useFrappeForm.useFrappeForm)({
|
|
220
|
+
doctype: props.doctype,
|
|
221
|
+
name: props.name,
|
|
222
|
+
baseURL: props.baseURL,
|
|
223
|
+
auth: props.auth,
|
|
224
|
+
syncOptions: props.syncOptions,
|
|
225
|
+
fields: props.fields,
|
|
226
|
+
sections: props.sections,
|
|
227
|
+
hideFields: props.hideFields,
|
|
228
|
+
hideSections: props.hideSections,
|
|
229
|
+
roles: props.roles,
|
|
230
|
+
readShares: props.showSidebar ?? true,
|
|
231
|
+
disabled: props.disabled,
|
|
232
|
+
initialDoc: props.initialDoc
|
|
233
|
+
});
|
|
234
|
+
return /* @__PURE__ */(0, import_jsx_runtime.jsx)(FrappeFormView, {
|
|
235
|
+
...props,
|
|
236
|
+
form
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
function FrappeFormView({
|
|
240
|
+
form,
|
|
243
241
|
doctype,
|
|
244
242
|
name,
|
|
245
|
-
fields,
|
|
246
243
|
children,
|
|
247
244
|
overrides,
|
|
248
|
-
hideFields,
|
|
249
245
|
readOnlyFields,
|
|
250
|
-
sections,
|
|
251
246
|
order,
|
|
252
|
-
roles,
|
|
253
247
|
onSave,
|
|
254
248
|
onCancel,
|
|
255
249
|
onDelete,
|
|
@@ -258,73 +252,55 @@ function FrappeFormBody({
|
|
|
258
252
|
showToolbar = true,
|
|
259
253
|
showSidebar = true,
|
|
260
254
|
showTimeline = true,
|
|
255
|
+
showBanners = true,
|
|
261
256
|
disabled = false,
|
|
262
257
|
sectionHeadingLevel,
|
|
263
258
|
connections,
|
|
264
259
|
showConnections = true,
|
|
265
|
-
|
|
260
|
+
extraTabs,
|
|
261
|
+
renderFieldWrapper,
|
|
262
|
+
renderTab,
|
|
266
263
|
loadingFallback,
|
|
267
264
|
notFoundFallback,
|
|
268
265
|
errorFallback,
|
|
269
266
|
routePage
|
|
270
267
|
}) {
|
|
271
|
-
const config = (0, import_FrappeProvider.useFrappeConfig)();
|
|
272
268
|
const {
|
|
273
269
|
knobProps
|
|
274
270
|
} = (0, import_theme.useResolvedKnobs)();
|
|
275
271
|
const {
|
|
276
272
|
t
|
|
277
273
|
} = (0, import_react_i18next.useTranslation)();
|
|
278
|
-
const seedDoc = name && initialDoc && initialDoc.name === name ? initialDoc : void 0;
|
|
279
|
-
const seedRef = (0, import_react2.useRef)(seedDoc);
|
|
280
|
-
seedRef.current = seedDoc;
|
|
281
|
-
const [localDoc, setLocalDoc] = (0, import_react2.useState)(() => seedDoc ?? {});
|
|
282
|
-
const [baselineDoc, setBaselineDoc] = (0, import_react2.useState)(() => seedDoc);
|
|
283
|
-
const [docError, setDocError] = (0, import_react2.useState)(null);
|
|
284
|
-
const [conflictFields, setConflictFields] = (0, import_react2.useState)([]);
|
|
285
|
-
const [wasDeleted, setWasDeleted] = (0, import_react2.useState)(false);
|
|
286
|
-
const [isSubmitting, setIsSubmitting] = (0, import_react2.useState)(false);
|
|
287
|
-
const [errors, setErrors] = (0, import_react2.useState)({});
|
|
288
|
-
const [activeTab, setActiveTab] = (0, import_react2.useState)(void 0);
|
|
289
|
-
const everLoadedRef = (0, import_react2.useRef)(false);
|
|
290
|
-
const localDocRef = (0, import_react2.useRef)(localDoc);
|
|
291
|
-
localDocRef.current = localDoc;
|
|
292
|
-
const baselineRef = (0, import_react2.useRef)(baselineDoc);
|
|
293
|
-
baselineRef.current = baselineDoc;
|
|
294
|
-
const createDraftRef = (0, import_react2.useRef)(void 0);
|
|
295
|
-
const finalBaseURL = baseURL ?? config?.baseURL;
|
|
296
|
-
const finalAuth = auth ?? config?.auth;
|
|
297
|
-
const finalSyncOptions = syncOptions ?? config?.syncOptions;
|
|
298
|
-
if (!finalBaseURL) {
|
|
299
|
-
throw new Error("FrappeForm requires baseURL prop or FrappeProvider with baseURL");
|
|
300
|
-
}
|
|
301
|
-
const frappeConfig = (0, import_react2.useMemo)(() => ({
|
|
302
|
-
baseURL: finalBaseURL,
|
|
303
|
-
socketPort: config?.socketPort,
|
|
304
|
-
siteName: config?.siteName,
|
|
305
|
-
socketBaseURL: config?.socketBaseURL,
|
|
306
|
-
auth: finalAuth,
|
|
307
|
-
syncOptions: finalSyncOptions,
|
|
308
|
-
realtime: config?.realtime,
|
|
309
|
-
fixtures: config?.fixtures
|
|
310
|
-
}), [finalBaseURL, config?.socketPort, config?.siteName, config?.socketBaseURL, config?.realtime, finalAuth, finalSyncOptions, config?.fixtures]);
|
|
311
274
|
const {
|
|
312
275
|
meta,
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
276
|
+
metaLoading: isMetaLoading,
|
|
277
|
+
metaError,
|
|
278
|
+
doc: localDoc,
|
|
279
|
+
baseline: baselineDoc,
|
|
280
|
+
setValue,
|
|
281
|
+
errors,
|
|
282
|
+
isSubmitting,
|
|
283
|
+
docstatus,
|
|
284
|
+
isSubmittable,
|
|
285
|
+
rights,
|
|
286
|
+
rightsPending,
|
|
287
|
+
canWrite: canWriteRecord,
|
|
288
|
+
wasDeleted,
|
|
289
|
+
conflictFields,
|
|
290
|
+
docError,
|
|
291
|
+
tabs: formTabs,
|
|
292
|
+
promptNamed,
|
|
293
|
+
activeTab,
|
|
294
|
+
setActiveTab,
|
|
295
|
+
amendedAs
|
|
296
|
+
} = form;
|
|
297
|
+
const frappeConfig = form.connection;
|
|
317
298
|
const isCreate = !name;
|
|
318
|
-
const
|
|
319
|
-
const layoutFields = (0, import_react2.useMemo)(() => {
|
|
320
|
-
if (!meta) return void 0;
|
|
321
|
-
return sections ? sectionsToLayoutFields(sections) : meta.fields;
|
|
322
|
-
}, [meta, sections]);
|
|
323
|
-
const amendedAs = (0, import_useAmendedAs.useAmendedAs)(isSubmittable && docstatus === 2 ? frappeConfig : void 0, doctype, name);
|
|
299
|
+
const hasUnsavedChanges = form.isDirty;
|
|
324
300
|
const readsWithoutMeta = !children && !meta && Boolean(metaError) && Boolean(name);
|
|
325
301
|
const recordTabs = (0, import_react2.useMemo)(() => {
|
|
326
302
|
if (!readsWithoutMeta || !baselineDoc) return void 0;
|
|
327
|
-
const recordFields =
|
|
303
|
+
const recordFields = schemaFieldsFromRecord(baselineDoc);
|
|
328
304
|
return [{
|
|
329
305
|
key: "__details",
|
|
330
306
|
label: t("Details"),
|
|
@@ -338,87 +314,7 @@ function FrappeFormBody({
|
|
|
338
314
|
}
|
|
339
315
|
}];
|
|
340
316
|
}, [readsWithoutMeta, baselineDoc, t]);
|
|
341
|
-
const
|
|
342
|
-
const fetchMap = (0, import_react2.useMemo)(() => meta ? (0, import_fetchFrom.buildFetchMap)(meta.fields) : void 0, [meta]);
|
|
343
|
-
const handleDocSyncError = (0, import_react2.useCallback)(err => {
|
|
344
|
-
setDocError(err instanceof Error ? err : new Error(String(err)));
|
|
345
|
-
}, []);
|
|
346
|
-
const docCollection = (0, import_frappe.useFrappeCollection)(name ? frappeConfig : void 0, doctype, {
|
|
347
|
-
fields,
|
|
348
|
-
filters: name ? {
|
|
349
|
-
name
|
|
350
|
-
} : void 0,
|
|
351
|
-
onSyncError: handleDocSyncError
|
|
352
|
-
});
|
|
353
|
-
const {
|
|
354
|
-
data: rawDocData,
|
|
355
|
-
isLoading: isDocLoading
|
|
356
|
-
} = (0, import_frappe.useLiveQuery)(q => {
|
|
357
|
-
if (!docCollection || !name) return null;
|
|
358
|
-
return q.from({
|
|
359
|
-
_doc: docCollection
|
|
360
|
-
}).where(({
|
|
361
|
-
_doc
|
|
362
|
-
}) => {
|
|
363
|
-
if (!_doc) return (0, import_db.eq)(name, name);
|
|
364
|
-
return (0, import_db.eq)(_doc.name, name);
|
|
365
|
-
});
|
|
366
|
-
}, [docCollection, name]);
|
|
367
|
-
const liveDoc = (0, import_react2.useMemo)(() => {
|
|
368
|
-
const arr = Array.isArray(rawDocData) ? rawDocData : rawDocData ? [rawDocData] : [];
|
|
369
|
-
const doc = arr[0] ?? null;
|
|
370
|
-
return doc ? {
|
|
371
|
-
data: doc,
|
|
372
|
-
isLoading: isDocLoading
|
|
373
|
-
} : name ? {
|
|
374
|
-
data: null,
|
|
375
|
-
isLoading: isDocLoading
|
|
376
|
-
} : null;
|
|
377
|
-
}, [rawDocData, isDocLoading, name]);
|
|
378
|
-
const collection = (0, import_frappe.useFrappeCollection)(name ? void 0 : frappeConfig, doctype, {
|
|
379
|
-
fields
|
|
380
|
-
});
|
|
381
|
-
const shareCollection = (0, import_frappe.useFrappeCollection)(showSidebar && name ? frappeConfig : void 0, "DocShare", {
|
|
382
|
-
fields: ["name", "user", "everyone", "read", "write", "share"],
|
|
383
|
-
filters: {
|
|
384
|
-
share_doctype: doctype,
|
|
385
|
-
share_name: name
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
const {
|
|
389
|
-
data: rawShareRows
|
|
390
|
-
} = (0, import_frappe.useLiveQuery)(q => shareCollection ? q.from({
|
|
391
|
-
_share: shareCollection
|
|
392
|
-
}) : null, [shareCollection]);
|
|
393
|
-
const shareRows = (0, import_react2.useMemo)(() => shareCollection ? rawShareRows ?? [] : void 0, [shareCollection, rawShareRows]);
|
|
394
|
-
const owner = baselineDoc?.owner;
|
|
395
|
-
const {
|
|
396
|
-
rights,
|
|
397
|
-
pending: rightsPending,
|
|
398
|
-
roles: effectiveRoles
|
|
399
|
-
} = (0, import_useDocRights.useDocRights)(frappeConfig, meta, {
|
|
400
|
-
roles,
|
|
401
|
-
owner: typeof owner === "string" ? owner : void 0,
|
|
402
|
-
shares: shareRows
|
|
403
|
-
});
|
|
404
|
-
const permLevels = (0, import_react2.useMemo)(() => (0, import_fieldPermissions.buildPermLevelMatrix)(meta?.permissions, effectiveRoles), [meta?.permissions, effectiveRoles]);
|
|
405
|
-
const formTabs = (0, import_react2.useMemo)(() => {
|
|
406
|
-
if (!layoutFields) return void 0;
|
|
407
|
-
return (0, import_formLayout.buildFormTabs)({
|
|
408
|
-
fields: layoutFields,
|
|
409
|
-
doc: {
|
|
410
|
-
...localDoc,
|
|
411
|
-
__islocal: isCreate ? 1 : 0
|
|
412
|
-
},
|
|
413
|
-
docstatus,
|
|
414
|
-
formReadOnly: !!meta?.read_only,
|
|
415
|
-
isCreate,
|
|
416
|
-
detailsLabel: t("Details"),
|
|
417
|
-
permLevels,
|
|
418
|
-
hiddenFields: hideFields
|
|
419
|
-
});
|
|
420
|
-
}, [layoutFields, localDoc, docstatus, meta?.read_only, isCreate, permLevels, hideFields, t]);
|
|
421
|
-
const assignmentCollection = (0, import_frappe.useFrappeCollection)(showSidebar && name && !frappeConfig.fixtures ? frappeConfig : void 0, "ToDo", {
|
|
317
|
+
const assignmentCollection = (0, import_frappe.useFrappeCollection)(showSidebar && name && frappeConfig && !frappeConfig.fixtures ? frappeConfig : void 0, "ToDo", {
|
|
422
318
|
fields: ["name", "allocated_to", "status", "reference_type", "reference_name"],
|
|
423
319
|
filters: {
|
|
424
320
|
reference_type: doctype,
|
|
@@ -432,16 +328,6 @@ function FrappeFormBody({
|
|
|
432
328
|
_assignment: assignmentCollection
|
|
433
329
|
}) : null, [assignmentCollection]);
|
|
434
330
|
const assignmentRows = (0, import_react2.useMemo)(() => assignmentCollection ? rawAssignmentRows ?? [] : void 0, [assignmentCollection, rawAssignmentRows]);
|
|
435
|
-
(0, import_react2.useEffect)(() => {
|
|
436
|
-
everLoadedRef.current = false;
|
|
437
|
-
if (name) createDraftRef.current = void 0;
|
|
438
|
-
setWasDeleted(false);
|
|
439
|
-
setConflictFields([]);
|
|
440
|
-
setDocError(null);
|
|
441
|
-
const seed = seedRef.current;
|
|
442
|
-
setBaselineDoc(seed);
|
|
443
|
-
if (seed) setLocalDoc(seed);
|
|
444
|
-
}, [doctype, name]);
|
|
445
331
|
const effectiveConnections = (0, import_react2.useMemo)(() => connections ?? (0, import_frappeConnections.connectionsFromMeta)(meta), [connections, meta]);
|
|
446
332
|
const readsConnections = Boolean(children) && Boolean(name) && effectiveConnections.length > 0;
|
|
447
333
|
const [connectionSnapshots, setConnectionSnapshots] = (0, import_react2.useState)({});
|
|
@@ -472,262 +358,48 @@ function FrappeFormBody({
|
|
|
472
358
|
const connectionsLoading = connectionReads.some(({
|
|
473
359
|
link
|
|
474
360
|
}) => connectionSnapshots[link.doctype]?.isLoading ?? true);
|
|
475
|
-
(0, import_frappe.useFrappeDoctypeEvents)(name ? frappeConfig : void 0, doctype, event => {
|
|
476
|
-
if (event.type !== "doc_deleted") return;
|
|
477
|
-
const payload = event.payload;
|
|
478
|
-
if (payload?.name === name) setWasDeleted(true);
|
|
479
|
-
}, Boolean(name));
|
|
480
|
-
(0, import_react2.useEffect)(() => {
|
|
481
|
-
const incoming = liveDoc?.data;
|
|
482
|
-
if (incoming) {
|
|
483
|
-
everLoadedRef.current = true;
|
|
484
|
-
setWasDeleted(false);
|
|
485
|
-
const baseline = baselineRef.current;
|
|
486
|
-
if (!baseline) {
|
|
487
|
-
setBaselineDoc(incoming);
|
|
488
|
-
setLocalDoc(incoming);
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
const local = localDocRef.current;
|
|
492
|
-
const merged = {
|
|
493
|
-
...incoming
|
|
494
|
-
};
|
|
495
|
-
const newConflicts = [];
|
|
496
|
-
for (const key of Object.keys(local)) {
|
|
497
|
-
const localValue = local[key];
|
|
498
|
-
if (localValue === baseline[key]) continue;
|
|
499
|
-
merged[key] = localValue;
|
|
500
|
-
const remote = incoming[key];
|
|
501
|
-
if (remote !== baseline[key] && remote !== localValue) newConflicts.push(key);
|
|
502
|
-
}
|
|
503
|
-
setBaselineDoc(incoming);
|
|
504
|
-
setLocalDoc(merged);
|
|
505
|
-
if (newConflicts.length > 0) {
|
|
506
|
-
setConflictFields(prev => Array.from(/* @__PURE__ */new Set([...prev, ...newConflicts])));
|
|
507
|
-
}
|
|
508
|
-
} else if (name && everLoadedRef.current && !liveDoc?.isLoading) {
|
|
509
|
-
setWasDeleted(true);
|
|
510
|
-
} else if (!name) {
|
|
511
|
-
if (createDraftRef.current?.doctype !== doctype) {
|
|
512
|
-
createDraftRef.current = {
|
|
513
|
-
doctype,
|
|
514
|
-
values: (0, import_createPrefill.takeCreatePrefill)(doctype)
|
|
515
|
-
};
|
|
516
|
-
}
|
|
517
|
-
setLocalDoc({
|
|
518
|
-
...createDraftRef.current.values,
|
|
519
|
-
doctype
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
}, [liveDoc?.data, liveDoc?.isLoading, doctype, name]);
|
|
523
|
-
const dirtyFieldNames = (0, import_react2.useMemo)(() => {
|
|
524
|
-
const local = localDoc;
|
|
525
|
-
const base = baselineDoc;
|
|
526
|
-
const dirty = [];
|
|
527
|
-
for (const key of Object.keys(local)) {
|
|
528
|
-
if (key === "doctype" || key === "name") continue;
|
|
529
|
-
if (base ? local[key] !== base[key] : local[key] !== void 0) dirty.push(key);
|
|
530
|
-
}
|
|
531
|
-
return dirty;
|
|
532
|
-
}, [localDoc, baselineDoc]);
|
|
533
|
-
const hasUnsavedChanges = dirtyFieldNames.length > 0;
|
|
534
|
-
const runFetchFrom = (field, value) => {
|
|
535
|
-
const rules = fetchMap?.get(field);
|
|
536
|
-
if (!rules || rules.length === 0) return;
|
|
537
|
-
const applyPatch = fetched2 => {
|
|
538
|
-
setLocalDoc(prev => {
|
|
539
|
-
const current = prev;
|
|
540
|
-
if (current[field] !== value) return prev;
|
|
541
|
-
const patch = (0, import_fetchFrom.applyFetchedValues)(rules, fetched2, current);
|
|
542
|
-
return Object.keys(patch).length > 0 ? {
|
|
543
|
-
...current,
|
|
544
|
-
...patch
|
|
545
|
-
} : prev;
|
|
546
|
-
});
|
|
547
|
-
};
|
|
548
|
-
if (isEmptyFieldValue(value)) {
|
|
549
|
-
applyPatch({});
|
|
550
|
-
return;
|
|
551
|
-
}
|
|
552
|
-
const linkField = meta?.fields.find(metaField => metaField.fieldname === field);
|
|
553
|
-
const targetDoctype = typeof linkField?.options === "string" ? linkField.options : "";
|
|
554
|
-
if (!targetDoctype) return;
|
|
555
|
-
const sources = Array.from(new Set(rules.map(rule => rule.source)));
|
|
556
|
-
const fixtures = frappeConfig.fixtures;
|
|
557
|
-
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);
|
|
558
|
-
fetched.then(applyPatch).catch(() => void 0);
|
|
559
|
-
};
|
|
560
|
-
const setValue = (field, value) => {
|
|
561
|
-
setLocalDoc(prev => ({
|
|
562
|
-
...prev,
|
|
563
|
-
[field]: value
|
|
564
|
-
}));
|
|
565
|
-
setErrors(prev => {
|
|
566
|
-
const newErrors = {
|
|
567
|
-
...prev
|
|
568
|
-
};
|
|
569
|
-
delete newErrors[String(field)];
|
|
570
|
-
return newErrors;
|
|
571
|
-
});
|
|
572
|
-
runFetchFrom(String(field), value);
|
|
573
|
-
};
|
|
574
|
-
const validateRequiredFields = () => {
|
|
575
|
-
if (!formTabs) return {};
|
|
576
|
-
const validationErrors = {};
|
|
577
|
-
const doc = localDoc;
|
|
578
|
-
if (promptNamed && isEmptyFieldValue(doc.name)) {
|
|
579
|
-
validationErrors.name = t("Name is required");
|
|
580
|
-
}
|
|
581
|
-
for (const tab of formTabs) {
|
|
582
|
-
for (const field of tab.schema.fields) {
|
|
583
|
-
if (!field.required) continue;
|
|
584
|
-
if (isEmptyFieldValue(doc[field.name])) {
|
|
585
|
-
validationErrors[field.name] = t("{{label}} is required", {
|
|
586
|
-
label: field.label || field.name
|
|
587
|
-
});
|
|
588
|
-
}
|
|
589
|
-
}
|
|
590
|
-
}
|
|
591
|
-
return validationErrors;
|
|
592
|
-
};
|
|
593
|
-
const canWriteRecord = isCreate ? rights.create : rights.write;
|
|
594
361
|
const handleSave = async () => {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
}
|
|
601
|
-
setIsSubmitting(true);
|
|
602
|
-
setErrors({});
|
|
603
|
-
try {
|
|
604
|
-
if (name) {
|
|
605
|
-
if (!docCollection) return;
|
|
606
|
-
const changedFields = dirtyFieldNames;
|
|
607
|
-
if (changedFields.length > 0) {
|
|
608
|
-
const local = localDoc;
|
|
609
|
-
const tx = docCollection.update(name, draft => {
|
|
610
|
-
for (const key of changedFields) {
|
|
611
|
-
draft[key] = local[key];
|
|
612
|
-
}
|
|
613
|
-
});
|
|
614
|
-
await tx.isPersisted.promise;
|
|
615
|
-
}
|
|
616
|
-
setConflictFields([]);
|
|
617
|
-
} else {
|
|
618
|
-
if (!collection) return;
|
|
619
|
-
const temporaryName = localDoc.name ?? `new-${Date.now()}`;
|
|
620
|
-
const docToInsert = {
|
|
621
|
-
...localDoc,
|
|
622
|
-
doctype,
|
|
623
|
-
name: temporaryName
|
|
624
|
-
};
|
|
625
|
-
const tx = collection.insert(docToInsert);
|
|
626
|
-
await tx.isPersisted.promise;
|
|
627
|
-
const createdName = (0, import_frappe.getFrappeSyncModule)(frappeConfig)?.createdName(temporaryName) ?? temporaryName;
|
|
628
|
-
onSave?.({
|
|
629
|
-
...localDoc,
|
|
630
|
-
name: createdName
|
|
631
|
-
});
|
|
632
|
-
return;
|
|
633
|
-
}
|
|
634
|
-
onSave?.(localDoc);
|
|
635
|
-
} catch (err) {
|
|
636
|
-
const e = err;
|
|
637
|
-
if (e?.exc_type === "ValidationError") {
|
|
638
|
-
const validationErrors = {};
|
|
639
|
-
if (e._server_messages) {
|
|
640
|
-
try {
|
|
641
|
-
const messages = JSON.parse(e._server_messages);
|
|
642
|
-
for (const msg of messages) {
|
|
643
|
-
const parsed = typeof msg === "string" ? JSON.parse(msg) : msg;
|
|
644
|
-
if (parsed.message) {
|
|
645
|
-
validationErrors.general = parsed.message;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
} catch {
|
|
649
|
-
validationErrors.general = t("Validation error occurred");
|
|
650
|
-
}
|
|
651
|
-
}
|
|
652
|
-
setErrors(validationErrors);
|
|
653
|
-
} else {
|
|
654
|
-
setErrors({
|
|
655
|
-
general: e?.message || t("Failed to save document")
|
|
656
|
-
});
|
|
657
|
-
}
|
|
658
|
-
} finally {
|
|
659
|
-
setIsSubmitting(false);
|
|
660
|
-
}
|
|
362
|
+
const saved = await form.save();
|
|
363
|
+
if (!saved) return;
|
|
364
|
+
onSave?.(isCreate ? {
|
|
365
|
+
...localDoc,
|
|
366
|
+
name: saved
|
|
367
|
+
} : localDoc);
|
|
661
368
|
};
|
|
662
369
|
const handleCancel = () => {
|
|
663
|
-
|
|
664
|
-
setLocalDoc(baselineDoc);
|
|
665
|
-
} else if (liveDoc?.data) {
|
|
666
|
-
setLocalDoc(liveDoc.data);
|
|
667
|
-
} else {
|
|
668
|
-
setLocalDoc({
|
|
669
|
-
doctype
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
setConflictFields([]);
|
|
673
|
-
setErrors({});
|
|
370
|
+
form.reset();
|
|
674
371
|
onCancel?.();
|
|
675
372
|
};
|
|
676
373
|
const handleDelete = async () => {
|
|
677
|
-
if (!
|
|
374
|
+
if (!name || wasDeleted || !rights.delete) return;
|
|
678
375
|
if (!(await import_desktop.dialog.confirm(t("Delete this {{doctype}}?", {
|
|
679
376
|
doctype
|
|
680
377
|
})))) return;
|
|
681
|
-
|
|
682
|
-
setErrors({});
|
|
683
|
-
try {
|
|
684
|
-
const tx = docCollection.delete(name);
|
|
685
|
-
await tx.isPersisted.promise;
|
|
686
|
-
onDelete?.(localDoc);
|
|
687
|
-
} catch (err) {
|
|
688
|
-
setErrors({
|
|
689
|
-
general: err?.message || t("Failed to delete")
|
|
690
|
-
});
|
|
691
|
-
} finally {
|
|
692
|
-
setIsSubmitting(false);
|
|
693
|
-
}
|
|
378
|
+
if (await form.remove()) onDelete?.(localDoc);
|
|
694
379
|
};
|
|
695
|
-
const
|
|
696
|
-
if (!
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
return;
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
if (!(await import_desktop.dialog.confirm(question))) return;
|
|
705
|
-
setIsSubmitting(true);
|
|
706
|
-
setErrors({});
|
|
707
|
-
try {
|
|
708
|
-
const tx = docCollection.update(name, draft => {
|
|
709
|
-
draft.docstatus = to;
|
|
710
|
-
});
|
|
711
|
-
await tx.isPersisted.promise;
|
|
712
|
-
} catch (err) {
|
|
713
|
-
setErrors({
|
|
714
|
-
general: (0, import_useFormEngine.extractServerError)(err, failure)
|
|
715
|
-
});
|
|
716
|
-
} finally {
|
|
717
|
-
setIsSubmitting(false);
|
|
380
|
+
const handleSubmitDocument = async () => {
|
|
381
|
+
if (!name || wasDeleted || !rights.submit) return;
|
|
382
|
+
const requiredErrors = form.validate();
|
|
383
|
+
if (Object.keys(requiredErrors).length > 0) {
|
|
384
|
+
form.setErrors(requiredErrors);
|
|
385
|
+
return;
|
|
718
386
|
}
|
|
387
|
+
if (!(await import_desktop.dialog.confirm(t("Permanently Submit {{name}}?", {
|
|
388
|
+
name
|
|
389
|
+
})))) return;
|
|
390
|
+
await form.submitDocument();
|
|
391
|
+
};
|
|
392
|
+
const handleCancelDocument = async () => {
|
|
393
|
+
if (!name || wasDeleted || !rights.cancel) return;
|
|
394
|
+
if (!(await import_desktop.dialog.confirm(t("Permanently Cancel {{name}}?", {
|
|
395
|
+
name
|
|
396
|
+
})))) return;
|
|
397
|
+
await form.cancelDocument();
|
|
719
398
|
};
|
|
720
|
-
const handleSubmitDocument = () => transitionDocstatus(1, t("Permanently Submit {{name}}?", {
|
|
721
|
-
name
|
|
722
|
-
}), t("Failed to submit"));
|
|
723
|
-
const handleCancelDocument = () => transitionDocstatus(2, t("Permanently Cancel {{name}}?", {
|
|
724
|
-
name
|
|
725
|
-
}), t("Failed to cancel"));
|
|
726
399
|
const handleAmend = () => {
|
|
727
|
-
if (!
|
|
728
|
-
const draft =
|
|
729
|
-
(
|
|
730
|
-
onAmend(draft);
|
|
400
|
+
if (!onAmend) return;
|
|
401
|
+
const draft = form.amend();
|
|
402
|
+
if (draft) onAmend(draft);
|
|
731
403
|
};
|
|
732
404
|
const titleField = meta?.title_field;
|
|
733
405
|
const titleValue = titleField ? localDoc[titleField] : void 0;
|
|
@@ -787,27 +459,34 @@ function FrappeFormBody({
|
|
|
787
459
|
}));
|
|
788
460
|
}
|
|
789
461
|
if (!children && metaError && !meta && !name) {
|
|
790
|
-
return frame(/* @__PURE__ */(0, import_jsx_runtime.
|
|
462
|
+
return frame((0, import_liveErrors.isPermissionError)(metaError) ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.EmptyState, {
|
|
463
|
+
testID: "frappe-form-not-permitted",
|
|
464
|
+
title: t("You can't create {{doctype}}", {
|
|
465
|
+
doctype
|
|
466
|
+
}),
|
|
467
|
+
description: metaError.message
|
|
468
|
+
}) : /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.AsyncBoundary, {
|
|
791
469
|
...knobProps.panelPadding,
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
...knobProps.body,
|
|
797
|
-
children: t("Failed to load {{doctype}} form", {
|
|
798
|
-
doctype
|
|
799
|
-
})
|
|
800
|
-
}), /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
801
|
-
color: import_forms.formCommonColors.muted,
|
|
802
|
-
...knobProps.body,
|
|
803
|
-
children: metaError.message
|
|
804
|
-
})]
|
|
470
|
+
error: metaError,
|
|
471
|
+
errorTitle: t("Failed to load {{doctype}} form", {
|
|
472
|
+
doctype
|
|
473
|
+
})
|
|
805
474
|
}));
|
|
806
475
|
}
|
|
807
|
-
|
|
808
|
-
const showsSeed = Boolean(seedDoc) && isDocReading;
|
|
809
|
-
if (name && docError && !liveDoc?.data && !wasDeleted) {
|
|
476
|
+
if (name && form.status === "error" && docError) {
|
|
810
477
|
if (errorFallback !== void 0) return frame(errorFallback);
|
|
478
|
+
if ((0, import_liveErrors.isPermissionError)(docError)) {
|
|
479
|
+
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.EmptyState, {
|
|
480
|
+
testID: "frappe-form-not-permitted",
|
|
481
|
+
title: t("You can't open {{doctype}} {{name}}", {
|
|
482
|
+
doctype,
|
|
483
|
+
name
|
|
484
|
+
}),
|
|
485
|
+
description: t("Your session can't read this {{doctype}}.", {
|
|
486
|
+
doctype
|
|
487
|
+
})
|
|
488
|
+
}));
|
|
489
|
+
}
|
|
811
490
|
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_components.AsyncBoundary, {
|
|
812
491
|
...knobProps.panelPadding,
|
|
813
492
|
error: docError,
|
|
@@ -816,7 +495,7 @@ function FrappeFormBody({
|
|
|
816
495
|
})
|
|
817
496
|
}));
|
|
818
497
|
}
|
|
819
|
-
if (name &&
|
|
498
|
+
if (name && form.status === "loading") {
|
|
820
499
|
if (loadingFallback !== void 0) return frame(loadingFallback);
|
|
821
500
|
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.YStack, {
|
|
822
501
|
...knobProps.panelPadding,
|
|
@@ -826,7 +505,7 @@ function FrappeFormBody({
|
|
|
826
505
|
})
|
|
827
506
|
}));
|
|
828
507
|
}
|
|
829
|
-
if (name &&
|
|
508
|
+
if (name && form.status === "notFound") {
|
|
830
509
|
if (notFoundFallback !== void 0) return frame(notFoundFallback);
|
|
831
510
|
return frame(/* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_tamagui.YStack, {
|
|
832
511
|
...knobProps.panelPadding,
|
|
@@ -876,15 +555,13 @@ function FrappeFormBody({
|
|
|
876
555
|
const toolbarShown = showToolbar && !readsWithoutMeta && Boolean(indicator || docAction || showDelete || showEdit || showClose);
|
|
877
556
|
const shownTabs = formTabs ?? recordTabs;
|
|
878
557
|
const imageFieldName = meta?.image_field;
|
|
879
|
-
const sidebarImageUrl = imageFieldName ? resolveFileUrl(localDoc[imageFieldName],
|
|
558
|
+
const sidebarImageUrl = imageFieldName ? resolveFileUrl(localDoc[imageFieldName], frappeConfig?.baseURL) : void 0;
|
|
880
559
|
const conflictLabels = conflictFields.map(fieldname => {
|
|
881
560
|
const field = meta?.fields.find(metaField => metaField.fieldname === fieldname);
|
|
882
561
|
return field?.label || fieldname;
|
|
883
562
|
}).join(", ");
|
|
884
|
-
const formTabItems = (shownTabs ?? []).map(tab =>
|
|
885
|
-
|
|
886
|
-
label: tab.label,
|
|
887
|
-
content: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_schemaForm.SchemaForm, {
|
|
563
|
+
const formTabItems = (shownTabs ?? []).map(tab => {
|
|
564
|
+
const content = /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_schemaForm.SchemaForm, {
|
|
888
565
|
schema: tab.schema,
|
|
889
566
|
doc: localDoc,
|
|
890
567
|
setValue: (field, value) => setValue(field, value),
|
|
@@ -893,10 +570,16 @@ function FrappeFormBody({
|
|
|
893
570
|
overrides,
|
|
894
571
|
readOnlyFields,
|
|
895
572
|
sectionHeadingLevel,
|
|
896
|
-
order
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
573
|
+
order,
|
|
574
|
+
renderFieldWrapper
|
|
575
|
+
});
|
|
576
|
+
return {
|
|
577
|
+
value: tab.key,
|
|
578
|
+
label: tab.label,
|
|
579
|
+
content: renderTab ? renderTab(tab, content) : content
|
|
580
|
+
};
|
|
581
|
+
});
|
|
582
|
+
const tabItems = [...formTabItems, ...(showConnections && name && frappeConfig && effectiveConnections.length > 0 ? [{
|
|
900
583
|
value: "__connections",
|
|
901
584
|
label: t("Connections"),
|
|
902
585
|
content: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeFormConnections.FrappeFormConnections, {
|
|
@@ -904,12 +587,12 @@ function FrappeFormBody({
|
|
|
904
587
|
connections: effectiveConnections,
|
|
905
588
|
name
|
|
906
589
|
})
|
|
907
|
-
}] :
|
|
590
|
+
}] : []), ...(extraTabs ?? [])];
|
|
908
591
|
const effectiveTab = activeTab && tabItems.some(tab => tab.value === activeTab) ? activeTab : tabItems[0]?.value;
|
|
909
592
|
const localName = localDoc.name;
|
|
910
593
|
const sidebar = showSidebar && name && meta ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FormSidebar.FormSidebar, {
|
|
911
594
|
imageUrl: sidebarImageUrl,
|
|
912
|
-
sections: buildSidebarSections(localDoc, shareRows, t, assignmentRows),
|
|
595
|
+
sections: buildSidebarSections(localDoc, form.shareRows, t, assignmentRows),
|
|
913
596
|
metadata: mapDocToSidebarMetadata(localDoc, t)
|
|
914
597
|
}) : void 0;
|
|
915
598
|
return frame(
|
|
@@ -923,14 +606,14 @@ function FrappeFormBody({
|
|
|
923
606
|
flexGrow: 1,
|
|
924
607
|
flexShrink: 1,
|
|
925
608
|
flexBasis: "auto",
|
|
926
|
-
children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeReconnectIndicator.FrappeReconnectIndicator, {
|
|
609
|
+
children: [frappeConfig ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeReconnectIndicator.FrappeReconnectIndicator, {
|
|
927
610
|
config: frappeConfig
|
|
928
|
-
}), connectionReads.map(read => /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeRowsReader.FrappeRowsReader, {
|
|
611
|
+
}) : null, frappeConfig ? connectionReads.map(read => /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeRowsReader.FrappeRowsReader, {
|
|
929
612
|
connection: frappeConfig,
|
|
930
613
|
doctype: read.link.doctype,
|
|
931
614
|
options: read.options,
|
|
932
615
|
onChange: read.onChange
|
|
933
|
-
}, read.link.doctype)), wasDeleted && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.XStack, {
|
|
616
|
+
}, read.link.doctype)) : null, showBanners && wasDeleted && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.XStack, {
|
|
934
617
|
role: "alert",
|
|
935
618
|
alignItems: "center",
|
|
936
619
|
...knobProps.containerRadius,
|
|
@@ -946,7 +629,7 @@ function FrappeFormBody({
|
|
|
946
629
|
doctype
|
|
947
630
|
})
|
|
948
631
|
})
|
|
949
|
-
}), !wasDeleted && conflictFields.length > 0 && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.XStack, {
|
|
632
|
+
}), showBanners && !wasDeleted && conflictFields.length > 0 && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.XStack, {
|
|
950
633
|
role: "status",
|
|
951
634
|
alignItems: "center",
|
|
952
635
|
...knobProps.containerRadius,
|
|
@@ -1008,6 +691,7 @@ function FrappeFormBody({
|
|
|
1008
691
|
}), errors.general && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_tamagui.Text, {
|
|
1009
692
|
color: import_forms.formCommonColors.error,
|
|
1010
693
|
...knobProps.body,
|
|
694
|
+
role: "alert",
|
|
1011
695
|
children: errors.general
|
|
1012
696
|
}), toolbarShown && /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_FrappeFormActions.FrappeFormActions, {
|
|
1013
697
|
indicator,
|