tp-react-elements 3.0.18 → 3.0.21
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.esm12.js +2 -2
- package/dist/_virtual/index.esm14.js +2 -2
- package/dist/_virtual/index.esm5.js +2 -2
- package/dist/_virtual/index.esm6.js +2 -2
- package/dist/components/Form/FormRender.esm.js +8 -8
- package/dist/components/FormComponents/index.esm.js +12 -29
- package/dist/components/PaginatedGrid/DynamicFilterBar.d.ts +66 -0
- package/dist/components/PaginatedGrid/DynamicFilterBar.esm.js +88 -2
- package/dist/components/PaginatedGrid/GenericPaginatedGrid.esm.js +23 -13
- package/dist/components/PaginatedGrid/mockData.d.ts +5 -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/DateInput/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/Month/index.esm.js +1 -1
- package/package.json +1 -1
|
@@ -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 DateInput = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DateInput as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var Calendar = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { Calendar as __exports };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var DefinedRange = {};
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { DefinedRange as __exports };
|
|
@@ -1,13 +1,5 @@
|
|
|
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';
|
|
11
3
|
import SingleSelect from '../FormComponents/Select/SingleSelect.esm.js';
|
|
12
4
|
import MultiSelectAutocomplete from '../FormComponents/Select/MultiSelectAutocomplete.esm.js';
|
|
13
5
|
import SingleSelectNonAutoComplete from '../FormComponents/Select/SingleSelectNonAutoComplete.esm.js';
|
|
@@ -19,6 +11,14 @@ import RichTextEditorWrapper from '../FormComponents/RichTextEditor/RichTextEdit
|
|
|
19
11
|
import SingleSelectSearchApi from '../FormComponents/Select/SingleSelectSearchApi.esm.js';
|
|
20
12
|
import MultiSelectSearchApi from '../FormComponents/Select/MultiSelectSearchApi.esm.js';
|
|
21
13
|
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,9 +1,3 @@
|
|
|
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';
|
|
7
1
|
export { default as SingleSelect } from './Select/SingleSelect.esm.js';
|
|
8
2
|
export { default as SingleSelectNonAutoComplete } from './Select/SingleSelectNonAutoComplete.esm.js';
|
|
9
3
|
export { default as SingleSelectSearchApi } from './Select/SingleSelectSearchApi.esm.js';
|
|
@@ -11,33 +5,22 @@ export { default as MultiSelectSearchApi } from './Select/MultiSelectSearchApi.e
|
|
|
11
5
|
export { default as MultiSelectV1 } from './Select/MultiSelectv1.esm.js';
|
|
12
6
|
export { default as MultiSelectTable } from './Select/MultiSelectTable.esm.js';
|
|
13
7
|
export { default as SearchableSelect } from './Select/SearchableSelect.esm.js';
|
|
14
|
-
export { default as FormCheckBoxGroup } from './FormCheckBoxGroup/FormCheckBoxGroup.esm.js';
|
|
15
|
-
export { default as FormRadioGroup } from './FormRadioGroup/FormRadioGroup.esm.js';
|
|
16
8
|
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
9
|
export { default as FormBottomField } from './FormBottomField/FormBottomField.esm.js';
|
|
26
|
-
|
|
27
|
-
export { default as
|
|
28
|
-
export { default as
|
|
10
|
+
export { default as FormCheckBox } from './FormCheckBox/FormCheckBox.esm.js';
|
|
11
|
+
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
|
+
export { default as FormRadioGroup } from './FormRadioGroup/FormRadioGroup.esm.js';
|
|
29
16
|
export { default as FormRenderFileUpload } from './FileUpload/FormRenderFileUpload.esm.js';
|
|
30
17
|
export { default as FormRenderMultiFileUpload } from './FileUpload/FormRenderMultiFileUpload.esm.js';
|
|
31
|
-
|
|
32
|
-
|
|
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';
|
|
18
|
+
export { default as FormTextAreaField } from './FormTextAreaField/FormTextAreaField.esm.js';
|
|
19
|
+
export { default as FormTextField } from './FormTextField/FormTextField.esm.js';
|
|
41
20
|
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';
|
|
42
23
|
export { default as RichTextEditor } from './RichTextEditor/RichTextEditor.esm.js';
|
|
43
24
|
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';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SearchOption } from '../../components/FormComponents/Select/SingleSelectSearchApi';
|
|
1
2
|
import type { MRT_ColumnFiltersState } from 'material-react-table';
|
|
2
3
|
/**
|
|
3
4
|
* Describes one server-side filter chip.
|
|
@@ -117,6 +118,71 @@ export type ServerFilterDef = {
|
|
|
117
118
|
* chips like the date picker. Default: `false` (multi-select).
|
|
118
119
|
*/
|
|
119
120
|
single?: boolean;
|
|
121
|
+
} | {
|
|
122
|
+
/**
|
|
123
|
+
* Single-select chip backed by `SingleSelectSearchApi` — options load
|
|
124
|
+
* from a remote API as the user types (debounced), instead of a fixed
|
|
125
|
+
* list. Use this over `searchableDropdown` when the option set is too
|
|
126
|
+
* large/dynamic to enumerate upfront (customers, products by ID, etc.).
|
|
127
|
+
* Selected value is stored in `filterValues[filterKey]`, same as
|
|
128
|
+
* `dropdown`/`searchableDropdown`.
|
|
129
|
+
*/
|
|
130
|
+
type: 'singleSelectSearch';
|
|
131
|
+
id: string;
|
|
132
|
+
label: string;
|
|
133
|
+
filterKey: string;
|
|
134
|
+
/** Preferred — consumer-supplied fetch (handles auth). Receives search text + AbortSignal. */
|
|
135
|
+
fetchOptions?: (searchText: string, signal: AbortSignal) => Promise<SearchOption[]>;
|
|
136
|
+
/** Fallback base API URL, used only when `fetchOptions` is omitted. */
|
|
137
|
+
api?: string;
|
|
138
|
+
jwtHeader?: any;
|
|
139
|
+
/** Query param name for the fallback `api` path. Default: `'searchvalue'`. */
|
|
140
|
+
searchValue?: string;
|
|
141
|
+
/** Minimum characters before the search fires. Default: `3`. */
|
|
142
|
+
minSearchLength?: number;
|
|
143
|
+
/** Debounce delay in ms. Default: `300`. */
|
|
144
|
+
debounceMs?: number;
|
|
145
|
+
/**
|
|
146
|
+
* Pre-known option(s) so a restored `filterValues[filterKey]` (e.g. a
|
|
147
|
+
* filter set before this chip was last opened) shows its label
|
|
148
|
+
* immediately without a search round-trip.
|
|
149
|
+
*/
|
|
150
|
+
options?: SearchOption[];
|
|
151
|
+
placeholder?: string;
|
|
152
|
+
/** Show this chip in the filter bar on first render. Default: `false`. */
|
|
153
|
+
defaultVisible?: boolean;
|
|
154
|
+
} | {
|
|
155
|
+
/**
|
|
156
|
+
* Multi-select chip backed by `MultiSelectSearchApi` — same remote-API
|
|
157
|
+
* search as `singleSelectSearch`, but multiple values can be picked.
|
|
158
|
+
* Selected values are joined as a comma-separated string in
|
|
159
|
+
* `filterValues[filterKey]` (e.g. `"P001,P004"`), same convention as
|
|
160
|
+
* `multiSelect`. Split on `","` in your `fetchPage` handler.
|
|
161
|
+
*/
|
|
162
|
+
type: 'multiSelectSearch';
|
|
163
|
+
id: string;
|
|
164
|
+
label: string;
|
|
165
|
+
filterKey: string;
|
|
166
|
+
/** Preferred — consumer-supplied fetch (handles auth). Receives search text + AbortSignal. */
|
|
167
|
+
fetchOptions?: (searchText: string, signal: AbortSignal) => Promise<SearchOption[]>;
|
|
168
|
+
/** Fallback base API URL, used only when `fetchOptions` is omitted. */
|
|
169
|
+
api?: string;
|
|
170
|
+
jwtHeader?: any;
|
|
171
|
+
/** Query param name for the fallback `api` path. Default: `'searchvalue'`. */
|
|
172
|
+
searchValue?: string;
|
|
173
|
+
/** Minimum characters before the search fires. Default: `3`. */
|
|
174
|
+
minSearchLength?: number;
|
|
175
|
+
/** Debounce delay in ms. Default: `300`. */
|
|
176
|
+
debounceMs?: number;
|
|
177
|
+
/** Pre-known option(s) so restored selections show their labels immediately. */
|
|
178
|
+
options?: SearchOption[];
|
|
179
|
+
/** Chips shown individually before collapsing into "N selected". Default: `2`. */
|
|
180
|
+
maxChips?: number;
|
|
181
|
+
/** Caps how many options can be selected at once. Default: no limit. */
|
|
182
|
+
maxSelections?: number;
|
|
183
|
+
placeholder?: string;
|
|
184
|
+
/** Show this chip in the filter bar on first render. Default: `false`. */
|
|
185
|
+
defaultVisible?: boolean;
|
|
120
186
|
};
|
|
121
187
|
interface AvailableColumn {
|
|
122
188
|
id: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
|
-
import { memo, useState, useEffect, useCallback } from 'react';
|
|
2
|
+
import { memo, useState, useEffect, useCallback, useMemo } from 'react';
|
|
3
3
|
import { useForm } from 'react-hook-form';
|
|
4
4
|
import dayjs from 'dayjs';
|
|
5
5
|
import customParseFormat from 'dayjs/plugin/customParseFormat';
|
|
@@ -9,6 +9,8 @@ import { DatePicker } from '@mui/x-date-pickers/DatePicker';
|
|
|
9
9
|
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
|
|
10
10
|
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
|
|
11
11
|
import SingleSelectNonAutoComplete from '../FormComponents/Select/SingleSelectNonAutoComplete.esm.js';
|
|
12
|
+
import SingleSelectSearchApi from '../FormComponents/Select/SingleSelectSearchApi.esm.js';
|
|
13
|
+
import MultiSelectSearchApi from '../FormComponents/Select/MultiSelectSearchApi.esm.js';
|
|
12
14
|
import { TextField, InputAdornment, IconButton, Box, Typography, Tooltip, Button, Popover, Stack, List, ListItemButton, ListItemText, Checkbox, Divider } from '@mui/material';
|
|
13
15
|
import CalendarTodayIcon from '@mui/icons-material/CalendarToday';
|
|
14
16
|
import TuneIcon from '@mui/icons-material/Tune';
|
|
@@ -33,6 +35,8 @@ const TYPE_PILL = {
|
|
|
33
35
|
searchableDropdown: { label: 'Search', color: '#bf360c', bg: '#fbe9e7' },
|
|
34
36
|
multiSelect: { label: 'Multi', color: '#0277bd', bg: '#e1f5fe' },
|
|
35
37
|
monthPicker: { label: 'Month', color: '#6a1b9a', bg: '#f3e5f5' },
|
|
38
|
+
singleSelectSearch: { label: 'API', color: '#ad1457', bg: '#fce4ec' },
|
|
39
|
+
multiSelectSearch: { label: 'API Multi', color: '#ad1457', bg: '#fce4ec' },
|
|
36
40
|
};
|
|
37
41
|
// Column filter type pills (used in COLUMN FILTERS section of Manage Filters)
|
|
38
42
|
const COLUMN_TYPE_PILL = {
|
|
@@ -407,6 +411,80 @@ const MonthPickerChip = ({ label, value, onApply, onRemove, chipStyle, baseId, s
|
|
|
407
411
|
borderTop: '1px solid', borderColor: 'divider',
|
|
408
412
|
}, children: jsx(Button, { size: "small", variant: "contained", disableElevation: true, onClick: handleApply, children: "Apply" }) }))] })] }));
|
|
409
413
|
};
|
|
414
|
+
const SingleSelectSearchChip = ({ label, value, onApply, onRemove, fetchOptions, api, jwtHeader, searchValue, minSearchLength, debounceMs, options, placeholder, chipStyle, baseId, }) => {
|
|
415
|
+
const [anchor, setAnchor] = useState(null);
|
|
416
|
+
// Captured from onChangeFn's fullOption when the user selects — the chip's
|
|
417
|
+
// own display text, since the committed filter value is just a raw id.
|
|
418
|
+
const [selectedLabel, setSelectedLabel] = useState('');
|
|
419
|
+
const active = Boolean(value);
|
|
420
|
+
const rhf = useForm({ defaultValues: { select: value || '' } });
|
|
421
|
+
const { register, control, getValues, clearErrors, watch, setValue: rhfSetValue } = rhf;
|
|
422
|
+
// Sync form value when external value changes (e.g. Clear All) — clear the
|
|
423
|
+
// cached label too so a stale one never outlives its filter value.
|
|
424
|
+
useEffect(() => {
|
|
425
|
+
rhfSetValue('select', value || '');
|
|
426
|
+
if (!value)
|
|
427
|
+
setSelectedLabel('');
|
|
428
|
+
}, [value]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
429
|
+
const item = useMemo(() => ({
|
|
430
|
+
name: 'select',
|
|
431
|
+
label,
|
|
432
|
+
inputType: 'single-select-search',
|
|
433
|
+
placeholder: placeholder ?? 'Type to search…',
|
|
434
|
+
api,
|
|
435
|
+
jwtHeader,
|
|
436
|
+
searchValue,
|
|
437
|
+
options,
|
|
438
|
+
onChangeFn: (v, fullOption) => {
|
|
439
|
+
setSelectedLabel(fullOption?.label ?? (v != null ? String(v) : ''));
|
|
440
|
+
onApply(v != null ? String(v) : '');
|
|
441
|
+
setAnchor(null);
|
|
442
|
+
},
|
|
443
|
+
}), [label, placeholder, api, jwtHeader, searchValue, options, onApply]);
|
|
444
|
+
const chipText = active ? `${label}: ${selectedLabel || value}` : label;
|
|
445
|
+
return (jsxs(Fragment, { children: [jsx(Tooltip, { title: active ? chipText : '', placement: "top", arrow: true, children: jsx(Button, { id: baseId ? `${baseId}_chip` : undefined, variant: "outlined", size: "small", onClick: (e) => setAnchor(e.currentTarget), startIcon: jsx(SearchIcon, { sx: { fontSize: '14px !important', mr: -0.25 } }), endIcon: jsx(CloseIcon, { id: baseId ? `${baseId}_remove_icon` : undefined, sx: { fontSize: '12px !important' }, onClick: (e) => { e.stopPropagation(); onRemove(); } }), sx: chipSx(active, chipStyle), children: jsx(ChipLabel, { text: chipText }) }) }), jsx(Popover, { open: Boolean(anchor), anchorEl: anchor, onClose: () => setAnchor(null), anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, PaperProps: { sx: { mt: 0.75, borderRadius: 2, boxShadow: 6, p: 1.5, width: 280 } }, children: jsx(SingleSelectSearchApi, { props: { item, register, control, errors: {}, getValues, clearErrors, setValue: rhfSetValue, watch }, variant: "outlined", fetchOptions: fetchOptions, minSearchLength: minSearchLength, debounceMs: debounceMs }) })] }));
|
|
446
|
+
};
|
|
447
|
+
const MultiSelectSearchChip = ({ label, value, onApply, onRemove, fetchOptions, api, jwtHeader, searchValue, minSearchLength, debounceMs, options, maxChips, maxSelections, placeholder, chipStyle, baseId, }) => {
|
|
448
|
+
const [anchor, setAnchor] = useState(null);
|
|
449
|
+
const [selectedOptions, setSelectedOptions] = useState([]);
|
|
450
|
+
const committedValues = value ? value.split(',').filter(Boolean) : [];
|
|
451
|
+
const active = committedValues.length > 0;
|
|
452
|
+
const rhf = useForm({ defaultValues: { select: committedValues } });
|
|
453
|
+
const { register, control, getValues, clearErrors, watch, setValue: rhfSetValue } = rhf;
|
|
454
|
+
useEffect(() => {
|
|
455
|
+
rhfSetValue('select', value ? value.split(',').filter(Boolean) : []);
|
|
456
|
+
if (!value)
|
|
457
|
+
setSelectedOptions([]);
|
|
458
|
+
}, [value]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
459
|
+
const item = useMemo(() => ({
|
|
460
|
+
name: 'select',
|
|
461
|
+
label,
|
|
462
|
+
inputType: 'multi-select-search',
|
|
463
|
+
placeholder: placeholder ?? 'Type to search…',
|
|
464
|
+
api,
|
|
465
|
+
jwtHeader,
|
|
466
|
+
searchValue,
|
|
467
|
+
options,
|
|
468
|
+
onChangeFn: (values, fullOptions) => {
|
|
469
|
+
setSelectedOptions(fullOptions ?? []);
|
|
470
|
+
onApply((values ?? []).join(','));
|
|
471
|
+
},
|
|
472
|
+
}), [label, placeholder, api, jwtHeader, searchValue, options, onApply]);
|
|
473
|
+
const chipText = (() => {
|
|
474
|
+
if (!active)
|
|
475
|
+
return label;
|
|
476
|
+
if (selectedOptions.length > 0) {
|
|
477
|
+
if (selectedOptions.length === 1)
|
|
478
|
+
return `${label}: ${selectedOptions[0].label}`;
|
|
479
|
+
if (selectedOptions.length === 2)
|
|
480
|
+
return `${label}: ${selectedOptions.map((o) => o.label).join(', ')}`;
|
|
481
|
+
return `${label}: ${selectedOptions.length} selected`;
|
|
482
|
+
}
|
|
483
|
+
// Labels not yet cached (e.g. restored value before any onChangeFn call) — fall back to the count.
|
|
484
|
+
return `${label}: ${committedValues.length} selected`;
|
|
485
|
+
})();
|
|
486
|
+
return (jsxs(Fragment, { children: [jsx(Tooltip, { title: active ? chipText : '', placement: "top", arrow: true, children: jsx(Button, { id: baseId ? `${baseId}_chip` : undefined, variant: "outlined", size: "small", onClick: (e) => setAnchor(e.currentTarget), startIcon: jsx(SearchIcon, { sx: { fontSize: '14px !important', mr: -0.25 } }), endIcon: jsx(CloseIcon, { id: baseId ? `${baseId}_remove_icon` : undefined, sx: { fontSize: '12px !important' }, onClick: (e) => { e.stopPropagation(); onRemove(); } }), sx: chipSx(active, chipStyle), children: jsx(ChipLabel, { text: chipText }) }) }), jsx(Popover, { open: Boolean(anchor), anchorEl: anchor, onClose: () => setAnchor(null), anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, PaperProps: { sx: { mt: 0.75, borderRadius: 2, boxShadow: 6, p: 1.5, width: 300 } }, children: jsx(MultiSelectSearchApi, { props: { item, register, control, errors: {}, getValues, clearErrors, setValue: rhfSetValue, watch }, variant: "outlined", fetchOptions: fetchOptions, minSearchLength: minSearchLength, debounceMs: debounceMs, maxChips: maxChips, maxSelections: maxSelections }) })] }));
|
|
487
|
+
};
|
|
410
488
|
const GlobalSearchInput = memo(({ value, onChange, chipStyle, placeholder = 'Search…' }) => {
|
|
411
489
|
const [draft, setDraft] = useState(value);
|
|
412
490
|
// Keep local draft in sync when the external value changes elsewhere
|
|
@@ -522,7 +600,9 @@ const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter,
|
|
|
522
600
|
def?.type === 'dropdown' ||
|
|
523
601
|
def?.type === 'searchableDropdown' ||
|
|
524
602
|
def?.type === 'multiSelect' ||
|
|
525
|
-
def?.type === 'monthPicker'
|
|
603
|
+
def?.type === 'monthPicker' ||
|
|
604
|
+
def?.type === 'singleSelectSearch' ||
|
|
605
|
+
def?.type === 'multiSelectSearch') {
|
|
526
606
|
onFilterValuesChange({ ...filterValues, [def.filterKey]: '' });
|
|
527
607
|
}
|
|
528
608
|
else if (def?.type === 'date') {
|
|
@@ -565,6 +645,12 @@ const DynamicFilterBar = ({ serverFilterDefs, visibleFilterIds, onToggleFilter,
|
|
|
565
645
|
if (def?.type === 'monthPicker') {
|
|
566
646
|
return (jsx(MonthPickerChip, { label: def.label, value: filterValues[def.filterKey] ?? '', onApply: (v) => onFilterValuesChange({ ...filterValues, [def.filterKey]: v }), onRemove: () => removeFilter(id), chipStyle: chipStyle, baseId: gridId ? `${gridId}_${id}` : undefined, single: def.single }, id));
|
|
567
647
|
}
|
|
648
|
+
if (def?.type === 'singleSelectSearch') {
|
|
649
|
+
return (jsx(SingleSelectSearchChip, { label: def.label, value: filterValues[def.filterKey] ?? '', onApply: (v) => onFilterValuesChange({ ...filterValues, [def.filterKey]: v }), onRemove: () => removeFilter(id), fetchOptions: def.fetchOptions, api: def.api, jwtHeader: def.jwtHeader, searchValue: def.searchValue, minSearchLength: def.minSearchLength, debounceMs: def.debounceMs, options: def.options, placeholder: def.placeholder, chipStyle: chipStyle, baseId: gridId ? `${gridId}_${id}` : undefined }, id));
|
|
650
|
+
}
|
|
651
|
+
if (def?.type === 'multiSelectSearch') {
|
|
652
|
+
return (jsx(MultiSelectSearchChip, { label: def.label, value: filterValues[def.filterKey] ?? '', onApply: (v) => onFilterValuesChange({ ...filterValues, [def.filterKey]: v }), onRemove: () => removeFilter(id), fetchOptions: def.fetchOptions, api: def.api, jwtHeader: def.jwtHeader, searchValue: def.searchValue, minSearchLength: def.minSearchLength, debounceMs: def.debounceMs, options: def.options, maxChips: def.maxChips, maxSelections: def.maxSelections, placeholder: def.placeholder, chipStyle: chipStyle, baseId: gridId ? `${gridId}_${id}` : undefined }, id));
|
|
653
|
+
}
|
|
568
654
|
if (def?.type === 'date') {
|
|
569
655
|
return (jsx(DatePickerChip, { label: def.label, value: getColValue(def.columnKey), onApply: (v) => applyColFilter(def.columnKey, v), onRemove: () => removeFilter(id), chipStyle: chipStyle, baseId: gridId ? `${gridId}_${id}` : undefined }, id));
|
|
570
656
|
}
|
|
@@ -390,19 +390,19 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
390
390
|
.map((d) => d.id);
|
|
391
391
|
// Column filter chips with defaultVisible: true.
|
|
392
392
|
// Mirror the same exclusion rules used by availableColumns:
|
|
393
|
-
// • must have
|
|
393
|
+
// • must have a filter identifier (accessorKey, falling back to id)
|
|
394
394
|
// • must not have enableColumnFilter: false
|
|
395
395
|
// • must not be managed by a server-side 'date' filter def
|
|
396
396
|
const serverManagedColKeys = new Set(serverFilterDefs
|
|
397
397
|
.filter((d) => d.type === 'date')
|
|
398
398
|
.map((d) => d.columnKey));
|
|
399
399
|
const markedCols = columns
|
|
400
|
-
.
|
|
401
|
-
|
|
400
|
+
.map((c) => ({ c, key: c.accessorKey ?? c.id }))
|
|
401
|
+
.filter(({ c, key }) => !!key &&
|
|
402
402
|
c.defaultVisible &&
|
|
403
403
|
c.enableColumnFilter !== false &&
|
|
404
|
-
!serverManagedColKeys.has(
|
|
405
|
-
.map((
|
|
404
|
+
!serverManagedColKeys.has(key))
|
|
405
|
+
.map(({ key }) => key);
|
|
406
406
|
const marked = [...markedServer, ...markedCols];
|
|
407
407
|
return marked.length > 0
|
|
408
408
|
? marked
|
|
@@ -563,23 +563,33 @@ function GenericPaginatedGrid({ columns, fetchPage, queryKey, serverFilterDefs,
|
|
|
563
563
|
const getColumnCanGlobalFilter = useCallback(() => true, []);
|
|
564
564
|
// ── Derive column list for filter chip picker ──────────────────────────────
|
|
565
565
|
//
|
|
566
|
+
// A column's filter identifier is its `accessorKey` when set, falling back to
|
|
567
|
+
// its `id` — TanStack Table's `row.getValue(columnId)` resolves correctly
|
|
568
|
+
// either way, whether the column was defined via `accessorKey` or via
|
|
569
|
+
// `accessorFn` + an explicit `id` (the standard pattern for a computed/mapped
|
|
570
|
+
// display column, e.g. a status label derived from two boolean fields). Using
|
|
571
|
+
// `accessorKey`-only here would silently exclude every such computed column
|
|
572
|
+
// from Manage Filters even when it has a real `filterType`/`options` already
|
|
573
|
+
// configured — a real, previously-observed gap across several grids.
|
|
574
|
+
//
|
|
566
575
|
// A column is excluded from the "Column Filters" section of Manage Filters
|
|
567
576
|
// when ANY of the following are true:
|
|
568
|
-
// 1. It has
|
|
569
|
-
// 2.
|
|
577
|
+
// 1. It has neither `accessorKey` nor `id` (no stable filter identifier).
|
|
578
|
+
// 2. That identifier is already handled by a server-side 'date' filter def.
|
|
570
579
|
// 3. Its MRT `enableColumnFilter` prop is explicitly set to `false` —
|
|
571
|
-
// use this for numeric/computed columns that don't need a filter chip
|
|
580
|
+
// use this for numeric/computed columns that don't need a filter chip
|
|
581
|
+
// (e.g. an actions column).
|
|
572
582
|
const availableColumns = useMemo(() => {
|
|
573
583
|
const serverManagedColKeys = new Set(serverFilterDefs
|
|
574
584
|
.filter((d) => d.type === 'date')
|
|
575
585
|
.map((d) => d.columnKey));
|
|
576
586
|
return columns
|
|
577
|
-
.
|
|
578
|
-
|
|
579
|
-
!serverManagedColKeys.has(
|
|
587
|
+
.map((c) => ({ c, key: c.accessorKey ?? c.id }))
|
|
588
|
+
.filter(({ c, key }) => !!key &&
|
|
589
|
+
!serverManagedColKeys.has(key) &&
|
|
580
590
|
c.enableColumnFilter !== false)
|
|
581
|
-
.map((c) => ({
|
|
582
|
-
id:
|
|
591
|
+
.map(({ c, key }) => ({
|
|
592
|
+
id: key,
|
|
583
593
|
label: c.header,
|
|
584
594
|
// Pass filterType directly from TPColumnDef (no meta unwrapping needed)
|
|
585
595
|
filterType: c.filterType,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import type { TPColumnDef, InvoiceDetail } from './types';
|
|
5
5
|
import type { PagedResult } from './GenericPaginatedGrid';
|
|
6
6
|
import type { ServerFilterDef } from './DynamicFilterBar';
|
|
7
|
+
import type { SearchOption } from '../../components/FormComponents/Select/SingleSelectSearchApi';
|
|
7
8
|
export interface EmployeeRow {
|
|
8
9
|
id: number;
|
|
9
10
|
name: string;
|
|
@@ -20,6 +21,10 @@ export declare const employeeColumns: TPColumnDef<EmployeeRow>[];
|
|
|
20
21
|
export declare const employeeFilterDefs: ServerFilterDef[];
|
|
21
22
|
export declare const employeeDefaultFilters: Record<string, string>;
|
|
22
23
|
export declare function fetchEmployeePage(filters: Record<string, string>, pageIndex: number, pageSize?: number): Promise<PagedResult<EmployeeRow>>;
|
|
24
|
+
/** Mock remote search — simulates network latency + case-insensitive filtering. */
|
|
25
|
+
export declare function searchManagers(text: string, signal: AbortSignal): Promise<SearchOption[]>;
|
|
26
|
+
export declare function searchLocations(text: string, signal: AbortSignal): Promise<SearchOption[]>;
|
|
27
|
+
export declare const employeeSearchFilterDefs: ServerFilterDef[];
|
|
23
28
|
export interface ProductRow {
|
|
24
29
|
sku: string;
|
|
25
30
|
title: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as Calendar } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as Calendar } 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 requireDayCell } from '../DayCell/index.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as DateInput } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as DateInput } from '../../../../../_virtual/index.esm14.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.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 requireStyles } from '../../styles.esm.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __exports as Month } from '../../../../../_virtual/index.
|
|
1
|
+
import { __exports as Month } 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 requireDayCell } from '../DayCell/index.esm.js';
|