@maherunlocker/custom-react-table
Version:
dynamic table based on react table v7
430 lines • 30.1 kB
JavaScript
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React from 'react';
import KeyboardArrowRight from '@mui/icons-material/KeyboardArrowRight';
import KeyboardArrowUp from '@mui/icons-material/KeyboardArrowUp';
import { Box, Grid, TableContainer, TableSortLabel, Tooltip, } from '@mui/material';
import { Card, CardBody, CardFooter, CardHeader } from 'reactstrap';
import cx from 'classnames';
import { useColumnOrder, useExpanded, useFilters, useFlexLayout, useGlobalFilter, useGroupBy, usePagination, useResizeColumns, useRowSelect, useSortBy, useTable, } from 'react-table';
import { HeaderCheckbox, RawTable, RowCheckbox, TableBody, TableCell, TableHead, TableHeadCell, TableHeadRow, TableLabel, TableRow, useStyles, } from './TableStyle';
import { camelToWords, filterByReference, useDebounce, useLocalStorage, } from '../utils';
import { fuzzyTextFilter, numericTextFilter } from './filters';
import ChoiceIcon from './Choice';
import CollapsibleTable from './CollapsibleTable';
import { ColumnHidePageCustom } from './ColumnHidePageCustom';
import { CrossIcon } from '../components/assets/CrossIcon';
import DefaultGlobalFilter from './filters/defaultGlobalFilter';
import { FilterChipBar } from './FilterChipBar';
import { FilterIcon } from '../components/assets/FilterIcon';
import FilterModalMobile from './FilterModalMobile';
import { FilterPageCustom } from './FilterPageCustom';
import { IsMobileView } from './isMobileView';
import { ResizeHandle } from './ResizeHandle';
import { StyledH2 } from '../components/assets/StyledH2';
import SvgNoData from '../components/assets/SvgNoData';
import { TablePagination } from './TablePagination';
import { TableToolbar } from './TableToolbar';
import { TooltipCellRenderer } from './TooltipCell';
import DefaultColumnFilter from './DefaultColumnFilter';
import ControlledCheckbox from '../components/ControlledCheckbox';
function DefaultHeader({ column }) {
return _jsx(_Fragment, { children: column.id.startsWith('_') ? null : camelToWords(column.id) });
}
// yes this is recursive, but the depth never exceeds three so it seems safe enough
export const findFirstColumn = (columns) => columns[0].columns ? findFirstColumn(columns[0].columns) : columns[0];
const getStyles = (props, disableResizing = false, align = 'left') => [
props,
{
style: {
justifyContent: 'start',
alignItems: 'center',
display: 'flex',
},
},
];
const cellProps = (props, { cell }) => getStyles(props, cell.column && cell.column.disableResizing, cell.column && cell.column.align);
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/ban-types
const defaultColumn = {
//Filter: MultiSelectColumnFilter,
Filter: DefaultColumnFilter,
Cell: TooltipCellRenderer,
Header: DefaultHeader,
// When using the useFlexLayout:
minWidth: 10,
// width: 150, // width is used for both the flex-basis and flex-grow
maxWidth: 200, // maxWidth is only used as a limit for resizing
};
const filterTypes = {
fuzzyText: fuzzyTextFilter,
numeric: numericTextFilter,
multiSelect: (rows, id, filterValues) => {
if (filterValues.length === 0)
return rows;
return rows.filter((r) => filterValues.includes(r.values[id]));
},
};
const selectionHook = (hooks) => {
hooks.allColumns.push((columns) => [
// Let's make a column for selection
{
id: '_selector',
disableResizing: true,
disableGroupBy: true,
minWidth: 45,
width: 45,
maxWidth: 45,
Aggregated: undefined,
// The header can use the table's getToggleAllRowsSelectedProps method
// to render a checkbox
Header: ({ getToggleAllRowsSelectedProps }) => (_jsx(HeaderCheckbox, Object.assign({}, getToggleAllRowsSelectedProps()))),
// The cell can use the individual row's getToggleRowSelectedProps method
// to the render a checkbox
Cell: ({ row }) => (_jsx(RowCheckbox, Object.assign({}, row.getToggleRowSelectedProps()))),
},
...columns,
]);
};
const customSelectionHook = (hooks) => {
hooks.allColumns.push((columns) => [
// Let's make a column for selection
{
id: '_selector',
disableResizing: true,
disableGroupBy: true,
minWidth: 45,
width: 45,
maxWidth: 45,
Aggregated: undefined,
// The header can use the table's getToggleAllRowsSelectedProps method
// to render a checkbox
Header: ({ row, dispatch, flatRows, isAllRowsSelected, state, toggleAllRowsSelected, }) => (_jsx(ControlledCheckbox, { isHeader: true, toggleAllRowsSelected: toggleAllRowsSelected, row: row, allRows: flatRows, dispatchSelectedRows: dispatch, selectedFlatRows: flatRows, isAllRowsSelected: isAllRowsSelected, selectedRows: state.customSelectedRows, indeterminate: isAllRowsSelected ||
(flatRows.length > 0 &&
flatRows.length === state.customSelectedRows.length)
? false
: state.customSelectedRows.length > 0 })),
Cell: ({ row, dispatch, flatRows, isAllRowsSelected, state, toggleAllRowsSelected, selectedFlatRows, }) => (_jsx(ControlledCheckbox, { isHeader: false, row: row, allRows: flatRows, dispatchSelectedRows: dispatch, selectedFlatRows: selectedFlatRows, isAllRowsSelected: isAllRowsSelected, selectedRows: state.customSelectedRows, indeterminate: false })),
},
...columns,
]);
};
const customSelectionHookWithMoveleft = (hooks) => {
hooks.allColumns.push((columns) => [
// Let's make a column for selection
{
id: '_selector',
disableResizing: true,
disableGroupBy: true,
minWidth: 45,
width: 45,
maxWidth: 45,
Aggregated: undefined,
// The header can use the table's getToggleAllRowsSelectedProps method
// to render a checkbox
Header: ({ row, dispatch, flatRows, isAllRowsSelected, state, toggleAllRowsSelected, }) => (_jsx(ControlledCheckbox, { isHeader: true, toggleAllRowsSelected: toggleAllRowsSelected, row: row, allRows: flatRows, dispatchSelectedRows: dispatch, selectedFlatRows: flatRows, isAllRowsSelected: flatRows.length > 0 &&
flatRows.length === state.customSelectedRows.length, selectedRows: state.customSelectedRows, indeterminate: isAllRowsSelected ||
(flatRows.length > 0 &&
flatRows.length === state.customSelectedRows.length)
? false
: state.customSelectedRows.length > 0 })),
Cell: ({ row, dispatch, flatRows, isAllRowsSelected, state, toggleAllRowsSelected, selectedFlatRows, }) => (_jsx(ControlledCheckbox, { isHeader: false, row: row, allRows: flatRows, dispatchSelectedRows: dispatch, selectedFlatRows: selectedFlatRows, isAllRowsSelected: isAllRowsSelected, selectedRows: state.customSelectedRows, indeterminate: false, movedLeft: true })),
},
...columns,
]);
};
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
export const headerProps = (
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
props, { column }) => getStyles(props, column && column.disableResizing, column && column.align);
export function Table(_a) {
var { name, columns, canMovedCheckboxLeftOnExpand, onClick, canGroupBy, canSort, canSelect, setSelectedRows, customSelect, canResize, actionColumn, showGlobalFilter, showFilter, showColumnIcon, filterActive, setLocalFilterActive, customJsxSideFilterButton, defaultHiddenColumns, defaultPaginationValues, elevationTable, minHeight, maxHeight } = _a, props = __rest(_a, ["name", "columns", "canMovedCheckboxLeftOnExpand", "onClick", "canGroupBy", "canSort", "canSelect", "setSelectedRows", "customSelect", "canResize", "actionColumn", "showGlobalFilter", "showFilter", "showColumnIcon", "filterActive", "setLocalFilterActive", "customJsxSideFilterButton", "defaultHiddenColumns", "defaultPaginationValues", "elevationTable", "minHeight", "maxHeight"]);
// const { t } = useTranslation();
const classes = useStyles();
if (name === undefined || name === null) {
name = 'mytable';
}
const isMobile = IsMobileView();
const [initialState, setInitialState] = useLocalStorage(`tableState2:${name}`, {});
const customHooks = (hooks) => {
hooks.allColumns.push((columns) => [
...columns,
{
id: 'hidecolumns',
accessor: 'hidecolumns',
disableResizing: false,
disableGroupBy: true,
disableFilters: true,
disableSortBy: true,
canFilter: false,
minWidth: 60,
width: 60,
maxWidth: 100,
Header: () => (_jsxs("div", Object.assign({ className: "dropdown " }, { children: [_jsx("div", Object.assign({ id: "dropdownHideColomuns", "data-bs-toggle": "dropdown" }, { children: _jsx(ChoiceIcon, { height: 25, width: 25 }) })), _jsx("ul", Object.assign({ className: "dropdown-menu ", "aria-labelledby": "dropdownHideColomuns" }, { children: _jsx(ColumnHidePageCustom, { instance: instance }) }))] }))),
Cell(cell) {
const ActionColumnComponent = actionColumn;
return _jsx(ActionColumnComponent, { selectedRow: cell.row });
},
},
]);
};
const hooks = [
useColumnOrder,
useFilters,
useGlobalFilter,
useGroupBy,
useSortBy,
useExpanded,
useFlexLayout,
usePagination,
useResizeColumns,
useRowSelect,
];
// eslint-disable-next-line
let localHooks = hooks;
if (canSelect) {
if (customSelect) {
canMovedCheckboxLeftOnExpand !== undefined && canMovedCheckboxLeftOnExpand
? localHooks.push(customSelectionHookWithMoveleft)
: localHooks.push(customSelectionHook);
}
else {
localHooks.push(selectionHook);
}
}
if (actionColumn !== undefined) {
localHooks.push(customHooks);
}
const filterOptions = { filteredIds: [] };
const instance = useTable(Object.assign(Object.assign({}, props), { columns,
filterTypes,
defaultColumn,
// styledRows: [],
getSubRows: (row) => row.subRows, globalFilter: (rows, columnIds, filterValue) => DefaultGlobalFilter(rows, columnIds, filterValue, filterOptions), initialState: Object.assign(Object.assign({}, initialState), { customSelectedRows: [], hiddenColumns: defaultHiddenColumns }),
/* in test mode wip */
// useControlledState: (state) =>
// React.useMemo(
// () => ({
// ...state,
// selectedFlatRows: tata,
// // selectedRowIds: [...state.customSelectedRows.map((elm: any) => ({ [elm.id as Record<IdType<T> ]: true }))],
// // pageIndex: controlledPageIndex,
// }),
// [state]
// ),
stateReducer: (newState, action, prevState) => {
switch (action.type) {
case 'customSelectRow':
return Object.assign(Object.assign({}, newState), { customSelectedRows: [
...newState.customSelectedRows,
action.payload,
] });
case 'customUnSelectRow':
return Object.assign(Object.assign({}, newState), { customSelectedRows: [
...newState.customSelectedRows.filter((elm) => elm.id !== action.payload),
] });
case 'unSelectedNestedRows':
const filteredRows = filterByReference(newState.customSelectedRows, action.payload, false);
return Object.assign(Object.assign({}, newState), { customSelectedRows: filteredRows });
case 'selectedNestedRows':
return Object.assign(Object.assign({}, newState), { customSelectedRows: [
...newState.customSelectedRows,
...action.payload,
] });
case 'customSelectAll':
return Object.assign(Object.assign({}, newState), { customSelectedRows: action.payload });
case 'customUnSelectAll':
return Object.assign(Object.assign({}, newState), { customSelectedRows: [] });
default:
return newState;
}
} }), ...localHooks);
const { headerGroups, getTableBodyProps, page, prepareRow, state, selectedFlatRows, } = instance;
const debouncedState = useDebounce(state, 200);
const cellClickHandler = (cell) => () => {
onClick &&
!cell.column.isGrouped &&
!cell.row.isGrouped &&
cell.column.id !== '_selector' &&
onClick(cell.row);
};
React.useEffect(() => {
const { sortBy, filters, pageSize, columnResizing, hiddenColumns, selectedRowIds, } = debouncedState;
setInitialState({
sortBy,
filters,
pageSize,
columnResizing,
hiddenColumns,
selectedRowIds,
});
if (setSelectedRows !== undefined) {
if (instance.isAllRowsSelected) {
setSelectedRows(instance.flatRows.map((row) => (Object.assign(Object.assign({}, row.original), { depth: row.depth }))));
}
else if (customSelect !== undefined) {
setSelectedRows(state.customSelectedRows.map((row) => (Object.assign(Object.assign({}, row.original), { depth: row.depth }))));
}
else {
setSelectedRows(selectedFlatRows.map((row) => (Object.assign(Object.assign({}, row.original), { depth: row.depth }))));
}
}
// eslint-disable-next-line
}, [setInitialState, state.customSelectedRows]);
React.useEffect(() => {
!instance.isAllRowsSelected &&
instance.dispatch({ type: 'customUnSelectAll', payload: [] });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [instance.isAllRowsSelected]);
React.useEffect(() => {
instance.dispatch({ type: 'customUnSelectAll', payload: [] });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [instance.data, instance]);
return (_jsx(_Fragment, { children: !isMobile ? (_jsxs("div", Object.assign({ style: {
display: 'grid',
gridTemplateColumns: filterActive ? '2fr 1fr ' : 'auto',
gridColumnGap: '4px',
fontFamily: 'Segoe UI, -apple-system, Helvetica Neue, Arial',
} }, { children: [_jsxs(Card, Object.assign({ style: { border: '0px' } }, { children: [_jsxs(CardHeader, Object.assign({ id: "TableToolbar", className: !showGlobalFilter && !showFilter && !showColumnIcon
? 'd-none'
: classes.cardHeaderCss }, { children: [_jsx(TableToolbar, Object.assign({ instance: instance }, {
showGlobalFilter,
showFilter,
showColumnIcon,
filterActive,
setLocalFilterActive,
customJsxSideFilterButton,
})), _jsx(FilterChipBar, { instance: instance })] })), _jsx(CardBody, Object.assign({ id: name, style: {
marginRight: '0',
marginLeft: '0',
padding: 0,
paddingTop: '4px !important ',
border: '1px solid rgba(0,0,0,.125)',
} }, { children: _jsx(Grid, Object.assign({ container: true, id: "tablecontainer", direction: 'row', sx: { display: 'grid' } }, { children: _jsxs(TableContainer, Object.assign({ sx: {
paddingRight: '0!important',
paddingLeft: '0!important',
overflowX: 'auto',
overflowY: page.length === 0 ? 'hidden' : 'auto',
display: 'block',
width: '100%',
WebkitOverflowScrolling: 'touch',
MsOverflowStyle: '-ms-autohiding-scrollbar',
// flex: '1 1 auto',
paddingBottom: '1rem',
marginTop: '0 !important',
paddingTop: '0 !important',
maxHeight: maxHeight === 0 ||
maxHeight === '' ||
maxHeight === undefined
? '630px'
: maxHeight,
minHeight: minHeight === 0 ||
minHeight === '' ||
minHeight === undefined
? '580px'
: minHeight,
}, className: "table-responsive" }, { children: [_jsxs(RawTable, { children: [_jsx(TableHead, { children: headerGroups.map((headerGroup) => {
const _a = headerGroup.getHeaderGroupProps(), { key: headerGroupKey, title: headerGroupTitle, role: headerGroupRole } = _a, getHeaderGroupProps = __rest(_a, ["key", "title", "role"]);
return (_jsx(TableHeadRow, Object.assign({}, getHeaderGroupProps, { children: headerGroup.headers.map((column) => {
const style = {
textAlign: column.align
? column.align
: 'center ',
};
const _a = column.getHeaderProps(headerProps), { key: headerKey, role: headerRole } = _a, getHeaderProps = __rest(_a, ["key", "role"]);
const _b = column.getGroupByToggleProps(), { title: groupTitle = '' } = _b, columnGroupByProps = __rest(_b, ["title"]);
const _c = column.getSortByToggleProps({
title: 'Trier',
}), { title: sortTitle = '' } = _c, columnSortByProps = __rest(_c, ["title"]);
return (_jsxs(TableHeadCell, Object.assign({}, getHeaderProps, { className: `${column.id
.toLowerCase()
.includes('action') && classes.stickyCol} ${column.id
.toLowerCase()
.includes('hidecolumns') &&
classes.hide_colomns_sticky}` }, { children: [canGroupBy
? column.canGroupBy && (_jsx(Tooltip, Object.assign({ title: groupTitle }, { children: _jsx(TableSortLabel, Object.assign({ active: true,
// direction={column.isGrouped ? 'desc' : 'asc'}
IconComponent: KeyboardArrowRight }, columnGroupByProps, { className: classes.headerIcon })) })))
: null, column.canSort && canSort ? (_jsx(Tooltip, Object.assign({ title: sortTitle }, { children: _jsx(TableSortLabel, Object.assign({ active: column.isSorted, direction: column.isSortedDesc ? 'desc' : 'asc' }, columnSortByProps, { className: classes.tableSortLabel, style: { flexDirection: 'row-reverse' } }, { children: column.render('Header') })) }))) : (_jsx(TableLabel, Object.assign({ style: style }, { children: column.render('Header') }))), canResize
? column.canResize && (_jsx(ResizeHandle, { column: column }))
: null] }), headerKey));
}) }), headerGroupKey));
}) }), _jsx(TableBody, Object.assign({}, getTableBodyProps(), { className: page.length === 0 ? classes.SvgNoDataCss : '' }, { children: page.length !== 0
? page.map((row) => {
prepareRow(row);
const _a = row.getRowProps(), { key: rowKey, role: rowRole } = _a, getRowProps = __rest(_a, ["key", "role"]);
return (_jsx(TableRow, Object.assign({}, getRowProps, { className: cx({
rowSelected: row.isSelected,
clickable: onClick,
}) }, { children: row.cells.map((cell) => {
const _a = cell.getCellProps(cellProps), { key: cellKey, role: cellRole } = _a, getCellProps = __rest(_a, ["key", "role"]);
return (_jsx(TableCell, Object.assign({}, getCellProps, { onClick: cellClickHandler(cell), className: `${cellKey
.toLowerCase()
.includes('action') &&
classes.stickyCol} ${cellKey
.toLowerCase()
.includes('hidecolumns') &&
classes.hide_colomns_sticky}` }, { children: cell.isGrouped ? (_jsxs(_Fragment, { children: [_jsx(TableSortLabel, Object.assign({ classes: {
iconDirectionAsc: classes.iconDirectionAsc,
iconDirectionDesc: classes.iconDirectionDesc,
}, active: true, direction: row.isExpanded ? 'desc' : 'asc', IconComponent: KeyboardArrowUp }, row.getToggleRowExpandedProps(), { className: classes.cellIcon })), ' ', cell.render('Cell', {
editable: false,
}), ' ', "(", row.subRows.length, ")"] })) : cell.isAggregated ? (cell.render('Aggregated')) : cell.isPlaceholder ? null : (cell.render('Cell')) }), cellKey));
}) }), rowKey));
})
: null }))] }), _jsx("div", Object.assign({ className: page.length === 0 ? classes.SvgNoDataCss : 'd-none' }, { children: _jsx(SvgNoData, {}) }))] })) })) })), _jsx(CardFooter, Object.assign({ id: "TablePagination", style: {
backgroundColor: 'white',
border: '1px solid rgba(0,0,0,.125)',
borderTop: '0px',
borderRadius: '0px 0px 12px 12px',
} }, { children: _jsx(TablePagination, { instance: instance, defaultPaginationValues: defaultPaginationValues ? defaultPaginationValues : [] }) }))] })), filterActive ? (_jsxs(Card, Object.assign({ style: { border: '0px' } }, { children: [_jsxs(CardHeader, Object.assign({ style: {
display: 'flex',
alignItems: 'center',
// marginBottom: '2px',
maxHeight: '64px !important',
justifyContent: 'space-between',
}, className: `${classes.FiltersCss} ${classes.cardHeaderCss}` }, { children: [_jsxs(Box, Object.assign({ sx: {
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
paddingLeft: '10px',
} }, { children: [_jsx(FilterIcon, { className: classes.tableFilterAltOutlinedIcon, style: { flexDirection: 'row-reverse' } }), _jsx(StyledH2, Object.assign({ style: { marginBottom: 0 } }, { children: "Filtre(s)" }))] })), _jsx(CrossIcon, { style: { cursor: 'pointer' }, height: 11, width: 25, onClick: () => {
setLocalFilterActive(false);
} })] })), _jsx(CardBody, Object.assign({ id: "filterbody", style: {
marginRight: '0',
marginLeft: '0',
padding: 0,
paddingTop: '4px !important ',
border: '1px solid rgba(0,0,0,.125)',
backgroundColor: 'white',
borderTop: '1px solid rgba(0,0,0,.125)',
borderRadius: '0px 0px 12px 12px ',
// borderRadius: '20px 20px 12px 12px !important;',
} }, { children: _jsx(FilterPageCustom, { instance: instance, setLocalFilterActive: setLocalFilterActive, filterActive: filterActive, tableName: name }) }))] }))) : null] }))) : (_jsxs(React.Fragment, { children: [_jsxs(CardHeader, Object.assign({ id: "TablePagination", style: { marginBottom: '2px' }, className: !showGlobalFilter && !showFilter && !showColumnIcon
? 'd-none'
: classes.cardHeaderCss }, { children: [_jsx(TableToolbar, Object.assign({ instance: instance }, {
showGlobalFilter,
showFilter,
showColumnIcon,
filterActive,
setLocalFilterActive,
customJsxSideFilterButton,
})), _jsx(FilterChipBar, { instance: instance })] })), _jsx(CardBody, Object.assign({ id: name, style: {
marginRight: '0',
marginLeft: '0',
padding: 0,
paddingTop: '4px ',
minHeight: '100vh',
fontFamily: 'Segoe UI, -apple-system, Helvetica Neue, Arial',
} }, { children: _jsx(CollapsibleTable, { props: instance }) })), _jsx(CardFooter, Object.assign({ id: "TablePagination", style: { backgroundColor: 'white', padding: '0' } }, { children: _jsx(TablePagination, { instance: instance, defaultPaginationValues: defaultPaginationValues ? defaultPaginationValues : [] }) })), filterActive ? (_jsx(FilterModalMobile, { instance: instance, setLocalFilterActive: setLocalFilterActive, filterActive: filterActive, tableName: name })) : null] })) }));
}
//# sourceMappingURL=Table.js.map