UNPKG

@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
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;