@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 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, Menu, MenuTrigger, MenuPopover, MenuList, MenuItem, MenuDivider, RadioGroup, Radio, Field, InlineDrawer, DrawerHeader, DrawerHeaderTitle, DrawerBody, Caption1Stronger, MenuButton, MenuGroup, mergeClasses, Skeleton, SkeletonItem, Subtitle2Stronger } 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, TextGrammarDismissRegular, Search24Regular, FilterDismissFilled, Dismiss24Regular, ArrowSortDown20Filled, ArrowSortDown20Regular, ArrowSortUp20Filled, ArrowSortUp20Regular, GroupListRegular, PinRegular, TextSortAscendingFilled, TextSortDescendingFilled, GroupDismissFilled, ArrowStepInLeftRegular, ArrowStepInRightRegular, PinOffRegular, DocumentSearch24Regular } from '@fluentui/react-icons';
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, applyTableState, tableViews } = props;
164
+ const { table, gridTitle, globalFilter, setGlobalFilter } = props;
165
165
  const styles = useGridHeaderStyles();
166
- const resetAllFilters = React.useCallback(() => {
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
- })] })) })] })), jsxs(Menu, { children: [jsx(MenuTrigger, Object.assign({ disableButtonEnhancement: true }, { children: jsx(Button
187
- // appearance="subtle"
188
- , {
189
- // appearance="subtle"
190
- icon: jsx(TextGrammarDismissRegular, {}), "aria-label": "View Menu" }) })), jsx(MenuPopover, { children: jsxs(MenuList, { children: [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" })), jsx(MenuDivider, {}), jsx(MenuItem, Object.assign({ icon: jsx(ClearFilterIcon, {}), onClick: props.resetToGridDefaultView }, { children: "Reset to Default View" })), tableViews.length > 0 && jsx(MenuDivider, {}), tableViews.map((view) => {
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(Button, { appearance: "subtle", title: 'Ad', icon: openFilterDrawer ? jsx(FilterDismissFilled, {}) : jsx(FilterFilled, {}), "aria-label": "View Menu", onClick: () => {
207
- setFilterDrawerOpen((open) => !open);
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
- includeArray: arrIncludesSome,
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 'includeArray':
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 'dateRange': {
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 'date': {
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: "Advance Filters" })) }), jsx(DrawerBody, Object.assign({ className: styles.drawerBody }, { children: headerGroups.map((headerGroup) => {
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
- return (jsxs(DndProvider, Object.assign({ backend: HTML5Backend }, { children: [jsx(GridHeader, { table: table, gridTitle: props.gridTitle, headerMenu: headerMenu, globalFilter: globalFilter, openFilterDrawer: isFilterDrawerOpen, setGlobalFilter: setGlobalFilter, setFilterDrawerOpen: setIsFilterDrawerOpen, resetToGridDefaultView: resetToDefaultView, tableViews: tableViews, 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(Pagination, { table: table, pageSizeOptions: props.pageSizeOptions })] })));
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.40.0-build.8.0",
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.40.0",
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
- resetToGridDefaultView: () => boolean;
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 {};
@@ -1,9 +1,9 @@
1
1
  import { FilterFn } from "@tanstack/react-table";
2
2
  declare module '@tanstack/table-core' {
3
3
  interface FilterFns {
4
- includeArray: FilterFn<unknown>;
5
- date: FilterFn<unknown>;
6
- dateRange: FilterFn<unknown>;
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
  };
@@ -3,5 +3,6 @@ export type TableView = {
3
3
  id: number;
4
4
  viewName: string;
5
5
  tableState: Partial<TableState>;
6
- isDefault?: boolean;
6
+ isGlobal?: boolean;
7
+ isViewOwner?: boolean;
7
8
  };