@pagamio/frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
130 lines (129 loc) • 6.04 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { MantineReactTable, } from 'mantine-react-table';
import { useMemo, useState } from 'react';
import LoaderComponent from '../../components/ui/Loader';
const CoreTable = ({ columns, isLoading = false, data, sortable = false, sortConfig = null, onSort = () => { }, selectable = false, selectedRows = [], onSelectRow = () => { }, onSelectAll = () => { }, enablePagination = false, expandable = false, renderExpandableComponent, pagination, enableGlobalFilters, enableManualSorting, enableManualPagination, multiSorting, setSortBy, setSortDir, onRowClick, rowClassName, ...props }) => {
const [expanded, setExpanded] = useState({});
const hideHeaderConfig = (column) => {
return {
...column,
header: '',
enableSorting: false,
enableColumnFilter: false,
enableColumnActions: false,
mantineTableHeadCellProps: {
sx: {
svg: {
display: 'none',
},
},
},
};
};
const memoizedColumns = useMemo(() => {
return columns.map((column) => {
const { showHeader = true, ...rest } = column;
if (showHeader) {
return {
...rest,
enableSorting: sortable && !!onSort,
};
}
return hideHeaderConfig(column);
});
}, [columns, sortable, onSort]);
const memoizedData = useMemo(() => data, [data]);
const sortingState = useMemo(() => {
if (!sortConfig?.sortBy || !sortConfig?.sortDir)
return [];
return [{ id: sortConfig.sortBy, desc: sortConfig.sortDir === 'desc' }];
}, [sortConfig]);
const handleSortingChange = (updaterOrValue) => {
const newSorting = typeof updaterOrValue === 'function' ? updaterOrValue([]) : updaterOrValue;
if (!Array.isArray(newSorting) || newSorting.length === 0) {
return;
}
const [sort] = newSorting;
const sortKey = sort.id;
const sortDirection = sort.desc ? 'desc' : 'asc';
// Check if the sort config has actually changed before updating state
if (sortConfig?.sortBy !== sortKey || sortConfig?.sortDir !== sortDirection) {
setSortBy?.(sortKey);
setSortDir?.(sortDirection);
onSort?.(sortKey, sortDirection);
}
};
const handlePaginationChangeInternal = (updaterOrValue) => {
let newPagination;
if (typeof updaterOrValue === 'function') {
newPagination = updaterOrValue(pagination
? {
pageIndex: pagination.pageIndex,
pageSize: pagination.pageSize,
}
: { pageIndex: 0, pageSize: 10 });
}
else {
newPagination = updaterOrValue;
}
// Trigger the onPaginationChange callback to update server-side state
pagination?.onPaginationChange?.(newPagination.pageIndex, newPagination.pageSize);
// Optionally trigger the onPageChange callback if needed
pagination?.onPageChange?.(newPagination.pageIndex);
// Reset expanded rows when pagination changes
setExpanded({});
};
// Handle row click for Mantine React Table
const handleRowClick = (row, event) => {
// Prevent row click when clicking on buttons/links within the row
const target = event.target;
if (target.tagName === 'BUTTON' ||
target.tagName === 'A' ||
target.closest('button') ||
target.closest('a') ||
target.closest('[data-mantine-stop-propagation]') ||
target.closest('.mantine-ActionIcon-root')) {
return;
}
if (onRowClick) {
onRowClick(row.original);
}
};
return (_jsx(MantineReactTable, { columns: memoizedColumns, data: memoizedData, enableSorting: true, manualSorting: true, onSortingChange: handleSortingChange, enableRowSelection: selectable, enableGlobalFilter: enableGlobalFilters, onRowSelectionChange: (rowSelection) => { }, enableSelectAll: selectable, manualPagination: enableManualPagination, enablePagination: enablePagination, initialState: {
pagination: {
pageIndex: pagination?.pageIndex ?? 0,
pageSize: pagination?.pageSize ?? 10,
},
sorting: [],
}, state: {
isLoading: isLoading,
pagination: {
pageIndex: pagination?.pageIndex ?? 0,
pageSize: pagination?.pageSize ?? 10,
},
sorting: sortingState,
expanded,
}, onPaginationChange: handlePaginationChangeInternal, renderEmptyRowsFallback: () => (_jsxs("div", { style: { textAlign: 'center', padding: '20px', color: '#888' }, children: [_jsx("p", { children: "No data available" }), _jsx("p", { children: "Please adjust your filters or try again later." })] })), mantineTableContainerProps: {
sx: {
border: 'transparent',
borderRadius: '4px',
minHeight: '400px',
},
}, mantineLoadingOverlayProps: {
loader: _jsx(LoaderComponent, { size: "lg" }),
overlayColor: 'rgba(255, 255, 255, 0.8)',
overlayBlur: 2,
}, onExpandedChange: setExpanded, enableExpanding: expandable, renderDetailPanel: renderExpandableComponent, mantineTableBodyRowProps: ({ row }) => ({
onClick: (event) => handleRowClick(row, event),
sx: {
cursor: onRowClick ? 'pointer' : 'default',
'&:hover': onRowClick
? {
backgroundColor: 'rgba(0, 0, 0, 0.04)',
}
: {},
},
className: rowClassName,
}), ...props }));
};
export default CoreTable;