@multiplatform.one/backoffice 7.28.1 → 7.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cjs/desk/DeskSurface.native.js.map +1 -1
- package/dist/cjs/form/DocFormScreen.cjs +167 -224
- package/dist/cjs/form/DocFormScreen.native.js +182 -259
- package/dist/cjs/form/DocFormScreen.native.js.map +1 -1
- package/dist/cjs/i18n/en.cjs +1 -0
- package/dist/cjs/i18n/en.native.js +1 -0
- package/dist/cjs/i18n/en.native.js.map +1 -1
- package/dist/cjs/list/ListBulkActionsBar.cjs +30 -18
- package/dist/cjs/list/ListBulkActionsBar.native.js +43 -31
- package/dist/cjs/list/ListBulkActionsBar.native.js.map +1 -1
- package/dist/cjs/list/sidebar-section.cjs +15 -7
- package/dist/cjs/list/sidebar-section.native.js +16 -7
- package/dist/cjs/list/sidebar-section.native.js.map +1 -1
- package/dist/cjs/report/DoctypeReportView.cjs +20 -374
- package/dist/cjs/report/DoctypeReportView.native.js +23 -455
- package/dist/cjs/report/DoctypeReportView.native.js.map +1 -1
- package/dist/cjs/report/QueryReportScreen.cjs +33 -23
- package/dist/cjs/report/QueryReportScreen.native.js +33 -23
- package/dist/cjs/report/QueryReportScreen.native.js.map +1 -1
- package/dist/cjs/report/queryReportColumns.cjs +3 -105
- package/dist/cjs/report/queryReportColumns.native.js +2 -129
- package/dist/cjs/report/queryReportColumns.native.js.map +1 -1
- package/dist/cjs/report/queryReportFilterBar.cjs +3 -4
- package/dist/cjs/report/queryReportFilterBar.native.js +3 -4
- package/dist/cjs/report/queryReportFilterBar.native.js.map +1 -1
- package/dist/cjs/report/queryReportUrlState.cjs +2 -2
- package/dist/cjs/report/queryReportUrlState.native.js +2 -2
- package/dist/cjs/report/queryReportUrlState.native.js.map +1 -1
- package/dist/cjs/report/report-grid.cjs +2 -426
- package/dist/cjs/report/report-grid.native.js +1 -479
- package/dist/cjs/report/report-grid.native.js.map +1 -1
- package/dist/cjs/report/report-toolbar.cjs +2 -228
- package/dist/cjs/report/report-toolbar.native.js +1 -274
- package/dist/cjs/report/report-toolbar.native.js.map +1 -1
- package/dist/cjs/report/reportShapes.cjs +12 -383
- package/dist/cjs/report/reportShapes.native.js +12 -501
- package/dist/cjs/report/reportShapes.native.js.map +1 -1
- package/dist/cjs/report/reportViewModel.cjs +20 -360
- package/dist/cjs/report/reportViewModel.native.js +19 -627
- package/dist/cjs/report/reportViewModel.native.js.map +1 -1
- package/dist/cjs/report/savedReports.cjs +2 -106
- package/dist/cjs/report/savedReports.native.js +1 -132
- package/dist/cjs/report/savedReports.native.js.map +1 -1
- package/dist/cjs/report/useQueryReport.cjs +11 -219
- package/dist/cjs/report/useQueryReport.native.js +11 -244
- package/dist/cjs/report/useQueryReport.native.js.map +1 -1
- package/dist/cjs/shared/measures.cjs +3 -5
- package/dist/cjs/shared/measures.native.js +3 -5
- package/dist/cjs/shared/measures.native.js.map +1 -1
- package/dist/cjs/views/ReportView.cjs +3 -256
- package/dist/cjs/views/ReportView.native.js +3 -382
- package/dist/cjs/views/ReportView.native.js.map +1 -1
- package/dist/cjs/views/report-controls.cjs +6 -6
- package/dist/cjs/views/report-controls.native.js +6 -6
- package/dist/cjs/views/report-controls.native.js.map +1 -1
- package/dist/esm/desk/DeskSurface.mjs.map +1 -1
- package/dist/esm/desk/DeskSurface.native.js.map +1 -1
- package/dist/esm/form/DocFormScreen.mjs +169 -226
- package/dist/esm/form/DocFormScreen.mjs.map +1 -1
- package/dist/esm/form/DocFormScreen.native.js +184 -261
- package/dist/esm/form/DocFormScreen.native.js.map +1 -1
- package/dist/esm/i18n/en.mjs +1 -0
- package/dist/esm/i18n/en.mjs.map +1 -1
- package/dist/esm/i18n/en.native.js +1 -0
- package/dist/esm/i18n/en.native.js.map +1 -1
- package/dist/esm/list/ListBulkActionsBar.mjs +31 -19
- package/dist/esm/list/ListBulkActionsBar.mjs.map +1 -1
- package/dist/esm/list/ListBulkActionsBar.native.js +37 -25
- package/dist/esm/list/ListBulkActionsBar.native.js.map +1 -1
- package/dist/esm/list/sidebar-section.mjs +16 -8
- package/dist/esm/list/sidebar-section.mjs.map +1 -1
- package/dist/esm/list/sidebar-section.native.js +17 -8
- package/dist/esm/list/sidebar-section.native.js.map +1 -1
- package/dist/esm/report/DoctypeReportView.mjs +21 -375
- package/dist/esm/report/DoctypeReportView.mjs.map +1 -1
- package/dist/esm/report/DoctypeReportView.native.js +24 -456
- package/dist/esm/report/DoctypeReportView.native.js.map +1 -1
- package/dist/esm/report/QueryReportScreen.mjs +26 -16
- package/dist/esm/report/QueryReportScreen.mjs.map +1 -1
- package/dist/esm/report/QueryReportScreen.native.js +26 -16
- package/dist/esm/report/QueryReportScreen.native.js.map +1 -1
- package/dist/esm/report/queryReportColumns.mjs +1 -103
- package/dist/esm/report/queryReportColumns.mjs.map +1 -1
- package/dist/esm/report/queryReportColumns.native.js +1 -117
- package/dist/esm/report/queryReportColumns.native.js.map +1 -1
- package/dist/esm/report/queryReportFilterBar.mjs +1 -2
- package/dist/esm/report/queryReportFilterBar.mjs.map +1 -1
- package/dist/esm/report/queryReportFilterBar.native.js +1 -2
- package/dist/esm/report/queryReportFilterBar.native.js.map +1 -1
- package/dist/esm/report/queryReportUrlState.mjs +1 -1
- package/dist/esm/report/queryReportUrlState.native.js +1 -1
- package/dist/esm/report/report-grid.mjs +1 -425
- package/dist/esm/report/report-grid.mjs.map +1 -1
- package/dist/esm/report/report-grid.native.js +1 -468
- package/dist/esm/report/report-grid.native.js.map +1 -1
- package/dist/esm/report/report-toolbar.mjs +2 -228
- package/dist/esm/report/report-toolbar.mjs.map +1 -1
- package/dist/esm/report/report-toolbar.native.js +2 -264
- package/dist/esm/report/report-toolbar.native.js.map +1 -1
- package/dist/esm/report/reportShapes.mjs +2 -373
- package/dist/esm/report/reportShapes.mjs.map +1 -1
- package/dist/esm/report/reportShapes.native.js +2 -491
- package/dist/esm/report/reportShapes.native.js.map +1 -1
- package/dist/esm/report/reportViewModel.mjs +2 -342
- package/dist/esm/report/reportViewModel.mjs.map +1 -1
- package/dist/esm/report/reportViewModel.native.js +2 -610
- package/dist/esm/report/reportViewModel.native.js.map +1 -1
- package/dist/esm/report/savedReports.mjs +1 -105
- package/dist/esm/report/savedReports.mjs.map +1 -1
- package/dist/esm/report/savedReports.native.js +1 -132
- package/dist/esm/report/savedReports.native.js.map +1 -1
- package/dist/esm/report/useQueryReport.mjs +2 -210
- package/dist/esm/report/useQueryReport.mjs.map +1 -1
- package/dist/esm/report/useQueryReport.native.js +2 -235
- package/dist/esm/report/useQueryReport.native.js.map +1 -1
- package/dist/esm/shared/measures.mjs +1 -3
- package/dist/esm/shared/measures.mjs.map +1 -1
- package/dist/esm/shared/measures.native.js +1 -3
- package/dist/esm/shared/measures.native.js.map +1 -1
- package/dist/esm/views/ReportView.mjs +3 -256
- package/dist/esm/views/ReportView.mjs.map +1 -1
- package/dist/esm/views/ReportView.native.js +3 -382
- package/dist/esm/views/ReportView.native.js.map +1 -1
- package/dist/esm/views/report-controls.mjs +3 -3
- package/dist/esm/views/report-controls.mjs.map +1 -1
- package/dist/esm/views/report-controls.native.js +3 -3
- package/dist/esm/views/report-controls.native.js.map +1 -1
- package/dist/jsx/desk/DeskSurface.mjs.map +1 -1
- package/dist/jsx/desk/DeskSurface.native.js.map +1 -1
- package/dist/jsx/form/DocFormScreen.mjs +169 -226
- package/dist/jsx/form/DocFormScreen.mjs.map +1 -1
- package/dist/jsx/form/DocFormScreen.native.js +182 -259
- package/dist/jsx/form/DocFormScreen.native.js.map +1 -1
- package/dist/jsx/i18n/en.mjs +1 -0
- package/dist/jsx/i18n/en.mjs.map +1 -1
- package/dist/jsx/i18n/en.native.js +1 -0
- package/dist/jsx/i18n/en.native.js.map +1 -1
- package/dist/jsx/list/ListBulkActionsBar.mjs +31 -19
- package/dist/jsx/list/ListBulkActionsBar.mjs.map +1 -1
- package/dist/jsx/list/ListBulkActionsBar.native.js +43 -31
- package/dist/jsx/list/ListBulkActionsBar.native.js.map +1 -1
- package/dist/jsx/list/sidebar-section.mjs +16 -8
- package/dist/jsx/list/sidebar-section.mjs.map +1 -1
- package/dist/jsx/list/sidebar-section.native.js +16 -7
- package/dist/jsx/list/sidebar-section.native.js.map +1 -1
- package/dist/jsx/report/DoctypeReportView.mjs +21 -375
- package/dist/jsx/report/DoctypeReportView.mjs.map +1 -1
- package/dist/jsx/report/DoctypeReportView.native.js +23 -455
- package/dist/jsx/report/DoctypeReportView.native.js.map +1 -1
- package/dist/jsx/report/QueryReportScreen.mjs +26 -16
- package/dist/jsx/report/QueryReportScreen.mjs.map +1 -1
- package/dist/jsx/report/QueryReportScreen.native.js +33 -23
- package/dist/jsx/report/QueryReportScreen.native.js.map +1 -1
- package/dist/jsx/report/queryReportColumns.mjs +1 -103
- package/dist/jsx/report/queryReportColumns.mjs.map +1 -1
- package/dist/jsx/report/queryReportColumns.native.js +2 -129
- package/dist/jsx/report/queryReportColumns.native.js.map +1 -1
- package/dist/jsx/report/queryReportFilterBar.mjs +1 -2
- package/dist/jsx/report/queryReportFilterBar.mjs.map +1 -1
- package/dist/jsx/report/queryReportFilterBar.native.js +3 -4
- package/dist/jsx/report/queryReportFilterBar.native.js.map +1 -1
- package/dist/jsx/report/queryReportUrlState.mjs +1 -1
- package/dist/jsx/report/queryReportUrlState.native.js +2 -2
- package/dist/jsx/report/queryReportUrlState.native.js.map +1 -1
- package/dist/jsx/report/report-grid.mjs +1 -425
- package/dist/jsx/report/report-grid.mjs.map +1 -1
- package/dist/jsx/report/report-grid.native.js +1 -479
- package/dist/jsx/report/report-grid.native.js.map +1 -1
- package/dist/jsx/report/report-toolbar.mjs +2 -228
- package/dist/jsx/report/report-toolbar.mjs.map +1 -1
- package/dist/jsx/report/report-toolbar.native.js +1 -274
- package/dist/jsx/report/report-toolbar.native.js.map +1 -1
- package/dist/jsx/report/reportShapes.mjs +2 -373
- package/dist/jsx/report/reportShapes.mjs.map +1 -1
- package/dist/jsx/report/reportShapes.native.js +12 -501
- package/dist/jsx/report/reportShapes.native.js.map +1 -1
- package/dist/jsx/report/reportViewModel.mjs +2 -342
- package/dist/jsx/report/reportViewModel.mjs.map +1 -1
- package/dist/jsx/report/reportViewModel.native.js +19 -627
- package/dist/jsx/report/reportViewModel.native.js.map +1 -1
- package/dist/jsx/report/savedReports.mjs +1 -105
- package/dist/jsx/report/savedReports.mjs.map +1 -1
- package/dist/jsx/report/savedReports.native.js +1 -132
- package/dist/jsx/report/savedReports.native.js.map +1 -1
- package/dist/jsx/report/useQueryReport.mjs +2 -210
- package/dist/jsx/report/useQueryReport.mjs.map +1 -1
- package/dist/jsx/report/useQueryReport.native.js +11 -244
- package/dist/jsx/report/useQueryReport.native.js.map +1 -1
- package/dist/jsx/shared/measures.mjs +1 -3
- package/dist/jsx/shared/measures.mjs.map +1 -1
- package/dist/jsx/shared/measures.native.js +3 -5
- package/dist/jsx/shared/measures.native.js.map +1 -1
- package/dist/jsx/views/ReportView.mjs +3 -256
- package/dist/jsx/views/ReportView.mjs.map +1 -1
- package/dist/jsx/views/ReportView.native.js +3 -382
- package/dist/jsx/views/ReportView.native.js.map +1 -1
- package/dist/jsx/views/report-controls.mjs +3 -3
- package/dist/jsx/views/report-controls.mjs.map +1 -1
- package/dist/jsx/views/report-controls.native.js +6 -6
- package/dist/jsx/views/report-controls.native.js.map +1 -1
- package/package.json +12 -12
- package/src/backofficeScreens.designLaw.spec.ts +0 -5
- package/src/desk/DeskSurface.tsx +4 -7
- package/src/form/DocFormScreen.chrome.spec.ts +77 -0
- package/src/form/DocFormScreen.guest.screen.spec.tsx +175 -0
- package/src/form/DocFormScreen.rights.spec.tsx +7 -3
- package/src/form/DocFormScreen.tsx +214 -315
- package/src/i18n/en.ts +1 -0
- package/src/list/ListBulkActionsBar.rights.spec.tsx +134 -0
- package/src/list/ListBulkActionsBar.screen.spec.tsx +7 -1
- package/src/list/ListBulkActionsBar.tsx +76 -57
- package/src/list/ListFilterBar.screen.spec.tsx +14 -13
- package/src/list/sidebar-section.tsx +11 -3
- package/src/report/DoctypeReportView.tsx +28 -550
- package/src/report/QueryReportScreen.spec.tsx +75 -1
- package/src/report/QueryReportScreen.tsx +38 -22
- package/src/report/queryReportColumns.tsx +4 -123
- package/src/report/queryReportFilterBar.tsx +3 -5
- package/src/report/queryReportUrlState.ts +1 -1
- package/src/report/report-grid.tsx +4 -529
- package/src/report/report-toolbar.tsx +4 -308
- package/src/report/reportShapes.ts +25 -613
- package/src/report/reportShim.spec.ts +162 -0
- package/src/report/reportViewModel.ts +32 -605
- package/src/report/savedReports.ts +4 -161
- package/src/report/useQueryReport.ts +9 -347
- package/src/shared/measures.ts +3 -11
- package/src/views/ReportView.screen.spec.tsx +25 -20
- package/src/views/ReportView.tsx +7 -439
- package/src/views/report-controls.tsx +12 -20
- package/types/desk/DeskSurface.d.ts.map +1 -1
- package/types/form/DocFormScreen.d.ts +2 -2
- package/types/form/DocFormScreen.d.ts.map +1 -1
- package/types/i18n/en.d.ts +1 -0
- package/types/i18n/en.d.ts.map +1 -1
- package/types/list/ListBulkActionsBar.d.ts.map +1 -1
- package/types/list/sidebar-section.d.ts.map +1 -1
- package/types/report/DoctypeReportView.d.ts.map +1 -1
- package/types/report/QueryReportScreen.d.ts +1 -1
- package/types/report/QueryReportScreen.d.ts.map +1 -1
- package/types/report/queryReportColumns.d.ts +2 -11
- package/types/report/queryReportColumns.d.ts.map +1 -1
- package/types/report/queryReportFilterBar.d.ts +1 -1
- package/types/report/queryReportFilterBar.d.ts.map +1 -1
- package/types/report/queryReportUrlState.d.ts +1 -1
- package/types/report/queryReportUrlState.d.ts.map +1 -1
- package/types/report/report-grid.d.ts +2 -19
- package/types/report/report-grid.d.ts.map +1 -1
- package/types/report/report-toolbar.d.ts +2 -29
- package/types/report/report-toolbar.d.ts.map +1 -1
- package/types/report/reportShapes.d.ts +2 -115
- package/types/report/reportShapes.d.ts.map +1 -1
- package/types/report/reportViewModel.d.ts +2 -135
- package/types/report/reportViewModel.d.ts.map +1 -1
- package/types/report/savedReports.d.ts +2 -18
- package/types/report/savedReports.d.ts.map +1 -1
- package/types/report/useQueryReport.d.ts +2 -35
- package/types/report/useQueryReport.d.ts.map +1 -1
- package/types/shared/measures.d.ts +1 -2
- package/types/shared/measures.d.ts.map +1 -1
- package/types/views/ReportView.d.ts +3 -22
- package/types/views/ReportView.d.ts.map +1 -1
- package/types/views/report-controls.d.ts +2 -5
- package/types/views/report-controls.d.ts.map +1 -1
- package/src/report/report-grid.spec.tsx +0 -175
- package/src/report/report-toolbar.spec.tsx +0 -90
- package/src/report/reportShapes.spec.ts +0 -391
- package/src/report/reportViewModel.spec.ts +0 -393
package/src/views/ReportView.tsx
CHANGED
|
@@ -1,439 +1,7 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// so selection is driven through `initialColumns`/`initialGroupBy`
|
|
9
|
-
// plus a remount key.
|
|
10
|
-
// - `?f=` URL param (urlencoded JSON FrappeFilters) → base filters
|
|
11
|
-
// (chips + clear); FrappeReportBuilder accepts filter tuples directly.
|
|
12
|
-
// - page-size selector (20/100/500) + pagination: a parallel name-window
|
|
13
|
-
// query (name + sort + numeric fields) orders the full filtered result
|
|
14
|
-
// client-side, and the current page is handed to the grid as a
|
|
15
|
-
// `["name","in",names]` filter — the builder reacts to filter-prop
|
|
16
|
-
// changes without remounting. Small results (≤ page size) skip the
|
|
17
|
-
// window entirely and keep the pure live path.
|
|
18
|
-
// - totals strip over the full filtered result (ReportBuilder has no
|
|
19
|
-
// totals row) and an "Open" record jump in the footer.
|
|
20
|
-
// - grid rows click through to the form via onRowPress (threaded
|
|
21
|
-
// through FrappeReportBuilder → ReportBuilder).
|
|
22
|
-
// - CSV export via onExport: current page rows / enabled columns,
|
|
23
|
-
// web-guarded (Blob + anchor download); native shows an honest toast.
|
|
24
|
-
// Known gaps vs desk (component limitations, documented for integrator):
|
|
25
|
-
// - the component's own Save/Load applies loaded configs to its internal
|
|
26
|
-
// state only — this screen's pickers stay the source of truth
|
|
27
|
-
// - CSV exports the loaded page, not a server-side full export
|
|
28
|
-
import { isWeb, notify, YStack } from "@multiplatform.one/components";
|
|
29
|
-
import {
|
|
30
|
-
Order,
|
|
31
|
-
useFrappeCollection,
|
|
32
|
-
useLiveQuery,
|
|
33
|
-
type UseFrappeCollectionConfig,
|
|
34
|
-
} from "@multiplatform.one/frappe";
|
|
35
|
-
import {
|
|
36
|
-
FrappeReportBuilder,
|
|
37
|
-
type GroupByConfig,
|
|
38
|
-
type ReportColumn,
|
|
39
|
-
} from "@multiplatform.one/frappe-ui";
|
|
40
|
-
import { downloadBlob } from "@multiplatform.one/platform";
|
|
41
|
-
import { useResolvedKnobs } from "@multiplatform.one/theme";
|
|
42
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
43
|
-
import { useTranslation } from "react-i18next";
|
|
44
|
-
import { useBackofficeNavigator, useBackofficePaths } from "../config/BackofficeProvider";
|
|
45
|
-
import { useDeskScope } from "../desk/scope";
|
|
46
|
-
import { BACKOFFICE_I18N_NAMESPACE } from "../i18n";
|
|
47
|
-
import type { FrappeFilters } from "../shared/types";
|
|
48
|
-
import { useViewConnection } from "./connection";
|
|
49
|
-
import {
|
|
50
|
-
REPORT_NUMERIC_FIELDTYPES,
|
|
51
|
-
ReportFooter,
|
|
52
|
-
ReportToolbar,
|
|
53
|
-
type ReportRecordRef,
|
|
54
|
-
type ReportTotal,
|
|
55
|
-
} from "./report-controls";
|
|
56
|
-
import { useViewMeta } from "./viewMeta";
|
|
57
|
-
import { ViewError, ViewLoading } from "./ViewStates";
|
|
58
|
-
|
|
59
|
-
export interface ReportViewProps {
|
|
60
|
-
/** Proper-cased doctype name (e.g. "ToDo", "Sales Order") */
|
|
61
|
-
doctype: string;
|
|
62
|
-
/**
|
|
63
|
-
* Raw `?f=` search-param value (urlencoded JSON FrappeFilters), read by
|
|
64
|
-
* the route wrapper (DoctypeViewScreen) — the screen itself stays
|
|
65
|
-
* search-param free so it mounts outside a One navigation container
|
|
66
|
-
* (stories/tests).
|
|
67
|
-
*/
|
|
68
|
-
filtersParam?: string;
|
|
69
|
-
/** Base filters when no `?f=` URL param is present (stories/tests). */
|
|
70
|
-
initialFilters?: FrappeFilters;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const LAYOUT_FIELDTYPES = new Set(["Section Break", "Column Break", "Tab Break"]);
|
|
74
|
-
const EMPTY_FILTERS: FrappeFilters = [];
|
|
75
|
-
const DEFAULT_PAGE_SIZE = 20;
|
|
76
|
-
|
|
77
|
-
type StatsRow = { name: string; doctype: string } & Record<string, unknown>;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Parse the `?f=` search param: urlencoded JSON FrappeFilters
|
|
81
|
-
* (e.g. `?f=%5B%5B%22status%22%2C%22%3D%22%2C%22Open%22%5D%5D`).
|
|
82
|
-
* The router usually decodes the param already, so the raw value is tried
|
|
83
|
-
* first. Malformed input degrades to "no filters" (honest default).
|
|
84
|
-
*/
|
|
85
|
-
export function parseReportFiltersParam(raw: unknown): FrappeFilters | undefined {
|
|
86
|
-
if (typeof raw !== "string" || !raw) return undefined;
|
|
87
|
-
const candidates = [raw];
|
|
88
|
-
try {
|
|
89
|
-
const decoded = decodeURIComponent(raw);
|
|
90
|
-
if (decoded !== raw) candidates.push(decoded);
|
|
91
|
-
} catch {
|
|
92
|
-
// raw is not percent-encoded — the direct candidate covers it
|
|
93
|
-
}
|
|
94
|
-
for (const candidate of candidates) {
|
|
95
|
-
try {
|
|
96
|
-
const parsed: unknown = JSON.parse(candidate);
|
|
97
|
-
if (!Array.isArray(parsed)) continue;
|
|
98
|
-
const filters: FrappeFilters = [];
|
|
99
|
-
for (const tuple of parsed) {
|
|
100
|
-
if (
|
|
101
|
-
Array.isArray(tuple) &&
|
|
102
|
-
tuple.length === 3 &&
|
|
103
|
-
typeof tuple[0] === "string" &&
|
|
104
|
-
typeof tuple[1] === "string"
|
|
105
|
-
) {
|
|
106
|
-
filters.push([tuple[0], tuple[1], tuple[2]]);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (filters.length > 0) return filters;
|
|
110
|
-
} catch {
|
|
111
|
-
// not JSON — try the next candidate
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return undefined;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function isNullish(value: unknown): value is null | undefined {
|
|
118
|
-
return value === null || value === undefined;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function compareValues(a: unknown, b: unknown): number {
|
|
122
|
-
if (isNullish(a) && isNullish(b)) return 0;
|
|
123
|
-
if (isNullish(a)) return 1;
|
|
124
|
-
if (isNullish(b)) return -1;
|
|
125
|
-
if (typeof a === "number" && typeof b === "number") return a - b;
|
|
126
|
-
const left = String(a);
|
|
127
|
-
const right = String(b);
|
|
128
|
-
return left < right ? -1 : left > right ? 1 : 0;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function ReportView({ doctype, filtersParam, initialFilters }: ReportViewProps) {
|
|
132
|
-
const { t } = useTranslation(BACKOFFICE_I18N_NAMESPACE);
|
|
133
|
-
const navigator = useBackofficeNavigator();
|
|
134
|
-
const paths = useBackofficePaths();
|
|
135
|
-
const { knobProps } = useResolvedKnobs();
|
|
136
|
-
const deskScope = useDeskScope();
|
|
137
|
-
const connection = useViewConnection();
|
|
138
|
-
const { meta, isLoading: isMetaLoading, error: metaError } = useViewMeta(doctype);
|
|
139
|
-
|
|
140
|
-
// ---------------------------------------------------------------------
|
|
141
|
-
// Base filters: ?f= URL param wins, then the initialFilters prop.
|
|
142
|
-
// ---------------------------------------------------------------------
|
|
143
|
-
const urlFilters = useMemo(() => parseReportFiltersParam(filtersParam), [filtersParam]);
|
|
144
|
-
const [filtersCleared, setFiltersCleared] = useState(false);
|
|
145
|
-
useEffect(() => setFiltersCleared(false), [filtersParam, doctype]);
|
|
146
|
-
const baseFilters = filtersCleared
|
|
147
|
-
? EMPTY_FILTERS
|
|
148
|
-
: (urlFilters ?? initialFilters ?? EMPTY_FILTERS);
|
|
149
|
-
// Desk scope (GL-5) ANDs into both queries, invisible to the filter chips
|
|
150
|
-
// and not clearable by the user.
|
|
151
|
-
const queryFilters = useMemo(() => [...deskScope, ...baseFilters], [deskScope, baseFilters]);
|
|
152
|
-
const handleClearFilters = useCallback(() => {
|
|
153
|
-
setFiltersCleared(true);
|
|
154
|
-
// Drop the ?f= param from the URL so the cleared state survives reloads.
|
|
155
|
-
if (urlFilters) navigator.replace(paths.view(doctype, "report"));
|
|
156
|
-
}, [urlFilters, navigator, paths, doctype]);
|
|
157
|
-
|
|
158
|
-
// ---------------------------------------------------------------------
|
|
159
|
-
// Columns: all non-layout meta fields, plus a synthetic ID column.
|
|
160
|
-
// Initial selection = in_list_view fields (+ name), desk parity.
|
|
161
|
-
// ---------------------------------------------------------------------
|
|
162
|
-
const allColumns = useMemo<ReportColumn[]>(() => {
|
|
163
|
-
if (!meta) return [];
|
|
164
|
-
const idColumn: ReportColumn = {
|
|
165
|
-
fieldname: "name",
|
|
166
|
-
label: t("report.idColumn", "ID"),
|
|
167
|
-
fieldtype: "Data",
|
|
168
|
-
enabled: true,
|
|
169
|
-
};
|
|
170
|
-
return [
|
|
171
|
-
idColumn,
|
|
172
|
-
...meta.fields
|
|
173
|
-
.filter((field) => field.fieldname && !LAYOUT_FIELDTYPES.has(field.fieldtype))
|
|
174
|
-
.map((field) => ({
|
|
175
|
-
fieldname: field.fieldname,
|
|
176
|
-
label: field.label || field.fieldname,
|
|
177
|
-
fieldtype: field.fieldtype as string,
|
|
178
|
-
enabled: Boolean(field.in_list_view),
|
|
179
|
-
})),
|
|
180
|
-
];
|
|
181
|
-
}, [meta, t]);
|
|
182
|
-
|
|
183
|
-
const defaultSelected = useMemo(
|
|
184
|
-
() => allColumns.filter((column) => column.enabled).map((column) => column.fieldname),
|
|
185
|
-
[allColumns],
|
|
186
|
-
);
|
|
187
|
-
const [selectedOverride, setSelectedOverride] = useState<string[] | null>(null);
|
|
188
|
-
const selected = selectedOverride ?? defaultSelected;
|
|
189
|
-
|
|
190
|
-
const handleToggleColumn = useCallback(
|
|
191
|
-
(fieldname: string) => {
|
|
192
|
-
setSelectedOverride((previous) => {
|
|
193
|
-
const current = previous ?? defaultSelected;
|
|
194
|
-
if (current.includes(fieldname)) {
|
|
195
|
-
// Keep at least one column visible (the toolbar disables the last
|
|
196
|
-
// enabled row too — this guard covers races).
|
|
197
|
-
if (current.length === 1) return current;
|
|
198
|
-
return current.filter((entry) => entry !== fieldname);
|
|
199
|
-
}
|
|
200
|
-
return [...current, fieldname];
|
|
201
|
-
});
|
|
202
|
-
},
|
|
203
|
-
[defaultSelected],
|
|
204
|
-
);
|
|
205
|
-
|
|
206
|
-
const builderColumns = useMemo<ReportColumn[]>(
|
|
207
|
-
() => allColumns.map((column) => ({ ...column, enabled: selected.includes(column.fieldname) })),
|
|
208
|
-
[allColumns, selected],
|
|
209
|
-
);
|
|
210
|
-
|
|
211
|
-
// ---------------------------------------------------------------------
|
|
212
|
-
// Group-by + paging state. Reset per doctype; page resets on any change
|
|
213
|
-
// that alters result membership.
|
|
214
|
-
// ---------------------------------------------------------------------
|
|
215
|
-
const [groupBy, setGroupBy] = useState<GroupByConfig | null>(null);
|
|
216
|
-
const [pageSize, setPageSize] = useState<number>(DEFAULT_PAGE_SIZE);
|
|
217
|
-
const [page, setPage] = useState(0);
|
|
218
|
-
|
|
219
|
-
useEffect(() => {
|
|
220
|
-
setSelectedOverride(null);
|
|
221
|
-
setGroupBy(null);
|
|
222
|
-
setPage(0);
|
|
223
|
-
}, [doctype]);
|
|
224
|
-
|
|
225
|
-
const filtersKey = useMemo(() => JSON.stringify(queryFilters), [queryFilters]);
|
|
226
|
-
useEffect(() => {
|
|
227
|
-
setPage(0);
|
|
228
|
-
}, [filtersKey, pageSize]);
|
|
229
|
-
|
|
230
|
-
// ---------------------------------------------------------------------
|
|
231
|
-
// Parallel stats query: names (ordered by the doctype sort field) drive
|
|
232
|
-
// pagination windows; numeric fields drive the totals strip; the title
|
|
233
|
-
// field feeds the open-record jump. Kept independent of the column
|
|
234
|
-
// selection so toggles never resubscribe it.
|
|
235
|
-
// ---------------------------------------------------------------------
|
|
236
|
-
const numericColumns = useMemo(
|
|
237
|
-
() => allColumns.filter((column) => REPORT_NUMERIC_FIELDTYPES.has(column.fieldtype)),
|
|
238
|
-
[allColumns],
|
|
239
|
-
);
|
|
240
|
-
const titleField = meta?.title_field;
|
|
241
|
-
const sortField = (meta?.sort_field || "modified").split(" ")[0];
|
|
242
|
-
const sortAscending = (meta?.sort_order || "DESC").toLowerCase() === "asc";
|
|
243
|
-
|
|
244
|
-
const statsFields = useMemo(() => {
|
|
245
|
-
const fields = new Set<string>(["name", sortField]);
|
|
246
|
-
if (titleField) fields.add(titleField);
|
|
247
|
-
for (const column of numericColumns) fields.add(column.fieldname);
|
|
248
|
-
return [...fields];
|
|
249
|
-
}, [sortField, titleField, numericColumns]);
|
|
250
|
-
|
|
251
|
-
const [statsError, setStatsError] = useState<Error | null>(null);
|
|
252
|
-
const handleStatsError = useCallback((error: unknown) => {
|
|
253
|
-
setStatsError(error instanceof Error ? error : new Error(String(error)));
|
|
254
|
-
}, []);
|
|
255
|
-
|
|
256
|
-
// ViewConnection carries syncOptions as `unknown`; the shapes match the
|
|
257
|
-
// collection config (same FrappeProvider source) — assert once here.
|
|
258
|
-
const statsConfig = useMemo(
|
|
259
|
-
() => (connection && meta ? (connection as unknown as UseFrappeCollectionConfig) : undefined),
|
|
260
|
-
[connection, meta],
|
|
261
|
-
);
|
|
262
|
-
const statsCollection = useFrappeCollection<StatsRow>(statsConfig, doctype, {
|
|
263
|
-
fields: statsFields,
|
|
264
|
-
filters: queryFilters,
|
|
265
|
-
orderBy: { field: sortField, order: sortAscending ? Order.Asc : Order.Desc },
|
|
266
|
-
onSyncError: handleStatsError,
|
|
267
|
-
});
|
|
268
|
-
useEffect(() => setStatsError(null), [statsCollection]);
|
|
269
|
-
const { data: statsData, isLoading: statsLoading } = useLiveQuery(
|
|
270
|
-
(q) => (statsCollection ? q.from({ _stats: statsCollection }) : null),
|
|
271
|
-
[statsCollection],
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
// Live-query row order is not guaranteed — order deterministically by the
|
|
275
|
-
// doctype sort field (name tiebreak) so page windows are stable.
|
|
276
|
-
const statsRows = useMemo(() => {
|
|
277
|
-
const rows = [...((statsData as StatsRow[] | undefined) ?? [])];
|
|
278
|
-
const direction = sortAscending ? 1 : -1;
|
|
279
|
-
rows.sort((a, b) => {
|
|
280
|
-
const left = a[sortField];
|
|
281
|
-
const right = b[sortField];
|
|
282
|
-
const ordered =
|
|
283
|
-
isNullish(left) || isNullish(right)
|
|
284
|
-
? compareValues(left, right)
|
|
285
|
-
: direction * compareValues(left, right);
|
|
286
|
-
return ordered || compareValues(a.name, b.name);
|
|
287
|
-
});
|
|
288
|
-
return rows;
|
|
289
|
-
}, [statsData, sortField, sortAscending]);
|
|
290
|
-
|
|
291
|
-
const statsReady = Boolean(statsError) || !statsLoading;
|
|
292
|
-
const total = statsRows.length;
|
|
293
|
-
const pageCount = Math.max(1, Math.ceil(total / pageSize));
|
|
294
|
-
const effectivePage = Math.min(page, pageCount - 1);
|
|
295
|
-
// Small results (or a failed stats query) skip the window: the grid keeps
|
|
296
|
-
// the pure live path and refreshes rows in place on realtime events.
|
|
297
|
-
const needsWindow = !statsError && total > pageSize;
|
|
298
|
-
const pageRows = useMemo(
|
|
299
|
-
() =>
|
|
300
|
-
needsWindow
|
|
301
|
-
? statsRows.slice(effectivePage * pageSize, (effectivePage + 1) * pageSize)
|
|
302
|
-
: statsRows,
|
|
303
|
-
[needsWindow, statsRows, effectivePage, pageSize],
|
|
304
|
-
);
|
|
305
|
-
|
|
306
|
-
const builderFilters = useMemo<FrappeFilters>(() => {
|
|
307
|
-
if (!needsWindow) return queryFilters;
|
|
308
|
-
return [...queryFilters, ["name", "in", pageRows.map((row) => row.name)]];
|
|
309
|
-
}, [needsWindow, queryFilters, pageRows]);
|
|
310
|
-
|
|
311
|
-
// ---------------------------------------------------------------------
|
|
312
|
-
// Footer inputs: open-record jump + totals over the FULL filtered result
|
|
313
|
-
// (not just the page) — desk totals-row parity.
|
|
314
|
-
// ---------------------------------------------------------------------
|
|
315
|
-
const records = useMemo<ReportRecordRef[]>(
|
|
316
|
-
() =>
|
|
317
|
-
pageRows.map((row) => ({
|
|
318
|
-
name: row.name,
|
|
319
|
-
title:
|
|
320
|
-
titleField && !isNullish(row[titleField]) && row[titleField] !== ""
|
|
321
|
-
? String(row[titleField])
|
|
322
|
-
: row.name,
|
|
323
|
-
})),
|
|
324
|
-
[pageRows, titleField],
|
|
325
|
-
);
|
|
326
|
-
|
|
327
|
-
const totals = useMemo<ReportTotal[]>(() => {
|
|
328
|
-
if (total === 0) return [];
|
|
329
|
-
return builderColumns
|
|
330
|
-
.filter((column) => column.enabled && REPORT_NUMERIC_FIELDTYPES.has(column.fieldtype))
|
|
331
|
-
.map((column) => ({
|
|
332
|
-
label: column.label,
|
|
333
|
-
fieldtype: column.fieldtype,
|
|
334
|
-
value: statsRows.reduce((sum, row) => sum + (Number(row[column.fieldname]) || 0), 0),
|
|
335
|
-
}));
|
|
336
|
-
}, [builderColumns, statsRows, total]);
|
|
337
|
-
|
|
338
|
-
const handleOpenRecord = useCallback(
|
|
339
|
-
(name: string) => {
|
|
340
|
-
navigator.navigate(paths.form(doctype, name));
|
|
341
|
-
},
|
|
342
|
-
[navigator, paths, doctype],
|
|
343
|
-
);
|
|
344
|
-
|
|
345
|
-
// ---------------------------------------------------------------------
|
|
346
|
-
// CSV export: enabled columns of the rows the grid currently holds.
|
|
347
|
-
// Web-only (Blob + anchor download); native gets an honest toast.
|
|
348
|
-
// ---------------------------------------------------------------------
|
|
349
|
-
const handleExport = useCallback(
|
|
350
|
-
(exportData: Record<string, unknown>[]) => {
|
|
351
|
-
if (!isWeb) {
|
|
352
|
-
notify({
|
|
353
|
-
severity: "warning",
|
|
354
|
-
scope: "page",
|
|
355
|
-
body: t(
|
|
356
|
-
"report.exportUnsupported",
|
|
357
|
-
"CSV export needs a browser download — not available on this platform yet",
|
|
358
|
-
),
|
|
359
|
-
});
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
const enabledColumns = builderColumns.filter((column) => column.enabled);
|
|
363
|
-
const escapeCell = (value: unknown): string => {
|
|
364
|
-
if (value === null || value === undefined) return "";
|
|
365
|
-
const text = String(value);
|
|
366
|
-
return /[",\n]/.test(text) ? `"${text.replace(/"/g, '""')}"` : text;
|
|
367
|
-
};
|
|
368
|
-
const lines = [
|
|
369
|
-
enabledColumns.map((column) => escapeCell(column.label)).join(","),
|
|
370
|
-
...exportData.map((row) =>
|
|
371
|
-
enabledColumns.map((column) => escapeCell(row[column.fieldname])).join(","),
|
|
372
|
-
),
|
|
373
|
-
];
|
|
374
|
-
downloadBlob(
|
|
375
|
-
new Blob([lines.join("\n")], { type: "text/csv;charset=utf-8;" }),
|
|
376
|
-
`${doctype}_report.csv`,
|
|
377
|
-
);
|
|
378
|
-
},
|
|
379
|
-
[builderColumns, doctype, t],
|
|
380
|
-
);
|
|
381
|
-
|
|
382
|
-
// ---------------------------------------------------------------------
|
|
383
|
-
// Render
|
|
384
|
-
// ---------------------------------------------------------------------
|
|
385
|
-
if (isMetaLoading) return <ViewLoading />;
|
|
386
|
-
if (metaError && !meta) return <ViewError doctype={doctype} error={metaError} />;
|
|
387
|
-
|
|
388
|
-
// ReportBuilder initializes its enabled-column set (and FrappeReportBuilder
|
|
389
|
-
// its group-by state) at mount only — remount on selection/group changes.
|
|
390
|
-
const builderKey = `${doctype}::${[...selected].sort().join("|")}::${
|
|
391
|
-
groupBy ? `${groupBy.field}:${groupBy.aggregation}:${groupBy.aggregationField ?? ""}` : "none"
|
|
392
|
-
}`;
|
|
393
|
-
|
|
394
|
-
return (
|
|
395
|
-
<YStack flex={1} {...knobProps.gap}>
|
|
396
|
-
<ReportToolbar
|
|
397
|
-
columns={builderColumns}
|
|
398
|
-
onToggleColumn={handleToggleColumn}
|
|
399
|
-
groupBy={groupBy}
|
|
400
|
-
onGroupByChange={setGroupBy}
|
|
401
|
-
pageSize={pageSize}
|
|
402
|
-
onPageSizeChange={setPageSize}
|
|
403
|
-
filters={baseFilters}
|
|
404
|
-
onClearFilters={baseFilters.length > 0 ? handleClearFilters : undefined}
|
|
405
|
-
/>
|
|
406
|
-
{statsReady ? (
|
|
407
|
-
<FrappeReportBuilder
|
|
408
|
-
key={builderKey}
|
|
409
|
-
doctype={doctype}
|
|
410
|
-
initialColumns={builderColumns}
|
|
411
|
-
initialGroupBy={groupBy ?? undefined}
|
|
412
|
-
filters={builderFilters}
|
|
413
|
-
showChart
|
|
414
|
-
onExport={handleExport}
|
|
415
|
-
onRowPress={(row) => {
|
|
416
|
-
if (typeof row.name === "string" && row.name) {
|
|
417
|
-
navigator.navigate(paths.form(doctype, row.name));
|
|
418
|
-
}
|
|
419
|
-
}}
|
|
420
|
-
flex={1}
|
|
421
|
-
/>
|
|
422
|
-
) : (
|
|
423
|
-
<ViewLoading />
|
|
424
|
-
)}
|
|
425
|
-
{!statsError && statsReady && (
|
|
426
|
-
<ReportFooter
|
|
427
|
-
page={effectivePage}
|
|
428
|
-
pageCount={pageCount}
|
|
429
|
-
pageSize={pageSize}
|
|
430
|
-
totalItems={total}
|
|
431
|
-
onPageChange={setPage}
|
|
432
|
-
records={records}
|
|
433
|
-
onOpenRecord={handleOpenRecord}
|
|
434
|
-
totals={totals}
|
|
435
|
-
/>
|
|
436
|
-
)}
|
|
437
|
-
</YStack>
|
|
438
|
-
);
|
|
439
|
-
}
|
|
1
|
+
// The compatibility name for the desk's report view. It used to compose its
|
|
2
|
+
// own grid around the old FrappeReportBuilder; the desk report is
|
|
3
|
+
// DoctypeReportView (FrappeReportBuilder under the desk's navigation) and
|
|
4
|
+
// this name renders exactly that now (MPO-15, GL-28).
|
|
5
|
+
export { parseReportFiltersParam } from "@multiplatform.one/frappe-ui";
|
|
6
|
+
export { DoctypeReportView as ReportView } from "../report/DoctypeReportView";
|
|
7
|
+
export type { DoctypeReportViewProps as ReportViewProps } from "../report/DoctypeReportView";
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// The toolbar and footer the old compatibility ReportView composed around
|
|
2
|
+
// the generic ReportBuilder. That view is DoctypeReportView now (MPO-15,
|
|
3
|
+
// GL-28) and renders neither; both stay exported for hosts that built on
|
|
4
|
+
// them:
|
|
5
5
|
// - ReportToolbar: column add/remove picker across all meta fields,
|
|
6
6
|
// group-by + aggregation pickers, page-size selector, filter chips
|
|
7
|
-
// - ReportFooter: totals strip
|
|
8
|
-
// the full filtered result), an "Open" record jump (interim affordance
|
|
9
|
-
// for the missing per-row click-through), numbered pagination
|
|
7
|
+
// - ReportFooter: totals strip, an "Open" record jump, numbered pagination
|
|
10
8
|
import {
|
|
11
9
|
Button,
|
|
12
10
|
Chip,
|
|
@@ -16,7 +14,12 @@ import {
|
|
|
16
14
|
XStack,
|
|
17
15
|
YStack,
|
|
18
16
|
} from "@multiplatform.one/components";
|
|
19
|
-
import
|
|
17
|
+
import {
|
|
18
|
+
REPORT_NUMERIC_FIELDTYPES,
|
|
19
|
+
REPORT_PAGE_SIZES,
|
|
20
|
+
type GroupByConfig,
|
|
21
|
+
type ReportColumn,
|
|
22
|
+
} from "@multiplatform.one/frappe-ui";
|
|
20
23
|
import {
|
|
21
24
|
formatCurrency,
|
|
22
25
|
formatNumber,
|
|
@@ -29,18 +32,7 @@ import { BACKOFFICE_I18N_NAMESPACE } from "../i18n";
|
|
|
29
32
|
import type { FrappeFilters } from "../shared/types";
|
|
30
33
|
import { overlayListMaxHeight } from "../shared/measures";
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
export const REPORT_NUMERIC_FIELDTYPES = new Set([
|
|
34
|
-
"Int",
|
|
35
|
-
"Float",
|
|
36
|
-
"Currency",
|
|
37
|
-
"Percent",
|
|
38
|
-
"Rating",
|
|
39
|
-
"Duration",
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
/** Desk report page lengths. */
|
|
43
|
-
export const REPORT_PAGE_SIZES = [20, 100, 500] as const;
|
|
35
|
+
export { REPORT_NUMERIC_FIELDTYPES, REPORT_PAGE_SIZES } from "@multiplatform.one/frappe-ui";
|
|
44
36
|
|
|
45
37
|
const AGGREGATIONS: GroupByConfig["aggregation"][] = ["count", "sum", "avg", "min", "max"];
|
|
46
38
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DeskSurface.d.ts","sourceRoot":"","sources":["../../src/desk/DeskSurface.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAW,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAEjD,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAC3B,aAAa,CAAC,gBAAgB,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAEpD,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAoCzF,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,gEAAgE;IAChE,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACnC;AAED,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,SAAS,EACT,QAAQ,EACR,cAAc,EACd,KAAK,GACN,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"DeskSurface.d.ts","sourceRoot":"","sources":["../../src/desk/DeskSurface.tsx"],"names":[],"mappings":"AAUA,OAAO,EAAW,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAIpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAKrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAEjD,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,4DAA4D;AAC5D,MAAM,MAAM,mBAAmB,GAC3B,aAAa,CAAC,gBAAgB,CAAC,GAC/B,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAEpD,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAoCzF,MAAM,WAAW,oBAAqB,SAAQ,gBAAgB;IAC5D,SAAS,CAAC,EAAE,oBAAoB,CAAC;IACjC,gEAAgE;IAChE,cAAc,CAAC,EAAE,aAAa,CAAC;IAC/B,6DAA6D;IAC7D,KAAK,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACnC;AAED,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,SAAS,EACT,QAAQ,EACR,cAAc,EACd,KAAK,GACN,EAAE,oBAAoB,2CAoCtB;AAED,2EAA2E;AAC3E,wBAAgB,kBAAkB,4CAMjC"}
|
|
@@ -16,9 +16,9 @@ export interface DocFormScreenProps {
|
|
|
16
16
|
name: string;
|
|
17
17
|
/** Force the whole form read-only regardless of permissions. */
|
|
18
18
|
readOnly?: boolean;
|
|
19
|
-
/** Hide form sections/tabs by Section/Tab Break
|
|
19
|
+
/** Hide form sections/tabs by Section/Tab Break name or label. */
|
|
20
20
|
hiddenSections?: readonly string[];
|
|
21
|
-
/** Hide individual fields by
|
|
21
|
+
/** Hide individual fields by name. */
|
|
22
22
|
hiddenFields?: readonly string[];
|
|
23
23
|
/** Create-mode field prefill (merged over meta defaults). */
|
|
24
24
|
defaults?: Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocFormScreen.d.ts","sourceRoot":"","sources":["../../src/form/DocFormScreen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DocFormScreen.d.ts","sourceRoot":"","sources":["../../src/form/DocFormScreen.tsx"],"names":[],"mappings":"AA8CA,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAiCtC,oDAAoD;AACpD,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kEAAkE;IAClE,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,sCAAsC;IACtC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,+EAA+E;IAC/E,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACpE,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,wDAAwD;IACxD,eAAe,CAAC,EAAE,sBAAsB,CAAC;CAC1C;AAMD,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,IAAI,EACJ,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,QAAQ,EACR,OAAO,EACP,SAAS,EACT,eAAe,GAChB,EAAE,kBAAkB,2CA85BpB"}
|
package/types/i18n/en.d.ts
CHANGED
|
@@ -269,6 +269,7 @@ export declare const en: {
|
|
|
269
269
|
readonly executionTime: "ran in {{seconds}}s";
|
|
270
270
|
readonly filtersRequiredDescription: "Set the required filter(s) to run this report: {{filters}}";
|
|
271
271
|
readonly filtersRequiredTitle: "Filters required";
|
|
272
|
+
readonly notPermitted: "You can't run \"{{report}}\"";
|
|
272
273
|
readonly refresh: "Refresh";
|
|
273
274
|
readonly retry: "Retry";
|
|
274
275
|
readonly rowCount: "{{count}} row(s)";
|
package/types/i18n/en.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/i18n/en.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6aL,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ListBulkActionsBar.d.ts","sourceRoot":"","sources":["../../src/list/ListBulkActionsBar.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"ListBulkActionsBar.d.ts","sourceRoot":"","sources":["../../src/list/ListBulkActionsBar.tsx"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAU5D,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,8BAA8B;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,IAAI,CAAC;CAC9B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,OAAO,EACP,IAAI,EACJ,aAAa,EACb,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,uBAAuB,kDAyVzB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sidebar-section.d.ts","sourceRoot":"","sources":["../../src/list/sidebar-section.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sidebar-section.d.ts","sourceRoot":"","sources":["../../src/list/sidebar-section.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3E,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;wEACwE;AACxE,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC,2CAqB3F;AAED,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CAM7E;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,oBAAoB,2CA8CtF;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,sBAAsB,CAAC,EAAE,IAAQ,EAAE,EAAE,2BAA2B,2CAkB/E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DoctypeReportView.d.ts","sourceRoot":"","sources":["../../src/report/DoctypeReportView.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DoctypeReportView.d.ts","sourceRoot":"","sources":["../../src/report/DoctypeReportView.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,MAAM,WAAW,sBAAsB;IACrC,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,cAAc,CAAC,EAAE,aAAa,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,EAChC,OAAO,EACP,YAAY,EACZ,cAAc,GACf,EAAE,sBAAsB,2CAgDxB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type QueryReportFilters, type QueryReportFixture } from "
|
|
1
|
+
import { type QueryReportFilters, type QueryReportFixture } from "@multiplatform.one/frappe-ui";
|
|
2
2
|
export interface QueryReportScreenProps {
|
|
3
3
|
/** Report document name (proper-cased, e.g. "Permitted Documents For User"). */
|
|
4
4
|
reportName: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QueryReportScreen.d.ts","sourceRoot":"","sources":["../../src/report/QueryReportScreen.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"QueryReportScreen.d.ts","sourceRoot":"","sources":["../../src/report/QueryReportScreen.tsx"],"names":[],"mappings":"AAiCA,OAAO,EAQL,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACxB,MAAM,8BAA8B,CAAC;AAQtC,MAAM,WAAW,sBAAsB;IACrC,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAC7B,mFAAmF;IACnF,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,wCAAwC;IACxC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,0EAA0E;IAC1E,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD;AAID,wBAAgB,iBAAiB,CAAC,EAChC,UAAU,EACV,OAAO,EACP,cAAc,EACd,aAAa,EACb,SAAS,GACV,EAAE,sBAAsB,2CAuSxB"}
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export interface BuildQueryReportColumnsArgs {
|
|
4
|
-
columns: readonly QueryReportColumn[];
|
|
5
|
-
/** Open a Link cell's target document (doctype comes from column options). */
|
|
6
|
-
onOpenLink?: (doctype: string, name: string) => void;
|
|
7
|
-
}
|
|
8
|
-
/** Build DataTable columns for a query-report run result. */
|
|
9
|
-
export declare function buildQueryReportColumns({ columns, onOpenLink, }: BuildQueryReportColumnsArgs): DataTableColumn<QueryReportRow>[];
|
|
10
|
-
/** CSV over the full run result (Desk Export, not just the current page). */
|
|
11
|
-
export declare function buildQueryReportCsv(columns: readonly QueryReportColumn[], rows: readonly QueryReportRow[]): string;
|
|
1
|
+
export { buildQueryReportColumns, buildQueryReportCsv } from "@multiplatform.one/frappe-ui";
|
|
2
|
+
export type { BuildQueryReportColumnsArgs } from "@multiplatform.one/frappe-ui";
|
|
12
3
|
//# sourceMappingURL=queryReportColumns.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryReportColumns.d.ts","sourceRoot":"","sources":["../../src/report/queryReportColumns.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"queryReportColumns.d.ts","sourceRoot":"","sources":["../../src/report/queryReportColumns.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC5F,YAAY,EAAE,2BAA2B,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type QueryReportFilterMeta, type QueryReportFilters } from "
|
|
1
|
+
import { type QueryReportFilterMeta, type QueryReportFilters } from "@multiplatform.one/frappe-ui";
|
|
2
2
|
export declare function queryReportFilterLabel(filter: QueryReportFilterMeta): string;
|
|
3
3
|
/** Discrete kinds commit the run as soon as the value lands (Desk/Metabase). */
|
|
4
4
|
export declare function queryReportFilterAppliesOnChange(filter: QueryReportFilterMeta): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryReportFilterBar.d.ts","sourceRoot":"","sources":["../../src/report/queryReportFilterBar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"queryReportFilterBar.d.ts","sourceRoot":"","sources":["../../src/report/queryReportFilterBar.tsx"],"names":[],"mappings":"AA0BA,OAAO,EAQL,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACxB,MAAM,8BAA8B,CAAC;AAEtC,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,qBAAqB,GAAG,MAAM,CAE5E;AAED,gFAAgF;AAChF,wBAAgB,gCAAgC,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAGvF;AAED,8FAA8F;AAC9F,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,QAAQ,EAAE,MAAM,GACf,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAIzC;AAwJD,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC7C,OAAO,EAAE,kBAAkB,CAAC;IAC5B,OAAO,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;CAC7C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,yBAAyB,2CAuG/F"}
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* `setParams` (history REPLACE, no remount) and adopts inbound param changes
|
|
13
13
|
* (deep links, back/forward), so reload and shared links reproduce the run.
|
|
14
14
|
*/
|
|
15
|
-
import { type QueryReportFilters } from "
|
|
15
|
+
import { type QueryReportFilters } from "@multiplatform.one/frappe-ui";
|
|
16
16
|
/**
|
|
17
17
|
* Parse the `?filters=` deep-link value. The router usually decodes the
|
|
18
18
|
* param already, so the raw value is tried first (same contract as the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queryReportUrlState.d.ts","sourceRoot":"","sources":["../../src/report/queryReportUrlState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"queryReportUrlState.d.ts","sourceRoot":"","sources":["../../src/report/queryReportUrlState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAE3F;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GACjC,kBAAkB,CA0BpB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,GAAG,SAAS,CAUhG"}
|