@multiplatform.one/frappe-ui 7.28.0 → 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/ChartCard.native.js.map +1 -1
- package/dist/cjs/FileBrowser/AttachLibrary.native.js.map +1 -1
- package/dist/cjs/FileBrowser/folderTree.native.js.map +1 -1
- package/dist/cjs/FileBrowser/index.cjs +20 -3
- package/dist/cjs/FileBrowser/index.native.js +20 -3
- package/dist/cjs/FileBrowser/index.native.js.map +1 -1
- package/dist/cjs/FileBrowser/types.native.js.map +1 -1
- package/dist/cjs/FileBrowser/viewPersistence.native.js.map +1 -1
- package/dist/cjs/FormSidebar.native.js.map +1 -1
- package/dist/cjs/FrappeAssignment.native.js.map +1 -1
- 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/FrappeChartCard.native.js.map +1 -1
- package/dist/cjs/FrappeConnectionIndicator.native.js.map +1 -1
- package/dist/cjs/FrappeDashboard.native.js.map +1 -1
- package/dist/cjs/FrappeForm.cjs +148 -464
- package/dist/cjs/FrappeForm.native.js +153 -634
- package/dist/cjs/FrappeForm.native.js.map +1 -1
- package/dist/cjs/FrappeFormActions.native.js.map +1 -1
- package/dist/cjs/FrappeFormConnections.native.js.map +1 -1
- package/dist/cjs/FrappeGantt.native.js.map +1 -1
- package/dist/cjs/FrappeImageView.native.js.map +1 -1
- package/dist/cjs/FrappeInsights.native.js.map +1 -1
- package/dist/cjs/FrappeKPICard.native.js.map +1 -1
- package/dist/cjs/FrappeKanban.native.js.map +1 -1
- package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
- package/dist/cjs/FrappeList.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/FrappeNotConfigured.native.js.map +1 -1
- package/dist/cjs/FrappeProvider.native.js.map +1 -1
- package/dist/cjs/FrappeReconnectIndicator.native.js.map +1 -1
- package/dist/cjs/FrappeRecordView.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 +42 -286
- package/dist/cjs/FrappeReportView.native.js.map +1 -1
- package/dist/cjs/FrappeRowsReader.native.js.map +1 -1
- package/dist/cjs/FrappeTable.native.js.map +1 -1
- package/dist/cjs/FrappeTreeView.native.js.map +1 -1
- package/dist/cjs/SyncErrorNotice.native.js.map +1 -1
- package/dist/cjs/commentActions.native.js.map +1 -1
- package/dist/cjs/components/attachments.native.js.map +1 -1
- package/dist/cjs/components/tags.native.js.map +1 -1
- package/dist/cjs/components/timeline.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/desk/DeskFormPage.native.js.map +1 -1
- package/dist/cjs/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/cjs/desk/DeskListPage.native.js.map +1 -1
- package/dist/cjs/desk/DeskShell.native.js.map +1 -1
- package/dist/cjs/desk/DeskSidebar.native.js.map +1 -1
- package/dist/cjs/desk/awesomebar.native.js.map +1 -1
- package/dist/cjs/fieldOverrides.native.js.map +1 -1
- package/dist/cjs/fieldRegistry.native.js +31 -31
- package/dist/cjs/fieldRegistry.native.js.map +1 -1
- package/dist/cjs/fields/Barcode/index.native.js.map +1 -1
- package/dist/cjs/fields/Check/index.native.js.map +1 -1
- package/dist/cjs/fields/CodeEditor/index.native.js.map +1 -1
- package/dist/cjs/fields/Color/index.native.js.map +1 -1
- package/dist/cjs/fields/Data/index.native.js.map +1 -1
- package/dist/cjs/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/cjs/fields/Date/types.native.js.map +1 -1
- package/dist/cjs/fields/Date/wire.native.js.map +1 -1
- package/dist/cjs/fields/DateRange/index.native.js.map +1 -1
- package/dist/cjs/fields/Duration/index.native.js.map +1 -1
- package/dist/cjs/fields/DynamicLink.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload.native.js.map +1 -1
- package/dist/cjs/fields/FileUploadField/index.native.js.map +1 -1
- package/dist/cjs/fields/Geolocation/index.native.js.map +1 -1
- package/dist/cjs/fields/HTML/index.native.js.map +1 -1
- package/dist/cjs/fields/Heading/index.native.js.map +1 -1
- package/dist/cjs/fields/Icon/index.native.js.map +1 -1
- package/dist/cjs/fields/Link.native.js.map +1 -1
- package/dist/cjs/fields/LinkTree.native.js.map +1 -1
- package/dist/cjs/fields/LongText/index.native.js.map +1 -1
- package/dist/cjs/fields/MentionInput/index.native.js.map +1 -1
- package/dist/cjs/fields/Numeric/index.native.js.map +1 -1
- package/dist/cjs/fields/OTPInput/index.native.js.map +1 -1
- package/dist/cjs/fields/Password/index.native.js.map +1 -1
- package/dist/cjs/fields/Phone/index.native.js.map +1 -1
- package/dist/cjs/fields/Progress/index.native.js.map +1 -1
- package/dist/cjs/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/cjs/fields/Rating/index.native.js.map +1 -1
- package/dist/cjs/fields/ReadOnly/index.native.js.map +1 -1
- package/dist/cjs/fields/Select/index.native.js.map +1 -1
- package/dist/cjs/fields/Signature/index.native.js.map +1 -1
- package/dist/cjs/fields/Slider/index.native.js.map +1 -1
- package/dist/cjs/fields/SmallText/index.native.js.map +1 -1
- package/dist/cjs/fields/Switch/index.native.js.map +1 -1
- package/dist/cjs/fields/TableMultiSelect.native.js.map +1 -1
- package/dist/cjs/fields/TextEditor/types.native.js.map +1 -1
- package/dist/cjs/fields/TimePicker/index.native.js.map +1 -1
- package/dist/cjs/fields/ToggleGroup/index.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/filterFields.native.js.map +1 -1
- package/dist/cjs/formEngine/createPrefill.native.js.map +1 -1
- package/dist/cjs/formEngine/dirtyTracking.native.js.map +1 -1
- package/dist/cjs/formEngine/docLifecycle.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/doctypeMeta.native.js.map +1 -1
- package/dist/cjs/formEngine/fetchFrom.native.js.map +1 -1
- package/dist/cjs/formEngine/fieldPermissions.native.js.map +1 -1
- package/dist/cjs/formEngine/formActions.native.js.map +1 -1
- package/dist/cjs/formEngine/formLayout.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/formEngine/useAmendedAs.native.js.map +1 -1
- package/dist/cjs/formEngine/useDocRights.native.js.map +1 -1
- package/dist/cjs/formEngine/useFormEngine.native.js.map +1 -1
- package/dist/cjs/formEngine/useSessionRoles.native.js.map +1 -1
- package/dist/cjs/frappeConnections.native.js.map +1 -1
- package/dist/cjs/frappeEventColor.native.js.map +1 -1
- package/dist/cjs/frappeNavigation.native.js.map +1 -1
- package/dist/cjs/frappeStoryTarget.native.js.map +1 -1
- package/dist/cjs/frappeUsers.native.js.map +1 -1
- package/dist/cjs/index.cjs +67 -7
- package/dist/cjs/index.native.js +101 -41
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/insights/InsightsFacetTags.native.js.map +1 -1
- package/dist/cjs/insights/InsightsKpiBand.native.js.map +1 -1
- package/dist/cjs/insights/InsightsLeaders.native.js.map +1 -1
- package/dist/cjs/insights/InsightsRecords.native.js.map +1 -1
- package/dist/cjs/insights/InsightsTable.native.js.map +1 -1
- package/dist/cjs/insights/insightsData.native.js.map +1 -1
- package/dist/cjs/insights/insightsRecord.native.js.map +1 -1
- package/dist/cjs/list/FacetBadge.native.js.map +1 -1
- package/dist/cjs/list/FacetRail.native.js.map +1 -1
- package/dist/cjs/list/ImageWell.native.js.map +1 -1
- package/dist/cjs/list/ListControls.native.js.map +1 -1
- package/dist/cjs/list/ListToastHost.native.js.map +1 -1
- package/dist/cjs/list/RangeFilter.native.js.map +1 -1
- package/dist/cjs/list/ShufflePanel.native.js.map +1 -1
- package/dist/cjs/list/facetReading.native.js.map +1 -1
- package/dist/cjs/list/favorites.native.js.map +1 -1
- package/dist/cjs/list/listColumns.native.js.map +1 -1
- package/dist/cjs/list/listFields.native.js.map +1 -1
- package/dist/cjs/list/listFormat.native.js.map +1 -1
- package/dist/cjs/list/listState.native.js.map +1 -1
- package/dist/cjs/list/recordLook.native.js.map +1 -1
- package/dist/cjs/list/statusColors.native.js.map +1 -1
- package/dist/cjs/list/useListControls.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/record/RecordBars.native.js.map +1 -1
- package/dist/cjs/record/RecordGallery.native.js.map +1 -1
- package/dist/cjs/record/RecordHero.native.js.map +1 -1
- package/dist/cjs/record/RecordPage.native.js.map +1 -1
- package/dist/cjs/record/RecordPager.native.js.map +1 -1
- package/dist/cjs/record/RecordRows.native.js.map +1 -1
- package/dist/cjs/record/recordData.native.js.map +1 -1
- package/dist/cjs/record/recordSections.native.js.map +1 -1
- 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/resolveControl.native.js.map +1 -1
- package/dist/cjs/schemaForm/SchemaWizard.native.js.map +1 -1
- package/dist/cjs/schemaForm/applyFieldOrder.native.js.map +1 -1
- package/dist/cjs/schemaForm/index.native.js +1 -1
- package/dist/cjs/schemaForm/index.native.js.map +1 -1
- package/dist/cjs/shared/devWarn.native.js.map +1 -1
- package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/cjs/syncError.native.js.map +1 -1
- package/dist/cjs/useConnectionFilters.native.js.map +1 -1
- package/dist/cjs/useFrappeAggregate.native.js.map +1 -1
- package/dist/cjs/useFrappeFacets.native.js.map +1 -1
- 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/cjs/useFrappePagination.native.js.map +1 -1
- package/dist/cjs/useFrappeRows.native.js.map +1 -1
- package/dist/esm/ChartCard.native.js.map +1 -1
- package/dist/esm/FileBrowser/AttachLibrary.native.js.map +1 -1
- package/dist/esm/FileBrowser/folderTree.native.js.map +1 -1
- package/dist/esm/FileBrowser/index.mjs +20 -3
- package/dist/esm/FileBrowser/index.mjs.map +1 -1
- package/dist/esm/FileBrowser/index.native.js +20 -3
- package/dist/esm/FileBrowser/index.native.js.map +1 -1
- package/dist/esm/FileBrowser/types.native.js.map +1 -1
- package/dist/esm/FileBrowser/viewPersistence.native.js.map +1 -1
- package/dist/esm/FormSidebar.native.js.map +1 -1
- package/dist/esm/FrappeAssignment.native.js.map +1 -1
- 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/FrappeChartCard.native.js.map +1 -1
- package/dist/esm/FrappeConnectionIndicator.native.js.map +1 -1
- package/dist/esm/FrappeDashboard.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/FrappeFormActions.native.js.map +1 -1
- package/dist/esm/FrappeFormConnections.native.js.map +1 -1
- package/dist/esm/FrappeGantt.native.js.map +1 -1
- package/dist/esm/FrappeImageView.native.js.map +1 -1
- package/dist/esm/FrappeInsights.native.js.map +1 -1
- package/dist/esm/FrappeKPICard.native.js.map +1 -1
- package/dist/esm/FrappeKanban.native.js.map +1 -1
- package/dist/esm/FrappeLikedBy.native.js.map +1 -1
- package/dist/esm/FrappeList.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/FrappeNotConfigured.native.js.map +1 -1
- package/dist/esm/FrappeProvider.native.js.map +1 -1
- package/dist/esm/FrappeReconnectIndicator.native.js.map +1 -1
- package/dist/esm/FrappeRecordView.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/FrappeRowsReader.native.js.map +1 -1
- package/dist/esm/FrappeTable.native.js.map +1 -1
- package/dist/esm/FrappeTreeView.native.js.map +1 -1
- package/dist/esm/SyncErrorNotice.native.js.map +1 -1
- package/dist/esm/commentActions.native.js.map +1 -1
- package/dist/esm/components/attachments.native.js.map +1 -1
- package/dist/esm/components/tags.native.js.map +1 -1
- package/dist/esm/components/timeline.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/desk/DeskFormPage.native.js.map +1 -1
- package/dist/esm/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/esm/desk/DeskListPage.native.js.map +1 -1
- package/dist/esm/desk/DeskShell.native.js.map +1 -1
- package/dist/esm/desk/DeskSidebar.native.js.map +1 -1
- package/dist/esm/desk/awesomebar.native.js.map +1 -1
- package/dist/esm/fieldOverrides.native.js.map +1 -1
- package/dist/esm/fieldRegistry.native.js.map +1 -1
- package/dist/esm/fields/Barcode/index.native.js.map +1 -1
- package/dist/esm/fields/Check/index.native.js.map +1 -1
- package/dist/esm/fields/CodeEditor/index.native.js.map +1 -1
- package/dist/esm/fields/Color/index.native.js.map +1 -1
- package/dist/esm/fields/Data/index.native.js.map +1 -1
- package/dist/esm/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/esm/fields/Date/types.native.js.map +1 -1
- package/dist/esm/fields/Date/wire.native.js.map +1 -1
- package/dist/esm/fields/DateRange/index.native.js.map +1 -1
- package/dist/esm/fields/Duration/index.native.js.map +1 -1
- package/dist/esm/fields/DynamicLink.native.js.map +1 -1
- package/dist/esm/fields/FileUpload.native.js.map +1 -1
- package/dist/esm/fields/FileUploadField/index.native.js.map +1 -1
- package/dist/esm/fields/Geolocation/index.native.js.map +1 -1
- package/dist/esm/fields/HTML/index.native.js.map +1 -1
- package/dist/esm/fields/Heading/index.native.js.map +1 -1
- package/dist/esm/fields/Icon/index.native.js.map +1 -1
- package/dist/esm/fields/Link.native.js.map +1 -1
- package/dist/esm/fields/LinkTree.native.js.map +1 -1
- package/dist/esm/fields/LongText/index.native.js.map +1 -1
- package/dist/esm/fields/MentionInput/index.native.js.map +1 -1
- package/dist/esm/fields/Numeric/index.native.js.map +1 -1
- package/dist/esm/fields/OTPInput/index.native.js.map +1 -1
- package/dist/esm/fields/Password/index.native.js.map +1 -1
- package/dist/esm/fields/Phone/index.native.js.map +1 -1
- package/dist/esm/fields/Progress/index.native.js.map +1 -1
- package/dist/esm/fields/RadioGroup/index.native.js.map +1 -1
- package/dist/esm/fields/Rating/index.native.js.map +1 -1
- package/dist/esm/fields/ReadOnly/index.native.js.map +1 -1
- package/dist/esm/fields/Select/index.native.js.map +1 -1
- package/dist/esm/fields/Signature/index.native.js.map +1 -1
- package/dist/esm/fields/Slider/index.native.js.map +1 -1
- package/dist/esm/fields/SmallText/index.native.js.map +1 -1
- package/dist/esm/fields/Switch/index.native.js.map +1 -1
- package/dist/esm/fields/TableMultiSelect.native.js.map +1 -1
- package/dist/esm/fields/TextEditor/types.native.js.map +1 -1
- package/dist/esm/fields/TimePicker/index.native.js.map +1 -1
- package/dist/esm/fields/ToggleGroup/index.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/filterFields.native.js.map +1 -1
- package/dist/esm/formEngine/createPrefill.native.js.map +1 -1
- package/dist/esm/formEngine/dirtyTracking.native.js.map +1 -1
- package/dist/esm/formEngine/docLifecycle.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/doctypeMeta.native.js.map +1 -1
- package/dist/esm/formEngine/fetchFrom.native.js.map +1 -1
- package/dist/esm/formEngine/fieldPermissions.native.js.map +1 -1
- package/dist/esm/formEngine/formActions.native.js.map +1 -1
- package/dist/esm/formEngine/formLayout.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/formEngine/useAmendedAs.native.js.map +1 -1
- package/dist/esm/formEngine/useDocRights.native.js.map +1 -1
- package/dist/esm/formEngine/useFormEngine.native.js.map +1 -1
- package/dist/esm/formEngine/useSessionRoles.native.js.map +1 -1
- package/dist/esm/frappeConnections.native.js.map +1 -1
- package/dist/esm/frappeEventColor.native.js.map +1 -1
- package/dist/esm/frappeNavigation.native.js.map +1 -1
- package/dist/esm/frappeStoryTarget.native.js.map +1 -1
- package/dist/esm/frappeUsers.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/insights/InsightsFacetTags.native.js.map +1 -1
- package/dist/esm/insights/InsightsKpiBand.native.js.map +1 -1
- package/dist/esm/insights/InsightsLeaders.native.js.map +1 -1
- package/dist/esm/insights/InsightsRecords.native.js.map +1 -1
- package/dist/esm/insights/InsightsTable.native.js.map +1 -1
- package/dist/esm/insights/insightsData.native.js.map +1 -1
- package/dist/esm/insights/insightsRecord.native.js.map +1 -1
- package/dist/esm/list/FacetBadge.native.js.map +1 -1
- package/dist/esm/list/FacetRail.native.js.map +1 -1
- package/dist/esm/list/ImageWell.native.js.map +1 -1
- package/dist/esm/list/ListControls.native.js.map +1 -1
- package/dist/esm/list/ListToastHost.native.js.map +1 -1
- package/dist/esm/list/RangeFilter.native.js.map +1 -1
- package/dist/esm/list/ShufflePanel.native.js.map +1 -1
- package/dist/esm/list/facetReading.native.js.map +1 -1
- package/dist/esm/list/favorites.native.js.map +1 -1
- package/dist/esm/list/listColumns.native.js.map +1 -1
- package/dist/esm/list/listFields.native.js.map +1 -1
- package/dist/esm/list/listFormat.native.js.map +1 -1
- package/dist/esm/list/listState.native.js.map +1 -1
- package/dist/esm/list/recordLook.native.js.map +1 -1
- package/dist/esm/list/statusColors.native.js.map +1 -1
- package/dist/esm/list/useListControls.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/record/RecordBars.native.js.map +1 -1
- package/dist/esm/record/RecordGallery.native.js.map +1 -1
- package/dist/esm/record/RecordHero.native.js.map +1 -1
- package/dist/esm/record/RecordPage.native.js.map +1 -1
- package/dist/esm/record/RecordPager.native.js.map +1 -1
- package/dist/esm/record/RecordRows.native.js.map +1 -1
- package/dist/esm/record/recordData.native.js.map +1 -1
- package/dist/esm/record/recordSections.native.js.map +1 -1
- 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/resolveControl.native.js.map +1 -1
- package/dist/esm/schemaForm/SchemaWizard.native.js.map +1 -1
- package/dist/esm/schemaForm/applyFieldOrder.native.js.map +1 -1
- package/dist/esm/schemaForm/index.native.js.map +1 -1
- package/dist/esm/shared/devWarn.native.js.map +1 -1
- package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/esm/syncError.native.js.map +1 -1
- package/dist/esm/useConnectionFilters.native.js.map +1 -1
- package/dist/esm/useFrappeAggregate.native.js.map +1 -1
- package/dist/esm/useFrappeFacets.native.js.map +1 -1
- 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/esm/useFrappePagination.native.js.map +1 -1
- package/dist/esm/useFrappeRows.native.js.map +1 -1
- package/dist/jsx/FileBrowser/index.mjs +20 -3
- package/dist/jsx/FileBrowser/index.mjs.map +1 -1
- package/dist/jsx/FileBrowser/index.native.js +20 -3
- package/dist/jsx/FileBrowser/index.native.js.map +1 -1
- 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/FileBrowser/FileBrowser.spec.tsx +21 -0
- package/src/FileBrowser/FileBrowser.stories.tsx +27 -0
- package/src/FileBrowser/index.tsx +25 -2
- 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/FileBrowser/index.d.ts.map +1 -1
- 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
|
@@ -3,7 +3,14 @@
|
|
|
3
3
|
// get_role_permissions: permlevel 0 only, OR across the user's roles,
|
|
4
4
|
// if_owner rows scoped to the user's own records except create.
|
|
5
5
|
import { describe, expect, it } from "vitest";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
allDocRights,
|
|
8
|
+
docinfoRights,
|
|
9
|
+
fixtureDocRights,
|
|
10
|
+
resolveDocRights,
|
|
11
|
+
sessionDocRights,
|
|
12
|
+
type DocRights,
|
|
13
|
+
} from "./docPermissions";
|
|
7
14
|
import type { DocPermissionRule } from "./doctypeMeta";
|
|
8
15
|
|
|
9
16
|
const pokeMove: DocPermissionRule[] = [
|
|
@@ -143,3 +150,31 @@ describe("sessionDocRights", () => {
|
|
|
143
150
|
expect([rights.create, rights.write, rights.delete]).toEqual([true, true, true]);
|
|
144
151
|
});
|
|
145
152
|
});
|
|
153
|
+
|
|
154
|
+
describe("docinfoRights", () => {
|
|
155
|
+
it("takes the bench's per-record answer as it is", () => {
|
|
156
|
+
const rights = docinfoRights({ read: 1, write: 1, submit: 0, print: 1 });
|
|
157
|
+
expect(rights && granted(rights)).toEqual(["print", "read", "write"]);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("is no answer when the payload carries no read key (token-auth {null: 0})", () => {
|
|
161
|
+
expect(docinfoRights({ null: 0 })).toBeUndefined();
|
|
162
|
+
expect(docinfoRights(undefined)).toBeUndefined();
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe("fixtureDocRights", () => {
|
|
167
|
+
it("grants what any permlevel-0 row grants, never a higher level's rights", () => {
|
|
168
|
+
const rights = fixtureDocRights({ permissions: pokeMove });
|
|
169
|
+
expect(granted(rights)).toEqual(["create", "delete", "export", "read", "write"]);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("keeps write, create, email and print for a doctype without rows", () => {
|
|
173
|
+
expect(granted(fixtureDocRights({ permissions: [] }))).toEqual([
|
|
174
|
+
"create",
|
|
175
|
+
"email",
|
|
176
|
+
"print",
|
|
177
|
+
"write",
|
|
178
|
+
]);
|
|
179
|
+
});
|
|
180
|
+
});
|
|
@@ -126,3 +126,37 @@ export function sessionDocRights({
|
|
|
126
126
|
if (!meta || !roles) return allDocRights(false);
|
|
127
127
|
return resolveDocRights({ permissions: meta.permissions, roles, user, owner, shares });
|
|
128
128
|
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* A record's rights as the bench evaluated them for this user: docinfo's
|
|
132
|
+
* `permissions` (desk `frm.perm[0]` from getdoc). A payload with no `read`
|
|
133
|
+
* key is not an answer (a token-auth bench sends `{"null": 0}`), so it gives
|
|
134
|
+
* undefined and the caller keeps the session's rights.
|
|
135
|
+
*/
|
|
136
|
+
export function docinfoRights(
|
|
137
|
+
permissions: Readonly<Record<string, unknown>> | null | undefined,
|
|
138
|
+
): DocRights | undefined {
|
|
139
|
+
if (!permissions || !("read" in permissions)) return undefined;
|
|
140
|
+
const rights = allDocRights(false);
|
|
141
|
+
for (const right of docRightNames) rights[right] = !!permissions[right];
|
|
142
|
+
return rights;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The desk's rights on a fixtures connection, where no session exists: what
|
|
147
|
+
* any permlevel-0 DocPerm row of the doctype grants, so a story offers the
|
|
148
|
+
* actions its meta allows. A doctype without rows keeps write, create,
|
|
149
|
+
* email and print.
|
|
150
|
+
*/
|
|
151
|
+
export function fixtureDocRights(meta: Pick<DoctypeMeta, "permissions"> | undefined): DocRights {
|
|
152
|
+
const rows = (meta?.permissions ?? []).filter((row) => !(Number(row.permlevel ?? 0) || 0));
|
|
153
|
+
const rights = allDocRights(false);
|
|
154
|
+
for (const right of docRightNames) rights[right] = rows.some((row) => !!row[right]);
|
|
155
|
+
if ((meta?.permissions ?? []).length === 0) {
|
|
156
|
+
rights.write = true;
|
|
157
|
+
rights.create = true;
|
|
158
|
+
rights.email = true;
|
|
159
|
+
rights.print = true;
|
|
160
|
+
}
|
|
161
|
+
return rights;
|
|
162
|
+
}
|
package/src/formEngine/index.ts
CHANGED
|
@@ -35,7 +35,14 @@ export type { FormEngine } from "./useFormEngine";
|
|
|
35
35
|
export { useFrappeSession, useSessionRoles } from "./useSessionRoles";
|
|
36
36
|
export type { FrappeSession } from "./useSessionRoles";
|
|
37
37
|
|
|
38
|
-
export {
|
|
38
|
+
export {
|
|
39
|
+
allDocRights,
|
|
40
|
+
docinfoRights,
|
|
41
|
+
docRightNames,
|
|
42
|
+
fixtureDocRights,
|
|
43
|
+
resolveDocRights,
|
|
44
|
+
sessionDocRights,
|
|
45
|
+
} from "./docPermissions";
|
|
39
46
|
export type {
|
|
40
47
|
DocRight,
|
|
41
48
|
DocRights,
|
|
@@ -102,7 +102,15 @@ describe("Frappe remainder wrappers — design-law 100%", () => {
|
|
|
102
102
|
});
|
|
103
103
|
|
|
104
104
|
it("FrappeReportBuilder uses house Button + PopoverContent and R7 weight 400", () => {
|
|
105
|
-
|
|
105
|
+
// The builder composes its toolbar and grid (MPO-15, GL-28); the law
|
|
106
|
+
// holds over the three files together.
|
|
107
|
+
const source = [
|
|
108
|
+
"FrappeReportBuilder.tsx",
|
|
109
|
+
"report/ReportViewToolbar.tsx",
|
|
110
|
+
"report/ReportGrid.tsx",
|
|
111
|
+
]
|
|
112
|
+
.map(read)
|
|
113
|
+
.join("\n");
|
|
106
114
|
expect(source).toContain("PopoverContent");
|
|
107
115
|
expect(source).toContain('from "@multiplatform.one/forms"');
|
|
108
116
|
expect(source).toContain("Button");
|
|
@@ -69,6 +69,8 @@ let writes: Write[] = [];
|
|
|
69
69
|
let guest = false;
|
|
70
70
|
let session: { user: string; roles: string[] } | null = editor;
|
|
71
71
|
let sessionAnswered = false;
|
|
72
|
+
let movesListed: Promise<void> = Promise.resolve();
|
|
73
|
+
let markMovesListed = () => {};
|
|
72
74
|
let confirmDelete = vi.fn(() => true);
|
|
73
75
|
|
|
74
76
|
function json(body: unknown, status = 200) {
|
|
@@ -115,6 +117,7 @@ function stubBench() {
|
|
|
115
117
|
const rows = [...moves.values()].filter((row) =>
|
|
116
118
|
matchesNameFilter(row, url.searchParams.get("filters")),
|
|
117
119
|
);
|
|
120
|
+
if (url.searchParams.get("fields")?.includes('"move_name"')) markMovesListed();
|
|
118
121
|
return json({ data: rows });
|
|
119
122
|
}
|
|
120
123
|
if (url.pathname.startsWith(`${resource}/`)) {
|
|
@@ -209,6 +212,9 @@ beforeEach(() => {
|
|
|
209
212
|
guest = false;
|
|
210
213
|
session = editor;
|
|
211
214
|
sessionAnswered = false;
|
|
215
|
+
movesListed = new Promise((resolve) => {
|
|
216
|
+
markMovesListed = resolve;
|
|
217
|
+
});
|
|
212
218
|
writes = [];
|
|
213
219
|
moves = new Map([
|
|
214
220
|
[
|
|
@@ -283,6 +289,9 @@ describe("FrappeListView with a route", () => {
|
|
|
283
289
|
it("offers no Add to a reader who cannot load the doctype's meta", async () => {
|
|
284
290
|
guest = true;
|
|
285
291
|
const { container } = renderAt("/moves", "list");
|
|
292
|
+
// A 403 on meta costs two more round trips before a row can show: a
|
|
293
|
+
// one-doc peek, then the re-read with its keys. Wait for that read.
|
|
294
|
+
await movesListed;
|
|
286
295
|
await waitFor(() => expect(screen.getByText("tackle")).toBeTruthy());
|
|
287
296
|
expect(() => button(container, `Add ${doctype}`)).toThrow();
|
|
288
297
|
});
|
|
@@ -75,11 +75,24 @@ describe("Frappe view adapters — design-law 100%", () => {
|
|
|
75
75
|
expect(source).not.toMatch(/fontSize="\$1"|fontSize="\$2"/);
|
|
76
76
|
});
|
|
77
77
|
|
|
78
|
+
it("report view toolbar filters are catalog Chip, not 999-radius wells", () => {
|
|
79
|
+
const source = read("report/ReportViewToolbar.tsx");
|
|
80
|
+
expect(source).toContain("<Chip");
|
|
81
|
+
expect(source).not.toMatch(/borderRadius=\{999\}/);
|
|
82
|
+
});
|
|
83
|
+
|
|
78
84
|
it("FrappeReportBuilder toolbar is house Button and captions lock 400 (R7 / LC-54)", () => {
|
|
79
|
-
|
|
85
|
+
// The builder composes its toolbar and grid (MPO-15, GL-28); the law
|
|
86
|
+
// holds over the three files together.
|
|
87
|
+
const source = [
|
|
88
|
+
"FrappeReportBuilder.tsx",
|
|
89
|
+
"report/ReportViewToolbar.tsx",
|
|
90
|
+
"report/ReportGrid.tsx",
|
|
91
|
+
]
|
|
92
|
+
.map(read)
|
|
93
|
+
.join("\n");
|
|
80
94
|
expect(source).toMatch(/import \{[^}]*Button[^}]*\} from "@multiplatform.one\/forms"/);
|
|
81
95
|
expect(source).not.toMatch(/Button.*from "tamagui"/);
|
|
82
|
-
expect(source).toContain("formCommonColors");
|
|
83
96
|
expect(source).not.toMatch(/fontWeight="600"|fontWeight="500"/);
|
|
84
97
|
expect(source).toContain('fontWeight="400"');
|
|
85
98
|
expect(source).not.toMatch(/<Button\b[^>]*\b(?:controlFill|backgroundColor|borderColor)=/);
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
// LC-96 (MPO-15 AC10): a data-aware view degrades to the weakest honest
|
|
2
|
+
// rendering, never a blank. The bench below refuses getdoctype the way Frappe
|
|
3
|
+
// refuses it to Guest, answers or refuses the record reads per test, and
|
|
4
|
+
// refuses or breaks a query report's run. Each rung of the ladder is one test:
|
|
5
|
+
// meta refused but the rows readable, the record refused too, nothing to
|
|
6
|
+
// create from, and a read that failed for some other reason, for the form, the
|
|
7
|
+
// list and both report views.
|
|
8
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
9
|
+
import { cleanup, screen, waitFor } from "@testing-library/react";
|
|
10
|
+
import i18next from "i18next";
|
|
11
|
+
import { initReactI18next } from "react-i18next";
|
|
12
|
+
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
|
|
13
|
+
import { FrappeForm } from "./FrappeForm";
|
|
14
|
+
import { FrappeListView } from "./FrappeListView";
|
|
15
|
+
import { frappeRouteTarget, type FrappeNavigation } from "./frappeNavigation";
|
|
16
|
+
import { FrappeProvider } from "./FrappeProvider";
|
|
17
|
+
import { FrappeReportBuilder } from "./FrappeReportBuilder";
|
|
18
|
+
import { FrappeReportView } from "./FrappeReportView";
|
|
19
|
+
|
|
20
|
+
const doctype = "Poke Move";
|
|
21
|
+
const route = "/moves";
|
|
22
|
+
|
|
23
|
+
interface Move {
|
|
24
|
+
name: string;
|
|
25
|
+
doctype: string;
|
|
26
|
+
move_name?: string;
|
|
27
|
+
power?: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const tackle = {
|
|
31
|
+
name: "a1b2c3",
|
|
32
|
+
doctype,
|
|
33
|
+
owner: "Administrator",
|
|
34
|
+
modified: "2026-09-29 10:00:00",
|
|
35
|
+
docstatus: 0,
|
|
36
|
+
idx: 0,
|
|
37
|
+
_user_tags: null,
|
|
38
|
+
move_name: "tackle",
|
|
39
|
+
power: 40,
|
|
40
|
+
accuracy: 0.95,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const settle = { timeout: 8000 };
|
|
44
|
+
|
|
45
|
+
let run = 0;
|
|
46
|
+
let bench = "";
|
|
47
|
+
let metaAnswer: "refused" | "broken" = "refused";
|
|
48
|
+
let recordsReadable = true;
|
|
49
|
+
let reportRun: "refused" | "broken" = "refused";
|
|
50
|
+
const reportName = "Move Usage";
|
|
51
|
+
|
|
52
|
+
function json(body: unknown, status = 200) {
|
|
53
|
+
return new Response(JSON.stringify(body), {
|
|
54
|
+
status,
|
|
55
|
+
headers: { "content-type": "application/json" },
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function stubBench() {
|
|
60
|
+
vi.stubGlobal("fetch", async (input: string | URL | Request) => {
|
|
61
|
+
const url = new URL(String(input instanceof Request ? input.url : input));
|
|
62
|
+
const method = url.pathname.replace(/^\/api\/method\//, "");
|
|
63
|
+
if (method === "frappe.desk.form.load.getdoctype") {
|
|
64
|
+
return metaAnswer === "refused"
|
|
65
|
+
? json({ exc_type: "PermissionError", exception: "Not permitted" }, 403)
|
|
66
|
+
: json({ exc_type: "ValidationError", exception: "Poke Move is being migrated" }, 417);
|
|
67
|
+
}
|
|
68
|
+
if (method === "frappe.desk.query_report.run") {
|
|
69
|
+
return reportRun === "refused"
|
|
70
|
+
? json(
|
|
71
|
+
{
|
|
72
|
+
exc_type: "PermissionError",
|
|
73
|
+
_server_messages: JSON.stringify([
|
|
74
|
+
JSON.stringify({ message: `You don't have access to Report: ${reportName}` }),
|
|
75
|
+
]),
|
|
76
|
+
},
|
|
77
|
+
403,
|
|
78
|
+
)
|
|
79
|
+
: json({ exc_type: "ValidationError", exception: "Move Usage timed out" }, 417);
|
|
80
|
+
}
|
|
81
|
+
if (method === "frappe.auth.get_logged_user" || method.endsWith(".get_roles")) {
|
|
82
|
+
return json({ exc_type: "PermissionError" }, 403);
|
|
83
|
+
}
|
|
84
|
+
const resource = `/api/resource/${encodeURIComponent(doctype)}`;
|
|
85
|
+
if (url.pathname === resource || url.pathname.startsWith(`${resource}/`)) {
|
|
86
|
+
if (!recordsReadable) {
|
|
87
|
+
return json({ exc_type: "PermissionError", exception: "Not permitted" }, 403);
|
|
88
|
+
}
|
|
89
|
+
return url.pathname === resource ? json({ data: [tackle] }) : json({ data: tackle });
|
|
90
|
+
}
|
|
91
|
+
return json({ data: [], message: [] });
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function renderAt(pathname: string, page: "list" | "form") {
|
|
96
|
+
const navigation: FrappeNavigation = {
|
|
97
|
+
usePathname: () => pathname,
|
|
98
|
+
useNavigate: () => () => undefined,
|
|
99
|
+
};
|
|
100
|
+
return renderWithProviders(
|
|
101
|
+
<FrappeProvider baseURL={bench} realtime={false} navigation={navigation}>
|
|
102
|
+
{page === "list" ? (
|
|
103
|
+
<FrappeListView<Move> doctype={doctype} route={route} defaultViewMode="table" />
|
|
104
|
+
) : (
|
|
105
|
+
<FrappeForm<Move> doctype={doctype} route={route} />
|
|
106
|
+
)}
|
|
107
|
+
</FrappeProvider>,
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
beforeAll(async () => {
|
|
112
|
+
await i18next.use(initReactI18next).init({
|
|
113
|
+
lng: "en",
|
|
114
|
+
interpolation: { escapeValue: false },
|
|
115
|
+
resources: { en: { translation: {} } },
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
beforeEach(() => {
|
|
120
|
+
run += 1;
|
|
121
|
+
bench = `http://guest-fallback-${run}.spec.test`;
|
|
122
|
+
metaAnswer = "refused";
|
|
123
|
+
recordsReadable = true;
|
|
124
|
+
reportRun = "refused";
|
|
125
|
+
stubBench();
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
afterEach(() => {
|
|
129
|
+
cleanup();
|
|
130
|
+
vi.unstubAllGlobals();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
describe("LC-96 guest fallback: meta refused, rows readable", () => {
|
|
134
|
+
it("a record page lays out the record's own fields, read-only", async () => {
|
|
135
|
+
expect(frappeRouteTarget(route, "/moves/a1b2c3")).toEqual({ mode: "view", name: "a1b2c3" });
|
|
136
|
+
renderAt("/moves/a1b2c3", "form");
|
|
137
|
+
const power = (await screen.findByLabelText("Power", { exact: false }, settle)) as HTMLElement;
|
|
138
|
+
const input = power instanceof HTMLInputElement ? power : power.querySelector("input");
|
|
139
|
+
expect(input?.value).toBe("40");
|
|
140
|
+
expect(input?.disabled || input?.readOnly).toBe(true);
|
|
141
|
+
expect(screen.getByLabelText("Accuracy", { exact: false })).toBeTruthy();
|
|
142
|
+
for (const bookkeeping of ["Owner", "Modified", "Docstatus", "Idx", "User Tags"]) {
|
|
143
|
+
expect(screen.queryByLabelText(bookkeeping, { exact: true })).toBeNull();
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("a list table takes its columns from one record instead of a lone Name", async () => {
|
|
148
|
+
renderAt("/moves", "list");
|
|
149
|
+
await waitFor(() => expect(screen.getAllByText("tackle").length).toBeGreaterThan(0), settle);
|
|
150
|
+
await waitFor(() => expect(screen.getByText("Move Name")).toBeTruthy(), settle);
|
|
151
|
+
expect(screen.getByText("Power")).toBeTruthy();
|
|
152
|
+
expect(screen.queryByText("Owner")).toBeNull();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe("LC-96 guest fallback: nothing readable to fall back to", () => {
|
|
157
|
+
it("a create page says the reader can't create, with the server's reason, not a load failure", async () => {
|
|
158
|
+
renderAt("/moves/new", "form");
|
|
159
|
+
const state = await screen.findByTestId("frappe-form-not-permitted", {}, settle);
|
|
160
|
+
expect(state.textContent).toContain(`You can't create ${doctype}`);
|
|
161
|
+
expect(screen.queryByText(`Failed to load ${doctype} form`)).toBeNull();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("a record page whose record is refused too says the reader can't open it, with no retry", async () => {
|
|
165
|
+
recordsReadable = false;
|
|
166
|
+
renderAt("/moves/a1b2c3", "form");
|
|
167
|
+
const state = await screen.findByTestId("frappe-form-not-permitted", {}, settle);
|
|
168
|
+
expect(state.textContent).toContain(`You can't open ${doctype} a1b2c3`);
|
|
169
|
+
expect(screen.queryByText(`Failed to load ${doctype}`)).toBeNull();
|
|
170
|
+
expect(screen.queryByRole("button", { name: /retry/i })).toBeNull();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("a meta read that failed for another reason is an error state, not a permission one", async () => {
|
|
174
|
+
metaAnswer = "broken";
|
|
175
|
+
renderAt("/moves/new", "form");
|
|
176
|
+
const alert = await screen.findByText(`Failed to load ${doctype} form`, {}, settle);
|
|
177
|
+
expect(alert).toBeTruthy();
|
|
178
|
+
expect(screen.queryByTestId("frappe-form-not-permitted")).toBeNull();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
function renderReport(view: "builder" | "query") {
|
|
183
|
+
return renderWithProviders(
|
|
184
|
+
<FrappeProvider baseURL={bench} realtime={false}>
|
|
185
|
+
{view === "builder" ? (
|
|
186
|
+
<FrappeReportBuilder doctype={doctype} />
|
|
187
|
+
) : (
|
|
188
|
+
<FrappeReportView reportName={reportName} debounceMs={0} />
|
|
189
|
+
)}
|
|
190
|
+
</FrappeProvider>,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
describe("LC-96 guest fallback: report views", () => {
|
|
195
|
+
it("a doctype report takes its columns from one record and saves nothing", async () => {
|
|
196
|
+
renderReport("builder");
|
|
197
|
+
await waitFor(() => expect(screen.getAllByText("tackle").length).toBeGreaterThan(0), settle);
|
|
198
|
+
expect(screen.getByText("Move Name")).toBeTruthy();
|
|
199
|
+
expect(screen.getByText("Power")).toBeTruthy();
|
|
200
|
+
expect(screen.getByText("Accuracy")).toBeTruthy();
|
|
201
|
+
expect(screen.queryByText("Owner")).toBeNull();
|
|
202
|
+
expect(screen.queryByText(/Couldn't load/)).toBeNull();
|
|
203
|
+
expect(screen.queryByRole("button", { name: /save as/i })).toBeNull();
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it("a doctype report whose rows are refused too says the reader can't open it, with no retry", async () => {
|
|
207
|
+
recordsReadable = false;
|
|
208
|
+
renderReport("builder");
|
|
209
|
+
const state = await screen.findByTestId("frappe-report-not-permitted", {}, settle);
|
|
210
|
+
expect(state.textContent).toContain(`You can't open the ${doctype} report`);
|
|
211
|
+
expect(screen.queryByRole("button", { name: /retry/i })).toBeNull();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it("a doctype report whose meta failed for another reason stays an error", async () => {
|
|
215
|
+
metaAnswer = "broken";
|
|
216
|
+
renderReport("builder");
|
|
217
|
+
expect(await screen.findByText(`Couldn't load the ${doctype} report`, {}, settle)).toBeTruthy();
|
|
218
|
+
expect(screen.queryByTestId("frappe-report-not-permitted")).toBeNull();
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it("a refused query report says the reader can't run it, with the server's reason and no retry", async () => {
|
|
222
|
+
renderReport("query");
|
|
223
|
+
const state = await screen.findByTestId("frappe-report-not-permitted", {}, settle);
|
|
224
|
+
expect(state.textContent).toContain(`You can't run ${reportName}`);
|
|
225
|
+
expect(state.textContent).toContain(`You don't have access to Report: ${reportName}`);
|
|
226
|
+
expect(screen.queryByRole("button", { name: /retry|refresh/i })).toBeNull();
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it("a query report that failed for another reason stays a retryable error", async () => {
|
|
230
|
+
reportRun = "broken";
|
|
231
|
+
renderReport("query");
|
|
232
|
+
expect(await screen.findByText(`Error running ${reportName}`, {}, settle)).toBeTruthy();
|
|
233
|
+
expect(screen.queryByTestId("frappe-report-not-permitted")).toBeNull();
|
|
234
|
+
expect(screen.getByRole("button", { name: /retry/i })).toBeTruthy();
|
|
235
|
+
});
|
|
236
|
+
});
|
package/src/index.ts
CHANGED
|
@@ -54,6 +54,15 @@ export {
|
|
|
54
54
|
|
|
55
55
|
export { FrappeTable, filterValueToFrappeTuple, type FrappeTableProps } from "./FrappeTable";
|
|
56
56
|
export { FrappeForm, type FrappeConnectionRows, type FrappeFormProps } from "./FrappeForm";
|
|
57
|
+
export {
|
|
58
|
+
useFrappeForm,
|
|
59
|
+
type FrappeFormConnectionConfig,
|
|
60
|
+
type FrappeFormController,
|
|
61
|
+
type FrappeFormFieldTarget,
|
|
62
|
+
type FrappeFormMetaSource,
|
|
63
|
+
type FrappeFormStatus,
|
|
64
|
+
type UseFrappeFormOptions,
|
|
65
|
+
} from "./useFrappeForm";
|
|
57
66
|
export {
|
|
58
67
|
FrappeFormConnectionSection,
|
|
59
68
|
FrappeFormConnections,
|
|
@@ -146,13 +155,6 @@ export { FrappeGantt, type FrappeGanttProps } from "./FrappeGantt";
|
|
|
146
155
|
|
|
147
156
|
export { resolveFrappeEventColor, frappeEventColorNames } from "./frappeEventColor";
|
|
148
157
|
|
|
149
|
-
export {
|
|
150
|
-
FrappeReportBuilder,
|
|
151
|
-
type FrappeReportBuilderProps,
|
|
152
|
-
type ReportColumn,
|
|
153
|
-
type GroupByConfig,
|
|
154
|
-
} from "./FrappeReportBuilder";
|
|
155
|
-
|
|
156
158
|
export {
|
|
157
159
|
FrappeDashboard,
|
|
158
160
|
type FrappeDashboardProps,
|
|
@@ -207,6 +209,17 @@ export {
|
|
|
207
209
|
type UseFrappeRowsResult,
|
|
208
210
|
} from "./useFrappeRows";
|
|
209
211
|
|
|
212
|
+
// What a view lays itself out from when meta is refused (LC-96).
|
|
213
|
+
export {
|
|
214
|
+
fieldsFromRecord,
|
|
215
|
+
recordFieldKeys,
|
|
216
|
+
recordKeyLabel,
|
|
217
|
+
useRecordShape,
|
|
218
|
+
type RecordShape,
|
|
219
|
+
type RecordShapeConnection,
|
|
220
|
+
} from "./recordShape";
|
|
221
|
+
export { isPermissionError, refusalReason } from "./liveErrors";
|
|
222
|
+
|
|
210
223
|
export {
|
|
211
224
|
useFrappeAggregate,
|
|
212
225
|
type FrappeAggregateConnection,
|
|
@@ -455,32 +468,118 @@ export { useFrappeCollection, useLiveQuery } from "@multiplatform.one/frappe";
|
|
|
455
468
|
export type { DataTableColumn } from "@multiplatform.one/table";
|
|
456
469
|
|
|
457
470
|
// ---------------------------------------------------------------------------
|
|
458
|
-
// Report
|
|
471
|
+
// Report models (MPO-15, GL-28): a named query/script report and a doctype's
|
|
472
|
+
// report view, one model each. FrappeReportView and the desk's
|
|
473
|
+
// QueryReportScreen render the first through one transport;
|
|
474
|
+
// FrappeReportBuilder, the desk's view=report, renders the second.
|
|
459
475
|
// ---------------------------------------------------------------------------
|
|
460
476
|
|
|
461
477
|
export {
|
|
462
478
|
FrappeReportView,
|
|
463
|
-
|
|
479
|
+
reportColumnToDataTableColumn,
|
|
480
|
+
reportFieldtypeToTableField,
|
|
481
|
+
reportRowLabel,
|
|
482
|
+
type FrappeReportViewProps,
|
|
483
|
+
} from "./FrappeReportView";
|
|
484
|
+
export {
|
|
485
|
+
buildRunFilters,
|
|
464
486
|
compactFilterValues,
|
|
487
|
+
compactQueryReportFilters,
|
|
488
|
+
defaultFilterValues,
|
|
489
|
+
extractScriptFilters,
|
|
490
|
+
humanizeFrappeError,
|
|
491
|
+
isEmptyFilterValue,
|
|
492
|
+
normalizeFilterMeta,
|
|
493
|
+
normalizeQueryReportColumns,
|
|
494
|
+
normalizeQueryReportPayload,
|
|
495
|
+
normalizeQueryReportRows,
|
|
465
496
|
normalizeReportColumn,
|
|
466
497
|
normalizeReportPayload,
|
|
467
498
|
normalizeReportRows,
|
|
468
|
-
reportColumnToDataTableColumn,
|
|
469
|
-
reportFieldtypeToTableField,
|
|
470
|
-
reportRowLabel,
|
|
471
499
|
scrubFieldname,
|
|
500
|
+
stripHtml as stripReportHtml,
|
|
472
501
|
type FrappeReportColumn,
|
|
473
|
-
type FrappeReportConnection,
|
|
474
502
|
type FrappeReportFilterDef,
|
|
475
|
-
type FrappeReportFixture,
|
|
476
503
|
type FrappeReportPayload,
|
|
477
504
|
type FrappeReportRow,
|
|
478
505
|
type FrappeReportRunResponse,
|
|
479
506
|
type FrappeReportValues,
|
|
480
|
-
type
|
|
507
|
+
type QueryReportColumn,
|
|
508
|
+
type QueryReportFilterInput,
|
|
509
|
+
type QueryReportFilterMeta,
|
|
510
|
+
type QueryReportFilters,
|
|
511
|
+
type QueryReportFixture,
|
|
512
|
+
type QueryReportMeta,
|
|
513
|
+
type QueryReportPayload,
|
|
514
|
+
type QueryReportRow,
|
|
515
|
+
type QueryReportRunMessage,
|
|
516
|
+
type ScriptFilterExtraction,
|
|
517
|
+
} from "./report/queryReport";
|
|
518
|
+
export {
|
|
519
|
+
reportCall,
|
|
520
|
+
useFrappeReport,
|
|
521
|
+
type FrappeReportConnection,
|
|
522
|
+
type FrappeReportFixture,
|
|
481
523
|
type UseFrappeReportOptions,
|
|
482
524
|
type UseFrappeReportResult,
|
|
483
|
-
} from "./
|
|
525
|
+
} from "./report/useFrappeReport";
|
|
526
|
+
export {
|
|
527
|
+
useQueryReport,
|
|
528
|
+
type UseQueryReportOptions,
|
|
529
|
+
type UseQueryReportResult,
|
|
530
|
+
} from "./report/useQueryReport";
|
|
531
|
+
export {
|
|
532
|
+
buildQueryReportColumns,
|
|
533
|
+
buildQueryReportCsv,
|
|
534
|
+
type BuildQueryReportColumnsArgs,
|
|
535
|
+
} from "./report/queryReportColumns";
|
|
536
|
+
export {
|
|
537
|
+
FrappeReportBuilder,
|
|
538
|
+
type FrappeReportBuilderProps,
|
|
539
|
+
type ReportColumn,
|
|
540
|
+
type GroupByConfig,
|
|
541
|
+
} from "./FrappeReportBuilder";
|
|
542
|
+
export {
|
|
543
|
+
buildGridRows as buildReportGridRows,
|
|
544
|
+
buildReportCsv,
|
|
545
|
+
columnAlign as reportColumnAlign,
|
|
546
|
+
columnFilterTuple as reportColumnFilterTuple,
|
|
547
|
+
columnFilterTuples as reportColumnFilterTuples,
|
|
548
|
+
compareCellValues as compareReportCellValues,
|
|
549
|
+
computeTotals as computeReportTotals,
|
|
550
|
+
DEFAULT_REPORT_PAGE_SIZE,
|
|
551
|
+
defaultColumnWidth as defaultReportColumnWidth,
|
|
552
|
+
defaultReportFieldnames,
|
|
553
|
+
fromDeskReportSettings,
|
|
554
|
+
orderReportRows,
|
|
555
|
+
parseDeskOrderBy,
|
|
556
|
+
parseReportFiltersParam,
|
|
557
|
+
REPORT_NUMERIC_FIELDTYPES,
|
|
558
|
+
REPORT_PAGE_SIZES,
|
|
559
|
+
reportColumnsFromMeta,
|
|
560
|
+
resolveSelectedColumns as resolveReportColumns,
|
|
561
|
+
toDeskReportSettings,
|
|
562
|
+
type DeskReportSettings,
|
|
563
|
+
type ReportColumnDef,
|
|
564
|
+
type ReportDataRow,
|
|
565
|
+
type ReportFilters,
|
|
566
|
+
type ReportGridRow,
|
|
567
|
+
type ReportGroupHeader,
|
|
568
|
+
type ReportMetaSource,
|
|
569
|
+
type ReportRow,
|
|
570
|
+
type ReportSortState,
|
|
571
|
+
type ReportTotalsCell,
|
|
572
|
+
type ReportViewConfig,
|
|
573
|
+
} from "./report/reportViewModel";
|
|
574
|
+
export { ReportGrid, type ReportGridProps } from "./report/ReportGrid";
|
|
575
|
+
export { ReportViewToolbar, type ReportViewToolbarProps } from "./report/ReportViewToolbar";
|
|
576
|
+
export {
|
|
577
|
+
useSavedReports,
|
|
578
|
+
type SavedReportSummary,
|
|
579
|
+
type SavedReportsConnection,
|
|
580
|
+
type UseSavedReportsResult,
|
|
581
|
+
} from "./report/savedReports";
|
|
582
|
+
export { dialogBodyMinWidth, overlayListMaxHeight } from "./measures";
|
|
484
583
|
|
|
485
584
|
// ---------------------------------------------------------------------------
|
|
486
585
|
// Desk Form Engine (MPO-15)
|
|
@@ -507,7 +606,9 @@ export {
|
|
|
507
606
|
canReadLevel,
|
|
508
607
|
canWriteLevel,
|
|
509
608
|
computeDirtyFields,
|
|
609
|
+
docinfoRights,
|
|
510
610
|
docRightNames,
|
|
611
|
+
fixtureDocRights,
|
|
511
612
|
isEmptyValue,
|
|
512
613
|
isFetchLocked,
|
|
513
614
|
isPromptNamed,
|
package/src/liveErrors.spec.ts
CHANGED
|
@@ -8,6 +8,16 @@ describe("isPermissionError", () => {
|
|
|
8
8
|
expect(isPermissionError(Object.assign(new Error("nope"), { status: 500 }))).toBe(false);
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
+
it("treats a PermissionError exc_type as permission, whatever the sentence", () => {
|
|
12
|
+
const err = Object.assign(new Error("You don't have access to Report: ToDo"), {
|
|
13
|
+
exc_type: "PermissionError",
|
|
14
|
+
});
|
|
15
|
+
expect(isPermissionError(err)).toBe(true);
|
|
16
|
+
expect(
|
|
17
|
+
isPermissionError(Object.assign(new Error("Timed out"), { exc_type: "ValidationError" })),
|
|
18
|
+
).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
|
|
11
21
|
it("treats a PermissionError-shaped message as permission", () => {
|
|
12
22
|
expect(isPermissionError(new Error("PermissionError"))).toBe(true);
|
|
13
23
|
expect(isPermissionError(new Error("You don't have access to Report: ToDo"))).toBe(false);
|
package/src/liveErrors.ts
CHANGED
|
@@ -9,10 +9,14 @@
|
|
|
9
9
|
* from "the load failed".
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
/**
|
|
12
|
+
/**
|
|
13
|
+
* True when the error is an auth/permission rejection: a 403 or 401, a
|
|
14
|
+
* PermissionError `exc_type`, or a PermissionError-shaped message.
|
|
15
|
+
*/
|
|
13
16
|
export function isPermissionError(error: unknown): boolean {
|
|
14
|
-
const
|
|
15
|
-
if (status === 403 || status === 401) return true;
|
|
17
|
+
const shaped = error as { status?: number; exc_type?: unknown } | undefined;
|
|
18
|
+
if (shaped?.status === 403 || shaped?.status === 401) return true;
|
|
19
|
+
if (shaped?.exc_type === "PermissionError") return true;
|
|
16
20
|
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
17
21
|
return /permission|not permitted|forbidden/i.test(message);
|
|
18
22
|
}
|
|
@@ -22,6 +26,15 @@ function isTracebackDetail(detail: string): boolean {
|
|
|
22
26
|
return /Traceback \(most recent call last\)/i.test(detail);
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
/**
|
|
30
|
+
* The server's own sentence for a refusal, for a permission state's
|
|
31
|
+
* description: undefined when there is none or it is a python traceback.
|
|
32
|
+
*/
|
|
33
|
+
export function refusalReason(error: unknown): string | undefined {
|
|
34
|
+
const detail = error instanceof Error ? error.message : String(error ?? "");
|
|
35
|
+
return detail && !isTracebackDetail(detail) ? detail : undefined;
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
/**
|
|
26
39
|
* Normalizes an initial-sync failure into an Error with an honest,
|
|
27
40
|
* user-facing message. `permissionMessage` / `genericMessage` come from the
|
package/src/measures.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { sizeRecipeEscape } from "@multiplatform.one/theme";
|
|
2
|
+
|
|
3
|
+
export const dialogBodyMinWidth = sizeRecipeEscape(
|
|
4
|
+
280,
|
|
5
|
+
"dialog body floor: a reading width for the form inside a dialog or popover",
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
export const overlayListMaxHeight = sizeRecipeEscape(
|
|
9
|
+
360,
|
|
10
|
+
"overlay list cap: a menu or popover list scrolls past this height instead of growing",
|
|
11
|
+
);
|