@prt-ts/fluent-react-table-v2 9.40.0-build.8.0 → 9.41.0-build.2.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 +7 -7
- package/index.js +126 -42
- package/package.json +2 -2
- package/src/lib/components/grid-header/GridHeader.d.ts +2 -3
- package/src/lib/components/useGridContainer.d.ts +1 -0
- package/src/lib/components/views/ViewSaveForm.d.ts +9 -0
- package/src/lib/components/views/ViewsDrawer.d.ts +16 -0
- package/src/lib/index.d.ts +3 -3
- package/src/lib/types/TableProps.d.ts +8 -0
- package/src/lib/types/TableView.d.ts +2 -1
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# fluent-react-table-v2
|
|
2
|
-
|
|
3
|
-
This library was generated with [Nx](https://nx.dev).
|
|
4
|
-
|
|
5
|
-
## Running unit tests
|
|
6
|
-
|
|
7
|
-
Run `nx test fluent-react-table-v2` to execute the unit tests via [Vitest](https://vitest.dev/).
|
|
1
|
+
# fluent-react-table-v2
|
|
2
|
+
|
|
3
|
+
This library was generated with [Nx](https://nx.dev).
|
|
4
|
+
|
|
5
|
+
## Running unit tests
|
|
6
|
+
|
|
7
|
+
Run `nx test fluent-react-table-v2` to execute the unit tests via [Vitest](https://vitest.dev/).
|
package/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
1
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
2
2
|
import * as React from 'react';
|
|
3
3
|
import { useMemo } from 'react';
|
|
4
4
|
import { useDrop, useDrag, DndProvider } from 'react-dnd';
|
|
5
5
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
|
6
|
-
import { makeStaticStyles, makeStyles, shorthands, tokens, useId, Dropdown, Option, Input, Button, Divider, Popover, PopoverTrigger, PopoverSurface, MenuGroupHeader, Checkbox,
|
|
7
|
-
import { PreviousRegular, ArrowPreviousFilled, ArrowNextFilled, NextRegular, bundleIcon, SaveFilled, SaveRegular, TableSimpleCheckmarkFilled, TableSimpleCheckmarkRegular, SearchFilled, SearchRegular, FilterFilled, FilterRegular, CodeTextOff16Filled, CodeTextOff16Regular, ColumnEditFilled, ColumnEditRegular, GroupFilled, GroupRegular, ChevronRightFilled, ChevronRightRegular, ChevronDownRegular, ChevronDownFilled, DragFilled, DragRegular,
|
|
6
|
+
import { makeStaticStyles, makeStyles, shorthands, tokens, useId, Dropdown, Option, Input, Button, Divider, Popover, PopoverTrigger, Tooltip, PopoverSurface, MenuGroupHeader, Checkbox, RadioGroup, Radio, Field, InlineDrawer, DrawerHeader, DrawerHeaderTitle, DrawerBody, Caption1Stronger, Menu, MenuTrigger, MenuButton, MenuPopover, MenuList, MenuGroup, MenuItem, MenuDivider, mergeClasses, Skeleton, SkeletonItem, Subtitle2Stronger, MenuItemRadio, DrawerFooter } from '@fluentui/react-components';
|
|
7
|
+
import { PreviousRegular, ArrowPreviousFilled, ArrowNextFilled, NextRegular, bundleIcon, SaveFilled, SaveRegular, TableSimpleCheckmarkFilled, TableSimpleCheckmarkRegular, SearchFilled, SearchRegular, FilterFilled, FilterRegular, CodeTextOff16Filled, CodeTextOff16Regular, ColumnEditFilled, ColumnEditRegular, GroupFilled, GroupRegular, ChevronRightFilled, ChevronRightRegular, ChevronDownRegular, ChevronDownFilled, DragFilled, DragRegular, Album24Regular, Search24Regular, FilterDismissFilled, Dismiss24Regular, ArrowSortDown20Filled, ArrowSortDown20Regular, ArrowSortUp20Filled, ArrowSortUp20Regular, GroupListRegular, PinRegular, TextSortAscendingFilled, TextSortDescendingFilled, GroupDismissFilled, ArrowStepInLeftRegular, ArrowStepInRightRegular, PinOffRegular, DocumentSearch24Regular, Save20Filled, ViewDesktop20Filled, ViewDesktop20Regular } from '@fluentui/react-icons';
|
|
8
8
|
import { useReactTable, getCoreRowModel, getPaginationRowModel, getSortedRowModel, getFilteredRowModel, getGroupedRowModel, getExpandedRowModel, getFacetedUniqueValues, getFacetedMinMaxValues, flexRender } from '@tanstack/react-table';
|
|
9
9
|
export { createColumnHelper } from '@tanstack/react-table';
|
|
10
10
|
import { useVirtual } from 'react-virtual';
|
|
@@ -161,35 +161,23 @@ const useGridHeaderStyles = makeStyles({
|
|
|
161
161
|
});
|
|
162
162
|
|
|
163
163
|
const GridHeader = (props) => {
|
|
164
|
-
const { table, gridTitle, globalFilter, setGlobalFilter
|
|
164
|
+
const { table, gridTitle, globalFilter, setGlobalFilter } = props;
|
|
165
165
|
const styles = useGridHeaderStyles();
|
|
166
|
-
|
|
167
|
-
table.setGlobalFilter('');
|
|
168
|
-
table.resetColumnFilters();
|
|
169
|
-
}, [table]);
|
|
170
|
-
const resetAllGrouping = React.useCallback(() => {
|
|
171
|
-
table.resetGrouping();
|
|
172
|
-
}, [table]);
|
|
173
|
-
const clearAllSelection = React.useCallback(() => {
|
|
174
|
-
table.toggleAllRowsSelected(false);
|
|
175
|
-
}, [table]);
|
|
176
|
-
return (jsxs("div", Object.assign({ className: styles.tableTopHeaderContainer }, { children: [jsx("div", Object.assign({ className: styles.tableTopHeaderLeft }, { children: gridTitle })), jsxs("div", Object.assign({ className: styles.tableTopHeaderRight }, { children: [props.headerMenu, props.headerMenu && jsx(Divider, { vertical: true }), jsxs(Popover, Object.assign({ withArrow: true }, { children: [jsx(PopoverTrigger, Object.assign({ disableButtonEnhancement: true }, { children: jsx(Button, { icon: jsx(ToggleGroupColumnIcon, {}), "aria-label": "Toggle Group Column" }) })), jsx(PopoverSurface, { children: jsxs("div", Object.assign({ className: styles.tableTopHeaderColumnTogglePopover }, { children: [jsx(MenuGroupHeader, { children: "Group Columns" }), table.getAllLeafColumns().map((column) => {
|
|
166
|
+
return (jsxs("div", Object.assign({ className: styles.tableTopHeaderContainer }, { children: [jsx("div", Object.assign({ className: styles.tableTopHeaderLeft }, { children: gridTitle })), jsxs("div", Object.assign({ className: styles.tableTopHeaderRight }, { children: [props.headerMenu, props.headerMenu && jsx(Divider, { vertical: true }), jsxs(Popover, Object.assign({ withArrow: true }, { children: [jsx(PopoverTrigger, Object.assign({ disableButtonEnhancement: true }, { children: jsx(Tooltip, Object.assign({ content: 'Toggle Group Column', relationship: "label" }, { children: jsx(Button, { icon: jsx(ToggleGroupColumnIcon, {}), "aria-label": "Toggle Group Column" }) })) })), jsx(PopoverSurface, { children: jsxs("div", Object.assign({ className: styles.tableTopHeaderColumnTogglePopover }, { children: [jsx(MenuGroupHeader, { children: "Group Columns" }), table.getAllLeafColumns().map((column) => {
|
|
177
167
|
if (column.id === 'select')
|
|
178
168
|
return null;
|
|
179
169
|
if (column.id === 'id')
|
|
180
170
|
return null;
|
|
181
171
|
return (jsx(Checkbox, { checked: column.getIsGrouped(), onChange: column.getToggleGroupingHandler(), disabled: !column.getCanGroup() || !column.getIsVisible(), label: jsx("span", { children: column.columnDef.id }) }, column.id));
|
|
182
|
-
})] })) })] })), jsxs(Popover, Object.assign({ withArrow: true }, { children: [jsx(PopoverTrigger, Object.assign({ disableButtonEnhancement: true }, { children: jsx(Button, { icon: jsx(ToggleSelectColumnIcon, {}), "aria-label": "Toggle Column Visibility" }) })), jsx(PopoverSurface, { children: jsxs("div", Object.assign({ className: styles.tableTopHeaderColumnTogglePopover }, { children: [jsx(MenuGroupHeader, { children: "Toggle Columns" }), jsx(Checkbox, { checked: table.getIsAllColumnsVisible(), onChange: table.getToggleAllColumnsVisibilityHandler(), label: 'Toggle All' }), jsx(Divider, {}), table.getAllLeafColumns().map((column) => {
|
|
172
|
+
})] })) })] })), jsxs(Popover, Object.assign({ withArrow: true }, { children: [jsx(PopoverTrigger, Object.assign({ disableButtonEnhancement: true }, { children: jsx(Tooltip, Object.assign({ content: 'Toggle Column Visibility', relationship: "label" }, { children: jsx(Button, { icon: jsx(ToggleSelectColumnIcon, {}), "aria-label": "Toggle Column Visibility" }) })) })), jsx(PopoverSurface, { children: jsxs("div", Object.assign({ className: styles.tableTopHeaderColumnTogglePopover }, { children: [jsx(MenuGroupHeader, { children: "Toggle Columns" }), jsx(Checkbox, { checked: table.getIsAllColumnsVisible(), onChange: table.getToggleAllColumnsVisibilityHandler(), label: 'Toggle All' }), jsx(Divider, {}), table.getAllLeafColumns().map((column) => {
|
|
183
173
|
if (column.id === 'select')
|
|
184
174
|
return null;
|
|
185
175
|
return (jsx(Checkbox, { checked: column.getIsVisible(), onChange: column.getToggleVisibilityHandler(), label: column.id, disabled: !column.getCanHide() }, column.id));
|
|
186
|
-
})] })) })] })),
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return (jsx(MenuItem, Object.assign({ icon: jsx(ClearFilterIcon, {}), onClick: () => applyTableState(view.tableState) }, { children: view.viewName }), view.id));
|
|
192
|
-
})] }) })] }), jsx(DebouncedInput, { value: globalFilter !== null && globalFilter !== void 0 ? globalFilter : '', onChange: (value) => setGlobalFilter(String(value)), className: "p-2 font-lg shadow border border-block", placeholder: "Search all columns...", openFilterDrawer: props.openFilterDrawer, setFilterDrawerOpen: props.setFilterDrawerOpen })] }))] })));
|
|
176
|
+
})] })) })] })), jsx(Tooltip, Object.assign({ content: 'Table Views Management', relationship: "label" }, { children: jsx(Button
|
|
177
|
+
// appearance="subtle"
|
|
178
|
+
, {
|
|
179
|
+
// appearance="subtle"
|
|
180
|
+
onClick: () => props.setViewsDrawerOpen((value) => !value), icon: jsx(Album24Regular, {}), "aria-label": "View Menu" }) })), jsx(DebouncedInput, { value: globalFilter !== null && globalFilter !== void 0 ? globalFilter : '', onChange: (value) => setGlobalFilter(String(value)), className: "p-2 font-lg shadow border border-block", placeholder: "Search all columns...", openFilterDrawer: props.openFilterDrawer, setFilterDrawerOpen: props.setFilterDrawerOpen })] }))] })));
|
|
193
181
|
};
|
|
194
182
|
// A debounced input react component
|
|
195
183
|
function DebouncedInput({ value: initialValue, onChange, debounce = 500, openFilterDrawer, setFilterDrawerOpen, }) {
|
|
@@ -203,9 +191,9 @@ function DebouncedInput({ value: initialValue, onChange, debounce = 500, openFil
|
|
|
203
191
|
}, debounce);
|
|
204
192
|
return () => clearTimeout(timeout);
|
|
205
193
|
}, [value, onChange, debounce]);
|
|
206
|
-
return (jsx(Input, { placeholder: "Search Keyword", value: value, onChange: (_, data) => setValue(data.value), type: "search", autoComplete: "off", contentBefore: jsx(Search24Regular, {}), style: { width: '300px' }, contentAfter: jsx(
|
|
207
|
-
|
|
208
|
-
|
|
194
|
+
return (jsx(Input, { placeholder: "Search Keyword", value: value, onChange: (_, data) => setValue(data.value), type: "search", autoComplete: "off", contentBefore: jsx(Search24Regular, {}), style: { width: '300px' }, contentAfter: jsx(Tooltip, Object.assign({ content: openFilterDrawer ? 'Close Filter Window' : 'Open Advance Filter', relationship: "label" }, { children: jsx(Button, { appearance: "subtle", icon: openFilterDrawer ? jsx(FilterDismissFilled, {}) : jsx(FilterFilled, {}), "aria-label": "View Menu", onClick: () => {
|
|
195
|
+
setFilterDrawerOpen((open) => !open);
|
|
196
|
+
} }) })) }));
|
|
209
197
|
}
|
|
210
198
|
|
|
211
199
|
const arrIncludesSome = (row, columnId, value) => {
|
|
@@ -225,12 +213,15 @@ const dateRange = (row, columnId, value) => {
|
|
|
225
213
|
if (!value || value.length === 0) {
|
|
226
214
|
return true;
|
|
227
215
|
}
|
|
228
|
-
if (value.length === 2 && value[0] && !value[1]) {
|
|
216
|
+
else if (value.length === 2 && value[0] && !value[1]) {
|
|
229
217
|
return typeof rowValue.getMonth === 'function' && rowValue >= value[0];
|
|
230
218
|
}
|
|
231
|
-
if (value.length === 2 && !value[0] && value[1]) {
|
|
219
|
+
else if (value.length === 2 && !value[0] && value[1]) {
|
|
232
220
|
return typeof rowValue.getMonth === 'function' && rowValue <= value[1];
|
|
233
221
|
}
|
|
222
|
+
else if (value.length === 2 && !value[0] && !value[1]) {
|
|
223
|
+
return true;
|
|
224
|
+
}
|
|
234
225
|
const passed = typeof rowValue.getMonth === 'function' && value[0] <= rowValue && rowValue <= value[1];
|
|
235
226
|
return passed;
|
|
236
227
|
};
|
|
@@ -289,9 +280,9 @@ const useGridContainer = (props, ref) => {
|
|
|
289
280
|
columns: columns,
|
|
290
281
|
data,
|
|
291
282
|
filterFns: {
|
|
292
|
-
|
|
293
|
-
dateRange,
|
|
294
|
-
date
|
|
283
|
+
arrIncludesSome: arrIncludesSome,
|
|
284
|
+
inDateRange: dateRange,
|
|
285
|
+
matchDate: date,
|
|
295
286
|
},
|
|
296
287
|
initialState: {
|
|
297
288
|
expanded: true,
|
|
@@ -460,6 +451,7 @@ const useGridContainer = (props, ref) => {
|
|
|
460
451
|
setGlobalFilter,
|
|
461
452
|
resetToDefaultView,
|
|
462
453
|
applyTableState,
|
|
454
|
+
getTableState
|
|
463
455
|
};
|
|
464
456
|
};
|
|
465
457
|
|
|
@@ -678,13 +670,17 @@ const FilterDateRange = (props) => {
|
|
|
678
670
|
const min = (_b = (_a = column.getFacetedMinMaxValues()) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : undefined;
|
|
679
671
|
const max = (_d = (_c = column.getFacetedMinMaxValues()) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : undefined;
|
|
680
672
|
const handleMinChange = (date) => {
|
|
681
|
-
if (!date)
|
|
673
|
+
if (!date) {
|
|
674
|
+
column.setFilterValue((old) => [undefined, old === null || old === void 0 ? void 0 : old[1]]);
|
|
682
675
|
return;
|
|
676
|
+
}
|
|
683
677
|
column.setFilterValue((old) => [date, old === null || old === void 0 ? void 0 : old[1]]);
|
|
684
678
|
};
|
|
685
679
|
const handleMaxChange = (date) => {
|
|
686
|
-
if (!date)
|
|
680
|
+
if (!date) {
|
|
681
|
+
column.setFilterValue((old) => [old === null || old === void 0 ? void 0 : old[0], undefined]);
|
|
687
682
|
return;
|
|
683
|
+
}
|
|
688
684
|
column.setFilterValue((old) => [old === null || old === void 0 ? void 0 : old[0], date]);
|
|
689
685
|
};
|
|
690
686
|
const styles = useNumberRangeFilterStyles$1();
|
|
@@ -714,8 +710,10 @@ const FilterDate = (props) => {
|
|
|
714
710
|
const min = (_b = (_a = column.getFacetedMinMaxValues()) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : undefined;
|
|
715
711
|
const max = (_d = (_c = column.getFacetedMinMaxValues()) === null || _c === void 0 ? void 0 : _c[1]) !== null && _d !== void 0 ? _d : undefined;
|
|
716
712
|
const onDateSelect = (date) => {
|
|
717
|
-
if (!date)
|
|
713
|
+
if (!date) {
|
|
714
|
+
column.setFilterValue(undefined);
|
|
718
715
|
return;
|
|
716
|
+
}
|
|
719
717
|
column.setFilterValue(date);
|
|
720
718
|
};
|
|
721
719
|
const styles = useNumberRangeFilterStyles();
|
|
@@ -742,14 +740,14 @@ const Filter = ({ column, table, }) => {
|
|
|
742
740
|
const filterFunctionName = column.columnDef.filterFn;
|
|
743
741
|
const styles = useFilterStyles();
|
|
744
742
|
switch (filterFunctionName) {
|
|
745
|
-
case '
|
|
743
|
+
case 'arrIncludesSome':
|
|
746
744
|
return jsx(FilterMultiSelectCheckbox, { column: column, table: table });
|
|
747
745
|
case 'arrIncludesAll':
|
|
748
746
|
case 'arrIncludes':
|
|
749
747
|
return jsx(FilterSelectRadio, { column: column, table: table });
|
|
750
748
|
case 'inNumberRange':
|
|
751
749
|
return jsx(FilterNumberRange, { column: column, table: table });
|
|
752
|
-
case '
|
|
750
|
+
case 'inDateRange': {
|
|
753
751
|
const firstValue = (_a = table
|
|
754
752
|
.getPreFilteredRowModel()
|
|
755
753
|
.flatRows[0]) === null || _a === void 0 ? void 0 : _a.getValue(column.id);
|
|
@@ -758,7 +756,7 @@ const Filter = ({ column, table, }) => {
|
|
|
758
756
|
}
|
|
759
757
|
break;
|
|
760
758
|
}
|
|
761
|
-
case '
|
|
759
|
+
case 'matchDate': {
|
|
762
760
|
const firstValue = (_b = table
|
|
763
761
|
.getPreFilteredRowModel()
|
|
764
762
|
.flatRows[0]) === null || _b === void 0 ? void 0 : _b.getValue(column.id);
|
|
@@ -773,7 +771,7 @@ const Filter = ({ column, table, }) => {
|
|
|
773
771
|
}, placeholder: "Search Keyword...", size: "small", className: styles.searchInput }) })) })));
|
|
774
772
|
};
|
|
775
773
|
|
|
776
|
-
const useFilterDrawerStyles = makeStyles({
|
|
774
|
+
const useFilterDrawerStyles$1 = makeStyles({
|
|
777
775
|
drawerBody: Object.assign(Object.assign({}, shorthands.overflow('hidden', 'auto')), {
|
|
778
776
|
/* width */
|
|
779
777
|
':hover': Object.assign({}, shorthands.overflow('auto', 'auto')), '::-webkit-scrollbar': Object.assign({ width: '6px', height: '4px' }, shorthands.borderRadius('50%')),
|
|
@@ -792,8 +790,8 @@ const useFilterDrawerStyles = makeStyles({
|
|
|
792
790
|
});
|
|
793
791
|
const FilterDrawer = ({ open, setOpen, table }) => {
|
|
794
792
|
const headerGroups = table.getHeaderGroups();
|
|
795
|
-
const styles = useFilterDrawerStyles();
|
|
796
|
-
return (jsxs(InlineDrawer, Object.assign({ position: "end", open: open, separator: true }, { children: [jsx(DrawerHeader, { children: jsx(DrawerHeaderTitle, Object.assign({ action: jsx(Button, { appearance: "subtle", "aria-label": "Close", icon: jsx(Dismiss24Regular, {}), onClick: () => setOpen(false) }) }, { children: "
|
|
793
|
+
const styles = useFilterDrawerStyles$1();
|
|
794
|
+
return (jsxs(InlineDrawer, Object.assign({ position: "end", open: open, separator: true }, { children: [jsx(DrawerHeader, { children: jsx(DrawerHeaderTitle, Object.assign({ action: jsx(Button, { appearance: "subtle", "aria-label": "Close", icon: jsx(Dismiss24Regular, {}), onClick: () => setOpen(false) }) }, { children: "Advanced Filters" })) }), jsx(DrawerBody, Object.assign({ className: styles.drawerBody }, { children: headerGroups.map((headerGroup) => {
|
|
797
795
|
const canApplyFilter = headerGroup.depth === (headerGroups === null || headerGroups === void 0 ? void 0 : headerGroups.length) - 1;
|
|
798
796
|
if (!canApplyFilter)
|
|
799
797
|
return null;
|
|
@@ -1020,11 +1018,97 @@ const TableContainer = (props) => {
|
|
|
1020
1018
|
: table.getIsAllPageRowsSelected(), onChange: table.getToggleAllPageRowsSelectedHandler(), "aria-label": "Select All Current Page Rows", title: 'Select All Current Page Rows' }) })), jsxs("td", Object.assign({ colSpan: 20 }, { children: [table.getIsAllPageRowsSelected() ? 'Unselect' : 'Select', " All Current Page Rows (", table.getRowModel().rows.length, ")"] }))] }) })))] })), isLoading && jsx(Loading, {}), noItems && jsx(NoItemGrid, { message: props.noItemPage }), noSearchResult && jsx(NoSearchResult, { message: props.noFilterMatchPage })] })));
|
|
1021
1019
|
};
|
|
1022
1020
|
|
|
1021
|
+
const ViewSaveForm = (props) => {
|
|
1022
|
+
const [errorMessage, setErrorMessage] = React.useState('');
|
|
1023
|
+
const [isFormOpen, setIsFormOpen] = React.useState(false);
|
|
1024
|
+
const inputRef = React.useRef(null);
|
|
1025
|
+
const checkboxRef = React.useRef(null);
|
|
1026
|
+
if (!isFormOpen) {
|
|
1027
|
+
return (jsxs(Fragment, { children: [jsx(MenuList, { children: jsx(MenuItemRadio, Object.assign({ name: 'view-manager', value: 'View Manager', onClick: () => setIsFormOpen(true), icon: jsx(Save20Filled, {}) }, { children: "Save Current View" })) }), jsx(Divider, {})] }));
|
|
1028
|
+
}
|
|
1029
|
+
return (jsxs("div", Object.assign({ style: {
|
|
1030
|
+
boxSizing: 'border-box',
|
|
1031
|
+
padding: '0.4rem',
|
|
1032
|
+
border: '1px solid #ccc',
|
|
1033
|
+
marginBottom: '0.5rem'
|
|
1034
|
+
} }, { children: [jsx(Caption1Stronger, { children: "Enter View Details" }), jsx(Field, Object.assign({ label: "View Name", validationMessage: errorMessage, validationState: errorMessage ? "error" : undefined, hint: jsx(Fragment, { children: "Give your view a name and save it." }) }, { children: jsx(Input, { ref: inputRef, placeholder: "View Name" }) })), jsx(Field, Object.assign({ hint: jsx(Fragment, { children: "Global view is accessible to everybody in the system." }) }, { children: jsx(Checkbox, { ref: checkboxRef, label: "Set as global view" }) })), jsxs("div", Object.assign({ style: {
|
|
1035
|
+
display: 'flex',
|
|
1036
|
+
flexWrap: 'wrap',
|
|
1037
|
+
gap: '0.5rem'
|
|
1038
|
+
} }, { children: [jsx(Button, Object.assign({ onClick: () => {
|
|
1039
|
+
setIsFormOpen(false);
|
|
1040
|
+
setErrorMessage('');
|
|
1041
|
+
} }, { children: "Cancel" })), jsx(Button, Object.assign({ appearance: 'primary', onClick: () => {
|
|
1042
|
+
var _a, _b, _c;
|
|
1043
|
+
if (!((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value)) {
|
|
1044
|
+
setErrorMessage('View name is required');
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
const viewName = inputRef.current.value;
|
|
1048
|
+
const isGlobal = (_b = checkboxRef.current) === null || _b === void 0 ? void 0 : _b.checked;
|
|
1049
|
+
const tableView = {
|
|
1050
|
+
id: Math.random() * 100,
|
|
1051
|
+
viewName: viewName,
|
|
1052
|
+
tableState: props.getTableState(),
|
|
1053
|
+
isGlobal: isGlobal,
|
|
1054
|
+
isViewOwner: true
|
|
1055
|
+
};
|
|
1056
|
+
(_c = props === null || props === void 0 ? void 0 : props.onSave) === null || _c === void 0 ? void 0 : _c.call(props, tableView);
|
|
1057
|
+
setErrorMessage('');
|
|
1058
|
+
setIsFormOpen(false);
|
|
1059
|
+
} }, { children: "Save" }))] }))] })));
|
|
1060
|
+
};
|
|
1061
|
+
|
|
1062
|
+
const useFilterDrawerStyles = makeStyles({
|
|
1063
|
+
drawerBody: Object.assign(Object.assign({}, shorthands.overflow('hidden', 'auto')), {
|
|
1064
|
+
/* width */
|
|
1065
|
+
':hover': Object.assign({}, shorthands.overflow('auto', 'auto')), '::-webkit-scrollbar': Object.assign({ width: '6px', height: '4px' }, shorthands.borderRadius('50%')),
|
|
1066
|
+
/* Track */
|
|
1067
|
+
'::-webkit-scrollbar-track': {
|
|
1068
|
+
'background-color': '#f1f1f1',
|
|
1069
|
+
},
|
|
1070
|
+
/* Handle */
|
|
1071
|
+
'::-webkit-scrollbar-thumb': {
|
|
1072
|
+
'background-color': '#888',
|
|
1073
|
+
},
|
|
1074
|
+
/* Handle on hover */
|
|
1075
|
+
'::-webkit-scrollbar-thumb:hover': {
|
|
1076
|
+
'background-color': '#555',
|
|
1077
|
+
} }),
|
|
1078
|
+
});
|
|
1079
|
+
const ViewsDrawer = (props) => {
|
|
1080
|
+
const { open, setOpen, table, tableViews, applyTableState, resetToGridDefaultView, getTableState, onTableViewSave } = props;
|
|
1081
|
+
const styles = useFilterDrawerStyles();
|
|
1082
|
+
const [checkedValues, setCheckedValues] = React.useState({ font: ["calibri"] });
|
|
1083
|
+
const onChange = (e, { name, checkedItems }) => {
|
|
1084
|
+
setCheckedValues((s) => (Object.assign(Object.assign({}, s), { [name]: checkedItems })));
|
|
1085
|
+
};
|
|
1086
|
+
const resetAllFilters = React.useCallback(() => {
|
|
1087
|
+
table.setGlobalFilter('');
|
|
1088
|
+
table.resetColumnFilters();
|
|
1089
|
+
}, [table]);
|
|
1090
|
+
const resetAllGrouping = React.useCallback(() => {
|
|
1091
|
+
table.resetGrouping();
|
|
1092
|
+
}, [table]);
|
|
1093
|
+
const clearAllSelection = React.useCallback(() => {
|
|
1094
|
+
table.toggleAllRowsSelected(false);
|
|
1095
|
+
}, [table]);
|
|
1096
|
+
return (jsxs(InlineDrawer, Object.assign({ position: "end", open: open, separator: true }, { children: [jsx(DrawerHeader, { children: jsx(DrawerHeaderTitle, Object.assign({ action: jsx(Button, { appearance: "subtle", "aria-label": "Close", icon: jsx(Dismiss24Regular, {}), onClick: () => setOpen(false) }) }, { children: "Table Views" })) }), jsxs(DrawerBody, Object.assign({ className: styles.drawerBody }, { children: [onTableViewSave && jsx(ViewSaveForm, { mode: 'create', getTableState: getTableState, onSave: onTableViewSave }), jsxs(MenuList, Object.assign({ checkedValues: checkedValues, onCheckedValueChange: onChange }, { children: [jsx(MenuItemRadio, Object.assign({ name: 'table-views', value: 'Default View', icon: jsx(ViewDesktop20Filled, {}), onClick: resetToGridDefaultView }, { children: "Default View" })), tableViews.length > 0 && jsx(MenuDivider, { children: "Additional Views" }), tableViews.map((view) => {
|
|
1097
|
+
return (jsxs("div", Object.assign({ style: {
|
|
1098
|
+
display: 'flex',
|
|
1099
|
+
justifyContent: 'space-between',
|
|
1100
|
+
alignItems: 'center',
|
|
1101
|
+
width: '100%',
|
|
1102
|
+
} }, { children: [jsx(MenuItemRadio, Object.assign({ name: "table-views", value: view.viewName, onClick: () => applyTableState(view.tableState), icon: jsx(ViewDesktop20Regular, {}) }, { children: view.viewName })), props.onTableViewDelete && (view === null || view === void 0 ? void 0 : view.isViewOwner) && (jsx(Button, { appearance: "subtle", "aria-label": "Close", icon: jsx(Dismiss24Regular, {}), onClick: () => { var _a; return (_a = props.onTableViewDelete) === null || _a === void 0 ? void 0 : _a.call(props, view); } }))] }), view.id + view.viewName));
|
|
1103
|
+
})] }))] })), jsx(DrawerFooter, { children: jsxs(MenuList, { children: [jsx(MenuDivider, {}), jsx(MenuItem, Object.assign({ icon: jsx(ClearFilterIcon, {}), onClick: resetAllFilters }, { children: "Clear All Filters" })), jsx(MenuItem, Object.assign({ icon: jsx(ClearFilterIcon, {}), onClick: resetAllGrouping }, { children: "Clear All Grouping" })), jsx(MenuItem, Object.assign({ icon: jsx(ClearFilterIcon, {}), onClick: clearAllSelection }, { children: "Clear All Selection" }))] }) })] })));
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1023
1106
|
function AdvancedTable(props, ref) {
|
|
1024
1107
|
useStaticStyles();
|
|
1025
|
-
const { table, globalFilter, headerMenu, tableViews, setGlobalFilter, resetToDefaultView, applyTableState } = useGridContainer(props, ref);
|
|
1108
|
+
const { table, globalFilter, headerMenu, tableViews, setGlobalFilter, resetToDefaultView, applyTableState, getTableState } = useGridContainer(props, ref);
|
|
1026
1109
|
const [isFilterDrawerOpen, setIsFilterDrawerOpen] = React.useState(false);
|
|
1027
|
-
|
|
1110
|
+
const [isViewsDrawerOpen, setIsViewsDrawerOpen] = React.useState(false);
|
|
1111
|
+
return (jsxs(DndProvider, Object.assign({ backend: HTML5Backend }, { children: [jsx(GridHeader, { table: table, gridTitle: props.gridTitle, headerMenu: headerMenu, globalFilter: globalFilter, openFilterDrawer: isFilterDrawerOpen, openViewsDrawer: isViewsDrawerOpen, setGlobalFilter: setGlobalFilter, setFilterDrawerOpen: setIsFilterDrawerOpen, setViewsDrawerOpen: setIsViewsDrawerOpen, applyTableState: applyTableState }), jsxs("div", Object.assign({ style: { display: 'flex' } }, { children: [jsx(TableContainer, { table: table, data: props.data, isLoading: props.isLoading || false, rowSelectionMode: props.rowSelectionMode, noFilterMatchPage: props.noFilterMatchPage, noItemPage: props.noItemPage }), jsx(FilterDrawer, { open: isFilterDrawerOpen, setOpen: setIsFilterDrawerOpen, table: table }), jsx(ViewsDrawer, { table: table, open: isViewsDrawerOpen, setOpen: setIsViewsDrawerOpen, tableViews: tableViews, applyTableState: applyTableState, resetToGridDefaultView: resetToDefaultView, getTableState: getTableState, onTableViewSave: props.onTableViewSave, onTableViewDelete: props.onTableViewDelete })] })), jsx(Pagination, { table: table, pageSizeOptions: props.pageSizeOptions })] })));
|
|
1028
1112
|
}
|
|
1029
1113
|
const ForwardedAdvancedTable = React.forwardRef(AdvancedTable);
|
|
1030
1114
|
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prt-ts/fluent-react-table-v2",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.41.0-build.2.0",
|
|
4
4
|
"main": "./index.js",
|
|
5
5
|
"types": "./src\\index.d.ts",
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"react": ">=17.0.0",
|
|
8
8
|
"react-dom": ">=17.0.0",
|
|
9
|
-
"@fluentui/react-components": ">=9.
|
|
9
|
+
"@fluentui/react-components": ">=9.41.0",
|
|
10
10
|
"@fluentui/react-datepicker-compat": ">=0.4.5",
|
|
11
11
|
"@fluentui/react-icons": ">=2.0.221"
|
|
12
12
|
},
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Table, TableState } from '@tanstack/react-table';
|
|
3
|
-
import { TableView } from '../../types';
|
|
4
3
|
type GridHeaderProps<TItem extends object> = {
|
|
5
4
|
table: Table<TItem>;
|
|
6
5
|
gridTitle: JSX.Element | React.ReactNode;
|
|
7
6
|
headerMenu?: JSX.Element | React.ReactNode;
|
|
8
7
|
globalFilter: string;
|
|
9
8
|
setGlobalFilter: (value: string) => void;
|
|
10
|
-
tableViews: TableView[];
|
|
11
9
|
applyTableState: (tableState: Partial<TableState>) => boolean;
|
|
12
10
|
openFilterDrawer: boolean;
|
|
13
11
|
setFilterDrawerOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
14
|
-
|
|
12
|
+
openViewsDrawer: boolean;
|
|
13
|
+
setViewsDrawerOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
15
14
|
};
|
|
16
15
|
export declare const GridHeader: <TItem extends object>(props: GridHeaderProps<TItem>) => import("react/jsx-runtime").JSX.Element;
|
|
17
16
|
export {};
|
|
@@ -10,4 +10,5 @@ export declare const useGridContainer: <TItem extends object>(props: TableProps<
|
|
|
10
10
|
setGlobalFilter: React.Dispatch<React.SetStateAction<string>>;
|
|
11
11
|
resetToDefaultView: () => boolean;
|
|
12
12
|
applyTableState: (tableState: Partial<TableState>) => boolean;
|
|
13
|
+
getTableState: () => Partial<TableState>;
|
|
13
14
|
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TableProps } from "../../types";
|
|
2
|
+
import { TableState } from '@tanstack/react-table';
|
|
3
|
+
type ViewSaveFormProps<TItem extends object> = {
|
|
4
|
+
mode: 'create' | 'edit';
|
|
5
|
+
onSave: TableProps<TItem>['onTableViewSave'];
|
|
6
|
+
getTableState: () => Partial<TableState>;
|
|
7
|
+
};
|
|
8
|
+
export declare const ViewSaveForm: <TItem extends object>(props: ViewSaveFormProps<TItem>) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { TableProps, TableView } from '../../types';
|
|
3
|
+
import { Table, TableState } from '@tanstack/react-table';
|
|
4
|
+
type ViewsDrawerProps<TItem extends object> = {
|
|
5
|
+
open: boolean;
|
|
6
|
+
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
7
|
+
table: Table<TItem>;
|
|
8
|
+
tableViews: TableView[];
|
|
9
|
+
applyTableState: (tableView: Partial<TableState>) => void;
|
|
10
|
+
resetToGridDefaultView: () => boolean;
|
|
11
|
+
getTableState: () => Partial<TableState>;
|
|
12
|
+
onTableViewSave?: TableProps<TItem>['onTableViewSave'];
|
|
13
|
+
onTableViewDelete?: TableProps<TItem>['onTableViewDelete'];
|
|
14
|
+
};
|
|
15
|
+
export declare const ViewsDrawer: <TItem extends object>(props: ViewsDrawerProps<TItem>) => import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
package/src/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { FilterFn } from "@tanstack/react-table";
|
|
2
2
|
declare module '@tanstack/table-core' {
|
|
3
3
|
interface FilterFns {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
arrIncludesSome: FilterFn<unknown>;
|
|
5
|
+
matchDate: FilterFn<unknown>;
|
|
6
|
+
inDateRange: FilterFn<unknown>;
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
export { Table } from "./components";
|
|
@@ -84,4 +84,12 @@ export type TableProps<TItem extends object> = {
|
|
|
84
84
|
* Table Views
|
|
85
85
|
*/
|
|
86
86
|
views?: TableView[];
|
|
87
|
+
/**
|
|
88
|
+
* Callback when a table view is saved
|
|
89
|
+
*/
|
|
90
|
+
onTableViewSave?: (tableView: TableView) => void;
|
|
91
|
+
/**
|
|
92
|
+
* Callback when a table view is deleted
|
|
93
|
+
*/
|
|
94
|
+
onTableViewDelete?: (tableView: TableView) => void;
|
|
87
95
|
};
|