tp-react-elements 3.0.26 → 3.0.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_virtual/index.esm11.js +2 -2
- package/dist/_virtual/index.esm12.js +2 -2
- package/dist/_virtual/index.esm13.js +2 -2
- package/dist/_virtual/index.esm4.js +2 -2
- package/dist/_virtual/index.esm5.js +2 -2
- package/dist/_virtual/index.esm6.js +2 -2
- package/dist/_virtual/index.esm7.js +2 -2
- package/dist/components/Form/FormRender.esm.js +8 -8
- package/dist/components/FormComponents/index.esm.js +29 -12
- package/dist/components/PaginatedGrid/DynamicFilterBar.d.ts +2 -1
- package/dist/components/PaginatedGrid/DynamicFilterBar.esm.js +3 -4
- package/dist/components/PaginatedGrid/GenericPaginatedGrid.d.ts +29 -1
- package/dist/components/PaginatedGrid/GenericPaginatedGrid.esm.js +63 -4
- package/dist/components/PaginatedGrid/types.d.ts +10 -0
- package/dist/node_modules/react-date-range/dist/components/Calendar/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DateRange/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DateRangePicker/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DayCell/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/DefinedRange/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/InputRangeField/index.esm.js +1 -1
- package/dist/node_modules/react-date-range/dist/components/Month/index.esm.js +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var InputRangeField = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { InputRangeField as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var DayCell = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DayCell as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Month = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { Month as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var DefinedRange = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DefinedRange as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var DateRangePicker = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DateRangePicker as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var DateRange = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DateRange as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Calendar = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { Calendar as __exports };
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import require$$0__default, { lazy, Suspense } from 'react';
|
|
3
|
+
import FormCheckBox from '../FormComponents/FormCheckBox/FormCheckBox.esm.js';
|
|
4
|
+
import FormCheckBoxGroup from '../FormComponents/FormCheckBoxGroup/FormCheckBoxGroup.esm.js';
|
|
5
|
+
import FormNumberField from '../FormComponents/FormNumberField/FormNumberField.esm.js';
|
|
6
|
+
import FormNumberFieldDecimal from '../FormComponents/FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
7
|
+
import FormRadioGroup from '../FormComponents/FormRadioGroup/FormRadioGroup.esm.js';
|
|
8
|
+
import FormTextAreaField from '../FormComponents/FormTextAreaField/FormTextAreaField.esm.js';
|
|
9
|
+
import FormTextField from '../FormComponents/FormTextField/FormTextField.esm.js';
|
|
10
|
+
import PasswordField from '../FormComponents/PasswordField/PasswordField.esm.js';
|
|
3
11
|
import SingleSelect from '../FormComponents/Select/SingleSelect.esm.js';
|
|
4
12
|
import MultiSelectAutocomplete from '../FormComponents/Select/MultiSelectAutocomplete.esm.js';
|
|
5
13
|
import SingleSelectNonAutoComplete from '../FormComponents/Select/SingleSelectNonAutoComplete.esm.js';
|
|
@@ -11,14 +19,6 @@ import RichTextEditorWrapper from '../FormComponents/RichTextEditor/RichTextEdit
|
|
|
11
19
|
import SingleSelectSearchApi from '../FormComponents/Select/SingleSelectSearchApi.esm.js';
|
|
12
20
|
import MultiSelectSearchApi from '../FormComponents/Select/MultiSelectSearchApi.esm.js';
|
|
13
21
|
import DatetimepickerWrapper from '../FormComponents/DatePicker/DatetimepickerWrapper.esm.js';
|
|
14
|
-
import FormTextAreaField from '../FormComponents/FormTextAreaField/FormTextAreaField.esm.js';
|
|
15
|
-
import FormCheckBox from '../FormComponents/FormCheckBox/FormCheckBox.esm.js';
|
|
16
|
-
import FormRadioGroup from '../FormComponents/FormRadioGroup/FormRadioGroup.esm.js';
|
|
17
|
-
import FormCheckBoxGroup from '../FormComponents/FormCheckBoxGroup/FormCheckBoxGroup.esm.js';
|
|
18
|
-
import FormNumberFieldDecimal from '../FormComponents/FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
19
|
-
import FormNumberField from '../FormComponents/FormNumberField/FormNumberField.esm.js';
|
|
20
|
-
import PasswordField from '../FormComponents/PasswordField/PasswordField.esm.js';
|
|
21
|
-
import FormTextField from '../FormComponents/FormTextField/FormTextField.esm.js';
|
|
22
22
|
|
|
23
23
|
// Lazy-loaded heavy components
|
|
24
24
|
// const RichTextEditorWrapper = lazy(() =>
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
export { default as FormNumberField } from './FormNumberField/FormNumberField.esm.js';
|
|
2
|
+
export { default as FormNumberFieldDecimal } from './FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
3
|
+
export { default as FormTextAreaField } from './FormTextAreaField/FormTextAreaField.esm.js';
|
|
4
|
+
export { default as FormTextField } from './FormTextField/FormTextField.esm.js';
|
|
5
|
+
export { default as PasswordField } from './PasswordField/PasswordField.esm.js';
|
|
6
|
+
export { default as FormCheckBox } from './FormCheckBox/FormCheckBox.esm.js';
|
|
1
7
|
export { default as SingleSelect } from './Select/SingleSelect.esm.js';
|
|
2
8
|
export { default as SingleSelectNonAutoComplete } from './Select/SingleSelectNonAutoComplete.esm.js';
|
|
3
9
|
export { default as SingleSelectSearchApi } from './Select/SingleSelectSearchApi.esm.js';
|
|
@@ -5,22 +11,33 @@ export { default as MultiSelectSearchApi } from './Select/MultiSelectSearchApi.e
|
|
|
5
11
|
export { default as MultiSelectV1 } from './Select/MultiSelectv1.esm.js';
|
|
6
12
|
export { default as MultiSelectTable } from './Select/MultiSelectTable.esm.js';
|
|
7
13
|
export { default as SearchableSelect } from './Select/SearchableSelect.esm.js';
|
|
8
|
-
export { default as DatepickerWrapperV2 } from './DatePicker/DatepickerWrapperV2.esm.js';
|
|
9
|
-
export { default as FormBottomField } from './FormBottomField/FormBottomField.esm.js';
|
|
10
|
-
export { default as FormCheckBox } from './FormCheckBox/FormCheckBox.esm.js';
|
|
11
14
|
export { default as FormCheckBoxGroup } from './FormCheckBoxGroup/FormCheckBoxGroup.esm.js';
|
|
12
|
-
export { default as FormErrorField } from './FormErrorField/FormErrorField.esm.js';
|
|
13
|
-
export { default as FormNumberField } from './FormNumberField/FormNumberField.esm.js';
|
|
14
|
-
export { default as FormNumberFieldDecimal } from './FormNumberField/FormNumberFieldDecimal.esm.js';
|
|
15
15
|
export { default as FormRadioGroup } from './FormRadioGroup/FormRadioGroup.esm.js';
|
|
16
|
+
export { default as DatepickerWrapperV2 } from './DatePicker/DatepickerWrapperV2.esm.js';
|
|
17
|
+
export { default as Monthpickerrender } from './DatePicker/Monthpickerrender.esm.js';
|
|
18
|
+
import 'react/jsx-runtime';
|
|
19
|
+
import 'react';
|
|
20
|
+
import '@mui/material';
|
|
21
|
+
import '@mui/icons-material/CalendarToday';
|
|
22
|
+
import '@mui/icons-material/ChevronLeft';
|
|
23
|
+
import '@mui/icons-material/ChevronRight';
|
|
24
|
+
import 'react-hook-form';
|
|
25
|
+
export { default as FormBottomField } from './FormBottomField/FormBottomField.esm.js';
|
|
26
|
+
import 'dayjs';
|
|
27
|
+
export { default as YearPickerField } from './YearPickerField/YearPickerField.esm.js';
|
|
28
|
+
export { default as TimePicker } from './TimePicker/TimePicker.esm.js';
|
|
16
29
|
export { default as FormRenderFileUpload } from './FileUpload/FormRenderFileUpload.esm.js';
|
|
17
30
|
export { default as FormRenderMultiFileUpload } from './FileUpload/FormRenderMultiFileUpload.esm.js';
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
import '@mui/icons-material/Visibility';
|
|
32
|
+
import '@mui/icons-material/Close';
|
|
33
|
+
import '@mui/icons-material/NavigateBefore';
|
|
34
|
+
import '@mui/icons-material/NavigateNext';
|
|
35
|
+
import '@mui/icons-material/Delete';
|
|
36
|
+
import '@mui/icons-material/UploadFile';
|
|
37
|
+
import '@mui/icons-material/PictureAsPdf';
|
|
38
|
+
import '@mui/icons-material/TableChart';
|
|
39
|
+
import '@mui/icons-material/Description';
|
|
40
|
+
export { default as FormErrorField } from './FormErrorField/FormErrorField.esm.js';
|
|
20
41
|
export { default as HelperText } from './HelperText/HelperText.esm.js';
|
|
21
|
-
export { default as Monthpickerrender } from './DatePicker/Monthpickerrender.esm.js';
|
|
22
|
-
export { default as PasswordField } from './PasswordField/PasswordField.esm.js';
|
|
23
42
|
export { default as RichTextEditor } from './RichTextEditor/RichTextEditor.esm.js';
|
|
24
43
|
export { default as RichTextEditorWrapper } from './RichTextEditor/RichTextEditorWrapper.esm.js';
|
|
25
|
-
export { default as TimePicker } from './TimePicker/TimePicker.esm.js';
|
|
26
|
-
export { default as YearPickerField } from './YearPickerField/YearPickerField.esm.js';
|
|
@@ -213,6 +213,7 @@ export interface DynamicFilterBarProps {
|
|
|
213
213
|
uiDensity?: 'default' | 'compact';
|
|
214
214
|
filterChipFontSize?: number;
|
|
215
215
|
filterChipMinHeight?: number;
|
|
216
|
+
/** @deprecated No longer used — the "Filter by:" label was removed. Kept for backward compatibility; now a no-op. */
|
|
216
217
|
filterLabelFontSize?: number;
|
|
217
218
|
/**
|
|
218
219
|
* Current value of MRT's global filter (free-text search across every
|
|
@@ -227,5 +228,5 @@ export interface DynamicFilterBarProps {
|
|
|
227
228
|
/** ID prefix for all interactive elements — passed down to chips and ManageFilters. */
|
|
228
229
|
gridId?: string;
|
|
229
230
|
}
|
|
230
|
-
declare const _default: import("react").MemoExoticComponent<({ serverFilterDefs, visibleFilterIds, onToggleFilter, filterValues, onFilterValuesChange, columnFilters, onColumnFilterChange, availableColumns, maxVisibleFilters, uiDensity, filterChipFontSize, filterChipMinHeight,
|
|
231
|
+
declare const _default: import("react").MemoExoticComponent<({ serverFilterDefs, visibleFilterIds, onToggleFilter, filterValues, onFilterValuesChange, columnFilters, onColumnFilterChange, availableColumns, maxVisibleFilters, uiDensity, filterChipFontSize, filterChipMinHeight, globalFilter, onGlobalFilterChange, globalSearchPlaceholder, gridId, }: DynamicFilterBarProps) => import("react/jsx-runtime").JSX.Element>;
|
|
231
232
|
export default _default;
|
|
@@ -11,7 +11,7 @@ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
|
|
11
11
|
import SingleSelectNonAutoComplete from '../FormComponents/Select/SingleSelectNonAutoComplete.esm.js';
|
|
12
12
|
import SingleSelectSearchApi from '../FormComponents/Select/SingleSelectSearchApi.esm.js';
|
|
13
13
|
import MultiSelectSearchApi from '../FormComponents/Select/MultiSelectSearchApi.esm.js';
|
|
14
|
-
import { TextField, InputAdornment, IconButton, Box,
|
|
14
|
+
import { TextField, InputAdornment, IconButton, Box, Tooltip, Button, Popover, Typography, Stack, List, ListItemButton, ListItemText, Checkbox, Divider } from '@mui/material';
|
|
15
15
|
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
|
16
16
|
import TuneIcon from '@mui/icons-material/Tune';
|
|
17
17
|
import CloseIcon from '@mui/icons-material/Close';
|
|
@@ -566,12 +566,11 @@ const ManageFiltersButton = ({ serverFilterDefs, visibleIds, availableColumns, o
|
|
|
566
566
|
} }), selected && jsx(CheckIcon, { sx: { fontSize: 16, color: 'primary.main', flexShrink: 0 } })] }) }) }, col.id));
|
|
567
567
|
}) })] }))] })] })] }));
|
|
568
568
|
};
|
|
569
|
-
const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter, filterValues, onFilterValuesChange, columnFilters, onColumnFilterChange, availableColumns, maxVisibleFilters = 4, uiDensity = 'default', filterChipFontSize, filterChipMinHeight,
|
|
569
|
+
const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter, filterValues, onFilterValuesChange, columnFilters, onColumnFilterChange, availableColumns, maxVisibleFilters = 4, uiDensity = 'default', filterChipFontSize, filterChipMinHeight, globalFilter, onGlobalFilterChange, globalSearchPlaceholder, gridId, }) => {
|
|
570
570
|
const chipStyle = {
|
|
571
571
|
fontSize: filterChipFontSize ?? (uiDensity === 'compact' ? 11 : 12),
|
|
572
572
|
minHeight: filterChipMinHeight ?? (uiDensity === 'compact' ? 26 : 30),
|
|
573
573
|
};
|
|
574
|
-
const labelFontSize = filterLabelFontSize ?? (uiDensity === 'compact' ? 11 : 12);
|
|
575
574
|
// ── Single-value column filter helpers ──────────────────────────────────────
|
|
576
575
|
const getColValue = (id) => columnFilters.find((f) => f.id === id)?.value ?? '';
|
|
577
576
|
const applyColFilter = useCallback((id, value) => {
|
|
@@ -621,7 +620,7 @@ const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter,
|
|
|
621
620
|
}
|
|
622
621
|
}
|
|
623
622
|
}, [filterValues, serverFilterDefs, availableColumns, onFilterValuesChange, applyColFilter, applyColMultiFilter]);
|
|
624
|
-
return (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 0.75 }, children: [
|
|
623
|
+
return (jsxs(Box, { sx: { display: 'flex', alignItems: 'center', flexWrap: 'wrap', gap: 0.75 }, children: [visibleFilterIds.map((id) => {
|
|
625
624
|
const def = serverFilterDefs.find((d) => d.id === id);
|
|
626
625
|
if (def?.type === 'dateRange') {
|
|
627
626
|
return (jsx(DateRangeChip, { label: def.label, fromDate: filterValues[def.fromKey] ?? '', toDate: filterValues[def.toKey] ?? '', onApply: (from, to) => onFilterValuesChange({ ...filterValues, [def.fromKey]: from, [def.toKey]: to }), onRemove: () => clearFilter(id), chipStyle: chipStyle, baseId: gridId ? `${gridId}_${id}` : undefined }, id));
|
|
@@ -329,6 +329,34 @@ export interface GenericPaginatedGridProps<TData extends object> {
|
|
|
329
329
|
* Default: false.
|
|
330
330
|
*/
|
|
331
331
|
enableExpanding?: boolean;
|
|
332
|
+
/**
|
|
333
|
+
* Show a totals row summing every column whose `TPColumnDef` has
|
|
334
|
+
* `showTotal: true`. Computed client-side over the rows currently loaded
|
|
335
|
+
* on this page only — this grid never holds more than one page of data in
|
|
336
|
+
* memory (`manualPagination: true`, no accumulation), so the total always
|
|
337
|
+
* reflects "this page's rows," not a grand total across the full
|
|
338
|
+
* server-side dataset. Columns without `showTotal` render a blank footer
|
|
339
|
+
* cell; the leading column shows a "Total" label when it isn't itself
|
|
340
|
+
* summed. Default: `false`.
|
|
341
|
+
*/
|
|
342
|
+
displayTotals?: boolean;
|
|
343
|
+
/**
|
|
344
|
+
* Where the totals row appears when `displayTotals` is true.
|
|
345
|
+
*
|
|
346
|
+
* Only `'bottom'` is implemented: a native sticky footer row (the same
|
|
347
|
+
* mechanism `enableStickyHeader` uses for the header), pinned to the
|
|
348
|
+
* bottom of the grid's own scroll area — body rows scroll underneath it,
|
|
349
|
+
* it never scrolls away.
|
|
350
|
+
*
|
|
351
|
+
* `'top'` (a row directly under the header, scrolling normally with the
|
|
352
|
+
* body) is accepted by the type for forward compatibility but not yet
|
|
353
|
+
* implemented — it requires injecting a synthetic row into the data model
|
|
354
|
+
* itself, which isn't built yet. Passing `'top'` falls back to `'bottom'`
|
|
355
|
+
* behaviour with a one-time console warning in dev.
|
|
356
|
+
*
|
|
357
|
+
* Default: `'bottom'`.
|
|
358
|
+
*/
|
|
359
|
+
totalsPosition?: 'top' | 'bottom';
|
|
332
360
|
}
|
|
333
|
-
declare function GenericPaginatedGrid<TData extends object>({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize, exportFilename, gridId, tableHeight, tableMinHeight, tableMaxHeight, autoFillViewport, layoutMode, uiDensity, uiDensityOptions, responsiveBreakpoints, disableResponsive, pageSizeOptions, pageSize, showGlobalSearchByDefault, showDensityToggle, headerBgColor, exportHeaderBgColor, exportHeaderTextColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, getRowSx, getHeaderSx, renderDetailPanel, enableExpanding, }: GenericPaginatedGridProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
361
|
+
declare function GenericPaginatedGrid<TData extends object>({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize, exportFilename, gridId, tableHeight, tableMinHeight, tableMaxHeight, autoFillViewport, layoutMode, uiDensity, uiDensityOptions, responsiveBreakpoints, disableResponsive, pageSizeOptions, pageSize, showGlobalSearchByDefault, showDensityToggle, headerBgColor, exportHeaderBgColor, exportHeaderTextColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, getRowSx, getHeaderSx, renderDetailPanel, enableExpanding, displayTotals, totalsPosition, }: GenericPaginatedGridProps<TData>): import("react/jsx-runtime").JSX.Element;
|
|
334
362
|
export default GenericPaginatedGrid;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
2
|
import { useMemo, useState, useRef, useLayoutEffect, useCallback, useEffect } from 'react';
|
|
3
3
|
import { MRT_ToggleGlobalFilterButton, MRT_ShowHideColumnsButton, MRT_ToggleDensePaddingButton, MRT_ToggleFullScreenButton, useMaterialReactTable, MaterialReactTable } from 'material-react-table';
|
|
4
4
|
import { useQuery, keepPreviousData } from '@tanstack/react-query';
|
|
@@ -109,6 +109,16 @@ const buildBodyGlobalStyles = (bodyFont) => ({
|
|
|
109
109
|
userSelect: 'text',
|
|
110
110
|
},
|
|
111
111
|
});
|
|
112
|
+
/** Totals row: bold, subtly tinted, pinned above the body's bottom edge. */
|
|
113
|
+
const buildFooterGlobalStyles = (bodyFont) => ({
|
|
114
|
+
'.tp-gpg-root .MuiTableFooter-root .MuiTableCell-root': {
|
|
115
|
+
fontSize: `${bodyFont} !important`,
|
|
116
|
+
fontWeight: 700,
|
|
117
|
+
backgroundColor: 'rgba(0,0,0,0.03)',
|
|
118
|
+
borderTop: '2px solid rgba(224,224,224,1)',
|
|
119
|
+
borderRight: '1px solid rgba(224,224,224,1)',
|
|
120
|
+
},
|
|
121
|
+
});
|
|
112
122
|
const buildHeaderGlobalStyles = (headerMin, headerMax, headerFont, headerBgColor) => {
|
|
113
123
|
const headCell = {
|
|
114
124
|
height: `${headerMax} !important`,
|
|
@@ -340,7 +350,7 @@ const PaginationFooter = ({ pageIndex, pageSize, totalRecords, isFetching, isLoa
|
|
|
340
350
|
}, children: pageIndex + 1 }), jsx(Tooltip, { title: "Next page", children: jsx("span", { children: jsx(IconButton, { id: `${gridId}_next_page_icon`, size: "small", onClick: onNext, disabled: !canNext, sx: { p: 0.5 }, children: jsx(ChevronRightIcon, { sx: { fontSize: density.footerIconSize } }) }) }) }), jsx(Tooltip, { title: "Last page", children: jsx("span", { children: jsx(IconButton, { id: `${gridId}_last_page_icon`, size: "small", onClick: onLast, disabled: !canNext, sx: { p: 0.5 }, children: jsx(LastPageIcon, { sx: { fontSize: density.footerIconSize } }) }) }) })] })] }));
|
|
341
351
|
};
|
|
342
352
|
// ─── GenericPaginatedGrid ─────────────────────────────────────────────────────
|
|
343
|
-
function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize = 10000, exportFilename = 'export', gridId, tableHeight, tableMinHeight = '300px', tableMaxHeight, autoFillViewport = true, layoutMode = 'grid', uiDensity, uiDensityOptions, responsiveBreakpoints, disableResponsive = false, pageSizeOptions = [1000, 5000, 10000], pageSize, showGlobalSearchByDefault = false, showDensityToggle = false, headerBgColor, exportHeaderBgColor, exportHeaderTextColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters = 4, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, getRowSx, getHeaderSx, renderDetailPanel, enableExpanding = !!renderDetailPanel, }) {
|
|
353
|
+
function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs, defaultFilters, defaultVisibleFilterIds, batchSize = 10000, exportFilename = 'export', gridId, tableHeight, tableMinHeight = '300px', tableMaxHeight, autoFillViewport = true, layoutMode = 'grid', uiDensity, uiDensityOptions, responsiveBreakpoints, disableResponsive = false, pageSizeOptions = [1000, 5000, 10000], pageSize, showGlobalSearchByDefault = false, showDensityToggle = false, headerBgColor, exportHeaderBgColor, exportHeaderTextColor, headerMinHeight, headerMaxHeight, headerMaxLines, headerFontSize, bodyFontSize, maxVisibleFilters = 4, muiTableBodyCellProps: gridBodyCellProps, muiTableHeadCellProps: gridHeadCellProps, getRowSx, getHeaderSx, renderDetailPanel, enableExpanding = !!renderDetailPanel, displayTotals = false, totalsPosition = 'bottom', }) {
|
|
344
354
|
// ── Responsive tier detection ────────────────────────────────────────────────
|
|
345
355
|
// Three tiers (desktop / tablet / mobile) drive auto density, a progressively
|
|
346
356
|
// lower filter-chip cap, toolbar wrapping, and a stacked pagination footer —
|
|
@@ -384,6 +394,7 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
384
394
|
},
|
|
385
395
|
...buildHeaderGlobalStyles(resolvedHeaderMinHeight, resolvedHeaderMaxHeight, resolvedHeaderFontSize, headerBgColor),
|
|
386
396
|
...buildBodyGlobalStyles(resolvedBodyFontSize),
|
|
397
|
+
...buildFooterGlobalStyles(resolvedBodyFontSize),
|
|
387
398
|
}), [
|
|
388
399
|
resolvedHeaderMinHeight,
|
|
389
400
|
resolvedHeaderMaxHeight,
|
|
@@ -496,14 +507,60 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
496
507
|
// `getSearchText`. MRT doesn't know these props, so we strip them here. We
|
|
497
508
|
// also inject the appropriate `filterFn` automatically so callers never
|
|
498
509
|
// have to write one.
|
|
510
|
+
// Sum each `showTotal` column's raw value across the currently loaded page.
|
|
511
|
+
// A ref (synced below) lets the per-column `Footer` below always read the
|
|
512
|
+
// latest totals without forcing `processedColumns` to rebuild on every
|
|
513
|
+
// page fetch — only `columns`/`layoutMode`/`displayTotals` do that.
|
|
514
|
+
const totalsByColumnId = useMemo(() => {
|
|
515
|
+
if (!displayTotals)
|
|
516
|
+
return {};
|
|
517
|
+
const totals = {};
|
|
518
|
+
for (const col of columns) {
|
|
519
|
+
if (!col.showTotal)
|
|
520
|
+
continue;
|
|
521
|
+
const colId = col.id ?? col.accessorKey;
|
|
522
|
+
if (!colId)
|
|
523
|
+
continue;
|
|
524
|
+
let sum = 0;
|
|
525
|
+
for (const row of rows) {
|
|
526
|
+
const raw = typeof col.accessorFn === 'function'
|
|
527
|
+
? col.accessorFn(row)
|
|
528
|
+
: row[col.accessorKey];
|
|
529
|
+
const n = typeof raw === 'number' ? raw : parseFloat(raw);
|
|
530
|
+
if (!Number.isNaN(n))
|
|
531
|
+
sum += n;
|
|
532
|
+
}
|
|
533
|
+
totals[colId] = sum;
|
|
534
|
+
}
|
|
535
|
+
return totals;
|
|
536
|
+
}, [columns, rows, displayTotals]);
|
|
537
|
+
const totalsRef = useRef(totalsByColumnId);
|
|
538
|
+
totalsRef.current = totalsByColumnId;
|
|
539
|
+
// The leading column gets a "Total" label when it isn't itself summed.
|
|
540
|
+
const leadingColumnId = columns[0]?.id ?? columns[0]?.accessorKey;
|
|
541
|
+
const topWarnedRef = useRef(false);
|
|
542
|
+
if (totalsPosition === 'top' && !topWarnedRef.current && process.env.NODE_ENV !== 'production') {
|
|
543
|
+
topWarnedRef.current = true;
|
|
544
|
+
// eslint-disable-next-line no-console
|
|
545
|
+
console.warn("GenericPaginatedGrid: totalsPosition 'top' is not implemented yet — falling back to 'bottom'.");
|
|
546
|
+
}
|
|
499
547
|
const processedColumns = useMemo(() => {
|
|
500
548
|
const allowGrow = layoutMode === 'grid' || layoutMode === 'semantic';
|
|
501
549
|
return columns.map((col) => {
|
|
502
550
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
503
|
-
const { filterType, options, getSearchText, exportExcel, ...mrtCol } = col;
|
|
551
|
+
const { filterType, options, getSearchText, exportExcel, showTotal, ...mrtCol } = col;
|
|
504
552
|
if (allowGrow && mrtCol.grow === undefined) {
|
|
505
553
|
mrtCol.grow = true;
|
|
506
554
|
}
|
|
555
|
+
if (displayTotals) {
|
|
556
|
+
const colId = mrtCol.id ?? mrtCol.accessorKey;
|
|
557
|
+
if (showTotal) {
|
|
558
|
+
mrtCol.Footer = () => (jsx("span", { children: (totalsRef.current[colId] ?? 0).toLocaleString() }));
|
|
559
|
+
}
|
|
560
|
+
else if (colId === leadingColumnId) {
|
|
561
|
+
mrtCol.Footer = () => jsx("span", { style: { fontWeight: 700 }, children: "Total" });
|
|
562
|
+
}
|
|
563
|
+
}
|
|
507
564
|
// Auto-inject filterFn only when the user hasn't already supplied one.
|
|
508
565
|
// Note: `filterType` omitted defaults to the same plain text-input chip
|
|
509
566
|
// as `filterType: 'text'` (see `ColumnFilterType` doc comment), so the
|
|
@@ -543,7 +600,7 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
543
600
|
}
|
|
544
601
|
return mrtCol;
|
|
545
602
|
});
|
|
546
|
-
}, [columns, layoutMode]);
|
|
603
|
+
}, [columns, layoutMode, displayTotals, leadingColumnId]);
|
|
547
604
|
// ── Global Search: match formatted `Cell` text, not just the raw value ───────
|
|
548
605
|
//
|
|
549
606
|
// MRT's built-in global filter always compares against `row.getValue(columnId)`
|
|
@@ -917,6 +974,8 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
917
974
|
columnResizeMode: 'onChange',
|
|
918
975
|
enableExpanding,
|
|
919
976
|
renderDetailPanel,
|
|
977
|
+
enableTableFooter: displayTotals,
|
|
978
|
+
enableStickyFooter: displayTotals,
|
|
920
979
|
// Note: `enableFilters` is the master switch for column AND global
|
|
921
980
|
// filtering. Keep it enabled so the Global Search box (which relies on
|
|
922
981
|
// `getCanGlobalFilter()`) actually filters rows. MRT's native per-column
|
|
@@ -119,6 +119,16 @@ export type TPColumnDef<TData extends object = object, TValue = any> = MRT_Colum
|
|
|
119
119
|
* explicitly opted out.
|
|
120
120
|
*/
|
|
121
121
|
exportExcel?: boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Include this column in the grid's totals row (see `displayTotals` on
|
|
124
|
+
* `GenericPaginatedGrid`). Sums the column's raw value across every row
|
|
125
|
+
* currently loaded on the page — the grid never holds more than one page
|
|
126
|
+
* of data in memory, so the total always reflects "this page's rows," not
|
|
127
|
+
* a grand total across the full server-side dataset. Only meaningful on
|
|
128
|
+
* numeric columns. Non-numeric/unparseable values are skipped (treated as
|
|
129
|
+
* 0), not coerced. Default: `false`.
|
|
130
|
+
*/
|
|
131
|
+
showTotal?: boolean;
|
|
122
132
|
};
|
|
123
133
|
export interface InvoiceDetail {
|
|
124
134
|
Data_from: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as Calendar } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as Calendar } from '../../../../../_virtual/index.esm7.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireDayCell } from '../DayCell/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DateRange } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DateRange } from '../../../../../_virtual/index.esm6.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireCalendar } from '../Calendar/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DateRangePicker } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DateRangePicker } from '../../../../../_virtual/index.esm5.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireDateRange } from '../DateRange/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DayCell } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DayCell } from '../../../../../_virtual/index.esm12.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireClassnames } from '../../../../classnames/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DefinedRange } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DefinedRange } from '../../../../../_virtual/index.esm4.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireStyles } from '../../styles.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as InputRangeField } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as InputRangeField } from '../../../../../_virtual/index.esm11.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as Month } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as Month } from '../../../../../_virtual/index.esm13.js';
|
|
2
2
|
import require$$0__default from 'react';
|
|
3
3
|
import { __require as requirePropTypes } from '../../../../prop-types/index.esm.js';
|
|
4
4
|
import { __require as requireDayCell } from '../DayCell/index.esm.js';
|