@multiplatform.one/frappe-ui 7.7.6 → 7.8.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.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 +20 -17
- package/dist/cjs/FrappeCalendar.native.js +22 -21
- 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 +1 -1
- package/dist/cjs/FrappeForm.native.js +2 -2
- package/dist/cjs/FrappeForm.native.js.map +1 -1
- package/dist/cjs/FrappeGantt.cjs +25 -34
- package/dist/cjs/FrappeGantt.native.js +27 -38
- package/dist/cjs/FrappeGantt.native.js.map +1 -1
- package/dist/cjs/FrappeImageView.cjs +4 -2
- package/dist/cjs/FrappeImageView.native.js +8 -4
- package/dist/cjs/FrappeImageView.native.js.map +1 -1
- package/dist/cjs/FrappeKPICard.cjs +26 -1
- package/dist/cjs/FrappeKPICard.native.js +26 -1
- package/dist/cjs/FrappeKPICard.native.js.map +1 -1
- package/dist/cjs/FrappeKanban.cjs +16 -17
- package/dist/cjs/FrappeKanban.native.js +18 -21
- package/dist/cjs/FrappeKanban.native.js.map +1 -1
- package/dist/cjs/FrappeLikedBy.cjs +1 -1
- package/dist/cjs/FrappeLikedBy.native.js +1 -1
- package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
- package/dist/cjs/FrappeList.cjs +2 -2
- package/dist/cjs/FrappeList.native.js +2 -2
- package/dist/cjs/FrappeList.native.js.map +1 -1
- package/dist/cjs/FrappeListView.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/FrappeReportBuilder.cjs +2 -2
- package/dist/cjs/FrappeReportBuilder.native.js +2 -2
- package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
- package/dist/cjs/FrappeReportView.native.js +3 -3
- package/dist/cjs/FrappeReportView.native.js.map +1 -1
- package/dist/cjs/FrappeTable.cjs +35 -38
- package/dist/cjs/FrappeTable.native.js +38 -39
- package/dist/cjs/FrappeTable.native.js.map +1 -1
- package/dist/cjs/FrappeTreeView.cjs +85 -50
- package/dist/cjs/FrappeTreeView.native.js +129 -50
- package/dist/cjs/FrappeTreeView.native.js.map +1 -1
- package/dist/cjs/SyncErrorNotice.native.js.map +1 -1
- package/dist/cjs/commentActions.cjs +1 -1
- package/dist/cjs/commentActions.native.js +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.cjs +1 -1
- package/dist/cjs/components/timeline.native.js +1 -1
- package/dist/cjs/components/timeline.native.js.map +1 -1
- 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.cjs +2 -0
- package/dist/cjs/desk/DeskShell.native.js +2 -0
- 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.cjs +1 -1
- package/dist/cjs/desk/awesomebar.native.js +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.cjs +4 -1
- package/dist/cjs/fields/MentionInput/index.native.js +4 -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.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/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.native.js.map +1 -1
- package/dist/cjs/formEngine/useFormEngine.native.js.map +1 -1
- package/dist/cjs/frappeEventColor.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 +4 -0
- package/dist/cjs/index.native.js +38 -34
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/liveErrors.native.js.map +1 -1
- 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.cjs +10 -9
- package/dist/cjs/schemaForm/index.native.js +11 -10
- package/dist/cjs/schemaForm/index.native.js.map +1 -1
- package/dist/cjs/shared/devWarn.cjs +40 -0
- package/dist/cjs/shared/devWarn.native.js +45 -0
- package/dist/cjs/shared/devWarn.native.js.map +1 -0
- package/dist/cjs/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/cjs/syncError.native.js.map +1 -1
- package/dist/cjs/useFrappeAggregate.cjs +15 -8
- package/dist/cjs/useFrappeAggregate.native.js +15 -9
- package/dist/cjs/useFrappeAggregate.native.js.map +1 -1
- package/dist/cjs/useFrappeFacets.cjs +10 -9
- package/dist/cjs/useFrappeFacets.native.js +10 -10
- package/dist/cjs/useFrappeFacets.native.js.map +1 -1
- package/dist/cjs/useFrappePagination.native.js.map +1 -1
- package/dist/cjs/useFrappeRows.cjs +113 -0
- package/dist/cjs/useFrappeRows.native.js +129 -0
- package/dist/cjs/useFrappeRows.native.js.map +1 -0
- 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.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 +20 -17
- package/dist/esm/FrappeCalendar.mjs.map +1 -1
- package/dist/esm/FrappeCalendar.native.js +22 -21
- 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 +1 -1
- package/dist/esm/FrappeForm.mjs.map +1 -1
- package/dist/esm/FrappeForm.native.js +1 -1
- package/dist/esm/FrappeForm.native.js.map +1 -1
- package/dist/esm/FrappeGantt.mjs +27 -36
- package/dist/esm/FrappeGantt.mjs.map +1 -1
- package/dist/esm/FrappeGantt.native.js +29 -40
- package/dist/esm/FrappeGantt.native.js.map +1 -1
- package/dist/esm/FrappeImageView.mjs +5 -3
- package/dist/esm/FrappeImageView.mjs.map +1 -1
- package/dist/esm/FrappeImageView.native.js +9 -5
- package/dist/esm/FrappeImageView.native.js.map +1 -1
- package/dist/esm/FrappeKPICard.mjs +27 -2
- package/dist/esm/FrappeKPICard.mjs.map +1 -1
- package/dist/esm/FrappeKPICard.native.js +27 -2
- package/dist/esm/FrappeKPICard.native.js.map +1 -1
- package/dist/esm/FrappeKanban.mjs +16 -17
- package/dist/esm/FrappeKanban.mjs.map +1 -1
- package/dist/esm/FrappeKanban.native.js +18 -21
- package/dist/esm/FrappeKanban.native.js.map +1 -1
- package/dist/esm/FrappeLikedBy.mjs +1 -1
- package/dist/esm/FrappeLikedBy.mjs.map +1 -1
- package/dist/esm/FrappeLikedBy.native.js +1 -1
- package/dist/esm/FrappeLikedBy.native.js.map +1 -1
- package/dist/esm/FrappeList.mjs +2 -2
- package/dist/esm/FrappeList.mjs.map +1 -1
- package/dist/esm/FrappeList.native.js +2 -2
- package/dist/esm/FrappeList.native.js.map +1 -1
- package/dist/esm/FrappeListView.native.js.map +1 -1
- package/dist/esm/FrappeProvider.mjs.map +1 -1
- package/dist/esm/FrappeProvider.native.js.map +1 -1
- package/dist/esm/FrappeReconnectIndicator.native.js.map +1 -1
- package/dist/esm/FrappeReportBuilder.mjs +2 -2
- package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
- package/dist/esm/FrappeReportBuilder.native.js +2 -2
- package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
- package/dist/esm/FrappeReportView.native.js.map +1 -1
- package/dist/esm/FrappeTable.mjs +36 -39
- package/dist/esm/FrappeTable.mjs.map +1 -1
- package/dist/esm/FrappeTable.native.js +39 -40
- package/dist/esm/FrappeTable.native.js.map +1 -1
- package/dist/esm/FrappeTreeView.mjs +89 -55
- package/dist/esm/FrappeTreeView.mjs.map +1 -1
- package/dist/esm/FrappeTreeView.native.js +133 -55
- package/dist/esm/FrappeTreeView.native.js.map +1 -1
- package/dist/esm/SyncErrorNotice.native.js.map +1 -1
- package/dist/esm/commentActions.mjs +1 -1
- package/dist/esm/commentActions.mjs.map +1 -1
- package/dist/esm/commentActions.native.js +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.mjs +1 -1
- package/dist/esm/components/timeline.mjs.map +1 -1
- package/dist/esm/components/timeline.native.js +1 -1
- package/dist/esm/components/timeline.native.js.map +1 -1
- 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.mjs +2 -0
- package/dist/esm/desk/DeskShell.mjs.map +1 -1
- package/dist/esm/desk/DeskShell.native.js +2 -0
- 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.mjs +1 -1
- package/dist/esm/desk/awesomebar.mjs.map +1 -1
- package/dist/esm/desk/awesomebar.native.js +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.mjs +4 -1
- package/dist/esm/fields/MentionInput/index.mjs.map +1 -1
- package/dist/esm/fields/MentionInput/index.native.js +4 -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.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/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.native.js.map +1 -1
- package/dist/esm/formEngine/useFormEngine.native.js.map +1 -1
- package/dist/esm/frappeEventColor.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 +2 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +2 -1
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/liveErrors.native.js.map +1 -1
- 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.mjs +8 -7
- package/dist/esm/schemaForm/index.mjs.map +1 -1
- package/dist/esm/schemaForm/index.native.js +8 -7
- package/dist/esm/schemaForm/index.native.js.map +1 -1
- package/dist/esm/shared/devWarn.mjs +14 -0
- package/dist/esm/shared/devWarn.mjs.map +1 -0
- package/dist/esm/shared/devWarn.native.js +16 -0
- package/dist/esm/shared/devWarn.native.js.map +1 -0
- package/dist/esm/shared/useKeyboardInset.native.js.map +1 -1
- package/dist/esm/syncError.native.js.map +1 -1
- package/dist/esm/useFrappeAggregate.mjs +15 -8
- package/dist/esm/useFrappeAggregate.mjs.map +1 -1
- package/dist/esm/useFrappeAggregate.native.js +15 -9
- package/dist/esm/useFrappeAggregate.native.js.map +1 -1
- package/dist/esm/useFrappeFacets.mjs +10 -9
- package/dist/esm/useFrappeFacets.mjs.map +1 -1
- package/dist/esm/useFrappeFacets.native.js +10 -10
- package/dist/esm/useFrappeFacets.native.js.map +1 -1
- package/dist/esm/useFrappePagination.native.js.map +1 -1
- package/dist/esm/useFrappeRows.mjs +86 -0
- package/dist/esm/useFrappeRows.mjs.map +1 -0
- package/dist/esm/useFrappeRows.native.js +99 -0
- package/dist/esm/useFrappeRows.native.js.map +1 -0
- package/dist/jsx/FrappeCalendar.mjs +20 -17
- package/dist/jsx/FrappeCalendar.mjs.map +1 -1
- package/dist/jsx/FrappeCalendar.native.js +22 -21
- package/dist/jsx/FrappeCalendar.native.js.map +1 -1
- package/dist/jsx/FrappeForm.mjs +1 -1
- package/dist/jsx/FrappeForm.mjs.map +1 -1
- package/dist/jsx/FrappeForm.native.js +1 -1
- package/dist/jsx/FrappeForm.native.js.map +1 -1
- package/dist/jsx/FrappeGantt.mjs +27 -36
- package/dist/jsx/FrappeGantt.mjs.map +1 -1
- package/dist/jsx/FrappeGantt.native.js +27 -38
- package/dist/jsx/FrappeGantt.native.js.map +1 -1
- package/dist/jsx/FrappeImageView.mjs +5 -3
- package/dist/jsx/FrappeImageView.mjs.map +1 -1
- package/dist/jsx/FrappeImageView.native.js +8 -4
- package/dist/jsx/FrappeImageView.native.js.map +1 -1
- package/dist/jsx/FrappeKPICard.mjs +27 -2
- package/dist/jsx/FrappeKPICard.mjs.map +1 -1
- package/dist/jsx/FrappeKPICard.native.js +26 -1
- package/dist/jsx/FrappeKPICard.native.js.map +1 -1
- package/dist/jsx/FrappeKanban.mjs +16 -17
- package/dist/jsx/FrappeKanban.mjs.map +1 -1
- package/dist/jsx/FrappeKanban.native.js +18 -21
- package/dist/jsx/FrappeKanban.native.js.map +1 -1
- package/dist/jsx/FrappeLikedBy.mjs +1 -1
- package/dist/jsx/FrappeLikedBy.mjs.map +1 -1
- package/dist/jsx/FrappeLikedBy.native.js +1 -1
- package/dist/jsx/FrappeLikedBy.native.js.map +1 -1
- package/dist/jsx/FrappeList.mjs +2 -2
- package/dist/jsx/FrappeList.mjs.map +1 -1
- package/dist/jsx/FrappeList.native.js +2 -2
- package/dist/jsx/FrappeList.native.js.map +1 -1
- package/dist/jsx/FrappeProvider.mjs.map +1 -1
- package/dist/jsx/FrappeProvider.native.js.map +1 -1
- package/dist/jsx/FrappeReportBuilder.mjs +2 -2
- package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
- package/dist/jsx/FrappeReportBuilder.native.js +2 -2
- package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
- package/dist/jsx/FrappeTable.mjs +36 -39
- package/dist/jsx/FrappeTable.mjs.map +1 -1
- package/dist/jsx/FrappeTable.native.js +38 -39
- package/dist/jsx/FrappeTable.native.js.map +1 -1
- package/dist/jsx/FrappeTreeView.mjs +89 -55
- package/dist/jsx/FrappeTreeView.mjs.map +1 -1
- package/dist/jsx/FrappeTreeView.native.js +129 -50
- package/dist/jsx/FrappeTreeView.native.js.map +1 -1
- package/dist/jsx/commentActions.mjs +1 -1
- package/dist/jsx/commentActions.mjs.map +1 -1
- package/dist/jsx/commentActions.native.js +1 -1
- package/dist/jsx/commentActions.native.js.map +1 -1
- package/dist/jsx/components/timeline.mjs +1 -1
- package/dist/jsx/components/timeline.mjs.map +1 -1
- package/dist/jsx/components/timeline.native.js +1 -1
- package/dist/jsx/desk/DeskShell.mjs +2 -0
- package/dist/jsx/desk/DeskShell.mjs.map +1 -1
- package/dist/jsx/desk/DeskShell.native.js +2 -0
- package/dist/jsx/desk/DeskShell.native.js.map +1 -1
- package/dist/jsx/desk/awesomebar.mjs +1 -1
- package/dist/jsx/desk/awesomebar.mjs.map +1 -1
- package/dist/jsx/desk/awesomebar.native.js +1 -1
- package/dist/jsx/desk/awesomebar.native.js.map +1 -1
- package/dist/jsx/fields/MentionInput/index.mjs +4 -1
- package/dist/jsx/fields/MentionInput/index.mjs.map +1 -1
- package/dist/jsx/fields/MentionInput/index.native.js +4 -1
- package/dist/jsx/fields/MentionInput/index.native.js.map +1 -1
- package/dist/jsx/index.js +2 -1
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +2 -1
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +4 -0
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/schemaForm/index.mjs +8 -7
- package/dist/jsx/schemaForm/index.mjs.map +1 -1
- package/dist/jsx/schemaForm/index.native.js +10 -9
- package/dist/jsx/schemaForm/index.native.js.map +1 -1
- package/dist/jsx/shared/devWarn.mjs +14 -0
- package/dist/jsx/shared/devWarn.mjs.map +1 -0
- package/dist/jsx/shared/devWarn.native.js +45 -0
- package/dist/jsx/shared/devWarn.native.js.map +1 -0
- package/dist/jsx/useFrappeAggregate.mjs +15 -8
- package/dist/jsx/useFrappeAggregate.mjs.map +1 -1
- package/dist/jsx/useFrappeAggregate.native.js +15 -9
- package/dist/jsx/useFrappeAggregate.native.js.map +1 -1
- package/dist/jsx/useFrappeFacets.mjs +10 -9
- package/dist/jsx/useFrappeFacets.mjs.map +1 -1
- package/dist/jsx/useFrappeFacets.native.js +10 -10
- package/dist/jsx/useFrappeFacets.native.js.map +1 -1
- package/dist/jsx/useFrappeRows.mjs +86 -0
- package/dist/jsx/useFrappeRows.mjs.map +1 -0
- package/dist/jsx/useFrappeRows.native.js +129 -0
- package/dist/jsx/useFrappeRows.native.js.map +1 -0
- package/package.json +17 -16
- package/src/FileBrowser/FileBrowser.spec.tsx +11 -1
- package/src/FrappeCalendar.tsx +25 -22
- package/src/FrappeForm.tsx +7 -3
- package/src/FrappeGantt.tsx +29 -39
- package/src/FrappeImageView.tsx +5 -3
- package/src/FrappeKPICard.spec.tsx +128 -0
- package/src/FrappeKPICard.tsx +44 -4
- package/src/FrappeKanban.tsx +24 -17
- package/src/FrappeLikedBy.tsx +1 -1
- package/src/FrappeList.tsx +3 -2
- package/src/FrappeProvider.fixturesOnly.spec.tsx +129 -0
- package/src/FrappeProvider.tsx +16 -6
- package/src/FrappeReportBuilder.tsx +4 -2
- package/src/FrappeTable.autoHeight.spec.tsx +142 -0
- package/src/FrappeTable.rowAccumulator.spec.tsx +110 -0
- package/src/FrappeTable.tsx +75 -48
- package/src/FrappeTreeView.stories.tsx +59 -0
- package/src/FrappeTreeView.tsx +166 -56
- package/src/commentActions.ts +1 -1
- package/src/components/timeline.tsx +1 -1
- package/src/desk/DeskShell.tsx +2 -0
- package/src/desk/awesomebar.tsx +5 -2
- package/src/fields/CodeEditor/CodeEditor.spec.tsx +10 -9
- package/src/fields/Date/typeParity.spec.tsx +19 -9
- package/src/fields/Duration/Duration.spec.tsx +73 -0
- package/src/fields/MentionInput/MentionInput.spec.tsx +110 -0
- package/src/fields/MentionInput/index.tsx +4 -1
- package/src/fields/Password/index.tsx +1 -1
- package/src/fields/Progress/Progress.spec.tsx +9 -0
- package/src/fields/RadioGroup/RadioGroup.spec.tsx +93 -0
- package/src/fields/Signature/Signature.spec.tsx +105 -0
- package/src/fields/Slider/Slider.spec.tsx +73 -0
- package/src/fields/Switch/Switch.spec.tsx +65 -0
- package/src/fields/TextEditor/TextEditor.spec.tsx +2 -3
- package/src/fields/TextEditor/TextEditor.stories.tsx +31 -1
- package/src/fields/ToggleGroup/ToggleGroup.spec.tsx +110 -0
- package/src/frappeViews.designLaw.spec.ts +11 -7
- package/src/index.ts +13 -0
- package/src/schemaForm/index.tsx +6 -7
- package/src/shared/devWarn.ts +42 -0
- package/src/useFrappeAggregate.ts +17 -11
- package/src/useFrappeFacets.ts +17 -10
- package/src/useFrappeRows.spec.tsx +176 -0
- package/src/useFrappeRows.ts +293 -0
- package/types/FrappeCalendar.d.ts.map +1 -1
- package/types/FrappeForm.d.ts +6 -2
- package/types/FrappeForm.d.ts.map +1 -1
- package/types/FrappeGantt.d.ts.map +1 -1
- package/types/FrappeImageView.d.ts.map +1 -1
- package/types/FrappeKPICard.d.ts +9 -1
- package/types/FrappeKPICard.d.ts.map +1 -1
- package/types/FrappeKanban.d.ts.map +1 -1
- package/types/FrappeList.d.ts.map +1 -1
- package/types/FrappeProvider.d.ts +16 -6
- package/types/FrappeProvider.d.ts.map +1 -1
- package/types/FrappeReportBuilder.d.ts.map +1 -1
- package/types/FrappeTable.d.ts +20 -1
- package/types/FrappeTable.d.ts.map +1 -1
- package/types/FrappeTreeView.d.ts +38 -1
- package/types/FrappeTreeView.d.ts.map +1 -1
- package/types/desk/DeskShell.d.ts.map +1 -1
- package/types/desk/awesomebar.d.ts.map +1 -1
- package/types/fields/MentionInput/index.d.ts.map +1 -1
- package/types/fields/Password/index.d.ts +1 -1
- package/types/fields/Password/index.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/schemaForm/index.d.ts.map +1 -1
- package/types/shared/devWarn.d.ts +23 -0
- package/types/shared/devWarn.d.ts.map +1 -0
- package/types/useFrappeAggregate.d.ts +2 -1
- package/types/useFrappeAggregate.d.ts.map +1 -1
- package/types/useFrappeFacets.d.ts +2 -1
- package/types/useFrappeFacets.d.ts.map +1 -1
- package/types/useFrappeRows.d.ts +186 -0
- package/types/useFrappeRows.d.ts.map +1 -0
|
@@ -55,14 +55,15 @@ describe("Frappe view adapters — design-law 100%", () => {
|
|
|
55
55
|
expect(source).toMatch(/from "@multiplatform.one\/components"/);
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
it("FrappeGantt action
|
|
58
|
+
it("FrappeGantt action errors use Alert and keep the adapter boundary", () => {
|
|
59
59
|
const source = read("FrappeGantt.tsx");
|
|
60
|
-
expect(source).
|
|
60
|
+
expect(source).toMatch(/import \{[^}]*Alert[^}]*\} from "@multiplatform.one\/components"/);
|
|
61
|
+
expect(source).toMatch(/<Alert\b[^>]*intent="error"/);
|
|
61
62
|
expect(source).toContain("containerRadius");
|
|
63
|
+
expect(source).not.toContain("knobProps.borderRadius");
|
|
62
64
|
expect(source).not.toMatch(/fontSize=\{knobProps\.sizeToken\}/);
|
|
63
|
-
expect(source).not.
|
|
64
|
-
expect(source).
|
|
65
|
-
expect(source).toContain("MPO-14");
|
|
65
|
+
expect(source).not.toMatch(/\$red\d+/);
|
|
66
|
+
expect(source).not.toMatch(/from ["'](?:@multiplatform\.one\/backoffice|\.\/desk\/)/);
|
|
66
67
|
});
|
|
67
68
|
|
|
68
69
|
it("FrappeReportView uses the house Button and label fragments (LC-54)", () => {
|
|
@@ -81,12 +82,15 @@ describe("Frappe view adapters — design-law 100%", () => {
|
|
|
81
82
|
expect(source).toContain("formCommonColors");
|
|
82
83
|
expect(source).not.toMatch(/fontWeight="600"|fontWeight="500"/);
|
|
83
84
|
expect(source).toContain('fontWeight="400"');
|
|
84
|
-
expect(source).
|
|
85
|
+
expect(source).not.toMatch(/<Button\b[^>]*\b(?:controlFill|backgroundColor|borderColor)=/);
|
|
85
86
|
});
|
|
86
87
|
|
|
87
88
|
it("FrappeTreeView empty chrome is EmptyState and labels use the label fragment", () => {
|
|
88
89
|
const source = read("FrappeTreeView.tsx");
|
|
89
|
-
expect(source).
|
|
90
|
+
expect(source).toMatch(/import \{[^}]*EmptyState[^}]*\} from "@multiplatform.one\/components"/);
|
|
91
|
+
expect(source).toContain("<EmptyState");
|
|
92
|
+
expect(source).toContain("useGlyphColor(formCommonColors.muted)");
|
|
93
|
+
expect(source).not.toMatch(/<TreeStructureIcon\b[^>]*color=\{formCommonColors\./);
|
|
90
94
|
expect(source).not.toMatch(/size=\{48\}/);
|
|
91
95
|
expect(source).toContain("knobProps.label");
|
|
92
96
|
expect(source).not.toMatch(/fontSize=\{display === "compressed" \? 12 : 14\}/);
|
package/src/index.ts
CHANGED
|
@@ -120,6 +120,19 @@ export {
|
|
|
120
120
|
type FrappeChartDataSource,
|
|
121
121
|
} from "./FrappeChartCard";
|
|
122
122
|
|
|
123
|
+
// The composed doctype read (MPO-251) — the supported way to get rows out of
|
|
124
|
+
// a doctype when the panel shape has no shipped component. FrappeTable and
|
|
125
|
+
// the other live views read through it, so there is one implementation.
|
|
126
|
+
export {
|
|
127
|
+
useFrappeRows,
|
|
128
|
+
useFrappeConnection,
|
|
129
|
+
DEFAULT_FRAPPE_ROWS_LIMIT,
|
|
130
|
+
type FrappeRowsConnection,
|
|
131
|
+
type FrappeRowsMessages,
|
|
132
|
+
type UseFrappeRowsOptions,
|
|
133
|
+
type UseFrappeRowsResult,
|
|
134
|
+
} from "./useFrappeRows";
|
|
135
|
+
|
|
123
136
|
export {
|
|
124
137
|
useFrappeAggregate,
|
|
125
138
|
type FrappeAggregateConnection,
|
package/src/schemaForm/index.tsx
CHANGED
|
@@ -17,9 +17,10 @@ import {
|
|
|
17
17
|
type RequiredMarkStrategy,
|
|
18
18
|
} from "@multiplatform.one/forms";
|
|
19
19
|
import { useResolvedKnobs } from "@multiplatform.one/theme";
|
|
20
|
+
import { Card } from "@multiplatform.one/components";
|
|
20
21
|
import React, { useMemo } from "react";
|
|
21
22
|
import { useTranslation } from "react-i18next";
|
|
22
|
-
import {
|
|
23
|
+
import { Text, XStack, YStack } from "tamagui";
|
|
23
24
|
|
|
24
25
|
import { compileDependsOn } from "../dependsOn";
|
|
25
26
|
import { Heading, type HeadingLevel } from "../fields/Heading";
|
|
@@ -353,13 +354,12 @@ function SchemaFormSectionCard({ section, headingLevel, renderField }: SchemaFor
|
|
|
353
354
|
|
|
354
355
|
return (
|
|
355
356
|
<Card
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
backgroundColor={hideBorder ? "transparent" : undefined}
|
|
357
|
+
data-mpo-schema-form-card=""
|
|
358
|
+
data-mpo-schema-form-borderless={hideBorder ? "" : undefined}
|
|
359
|
+
{...(hideBorder ? { borderWidth: 0, backgroundColor: "transparent" } : {})}
|
|
360
360
|
>
|
|
361
361
|
{(section.label || section.description) && (
|
|
362
|
-
<Card.Header
|
|
362
|
+
<Card.Header>
|
|
363
363
|
{section.label ? (
|
|
364
364
|
<Heading
|
|
365
365
|
label={section.label}
|
|
@@ -380,7 +380,6 @@ function SchemaFormSectionCard({ section, headingLevel, renderField }: SchemaFor
|
|
|
380
380
|
{/* Kept mounted while collapsed (display none) so field state and the
|
|
381
381
|
collapse target survive toggles — matches desk's CSS hide. */}
|
|
382
382
|
<Card.Footer
|
|
383
|
-
{...knobProps.panelPadding}
|
|
384
383
|
display={effectiveCollapsed ? "none" : undefined}
|
|
385
384
|
aria-hidden={effectiveCollapsed || undefined}
|
|
386
385
|
>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Package-local DEV guardrails for frappe-ui, warned under a `[frappe-ui]`
|
|
3
|
+
* prefix.
|
|
4
|
+
*
|
|
5
|
+
* The canonical catalog is `devWarn` in `@multiplatform.one/theme`, whose
|
|
6
|
+
* `DevWarnCode` union is closed over design-guardrail codes. Live-data
|
|
7
|
+
* misconfiguration is a frappe-ui concern rather than a design-law one, so
|
|
8
|
+
* it warns from here, the same way AsyncBoundary keeps its own.
|
|
9
|
+
*
|
|
10
|
+
* No-ops when `NODE_ENV === "production"`, and each key warns once per
|
|
11
|
+
* process so a re-render never repeats a line.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export type FrappeDevWarnCode = "kpi-datasource-without-baseurl";
|
|
15
|
+
|
|
16
|
+
export type FrappeDevWarnDetail = {
|
|
17
|
+
component?: string;
|
|
18
|
+
id?: string;
|
|
19
|
+
doctype?: string;
|
|
20
|
+
suggest?: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const seen = new Set<string>();
|
|
24
|
+
|
|
25
|
+
export function frappeDevWarn(code: FrappeDevWarnCode, detail: FrappeDevWarnDetail = {}): void {
|
|
26
|
+
if (process.env.NODE_ENV === "production") return;
|
|
27
|
+
const key = [code, detail.component ?? "", detail.id ?? "", detail.doctype ?? ""].join(":");
|
|
28
|
+
if (seen.has(key)) return;
|
|
29
|
+
seen.add(key);
|
|
30
|
+
const bits = [
|
|
31
|
+
detail.component ? `component=${detail.component}` : undefined,
|
|
32
|
+
detail.id ? `id=${detail.id}` : undefined,
|
|
33
|
+
detail.doctype ? `doctype=${detail.doctype}` : undefined,
|
|
34
|
+
detail.suggest ? `suggest=${detail.suggest}` : undefined,
|
|
35
|
+
].filter(Boolean);
|
|
36
|
+
console.warn(`[frappe-ui] ${code}${bits.length ? ` (${bits.join(", ")})` : ""}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** @internal test helper */
|
|
40
|
+
export function __resetFrappeDevWarnSeen(): void {
|
|
41
|
+
seen.clear();
|
|
42
|
+
}
|
|
@@ -41,7 +41,8 @@ export type FrappeAggregateOperation = "count" | "sum" | "avg" | "min" | "max";
|
|
|
41
41
|
|
|
42
42
|
/** Connection shape shared with the other frappe-ui widgets. */
|
|
43
43
|
export interface FrappeAggregateConnection {
|
|
44
|
-
baseURL
|
|
44
|
+
/** Required unless `fixtures` is set (see FrappeConfig.baseURL). */
|
|
45
|
+
baseURL?: string;
|
|
45
46
|
/** False keeps HTTP reads without realtime subscriptions. */
|
|
46
47
|
realtime?: boolean;
|
|
47
48
|
socketPort?: number;
|
|
@@ -97,18 +98,18 @@ const DEFAULT_DEBOUNCE_MS = 300;
|
|
|
97
98
|
// One REST client per connection — widgets sharing a bench share it.
|
|
98
99
|
const dbCache = new Map<string, DbModule>();
|
|
99
100
|
|
|
100
|
-
function getDb(
|
|
101
|
-
const key = `${
|
|
101
|
+
function getDb(baseURL: string, auth: FrappeAggregateConnection["auth"]): DbModule {
|
|
102
|
+
const key = `${baseURL}:${auth?.token ?? ""}:${auth?.type ?? ""}`;
|
|
102
103
|
let db = dbCache.get(key);
|
|
103
104
|
if (!db) {
|
|
104
|
-
const authConfig: AuthConfig | undefined =
|
|
105
|
+
const authConfig: AuthConfig | undefined = auth
|
|
105
106
|
? {
|
|
106
|
-
useToken:
|
|
107
|
-
token:
|
|
108
|
-
type:
|
|
107
|
+
useToken: auth.useToken,
|
|
108
|
+
token: auth.token,
|
|
109
|
+
type: auth.type as AuthConfig["type"],
|
|
109
110
|
}
|
|
110
111
|
: undefined;
|
|
111
|
-
db = new DbModule(new HttpClient(
|
|
112
|
+
db = new DbModule(new HttpClient(baseURL, authConfig));
|
|
112
113
|
dbCache.set(key, db);
|
|
113
114
|
}
|
|
114
115
|
return db;
|
|
@@ -271,9 +272,14 @@ export function useFrappeAggregate(
|
|
|
271
272
|
if (!conn || !currentSpec.doctype) return;
|
|
272
273
|
const seq = ++fetchSeq.current;
|
|
273
274
|
try {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
let result: AggregateData;
|
|
276
|
+
if (conn.fixtures) {
|
|
277
|
+
result = await fetchFixtureAggregate(conn.fixtures, currentSpec);
|
|
278
|
+
} else if (conn.baseURL) {
|
|
279
|
+
result = await fetchLiveAggregate(getDb(conn.baseURL, conn.auth), currentSpec);
|
|
280
|
+
} else {
|
|
281
|
+
throw new Error("useFrappeAggregate requires a connection with baseURL or fixtures");
|
|
282
|
+
}
|
|
277
283
|
if (seq !== fetchSeq.current) return; // stale response — a newer fetch won
|
|
278
284
|
setData(result);
|
|
279
285
|
setError(undefined);
|
package/src/useFrappeFacets.ts
CHANGED
|
@@ -78,7 +78,8 @@ export interface FrappeFacetState {
|
|
|
78
78
|
|
|
79
79
|
/** Connection shape shared with the other frappe-ui widgets. */
|
|
80
80
|
export interface FrappeFacetsConnection {
|
|
81
|
-
baseURL
|
|
81
|
+
/** Required unless `fixtures` is set (see FrappeConfig.baseURL). */
|
|
82
|
+
baseURL?: string;
|
|
82
83
|
auth?: { useToken?: boolean; token?: string | (() => string | Promise<string>); type?: string };
|
|
83
84
|
fixtures?: FixtureProvider;
|
|
84
85
|
}
|
|
@@ -169,18 +170,18 @@ export function scrubUserFacetRows(
|
|
|
169
170
|
// One RPC client per connection — facets sharing a bench share it.
|
|
170
171
|
const callCache = new Map<string, CallModule>();
|
|
171
172
|
|
|
172
|
-
function getCall(
|
|
173
|
-
const key = `${
|
|
173
|
+
function getCall(baseURL: string, auth: FrappeFacetsConnection["auth"]): CallModule {
|
|
174
|
+
const key = `${baseURL}:${auth?.token ?? ""}:${auth?.type ?? ""}`;
|
|
174
175
|
let call = callCache.get(key);
|
|
175
176
|
if (!call) {
|
|
176
|
-
const authConfig: AuthConfig | undefined =
|
|
177
|
+
const authConfig: AuthConfig | undefined = auth
|
|
177
178
|
? {
|
|
178
|
-
useToken:
|
|
179
|
-
token:
|
|
180
|
-
type:
|
|
179
|
+
useToken: auth.useToken,
|
|
180
|
+
token: auth.token,
|
|
181
|
+
type: auth.type as AuthConfig["type"],
|
|
181
182
|
}
|
|
182
183
|
: undefined;
|
|
183
|
-
call = new CallModule(new HttpClient(
|
|
184
|
+
call = new CallModule(new HttpClient(baseURL, authConfig));
|
|
184
185
|
callCache.set(key, call);
|
|
185
186
|
}
|
|
186
187
|
return call;
|
|
@@ -439,7 +440,9 @@ export function useFrappeFacets(
|
|
|
439
440
|
useEffect(() => {
|
|
440
441
|
if (!enabled) return;
|
|
441
442
|
const conn = connectionRef.current;
|
|
442
|
-
|
|
443
|
+
// Neither a corpus nor a bench can answer, so stay idle instead of
|
|
444
|
+
// entering a loading state nothing will ever resolve.
|
|
445
|
+
if (!conn || (!conn.fixtures && !conn.baseURL)) return;
|
|
443
446
|
const seq = ++fetchSeq.current;
|
|
444
447
|
const activeFilters = JSON.parse(filtersKey) as FrappeFacetFilters;
|
|
445
448
|
|
|
@@ -525,7 +528,11 @@ export function useFrappeFacets(
|
|
|
525
528
|
return;
|
|
526
529
|
}
|
|
527
530
|
|
|
528
|
-
|
|
531
|
+
// Narrowing only: the guard at the top of the effect already returned
|
|
532
|
+
// when neither a corpus nor a baseURL is configured.
|
|
533
|
+
if (!conn.baseURL) return;
|
|
534
|
+
|
|
535
|
+
const call = getCall(conn.baseURL, conn.auth);
|
|
529
536
|
fetchGroupByCount(call, doctype, filtersExcludingField(activeFilters, "_assign"), "assigned_to")
|
|
530
537
|
.then((rows) => done("assigned", rows))
|
|
531
538
|
.catch((error) => fail("assigned", error));
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useFrappeRows — the composed doctype read (MPO-251).
|
|
3
|
+
*
|
|
4
|
+
* What this locks:
|
|
5
|
+
* 1. rows / isLoading / error come back from one hook, so a panel with no
|
|
6
|
+
* shipped component does not re-derive the read.
|
|
7
|
+
* 2. A 403 or an unreachable server surfaces as an ERROR, not as an empty
|
|
8
|
+
* result — the trap the copies each had to remember.
|
|
9
|
+
* 3. `limit` is defaulted by the hook (DEFAULT_FRAPPE_ROWS_LIMIT), with
|
|
10
|
+
* `limit: null` as the explicit bench-default opt-out FrappeTable takes.
|
|
11
|
+
* 4. Collection sharing is keyed on the options JSON: the same field list
|
|
12
|
+
* shares one collection, a different one does not.
|
|
13
|
+
*
|
|
14
|
+
* Fixture-hermetic: documents ride InMemoryFixtureProvider, so nothing
|
|
15
|
+
* dials a baseURL.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { InMemoryFixtureProvider, useFrappeCollection } from "@multiplatform.one/frappe";
|
|
19
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
20
|
+
import { cleanup, waitFor } from "@testing-library/react";
|
|
21
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
22
|
+
import { FrappeProvider } from "./FrappeProvider";
|
|
23
|
+
import { DEFAULT_FRAPPE_ROWS_LIMIT, useFrappeConnection, useFrappeRows } from "./useFrappeRows";
|
|
24
|
+
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
cleanup();
|
|
27
|
+
vi.restoreAllMocks();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
interface Account {
|
|
31
|
+
name: string;
|
|
32
|
+
doctype: string;
|
|
33
|
+
account: string;
|
|
34
|
+
balance: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const accounts: Account[] = [
|
|
38
|
+
{ name: "ACC-001", doctype: "Account", account: "Assets:Cash", balance: "10.00" },
|
|
39
|
+
{ name: "ACC-002", doctype: "Account", account: "Assets:Bank", balance: "9.00" },
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
const accountFields = ["name", "account", "balance"] as const;
|
|
43
|
+
|
|
44
|
+
function Harness({
|
|
45
|
+
onResult,
|
|
46
|
+
...options
|
|
47
|
+
}: {
|
|
48
|
+
onResult: (result: ReturnType<typeof useFrappeRows<Account>>) => void;
|
|
49
|
+
} & Parameters<typeof useFrappeRows<Account>>[2]) {
|
|
50
|
+
const connection = useFrappeConnection();
|
|
51
|
+
const result = useFrappeRows<Account>(connection, "Account", options);
|
|
52
|
+
onResult(result);
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function renderHarness(
|
|
57
|
+
options: Parameters<typeof useFrappeRows<Account>>[2] = {},
|
|
58
|
+
fixtures = new InMemoryFixtureProvider({ Account: accounts }),
|
|
59
|
+
) {
|
|
60
|
+
const results: Array<ReturnType<typeof useFrappeRows<Account>>> = [];
|
|
61
|
+
const utils = renderWithProviders(
|
|
62
|
+
<FrappeProvider baseURL="https://userows.spec.test" fixtures={fixtures}>
|
|
63
|
+
<Harness onResult={(r) => results.push(r)} {...options} />
|
|
64
|
+
</FrappeProvider>,
|
|
65
|
+
);
|
|
66
|
+
return { results, last: () => results[results.length - 1]!, ...utils };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
describe("useFrappeRows", () => {
|
|
70
|
+
it("reads a doctype into rows", async () => {
|
|
71
|
+
const { last } = renderHarness({ fields: accountFields });
|
|
72
|
+
await waitFor(() => expect(last().rows).toHaveLength(2));
|
|
73
|
+
expect(last().rows.map((r) => r.name)).toEqual(["ACC-001", "ACC-002"]);
|
|
74
|
+
expect(last().isLoading).toBe(false);
|
|
75
|
+
expect(last().error).toBeNull();
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("parks on enabled: false — no rows, not loading", () => {
|
|
79
|
+
const { last } = renderHarness({ fields: accountFields, enabled: false });
|
|
80
|
+
expect(last().rows).toEqual([]);
|
|
81
|
+
expect(last().isLoading).toBe(false);
|
|
82
|
+
expect(last().collection).toBeUndefined();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("surfaces a permission rejection as an error rather than an empty result", async () => {
|
|
86
|
+
const fixtures = new InMemoryFixtureProvider({ Account: accounts });
|
|
87
|
+
vi.spyOn(fixtures, "getList").mockRejectedValue(
|
|
88
|
+
Object.assign(new Error("PermissionError"), { status: 403 }),
|
|
89
|
+
);
|
|
90
|
+
const { last } = renderHarness(
|
|
91
|
+
{
|
|
92
|
+
fields: accountFields,
|
|
93
|
+
messages: { permission: "No permission for Account", generic: "Error loading Account" },
|
|
94
|
+
},
|
|
95
|
+
fixtures,
|
|
96
|
+
);
|
|
97
|
+
await waitFor(() => expect(last().error).toBeInstanceOf(Error));
|
|
98
|
+
expect(last().error?.message).toContain("No permission for Account");
|
|
99
|
+
expect(last().rows).toEqual([]);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("surfaces an unreachable server as an error rather than an empty result", async () => {
|
|
103
|
+
const fixtures = new InMemoryFixtureProvider({ Account: accounts });
|
|
104
|
+
vi.spyOn(fixtures, "getList").mockRejectedValue(new Error("Failed to fetch"));
|
|
105
|
+
const { last } = renderHarness(
|
|
106
|
+
{
|
|
107
|
+
fields: accountFields,
|
|
108
|
+
messages: { permission: "No permission for Account", generic: "Error loading Account" },
|
|
109
|
+
},
|
|
110
|
+
fixtures,
|
|
111
|
+
);
|
|
112
|
+
await waitFor(() => expect(last().error).toBeInstanceOf(Error));
|
|
113
|
+
expect(last().error?.message).toContain("Error loading Account");
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it("defaults the limit rather than leaving it to the caller", () => {
|
|
117
|
+
// Two readers of the same doctype: one taking the default limit, one
|
|
118
|
+
// passing null (the bench-default opt-out). The options JSON is the
|
|
119
|
+
// collection cache key and `limit` is part of it, so a differing limit
|
|
120
|
+
// must produce a DIFFERENT collection.
|
|
121
|
+
const fixtures = new InMemoryFixtureProvider({ Account: accounts });
|
|
122
|
+
const seen: Array<unknown> = [];
|
|
123
|
+
function TwoReaders() {
|
|
124
|
+
const connection = useFrappeConnection();
|
|
125
|
+
const defaulted = useFrappeRows<Account>(connection, "Account", { fields: accountFields });
|
|
126
|
+
const benchDefault = useFrappeRows<Account>(connection, "Account", {
|
|
127
|
+
fields: accountFields,
|
|
128
|
+
limit: null,
|
|
129
|
+
});
|
|
130
|
+
const explicit = useFrappeRows<Account>(connection, "Account", {
|
|
131
|
+
fields: accountFields,
|
|
132
|
+
limit: DEFAULT_FRAPPE_ROWS_LIMIT,
|
|
133
|
+
});
|
|
134
|
+
seen.push([defaulted.collection, benchDefault.collection, explicit.collection]);
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
renderWithProviders(
|
|
138
|
+
<FrappeProvider baseURL="https://userows.spec.test" fixtures={fixtures}>
|
|
139
|
+
<TwoReaders />
|
|
140
|
+
</FrappeProvider>,
|
|
141
|
+
);
|
|
142
|
+
const [defaulted, benchDefault, explicit] = seen[seen.length - 1] as unknown[];
|
|
143
|
+
expect(defaulted).toBeDefined();
|
|
144
|
+
expect(defaulted, "omitting limit is the same query as passing the default").toBe(explicit);
|
|
145
|
+
expect(benchDefault, "limit: null is a different query — no limit at all").not.toBe(defaulted);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it("shares one collection with an identical field list and splits on a different one", () => {
|
|
149
|
+
const fixtures = new InMemoryFixtureProvider({ Account: accounts });
|
|
150
|
+
const seen: Array<unknown[]> = [];
|
|
151
|
+
function ThreeReaders() {
|
|
152
|
+
const connection = useFrappeConnection();
|
|
153
|
+
const a = useFrappeRows<Account>(connection, "Account", { fields: accountFields });
|
|
154
|
+
const b = useFrappeRows<Account>(connection, "Account", {
|
|
155
|
+
fields: ["name", "account", "balance"],
|
|
156
|
+
});
|
|
157
|
+
const c = useFrappeRows<Account>(connection, "Account", { fields: ["name", "account"] });
|
|
158
|
+
seen.push([a.collection, b.collection, c.collection]);
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
renderWithProviders(
|
|
162
|
+
<FrappeProvider baseURL="https://userows.spec.test" fixtures={fixtures}>
|
|
163
|
+
<ThreeReaders />
|
|
164
|
+
</FrappeProvider>,
|
|
165
|
+
);
|
|
166
|
+
const [a, b, c] = seen[seen.length - 1]!;
|
|
167
|
+
expect(a, "same field list shares one collection").toBe(b);
|
|
168
|
+
expect(c, "a field list short by one entry does NOT share").not.toBe(a);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it("is the same primitive FrappeTable's read was built on", () => {
|
|
172
|
+
// Guardrail against the hook drifting away from useFrappeCollection —
|
|
173
|
+
// the point of MPO-251 is ONE implementation, not a second one.
|
|
174
|
+
expect(typeof useFrappeCollection).toBe("function");
|
|
175
|
+
});
|
|
176
|
+
});
|