@multiplatform.one/frappe-ui 7.11.0 → 7.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/cjs/FrappeDashboard.cjs +8 -10
- package/dist/cjs/FrappeDashboard.native.js +8 -14
- package/dist/cjs/FrappeDashboard.native.js.map +1 -1
- package/dist/cjs/FrappeForm.cjs +465 -175
- package/dist/cjs/FrappeForm.native.js +611 -207
- package/dist/cjs/FrappeForm.native.js.map +1 -1
- package/dist/cjs/FrappeFormConnections.cjs +125 -0
- package/dist/cjs/FrappeFormConnections.native.js +149 -0
- package/dist/cjs/FrappeFormConnections.native.js.map +1 -0
- package/dist/cjs/FrappeImageView.cjs +7 -9
- package/dist/cjs/FrappeImageView.native.js +7 -13
- package/dist/cjs/FrappeImageView.native.js.map +1 -1
- package/dist/cjs/FrappeList.cjs +29 -4
- package/dist/cjs/FrappeList.native.js +37 -5
- package/dist/cjs/FrappeList.native.js.map +1 -1
- package/dist/cjs/FrappeListView.cjs +102 -29
- package/dist/cjs/FrappeListView.native.js +109 -29
- package/dist/cjs/FrappeListView.native.js.map +1 -1
- package/dist/cjs/FrappeProvider.cjs +7 -2
- package/dist/cjs/FrappeProvider.native.js +7 -2
- package/dist/cjs/FrappeProvider.native.js.map +1 -1
- package/dist/cjs/FrappeReportBuilder.cjs +10 -11
- package/dist/cjs/FrappeReportBuilder.native.js +10 -16
- package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
- package/dist/cjs/FrappeRowsReader.cjs +49 -0
- package/dist/cjs/FrappeRowsReader.native.js +53 -0
- package/dist/cjs/FrappeRowsReader.native.js.map +1 -0
- package/dist/cjs/FrappeTable.cjs +18 -6
- package/dist/cjs/FrappeTable.native.js +24 -6
- package/dist/cjs/FrappeTable.native.js.map +1 -1
- package/dist/cjs/fieldRegistry.cjs +36 -11
- package/dist/cjs/fieldRegistry.native.js +59 -11
- package/dist/cjs/fieldRegistry.native.js.map +1 -1
- package/dist/cjs/fields/Date/index.native.js +5 -2
- package/dist/cjs/fields/Date/index.native.js.map +1 -1
- package/dist/cjs/fields/Date/sheetKeyboard.cjs +2 -2
- package/dist/cjs/fields/Date/sheetKeyboard.native.js +2 -2
- package/dist/cjs/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/cjs/fields/DateRange/index.cjs +2 -1
- package/dist/cjs/fields/DateRange/index.native.js +4 -1
- package/dist/cjs/fields/DateRange/index.native.js.map +1 -1
- package/dist/cjs/formEngine/index.cjs +4 -2
- package/dist/cjs/formEngine/index.native.js +3 -1
- package/dist/cjs/formEngine/index.native.js.map +1 -1
- package/dist/cjs/formEngine/useSessionRoles.cjs +77 -0
- package/dist/cjs/formEngine/useSessionRoles.native.js +84 -0
- package/dist/cjs/formEngine/useSessionRoles.native.js.map +1 -0
- package/dist/cjs/frappeConnections.cjs +41 -0
- package/dist/cjs/frappeConnections.native.js +50 -0
- package/dist/cjs/frappeConnections.native.js.map +1 -0
- package/dist/cjs/frappeNavigation.cjs +107 -0
- package/dist/cjs/frappeNavigation.native.js +112 -0
- package/dist/cjs/frappeNavigation.native.js.map +1 -0
- package/dist/cjs/index.cjs +18 -1
- package/dist/cjs/index.native.js +18 -1
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/schemaForm/index.cjs +4 -1
- package/dist/cjs/schemaForm/index.native.js +4 -1
- package/dist/cjs/schemaForm/index.native.js.map +1 -1
- package/dist/cjs/useConnectionFilters.cjs +146 -0
- package/dist/cjs/useConnectionFilters.native.js +213 -0
- package/dist/cjs/useConnectionFilters.native.js.map +1 -0
- package/dist/cjs/useFrappePagination.cjs +37 -18
- package/dist/cjs/useFrappePagination.native.js +59 -23
- package/dist/cjs/useFrappePagination.native.js.map +1 -1
- package/dist/cjs/useFrappeRows.native.js.map +1 -1
- package/dist/esm/FrappeDashboard.mjs +9 -11
- package/dist/esm/FrappeDashboard.mjs.map +1 -1
- package/dist/esm/FrappeDashboard.native.js +9 -15
- package/dist/esm/FrappeDashboard.native.js.map +1 -1
- package/dist/esm/FrappeForm.mjs +471 -181
- package/dist/esm/FrappeForm.mjs.map +1 -1
- package/dist/esm/FrappeForm.native.js +599 -195
- package/dist/esm/FrappeForm.native.js.map +1 -1
- package/dist/esm/FrappeFormConnections.mjs +99 -0
- package/dist/esm/FrappeFormConnections.mjs.map +1 -0
- package/dist/esm/FrappeFormConnections.native.js +120 -0
- package/dist/esm/FrappeFormConnections.native.js.map +1 -0
- package/dist/esm/FrappeImageView.mjs +8 -10
- package/dist/esm/FrappeImageView.mjs.map +1 -1
- package/dist/esm/FrappeImageView.native.js +8 -14
- package/dist/esm/FrappeImageView.native.js.map +1 -1
- package/dist/esm/FrappeList.mjs +31 -6
- package/dist/esm/FrappeList.mjs.map +1 -1
- package/dist/esm/FrappeList.native.js +39 -7
- package/dist/esm/FrappeList.native.js.map +1 -1
- package/dist/esm/FrappeListView.mjs +103 -30
- package/dist/esm/FrappeListView.mjs.map +1 -1
- package/dist/esm/FrappeListView.native.js +110 -30
- package/dist/esm/FrappeListView.native.js.map +1 -1
- package/dist/esm/FrappeProvider.mjs +7 -2
- package/dist/esm/FrappeProvider.mjs.map +1 -1
- package/dist/esm/FrappeProvider.native.js +7 -2
- package/dist/esm/FrappeProvider.native.js.map +1 -1
- package/dist/esm/FrappeReportBuilder.mjs +11 -12
- package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
- package/dist/esm/FrappeReportBuilder.native.js +11 -17
- package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
- package/dist/esm/FrappeRowsReader.mjs +24 -0
- package/dist/esm/FrappeRowsReader.mjs.map +1 -0
- package/dist/esm/FrappeRowsReader.native.js +25 -0
- package/dist/esm/FrappeRowsReader.native.js.map +1 -0
- package/dist/esm/FrappeTable.mjs +18 -6
- package/dist/esm/FrappeTable.mjs.map +1 -1
- package/dist/esm/FrappeTable.native.js +24 -6
- package/dist/esm/FrappeTable.native.js.map +1 -1
- package/dist/esm/fieldRegistry.mjs +35 -12
- package/dist/esm/fieldRegistry.mjs.map +1 -1
- package/dist/esm/fieldRegistry.native.js +58 -12
- package/dist/esm/fieldRegistry.native.js.map +1 -1
- package/dist/esm/fields/Date/index.native.js +6 -3
- package/dist/esm/fields/Date/index.native.js.map +1 -1
- package/dist/esm/fields/Date/sheetKeyboard.mjs +2 -2
- package/dist/esm/fields/Date/sheetKeyboard.mjs.map +1 -1
- package/dist/esm/fields/Date/sheetKeyboard.native.js +2 -2
- package/dist/esm/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/esm/fields/DateRange/index.mjs +2 -1
- package/dist/esm/fields/DateRange/index.mjs.map +1 -1
- package/dist/esm/fields/DateRange/index.native.js +4 -1
- package/dist/esm/fields/DateRange/index.native.js.map +1 -1
- package/dist/esm/formEngine/index.mjs +2 -1
- package/dist/esm/formEngine/index.mjs.map +1 -1
- package/dist/esm/formEngine/index.native.js +2 -1
- package/dist/esm/formEngine/index.native.js.map +1 -1
- package/dist/esm/formEngine/useSessionRoles.mjs +52 -0
- package/dist/esm/formEngine/useSessionRoles.mjs.map +1 -0
- package/dist/esm/formEngine/useSessionRoles.native.js +56 -0
- package/dist/esm/formEngine/useSessionRoles.native.js.map +1 -0
- package/dist/esm/frappeConnections.mjs +15 -0
- package/dist/esm/frappeConnections.mjs.map +1 -0
- package/dist/esm/frappeConnections.native.js +21 -0
- package/dist/esm/frappeConnections.native.js.map +1 -0
- package/dist/esm/frappeNavigation.mjs +78 -0
- package/dist/esm/frappeNavigation.mjs.map +1 -0
- package/dist/esm/frappeNavigation.native.js +80 -0
- package/dist/esm/frappeNavigation.native.js.map +1 -0
- package/dist/esm/index.mjs +7 -3
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +7 -3
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/schemaForm/index.mjs +4 -1
- package/dist/esm/schemaForm/index.mjs.map +1 -1
- package/dist/esm/schemaForm/index.native.js +4 -1
- package/dist/esm/schemaForm/index.native.js.map +1 -1
- package/dist/esm/useConnectionFilters.mjs +121 -0
- package/dist/esm/useConnectionFilters.mjs.map +1 -0
- package/dist/esm/useConnectionFilters.native.js +185 -0
- package/dist/esm/useConnectionFilters.native.js.map +1 -0
- package/dist/esm/useFrappePagination.mjs +38 -19
- package/dist/esm/useFrappePagination.mjs.map +1 -1
- package/dist/esm/useFrappePagination.native.js +60 -24
- package/dist/esm/useFrappePagination.native.js.map +1 -1
- package/dist/esm/useFrappeRows.mjs.map +1 -1
- package/dist/esm/useFrappeRows.native.js.map +1 -1
- package/dist/jsx/FrappeDashboard.mjs +9 -11
- package/dist/jsx/FrappeDashboard.mjs.map +1 -1
- package/dist/jsx/FrappeDashboard.native.js +8 -14
- package/dist/jsx/FrappeDashboard.native.js.map +1 -1
- package/dist/jsx/FrappeForm.mjs +471 -181
- package/dist/jsx/FrappeForm.mjs.map +1 -1
- package/dist/jsx/FrappeForm.native.js +611 -207
- package/dist/jsx/FrappeForm.native.js.map +1 -1
- package/dist/jsx/FrappeFormConnections.mjs +99 -0
- package/dist/jsx/FrappeFormConnections.mjs.map +1 -0
- package/dist/jsx/FrappeFormConnections.native.js +149 -0
- package/dist/jsx/FrappeFormConnections.native.js.map +1 -0
- package/dist/jsx/FrappeImageView.mjs +8 -10
- package/dist/jsx/FrappeImageView.mjs.map +1 -1
- package/dist/jsx/FrappeImageView.native.js +7 -13
- package/dist/jsx/FrappeImageView.native.js.map +1 -1
- package/dist/jsx/FrappeList.mjs +31 -6
- package/dist/jsx/FrappeList.mjs.map +1 -1
- package/dist/jsx/FrappeList.native.js +37 -5
- package/dist/jsx/FrappeList.native.js.map +1 -1
- package/dist/jsx/FrappeListView.mjs +103 -30
- package/dist/jsx/FrappeListView.mjs.map +1 -1
- package/dist/jsx/FrappeListView.native.js +109 -29
- package/dist/jsx/FrappeListView.native.js.map +1 -1
- package/dist/jsx/FrappeProvider.mjs +7 -2
- package/dist/jsx/FrappeProvider.mjs.map +1 -1
- package/dist/jsx/FrappeProvider.native.js +7 -2
- package/dist/jsx/FrappeProvider.native.js.map +1 -1
- package/dist/jsx/FrappeReportBuilder.mjs +11 -12
- package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
- package/dist/jsx/FrappeReportBuilder.native.js +10 -16
- package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
- package/dist/jsx/FrappeRowsReader.mjs +24 -0
- package/dist/jsx/FrappeRowsReader.mjs.map +1 -0
- package/dist/jsx/FrappeRowsReader.native.js +53 -0
- package/dist/jsx/FrappeRowsReader.native.js.map +1 -0
- package/dist/jsx/FrappeTable.mjs +18 -6
- package/dist/jsx/FrappeTable.mjs.map +1 -1
- package/dist/jsx/FrappeTable.native.js +24 -6
- package/dist/jsx/FrappeTable.native.js.map +1 -1
- package/dist/jsx/fieldRegistry.mjs +35 -12
- package/dist/jsx/fieldRegistry.mjs.map +1 -1
- package/dist/jsx/fieldRegistry.native.js +59 -11
- package/dist/jsx/fieldRegistry.native.js.map +1 -1
- package/dist/jsx/fields/Date/index.native.js +5 -2
- package/dist/jsx/fields/Date/index.native.js.map +1 -1
- package/dist/jsx/fields/Date/sheetKeyboard.mjs +2 -2
- package/dist/jsx/fields/Date/sheetKeyboard.mjs.map +1 -1
- package/dist/jsx/fields/Date/sheetKeyboard.native.js +2 -2
- package/dist/jsx/fields/Date/sheetKeyboard.native.js.map +1 -1
- package/dist/jsx/fields/DateRange/index.mjs +2 -1
- package/dist/jsx/fields/DateRange/index.mjs.map +1 -1
- package/dist/jsx/fields/DateRange/index.native.js +4 -1
- package/dist/jsx/fields/DateRange/index.native.js.map +1 -1
- package/dist/jsx/formEngine/index.mjs +2 -1
- package/dist/jsx/formEngine/index.mjs.map +1 -1
- package/dist/jsx/formEngine/index.native.js +3 -1
- package/dist/jsx/formEngine/index.native.js.map +1 -1
- package/dist/jsx/formEngine/useSessionRoles.mjs +52 -0
- package/dist/jsx/formEngine/useSessionRoles.mjs.map +1 -0
- package/dist/jsx/formEngine/useSessionRoles.native.js +84 -0
- package/dist/jsx/formEngine/useSessionRoles.native.js.map +1 -0
- package/dist/jsx/frappeConnections.mjs +15 -0
- package/dist/jsx/frappeConnections.mjs.map +1 -0
- package/dist/jsx/frappeConnections.native.js +50 -0
- package/dist/jsx/frappeConnections.native.js.map +1 -0
- package/dist/jsx/frappeNavigation.mjs +78 -0
- package/dist/jsx/frappeNavigation.mjs.map +1 -0
- package/dist/jsx/frappeNavigation.native.js +112 -0
- package/dist/jsx/frappeNavigation.native.js.map +1 -0
- package/dist/jsx/index.js +7 -3
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +7 -3
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +18 -1
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/schemaForm/index.mjs +4 -1
- package/dist/jsx/schemaForm/index.mjs.map +1 -1
- package/dist/jsx/schemaForm/index.native.js +4 -1
- package/dist/jsx/schemaForm/index.native.js.map +1 -1
- package/dist/jsx/useConnectionFilters.mjs +121 -0
- package/dist/jsx/useConnectionFilters.mjs.map +1 -0
- package/dist/jsx/useConnectionFilters.native.js +213 -0
- package/dist/jsx/useConnectionFilters.native.js.map +1 -0
- package/dist/jsx/useFrappePagination.mjs +38 -19
- package/dist/jsx/useFrappePagination.mjs.map +1 -1
- package/dist/jsx/useFrappePagination.native.js +59 -23
- package/dist/jsx/useFrappePagination.native.js.map +1 -1
- package/dist/jsx/useFrappeRows.mjs.map +1 -1
- package/dist/jsx/useFrappeRows.native.js.map +1 -1
- package/package.json +24 -20
- package/src/FileBrowser/AttachLibrary.stories.tsx +23 -0
- package/src/FrappeDashboard.tsx +11 -16
- package/src/FrappeForm.connections.spec.tsx +280 -0
- package/src/FrappeForm.connections.stories.tsx +93 -0
- package/src/FrappeForm.deskSemantics.spec.tsx +284 -0
- package/src/FrappeForm.tsx +560 -145
- package/src/FrappeFormConnections.tsx +148 -0
- package/src/FrappeGuestMeta.spec.tsx +143 -0
- package/src/FrappeImageView.tsx +8 -12
- package/src/FrappeList.tsx +71 -15
- package/src/FrappeListView.cards.spec.tsx +175 -0
- package/src/FrappeListView.cards.stories.tsx +131 -0
- package/src/FrappeListView.connections.spec.tsx +192 -0
- package/src/FrappeListView.connections.stories.tsx +99 -0
- package/src/FrappeListView.seed.spec.tsx +228 -0
- package/src/FrappeListView.tsx +177 -31
- package/src/FrappeProvider.tsx +13 -1
- package/src/FrappeReportBuilder.tsx +11 -19
- package/src/FrappeRowsReader.tsx +38 -0
- package/src/FrappeTable.optionalProps.spec.tsx +249 -0
- package/src/FrappeTable.spec.tsx +32 -42
- package/src/FrappeTable.stories.spec.tsx +55 -0
- package/src/FrappeTable.stories.tsx +28 -37
- package/src/FrappeTable.tsx +108 -45
- package/src/childTableDependsOn.spec.tsx +85 -0
- package/src/desk/DeskFormSidebar.spec.tsx +20 -0
- package/src/desk/DeskFormSidebar.stories.tsx +42 -0
- package/src/fieldRegistry.spec.tsx +27 -64
- package/src/fieldRegistry.ts +71 -14
- package/src/fields/Date/index.native.tsx +4 -2
- package/src/fields/Date/sheetKeyboard.spec.ts +14 -5
- package/src/fields/Date/sheetKeyboard.ts +12 -4
- package/src/fields/DateRange/DateRange.spec.tsx +67 -0
- package/src/fields/DateRange/index.tsx +5 -1
- package/src/fields/LinkTree.spec.tsx +8 -0
- package/src/fields/LinkTree.stories.tsx +28 -5
- package/src/fields/Select/Select.hydration.spec.tsx +177 -0
- package/src/formEngine/doctypeMeta.ts +15 -114
- package/src/formEngine/index.ts +2 -0
- package/src/formEngine/seam.spec.ts +23 -4
- package/src/formEngine/useSessionRoles.ts +73 -0
- package/src/frappeConnections.ts +50 -0
- package/src/frappeNavigation.tsx +112 -0
- package/src/frappeRoutes.spec.tsx +335 -0
- package/src/index.ts +28 -1
- package/src/schemaForm/index.tsx +1 -0
- package/src/useConnectionFilters.tsx +157 -0
- package/src/useFrappePagination.ts +70 -26
- package/src/useFrappeRows.sharedPath.spec.tsx +206 -0
- package/src/useFrappeRows.ts +5 -4
- package/types/FrappeDashboard.d.ts +3 -4
- package/types/FrappeDashboard.d.ts.map +1 -1
- package/types/FrappeForm.d.ts +57 -5
- package/types/FrappeForm.d.ts.map +1 -1
- package/types/FrappeFormConnections.d.ts +18 -0
- package/types/FrappeFormConnections.d.ts.map +1 -0
- package/types/FrappeImageView.d.ts +2 -3
- package/types/FrappeImageView.d.ts.map +1 -1
- package/types/FrappeList.d.ts +20 -2
- package/types/FrappeList.d.ts.map +1 -1
- package/types/FrappeListView.d.ts +53 -3
- package/types/FrappeListView.d.ts.map +1 -1
- package/types/FrappeProvider.d.ts +8 -1
- package/types/FrappeProvider.d.ts.map +1 -1
- package/types/FrappeReportBuilder.d.ts.map +1 -1
- package/types/FrappeRowsReader.d.ts +26 -0
- package/types/FrappeRowsReader.d.ts.map +1 -0
- package/types/FrappeTable.d.ts +39 -8
- package/types/FrappeTable.d.ts.map +1 -1
- package/types/fieldRegistry.d.ts +17 -3
- package/types/fieldRegistry.d.ts.map +1 -1
- package/types/fields/Date/index.native.d.ts.map +1 -1
- package/types/fields/Date/sheetKeyboard.d.ts +4 -3
- package/types/fields/Date/sheetKeyboard.d.ts.map +1 -1
- package/types/fields/DateRange/index.d.ts.map +1 -1
- package/types/formEngine/doctypeMeta.d.ts +10 -114
- package/types/formEngine/doctypeMeta.d.ts.map +1 -1
- package/types/formEngine/index.d.ts +1 -0
- package/types/formEngine/index.d.ts.map +1 -1
- package/types/formEngine/useSessionRoles.d.ts +19 -0
- package/types/formEngine/useSessionRoles.d.ts.map +1 -0
- package/types/frappeConnections.d.ts +33 -0
- package/types/frappeConnections.d.ts.map +1 -0
- package/types/frappeNavigation.d.ts +49 -0
- package/types/frappeNavigation.d.ts.map +1 -0
- package/types/index.d.ts +7 -3
- package/types/index.d.ts.map +1 -1
- package/types/schemaForm/index.d.ts.map +1 -1
- package/types/useConnectionFilters.d.ts +34 -0
- package/types/useConnectionFilters.d.ts.map +1 -0
- package/types/useFrappePagination.d.ts +18 -5
- package/types/useFrappePagination.d.ts.map +1 -1
- package/types/useFrappeRows.d.ts +5 -4
- package/types/useFrappeRows.d.ts.map +1 -1
- package/src/FileBrowser/AttachLibrary.spec.tsx +0 -74
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FrappeTable's two props that read as optional and were not (MPO-230).
|
|
3
|
+
*
|
|
4
|
+
* `filterableFields`: omitted under a provider carrying fixtures, the meta
|
|
5
|
+
* read stays inside the corpus. A fixture host that also carries a baseURL
|
|
6
|
+
* (what a generated app has) used to dial getdoctype on every page and fail
|
|
7
|
+
* CORS; now nothing reaches the network, DocType entry in the corpus or not.
|
|
8
|
+
*
|
|
9
|
+
* `fields`: omitted on a bench read (serverSide, or client mode without
|
|
10
|
+
* fixtures), the request used to ask for `name` alone and every other column
|
|
11
|
+
* rendered blank with no error. Now it asks for the columns' accessor keys,
|
|
12
|
+
* and the derived list is content-keyed so an inline `columns` literal does
|
|
13
|
+
* not refetch every render. Client mode over a corpus still reads whole
|
|
14
|
+
* documents.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { InMemoryFixtureProvider } from "@multiplatform.one/frappe";
|
|
18
|
+
import type { DataTableColumn } from "@multiplatform.one/table";
|
|
19
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
20
|
+
import { cleanup, screen, waitFor } from "@testing-library/react";
|
|
21
|
+
import i18next from "i18next";
|
|
22
|
+
import { initReactI18next } from "react-i18next";
|
|
23
|
+
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
|
24
|
+
import { FrappeProvider } from "./FrappeProvider";
|
|
25
|
+
import { FrappeTable } from "./FrappeTable";
|
|
26
|
+
|
|
27
|
+
beforeAll(async () => {
|
|
28
|
+
await i18next.use(initReactI18next).init({
|
|
29
|
+
lng: "en",
|
|
30
|
+
interpolation: { escapeValue: false },
|
|
31
|
+
resources: { en: { translation: {} } },
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
cleanup();
|
|
37
|
+
vi.restoreAllMocks();
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
interface Customer {
|
|
41
|
+
name: string;
|
|
42
|
+
doctype: string;
|
|
43
|
+
customer_name: string;
|
|
44
|
+
status: string;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const customers: Customer[] = [
|
|
48
|
+
{ name: "CUST-001", doctype: "Customer", customer_name: "Acme Corp", status: "Active" },
|
|
49
|
+
{ name: "CUST-002", doctype: "Customer", customer_name: "Globex", status: "Lead" },
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
const columns: DataTableColumn<Partial<Customer>>[] = [
|
|
53
|
+
{ id: "name", accessorKey: "name", header: "ID" },
|
|
54
|
+
{ id: "customer_name", accessorKey: "customer_name", header: "Customer Name" },
|
|
55
|
+
{ id: "status", accessorKey: "status", header: "Status" },
|
|
56
|
+
{ id: "actions", header: "Actions", cell: () => null },
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
function forbidFetch() {
|
|
60
|
+
return vi.spyOn(globalThis, "fetch").mockImplementation((input) => {
|
|
61
|
+
throw new Error(`unexpected network request: ${String(input)}`);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function pressRows(container: HTMLElement): HTMLElement[] {
|
|
66
|
+
return Array.from(container.querySelectorAll('[data-row-press="true"]')) as HTMLElement[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
describe("FrappeTable under a fixture corpus with a baseURL and no filterableFields", () => {
|
|
70
|
+
it("issues zero requests when the corpus has no DocType entry", async () => {
|
|
71
|
+
const fetchSpy = forbidFetch();
|
|
72
|
+
const { container } = renderWithProviders(
|
|
73
|
+
<FrappeProvider
|
|
74
|
+
baseURL="https://frappetable-optional.spec.test"
|
|
75
|
+
fixtures={new InMemoryFixtureProvider({ Customer: customers })}
|
|
76
|
+
>
|
|
77
|
+
<FrappeTable<Customer>
|
|
78
|
+
doctype="Customer"
|
|
79
|
+
columns={columns}
|
|
80
|
+
layout="table"
|
|
81
|
+
enablePagination={false}
|
|
82
|
+
onRowClick={() => {}}
|
|
83
|
+
/>
|
|
84
|
+
</FrappeProvider>,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
expect(await screen.findByText("Acme Corp")).toBeTruthy();
|
|
88
|
+
expect(await screen.findByText("Globex")).toBeTruthy();
|
|
89
|
+
// No meta: rows fall back to the document name for their label.
|
|
90
|
+
await waitFor(() => {
|
|
91
|
+
expect(pressRows(container).map((row) => row.getAttribute("aria-label"))).toEqual([
|
|
92
|
+
"CUST-001",
|
|
93
|
+
"CUST-002",
|
|
94
|
+
]);
|
|
95
|
+
});
|
|
96
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("issues zero requests when the corpus carries the DocType, and reads whole documents", async () => {
|
|
100
|
+
const fetchSpy = forbidFetch();
|
|
101
|
+
const { container } = renderWithProviders(
|
|
102
|
+
<FrappeProvider
|
|
103
|
+
baseURL="https://frappetable-optional.spec.test"
|
|
104
|
+
fixtures={
|
|
105
|
+
new InMemoryFixtureProvider({
|
|
106
|
+
DocType: [
|
|
107
|
+
{
|
|
108
|
+
name: "Customer",
|
|
109
|
+
doctype: "DocType",
|
|
110
|
+
module: "Selling",
|
|
111
|
+
title_field: "customer_name",
|
|
112
|
+
fields: [
|
|
113
|
+
{ fieldname: "customer_name", fieldtype: "Data", label: "Customer Name" },
|
|
114
|
+
{ fieldname: "status", fieldtype: "Data", label: "Status" },
|
|
115
|
+
],
|
|
116
|
+
permissions: [],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
Customer: customers,
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
>
|
|
123
|
+
<FrappeTable<Customer>
|
|
124
|
+
doctype="Customer"
|
|
125
|
+
columns={columns.filter((column) => column.id !== "customer_name")}
|
|
126
|
+
layout="table"
|
|
127
|
+
enablePagination={false}
|
|
128
|
+
onRowClick={() => {}}
|
|
129
|
+
/>
|
|
130
|
+
</FrappeProvider>,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
expect(await screen.findByText("Lead")).toBeTruthy();
|
|
134
|
+
// The title field is no column: its value labels the rows only because
|
|
135
|
+
// the corpus handed over whole documents.
|
|
136
|
+
await waitFor(() => {
|
|
137
|
+
expect(pressRows(container).map((row) => row.getAttribute("aria-label"))).toEqual([
|
|
138
|
+
"Acme Corp",
|
|
139
|
+
"Globex",
|
|
140
|
+
]);
|
|
141
|
+
});
|
|
142
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
describe("FrappeTable serverSide with columns and no fields", () => {
|
|
147
|
+
const host = "https://frappetable-serverfields.spec.test";
|
|
148
|
+
|
|
149
|
+
function jsonResponse(body: unknown): Response {
|
|
150
|
+
return new Response(JSON.stringify(body), {
|
|
151
|
+
status: 200,
|
|
152
|
+
headers: { "Content-Type": "application/json" },
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
it("requests name plus every column accessor key, once", async () => {
|
|
157
|
+
const listRequests: URL[] = [];
|
|
158
|
+
vi.spyOn(globalThis, "fetch").mockImplementation((input) => {
|
|
159
|
+
const urlStr =
|
|
160
|
+
typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
161
|
+
const url = new URL(urlStr);
|
|
162
|
+
if (url.pathname === "/api/method/frappe.client.get_count") {
|
|
163
|
+
return Promise.resolve(jsonResponse({ message: customers.length }));
|
|
164
|
+
}
|
|
165
|
+
if (url.pathname === "/api/resource/Customer") {
|
|
166
|
+
listRequests.push(url);
|
|
167
|
+
return Promise.resolve(jsonResponse({ data: customers }));
|
|
168
|
+
}
|
|
169
|
+
throw new Error(`unexpected network request: ${urlStr}`);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
renderWithProviders(
|
|
173
|
+
<FrappeProvider baseURL={host}>
|
|
174
|
+
<FrappeTable<Customer>
|
|
175
|
+
doctype="Customer"
|
|
176
|
+
columns={[...columns]}
|
|
177
|
+
filterableFields={[{ id: "status", label: "Status", type: "text" }]}
|
|
178
|
+
serverSide
|
|
179
|
+
layout="table"
|
|
180
|
+
initialState={{ pagination: { pageIndex: 0, pageSize: 10 } }}
|
|
181
|
+
/>
|
|
182
|
+
</FrappeProvider>,
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
expect(await screen.findByText("Acme Corp")).toBeTruthy();
|
|
186
|
+
expect(await screen.findByText("Lead")).toBeTruthy();
|
|
187
|
+
expect(listRequests.length).toBe(1);
|
|
188
|
+
expect(JSON.parse(listRequests[0].searchParams.get("fields") ?? "[]")).toEqual([
|
|
189
|
+
"name",
|
|
190
|
+
"customer_name",
|
|
191
|
+
"status",
|
|
192
|
+
]);
|
|
193
|
+
|
|
194
|
+
// The derived list is content-keyed: the post-load re-renders must not
|
|
195
|
+
// re-key the fetch and refetch.
|
|
196
|
+
await new Promise((resolve) => setTimeout(resolve, 300));
|
|
197
|
+
expect(listRequests.length).toBe(1);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe("FrappeTable client mode against a bench with columns and no fields", () => {
|
|
202
|
+
const host = "https://frappetable-clientfields.spec.test";
|
|
203
|
+
|
|
204
|
+
it("subscribes with name plus every column accessor key", async () => {
|
|
205
|
+
const listRequests: URL[] = [];
|
|
206
|
+
vi.spyOn(globalThis, "fetch").mockImplementation((input) => {
|
|
207
|
+
const urlStr =
|
|
208
|
+
typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
209
|
+
const url = new URL(urlStr);
|
|
210
|
+
if (url.pathname === "/api/resource/Customer") {
|
|
211
|
+
listRequests.push(url);
|
|
212
|
+
const fields: string[] = JSON.parse(url.searchParams.get("fields") ?? '["name"]');
|
|
213
|
+
const projected = customers.map((doc) =>
|
|
214
|
+
Object.fromEntries(
|
|
215
|
+
fields.map((field) => [field, (doc as unknown as Record<string, unknown>)[field]]),
|
|
216
|
+
),
|
|
217
|
+
);
|
|
218
|
+
return Promise.resolve(
|
|
219
|
+
new Response(JSON.stringify({ data: projected }), {
|
|
220
|
+
status: 200,
|
|
221
|
+
headers: { "Content-Type": "application/json" },
|
|
222
|
+
}),
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
throw new Error(`unexpected network request: ${urlStr}`);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
renderWithProviders(
|
|
229
|
+
<FrappeProvider baseURL={host} realtime={false}>
|
|
230
|
+
<FrappeTable<Customer>
|
|
231
|
+
doctype="Customer"
|
|
232
|
+
columns={columns}
|
|
233
|
+
filterableFields={[{ id: "status", label: "Status", type: "text" }]}
|
|
234
|
+
layout="table"
|
|
235
|
+
enablePagination={false}
|
|
236
|
+
/>
|
|
237
|
+
</FrappeProvider>,
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
// A bench answers a list read with no `fields` with `name` alone, so
|
|
241
|
+
// these cells render only because the request named the columns.
|
|
242
|
+
expect(await screen.findByText("Acme Corp")).toBeTruthy();
|
|
243
|
+
expect(await screen.findByText("Lead")).toBeTruthy();
|
|
244
|
+
expect(listRequests.length).toBeGreaterThan(0);
|
|
245
|
+
const requested: string[] = JSON.parse(listRequests[0].searchParams.get("fields") ?? "[]");
|
|
246
|
+
expect(requested).toEqual(expect.arrayContaining(["name", "customer_name", "status"]));
|
|
247
|
+
expect(requested).not.toContain("actions");
|
|
248
|
+
});
|
|
249
|
+
});
|
package/src/FrappeTable.spec.tsx
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* document name (DG-A11Y-06).
|
|
12
12
|
*
|
|
13
13
|
* Fixture-hermetic: documents ride InMemoryFixtureProvider; the one test
|
|
14
|
-
* that needs doctype meta
|
|
14
|
+
* that needs doctype meta carries it in the corpus's DocType entry.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { InMemoryFixtureProvider } from "@multiplatform.one/frappe";
|
|
@@ -56,9 +56,9 @@ const columns: DataTableColumn<Partial<Customer>>[] = [
|
|
|
56
56
|
{ id: "status", accessorKey: "status", header: "Status" },
|
|
57
57
|
];
|
|
58
58
|
|
|
59
|
-
// Explicit filterableFields skip the doctype-meta
|
|
60
|
-
//
|
|
61
|
-
//
|
|
59
|
+
// Explicit filterableFields skip the doctype-meta read (same contract
|
|
60
|
+
// DoctypeListScreen uses); the title-field test omits them and answers the
|
|
61
|
+
// read from the corpus instead.
|
|
62
62
|
const filterFields = [{ id: "status", label: "Status", type: "text" as const }];
|
|
63
63
|
|
|
64
64
|
function pressRows(container: HTMLElement): HTMLElement[] {
|
|
@@ -143,49 +143,38 @@ describe("FrappeTable onRowClick → DataTable onRowPress", () => {
|
|
|
143
143
|
});
|
|
144
144
|
|
|
145
145
|
it("labels rows by the doctype title-field value once meta loads", async () => {
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
const url =
|
|
151
|
-
typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
152
|
-
if (url.startsWith(metaHost)) {
|
|
153
|
-
if (url.includes("/api/method/frappe.desk.form.load.getdoctype")) {
|
|
154
|
-
return new Response(
|
|
155
|
-
JSON.stringify({
|
|
156
|
-
docs: [
|
|
157
|
-
{
|
|
158
|
-
name: "Customer",
|
|
159
|
-
module: "Selling",
|
|
160
|
-
title_field: "customer_name",
|
|
161
|
-
fields: [
|
|
162
|
-
{
|
|
163
|
-
fieldname: "customer_name",
|
|
164
|
-
fieldtype: "Data",
|
|
165
|
-
label: "Customer Name",
|
|
166
|
-
in_list_view: 1,
|
|
167
|
-
},
|
|
168
|
-
],
|
|
169
|
-
permissions: [],
|
|
170
|
-
},
|
|
171
|
-
],
|
|
172
|
-
}),
|
|
173
|
-
{ status: 200, headers: { "Content-Type": "application/json" } },
|
|
174
|
-
);
|
|
175
|
-
}
|
|
176
|
-
return new Response(JSON.stringify({ data: [] }), {
|
|
177
|
-
status: 200,
|
|
178
|
-
headers: { "Content-Type": "application/json" },
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
return realFetch(input, init);
|
|
146
|
+
// Meta comes from the corpus's DocType entry: a fixture host never dials
|
|
147
|
+
// getdoctype, whatever baseURL it carries (MPO-230).
|
|
148
|
+
const fetchSpy = vi.spyOn(globalThis, "fetch").mockImplementation((input) => {
|
|
149
|
+
throw new Error(`unexpected network request: ${String(input)}`);
|
|
182
150
|
});
|
|
183
151
|
|
|
184
152
|
const onRowClick = vi.fn();
|
|
185
153
|
const { container } = renderWithProviders(
|
|
186
154
|
<FrappeProvider
|
|
187
|
-
baseURL=
|
|
188
|
-
fixtures={
|
|
155
|
+
baseURL="https://frappetable-meta.spec.test"
|
|
156
|
+
fixtures={
|
|
157
|
+
new InMemoryFixtureProvider({
|
|
158
|
+
DocType: [
|
|
159
|
+
{
|
|
160
|
+
name: "Customer",
|
|
161
|
+
doctype: "DocType",
|
|
162
|
+
module: "Selling",
|
|
163
|
+
title_field: "customer_name",
|
|
164
|
+
fields: [
|
|
165
|
+
{
|
|
166
|
+
fieldname: "customer_name",
|
|
167
|
+
fieldtype: "Data",
|
|
168
|
+
label: "Customer Name",
|
|
169
|
+
in_list_view: 1,
|
|
170
|
+
},
|
|
171
|
+
],
|
|
172
|
+
permissions: [],
|
|
173
|
+
},
|
|
174
|
+
],
|
|
175
|
+
Customer: customers,
|
|
176
|
+
})
|
|
177
|
+
}
|
|
189
178
|
>
|
|
190
179
|
<FrappeTable<Customer>
|
|
191
180
|
doctype="Customer"
|
|
@@ -205,6 +194,7 @@ describe("FrappeTable onRowClick → DataTable onRowPress", () => {
|
|
|
205
194
|
"Initech",
|
|
206
195
|
]);
|
|
207
196
|
});
|
|
197
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
208
198
|
});
|
|
209
199
|
});
|
|
210
200
|
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FrappeTable's fixture stories carry a baseURL, and FrappeTable under a
|
|
3
|
+
* fixture corpus never dials it for meta (MPO-230), so their filter menu and
|
|
4
|
+
* title-field row labels exist only if the corpus carries the DocType entry.
|
|
5
|
+
*/
|
|
6
|
+
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
7
|
+
import { cleanup, waitFor } from "@testing-library/react";
|
|
8
|
+
import i18next from "i18next";
|
|
9
|
+
import { initReactI18next } from "react-i18next";
|
|
10
|
+
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
|
11
|
+
import { Default } from "./FrappeTable.stories";
|
|
12
|
+
|
|
13
|
+
vi.mock("@multiplatform.one/storybook", () => ({ action: () => vi.fn() }));
|
|
14
|
+
|
|
15
|
+
beforeAll(async () => {
|
|
16
|
+
await i18next.use(initReactI18next).init({
|
|
17
|
+
lng: "en",
|
|
18
|
+
interpolation: { escapeValue: false },
|
|
19
|
+
resources: { en: { translation: {} } },
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
cleanup();
|
|
25
|
+
vi.restoreAllMocks();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const customerNames = new Set([
|
|
29
|
+
"Acme Corp",
|
|
30
|
+
"Global Tech",
|
|
31
|
+
"John Smith",
|
|
32
|
+
"Jane Doe",
|
|
33
|
+
"Tech Solutions",
|
|
34
|
+
"Startup Inc",
|
|
35
|
+
"Bob Wilson",
|
|
36
|
+
"Enterprise Ltd",
|
|
37
|
+
]);
|
|
38
|
+
|
|
39
|
+
describe("FrappeTable stories", () => {
|
|
40
|
+
it("Main labels rows by the corpus meta's title field and issues no request", async () => {
|
|
41
|
+
const fetchSpy = vi.spyOn(globalThis, "fetch").mockImplementation((input) => {
|
|
42
|
+
throw new Error(`unexpected network request: ${String(input)}`);
|
|
43
|
+
});
|
|
44
|
+
const { container } = renderWithProviders(<Default />);
|
|
45
|
+
|
|
46
|
+
await waitFor(() => {
|
|
47
|
+
const labels = Array.from(container.querySelectorAll('[data-row-press="true"]')).map(
|
|
48
|
+
(row) => row.getAttribute("aria-label") ?? "",
|
|
49
|
+
);
|
|
50
|
+
expect(labels.length).toBeGreaterThan(0);
|
|
51
|
+
expect(labels.filter((label) => !customerNames.has(label))).toEqual([]);
|
|
52
|
+
});
|
|
53
|
+
expect(fetchSpy).not.toHaveBeenCalled();
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
docs: {
|
|
16
16
|
description: {
|
|
17
17
|
component:
|
|
18
|
-
"Table over useFrappeCollection / useLiveQuery (client) or Frappe REST (serverSide). Fixture stories are network-hermetic (G-15/D-05): documents
|
|
18
|
+
"Table over useFrappeCollection / useLiveQuery (client) or Frappe REST (serverSide). Fixture stories are network-hermetic (G-15/D-05): documents and DocType meta both come from InMemoryFixtureProvider, so nothing leaves the machine. The separately-named Live and ServerSide stories are the live-bench arm — they target STORYBOOK_FRAPPE_URL when reachable and fall back to fixtures otherwise.",
|
|
19
19
|
},
|
|
20
20
|
},
|
|
21
21
|
},
|
|
@@ -24,13 +24,11 @@ export default {
|
|
|
24
24
|
// ---------------------------------------------------------------------------
|
|
25
25
|
// Hermetic story host (G-15 story honesty / D-05, closes UX-P18).
|
|
26
26
|
//
|
|
27
|
-
// Fixture-backed stories
|
|
28
|
-
// fixture
|
|
29
|
-
// DocType
|
|
30
|
-
//
|
|
31
|
-
// the
|
|
32
|
-
// (real fetch, real meta shape) without leaving the machine; ERR_HOST is the
|
|
33
|
-
// deliberate failure host for the error-state story.
|
|
27
|
+
// Fixture-backed stories carry a baseURL the way a generated app does, and
|
|
28
|
+
// FrappeTable under a fixture corpus reads DocType meta from the corpus's
|
|
29
|
+
// "DocType" entry, never that host (MPO-230). MOCK_HOST still answers
|
|
30
|
+
// anything else locally so no stray request leaves the machine; ERR_HOST is
|
|
31
|
+
// the deliberate failure host for the error-state story.
|
|
34
32
|
// ---------------------------------------------------------------------------
|
|
35
33
|
|
|
36
34
|
const MOCK_HOST = "https://frappetable.mock.test";
|
|
@@ -39,6 +37,7 @@ const ERR_HOST = "https://forbidden.frappetable.mock.test";
|
|
|
39
37
|
function customerMetaRaw(name: string) {
|
|
40
38
|
return {
|
|
41
39
|
name,
|
|
40
|
+
doctype: "DocType",
|
|
42
41
|
module: "Selling",
|
|
43
42
|
title_field: "customer_name",
|
|
44
43
|
fields: [
|
|
@@ -85,9 +84,6 @@ function jsonResponse(body: unknown, status = 200): Response {
|
|
|
85
84
|
if (urlStr.startsWith(ERR_HOST)) return jsonResponse({ message: "Not permitted" }, 403);
|
|
86
85
|
if (urlStr.startsWith(MOCK_HOST)) {
|
|
87
86
|
const url = new URL(urlStr);
|
|
88
|
-
const metaMatch = url.pathname.match(/^\/api\/resource\/DocType\/(.+)$/);
|
|
89
|
-
if (metaMatch)
|
|
90
|
-
return jsonResponse({ data: customerMetaRaw(decodeURIComponent(metaMatch[1])) });
|
|
91
87
|
if (url.pathname === "/api/resource/DocType") {
|
|
92
88
|
return jsonResponse({ data: [{ name: "Customer", module: "Selling" }] });
|
|
93
89
|
}
|
|
@@ -183,6 +179,13 @@ const customerFixtures: Customer[] = [
|
|
|
183
179
|
},
|
|
184
180
|
];
|
|
185
181
|
|
|
182
|
+
function customerCorpus(customers: Customer[] = customerFixtures): InMemoryFixtureProvider {
|
|
183
|
+
return new InMemoryFixtureProvider({
|
|
184
|
+
DocType: [customerMetaRaw("Customer")],
|
|
185
|
+
Customer: customers,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
186
189
|
const customerColumns: DataTableColumn<Partial<Customer>>[] = [
|
|
187
190
|
{ id: "name", header: "ID", accessorKey: "name" },
|
|
188
191
|
{ id: "customer_name", header: "Customer Name", accessorKey: "customer_name" },
|
|
@@ -212,10 +215,7 @@ const customerColumns: DataTableColumn<Partial<Customer>>[] = [
|
|
|
212
215
|
];
|
|
213
216
|
|
|
214
217
|
export const Default = () => (
|
|
215
|
-
<FrappeProvider
|
|
216
|
-
baseURL={MOCK_HOST}
|
|
217
|
-
fixtures={new InMemoryFixtureProvider({ Customer: customerFixtures })}
|
|
218
|
-
>
|
|
218
|
+
<FrappeProvider baseURL={MOCK_HOST} fixtures={customerCorpus()}>
|
|
219
219
|
<FrappeTable<Customer>
|
|
220
220
|
doctype="Customer"
|
|
221
221
|
columns={customerColumns}
|
|
@@ -236,10 +236,7 @@ Default.parameters = {
|
|
|
236
236
|
|
|
237
237
|
Default.storyName = "Main";
|
|
238
238
|
export const WithPagination = () => (
|
|
239
|
-
<FrappeProvider
|
|
240
|
-
baseURL={MOCK_HOST}
|
|
241
|
-
fixtures={new InMemoryFixtureProvider({ Customer: customerFixtures })}
|
|
242
|
-
>
|
|
239
|
+
<FrappeProvider baseURL={MOCK_HOST} fixtures={customerCorpus()}>
|
|
243
240
|
<FrappeTable<Customer>
|
|
244
241
|
doctype="Customer"
|
|
245
242
|
columns={customerColumns}
|
|
@@ -258,10 +255,7 @@ WithPagination.parameters = {
|
|
|
258
255
|
};
|
|
259
256
|
|
|
260
257
|
export const WithSavedFilters = () => (
|
|
261
|
-
<FrappeProvider
|
|
262
|
-
baseURL={MOCK_HOST}
|
|
263
|
-
fixtures={new InMemoryFixtureProvider({ Customer: customerFixtures })}
|
|
264
|
-
>
|
|
258
|
+
<FrappeProvider baseURL={MOCK_HOST} fixtures={customerCorpus()}>
|
|
265
259
|
<FrappeTable<Customer>
|
|
266
260
|
doctype="Customer"
|
|
267
261
|
columns={customerColumns}
|
|
@@ -376,14 +370,17 @@ class PendingFixtureProvider extends InMemoryFixtureProvider {
|
|
|
376
370
|
|
|
377
371
|
/** Collection stuck syncing: the built-in loading panel renders (W9 / DG-ST-02). */
|
|
378
372
|
export const Loading = () => (
|
|
379
|
-
<FrappeProvider
|
|
373
|
+
<FrappeProvider
|
|
374
|
+
baseURL={MOCK_HOST}
|
|
375
|
+
fixtures={new PendingFixtureProvider({ DocType: [customerMetaRaw("Customer")] })}
|
|
376
|
+
>
|
|
380
377
|
<FrappeTable<Customer> doctype="Customer" columns={customerColumns} />
|
|
381
378
|
</FrappeProvider>
|
|
382
379
|
);
|
|
383
380
|
|
|
384
381
|
/** Zero documents, no filters, no failure — "No Customer records found" (empty ≠ error). */
|
|
385
382
|
export const Empty = () => (
|
|
386
|
-
<FrappeProvider baseURL={MOCK_HOST} fixtures={
|
|
383
|
+
<FrappeProvider baseURL={MOCK_HOST} fixtures={customerCorpus([])}>
|
|
387
384
|
<FrappeTable<Customer> doctype="Customer" columns={customerColumns} />
|
|
388
385
|
</FrappeProvider>
|
|
389
386
|
);
|
|
@@ -394,10 +391,7 @@ export const Empty = () => (
|
|
|
394
391
|
* from Empty per DG-TBL-06.
|
|
395
392
|
*/
|
|
396
393
|
export const NoResults = () => (
|
|
397
|
-
<FrappeProvider
|
|
398
|
-
baseURL={MOCK_HOST}
|
|
399
|
-
fixtures={new InMemoryFixtureProvider({ Customer: customerFixtures })}
|
|
400
|
-
>
|
|
394
|
+
<FrappeProvider baseURL={MOCK_HOST} fixtures={customerCorpus()}>
|
|
401
395
|
<FrappeTable<Customer>
|
|
402
396
|
doctype="Customer"
|
|
403
397
|
columns={customerColumns}
|
|
@@ -440,10 +434,10 @@ const minimalCustomerColumns: DataTableColumn<Partial<Customer>>[] = [
|
|
|
440
434
|
];
|
|
441
435
|
|
|
442
436
|
/**
|
|
443
|
-
*
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
* same
|
|
437
|
+
* Omitted, FrappeTable derives this list from the doctype meta
|
|
438
|
+
* (docFieldsToFilterFields), here the corpus's DocType entry. The story
|
|
439
|
+
* passes the equivalent list explicitly to show the prop — same contract,
|
|
440
|
+
* same UI.
|
|
447
441
|
*/
|
|
448
442
|
const customerFilterFields = [
|
|
449
443
|
{ id: "territory", label: "Territory", type: "text" as const },
|
|
@@ -478,10 +472,7 @@ const customerFilterFields = [
|
|
|
478
472
|
* field/operator/value dropdown.
|
|
479
473
|
*/
|
|
480
474
|
export const HiddenFieldFilters = () => (
|
|
481
|
-
<FrappeProvider
|
|
482
|
-
baseURL={MOCK_HOST}
|
|
483
|
-
fixtures={new InMemoryFixtureProvider({ Customer: customerFixtures })}
|
|
484
|
-
>
|
|
475
|
+
<FrappeProvider baseURL={MOCK_HOST} fixtures={customerCorpus()}>
|
|
485
476
|
<FrappeTable<Customer>
|
|
486
477
|
doctype="Customer"
|
|
487
478
|
columns={minimalCustomerColumns}
|