UNPKG

@ackplus/react-tanstack-data-table

Version:

A powerful React data table component built with MUI and TanStack Table

617 lines (616 loc) 27.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useDataTableApi = useDataTableApi; const tslib_1 = require("tslib"); const react_1 = require("react"); const export_utils_1 = require("../utils/export-utils"); function useDataTableApi(props, ref) { const { table, data, idKey, globalFilter, customColumnsFilter, sorting, pagination, columnOrder, columnPinning, enhancedColumns, enablePagination, enableColumnPinning, initialPageIndex, initialPageSize, pageSize, selectMode = 'page', onSelectionChange, handleColumnFilterStateChange, onDataStateChange, onFetchData, onDataChange, exportFilename = 'export', onExportProgress, onExportComplete, onExportError, onServerExport, exportController, setExportController, isExporting, dataMode = 'client', } = props; (0, react_1.useImperativeHandle)(ref, () => ({ table: { getTable: () => table, }, columnVisibility: { showColumn: (columnId) => { var _a; (_a = table.getColumn(columnId)) === null || _a === void 0 ? void 0 : _a.toggleVisibility(true); }, hideColumn: (columnId) => { var _a; (_a = table.getColumn(columnId)) === null || _a === void 0 ? void 0 : _a.toggleVisibility(false); }, toggleColumn: (columnId) => { var _a; (_a = table.getColumn(columnId)) === null || _a === void 0 ? void 0 : _a.toggleVisibility(); }, showAllColumns: () => { table.toggleAllColumnsVisible(true); }, hideAllColumns: () => { table.toggleAllColumnsVisible(false); }, resetColumnVisibility: () => { table.resetColumnVisibility(); }, }, columnOrdering: { setColumnOrder: (columnOrder) => { table.setColumnOrder(columnOrder); }, moveColumn: (columnId, toIndex) => { const currentOrder = table.getState().columnOrder || []; const currentIndex = currentOrder.indexOf(columnId); if (currentIndex === -1) return; const newOrder = [...currentOrder]; newOrder.splice(currentIndex, 1); newOrder.splice(toIndex, 0, columnId); table.setColumnOrder(newOrder); }, resetColumnOrder: () => { const initialOrder = enhancedColumns.map((col, index) => { if (col.id) return col.id; const anyCol = col; if (anyCol.accessorKey && typeof anyCol.accessorKey === 'string') { return anyCol.accessorKey; } return `column_${index}`; }); table.setColumnOrder(initialOrder); }, }, columnPinning: { pinColumnLeft: (columnId) => { const currentPinning = table.getState().columnPinning; const newPinning = Object.assign({}, currentPinning); newPinning.right = (newPinning.right || []).filter(id => id !== columnId); newPinning.left = [...(newPinning.left || []).filter(id => id !== columnId), columnId]; table.setColumnPinning(newPinning); }, pinColumnRight: (columnId) => { const currentPinning = table.getState().columnPinning; const newPinning = Object.assign({}, currentPinning); newPinning.left = (newPinning.left || []).filter(id => id !== columnId); newPinning.right = [...(newPinning.right || []).filter(id => id !== columnId), columnId]; table.setColumnPinning(newPinning); }, unpinColumn: (columnId) => { const currentPinning = table.getState().columnPinning; const newPinning = { left: (currentPinning.left || []).filter(id => id !== columnId), right: (currentPinning.right || []).filter(id => id !== columnId), }; table.setColumnPinning(newPinning); }, setPinning: (pinning) => { table.setColumnPinning(pinning); }, resetColumnPinning: () => { table.setColumnPinning(table.initialState.columnPinning); }, }, columnResizing: { resizeColumn: (columnId, width) => { const currentSizing = table.getState().columnSizing; table.setColumnSizing(Object.assign(Object.assign({}, currentSizing), { [columnId]: width })); }, autoSizeColumn: (columnId) => { var _a; (_a = table.getColumn(columnId)) === null || _a === void 0 ? void 0 : _a.resetSize(); }, autoSizeAllColumns: () => { table.resetColumnSizing(); }, resetColumnSizing: () => { table.resetColumnSizing(); }, }, filtering: { setGlobalFilter: (filter) => { table.setGlobalFilter(filter); }, clearGlobalFilter: () => { table.setGlobalFilter(''); }, setCustomColumnFilters: (filters) => { handleColumnFilterStateChange(filters); }, addColumnFilter: (columnId, operator, value) => { const newFilter = { id: `filter_${Date.now()}`, columnId, operator, value, }; const currentFilters = customColumnsFilter.filters || []; const newFilters = [...currentFilters, newFilter]; handleColumnFilterStateChange({ filters: newFilters, logic: customColumnsFilter.logic, pendingFilters: customColumnsFilter.pendingFilters || [], pendingLogic: customColumnsFilter.pendingLogic || 'AND', }); }, removeColumnFilter: (filterId) => { const currentFilters = customColumnsFilter.filters || []; const newFilters = currentFilters.filter((f) => f.id !== filterId); handleColumnFilterStateChange({ filters: newFilters, logic: customColumnsFilter.logic, pendingFilters: customColumnsFilter.pendingFilters || [], pendingLogic: customColumnsFilter.pendingLogic || 'AND', }); }, clearAllFilters: () => { table.setGlobalFilter(''); handleColumnFilterStateChange({ filters: [], logic: 'AND', pendingFilters: [], pendingLogic: 'AND', }); }, resetFilters: () => { table.resetGlobalFilter(); handleColumnFilterStateChange({ filters: [], logic: 'AND', pendingFilters: [], pendingLogic: 'AND', }); }, }, sorting: { setSorting: (sortingState) => { table.setSorting(sortingState); }, sortColumn: (columnId, direction) => { const column = table.getColumn(columnId); if (!column) return; if (direction === false) { column.clearSorting(); } else { column.toggleSorting(direction === 'desc'); } }, clearSorting: () => { table.resetSorting(); }, resetSorting: () => { table.resetSorting(); }, }, pagination: { goToPage: (pageIndex) => { table.setPageIndex(pageIndex); }, nextPage: () => { table.nextPage(); }, previousPage: () => { table.previousPage(); }, setPageSize: (pageSize) => { table.setPageSize(pageSize); }, goToFirstPage: () => { table.setPageIndex(0); }, goToLastPage: () => { const pageCount = table.getPageCount(); if (pageCount > 0) { table.setPageIndex(pageCount - 1); } }, }, selection: { selectRow: (rowId) => { var _a; return (_a = table.selectRow) === null || _a === void 0 ? void 0 : _a.call(table, rowId); }, deselectRow: (rowId) => { var _a; return (_a = table.deselectRow) === null || _a === void 0 ? void 0 : _a.call(table, rowId); }, toggleRowSelection: (rowId) => { var _a; return (_a = table.toggleRowSelected) === null || _a === void 0 ? void 0 : _a.call(table, rowId); }, selectAll: () => { var _a; return (_a = table.selectAll) === null || _a === void 0 ? void 0 : _a.call(table); }, deselectAll: () => { var _a; return (_a = table.deselectAll) === null || _a === void 0 ? void 0 : _a.call(table); }, toggleSelectAll: () => { var _a; return (_a = table.toggleAllRowsSelected) === null || _a === void 0 ? void 0 : _a.call(table); }, getSelectionState: () => { var _a; return ((_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table)) || { ids: [], type: 'include' }; }, getSelectedRows: () => table.getSelectedRows(), getSelectedCount: () => table.getSelectedCount(), isRowSelected: (rowId) => table.getIsRowSelected(rowId) || false, }, data: { refresh: () => { const currentFilters = { globalFilter, customColumnsFilter: customColumnsFilter, sorting, pagination, }; if (onDataStateChange) { const currentState = Object.assign(Object.assign({}, currentFilters), { columnOrder, columnPinning }); onDataStateChange(currentState); } if (onFetchData) { onFetchData(currentFilters); } }, reload: () => { const currentFilters = { globalFilter, customColumnsFilter: customColumnsFilter, sorting, pagination, }; if (onDataStateChange) { const currentState = Object.assign(Object.assign({}, currentFilters), { columnOrder, columnPinning }); onDataStateChange(Object.assign({}, currentState)); } if (onFetchData) { onFetchData(Object.assign({}, currentFilters)); } }, getAllData: () => { return [...data]; }, getRowData: (rowId) => { return data.find(row => String(row[idKey]) === rowId); }, getRowByIndex: (index) => { return data[index]; }, updateRow: (rowId, updates) => { const newData = data.map(row => String(row[idKey]) === rowId ? Object.assign(Object.assign({}, row), updates) : row); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, updateRowByIndex: (index, updates) => { const newData = [...data]; if (newData[index]) { newData[index] = Object.assign(Object.assign({}, newData[index]), updates); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); } }, insertRow: (newRow, index) => { const newData = [...data]; if (index !== undefined) { newData.splice(index, 0, newRow); } else { newData.push(newRow); } onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, deleteRow: (rowId) => { const newData = data.filter(row => String(row[idKey]) !== rowId); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, deleteRowByIndex: (index) => { const newData = [...data]; newData.splice(index, 1); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, deleteSelectedRows: () => { const selectedRowIds = Object.keys(table.getState().rowSelection) .filter(key => table.getState().rowSelection[key]); const newData = data.filter(row => !selectedRowIds.includes(String(row[idKey]))); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); table.resetRowSelection(); }, replaceAllData: (newData) => { onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, updateMultipleRows: (updates) => { const updateMap = new Map(updates.map(u => [u.rowId, u.data])); const newData = data.map(row => { const rowId = String(row[idKey]); const updateData = updateMap.get(rowId); return updateData ? Object.assign(Object.assign({}, row), updateData) : row; }); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, insertMultipleRows: (newRows, startIndex) => { const newData = [...data]; if (startIndex !== undefined) { newData.splice(startIndex, 0, ...newRows); } else { newData.push(...newRows); } onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, deleteMultipleRows: (rowIds) => { const idsToDelete = new Set(rowIds); const newData = data.filter(row => !idsToDelete.has(String(row[idKey]))); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, updateField: (rowId, fieldName, value) => { const newData = data.map(row => String(row[idKey]) === rowId ? Object.assign(Object.assign({}, row), { [fieldName]: value }) : row); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); }, updateFieldByIndex: (index, fieldName, value) => { const newData = [...data]; if (newData[index]) { newData[index] = Object.assign(Object.assign({}, newData[index]), { [fieldName]: value }); onDataChange === null || onDataChange === void 0 ? void 0 : onDataChange(newData); } }, findRows: (predicate) => { return data.filter(predicate); }, findRowIndex: (predicate) => { return data.findIndex(predicate); }, getDataCount: () => { return data.length; }, getFilteredDataCount: () => { return table.getFilteredRowModel().rows.length; }, }, layout: { resetLayout: () => { table.resetColumnSizing(); table.resetColumnVisibility(); table.resetSorting(); table.resetGlobalFilter(); }, resetAll: () => { table.resetColumnSizing(); table.resetColumnVisibility(); table.resetSorting(); table.resetGlobalFilter(); table.resetColumnOrder(); table.resetExpanded(); table.resetRowSelection(); table.resetColumnPinning(); handleColumnFilterStateChange({ filters: [], logic: 'AND', pendingFilters: [], pendingLogic: 'AND', }); if (enablePagination) { table.setPageIndex(initialPageIndex); table.setPageSize(initialPageSize || pageSize); } if (enableColumnPinning) { table.setColumnPinning({ left: [], right: [], }); } }, saveLayout: () => { return { columnVisibility: table.getState().columnVisibility, columnSizing: table.getState().columnSizing, columnOrder: table.getState().columnOrder, columnPinning: table.getState().columnPinning, sorting: table.getState().sorting, pagination: table.getState().pagination, globalFilter: table.getState().globalFilter, customColumnsFilter: customColumnsFilter, }; }, restoreLayout: (layout) => { if (layout.columnVisibility) { table.setColumnVisibility(layout.columnVisibility); } if (layout.columnSizing) { table.setColumnSizing(layout.columnSizing); } if (layout.columnOrder) { table.setColumnOrder(layout.columnOrder); } if (layout.columnPinning) { table.setColumnPinning(layout.columnPinning); } if (layout.sorting) { table.setSorting(layout.sorting); } if (layout.pagination && enablePagination) { table.setPagination(layout.pagination); } if (layout.globalFilter !== undefined) { table.setGlobalFilter(layout.globalFilter); } if (layout.customColumnsFilter) { handleColumnFilterStateChange(layout.customColumnsFilter); } }, }, state: { getTableState: () => { return table.getState(); }, getCurrentFilters: () => { return customColumnsFilter; }, getCurrentSorting: () => { return table.getState().sorting; }, getCurrentPagination: () => { return table.getState().pagination; }, getCurrentSelection: () => { return Object.keys(table.getState().rowSelection) .filter(key => table.getState().rowSelection[key]); }, }, export: { exportCSV: (...args_1) => tslib_1.__awaiter(this, [...args_1], void 0, function* (options = {}) { var _a; const { filename = exportFilename, } = options; try { const controller = new AbortController(); setExportController === null || setExportController === void 0 ? void 0 : setExportController(controller); if (dataMode === 'server' && onServerExport) { const currentFilters = { globalFilter, customColumnsFilter, sorting, pagination, columnOrder, columnPinning, }; yield (0, export_utils_1.exportServerData)(table, { format: 'csv', filename, fetchData: (filters, selection) => onServerExport(filters, selection), currentFilters, selection: (_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table), onProgress: onExportProgress, onComplete: onExportComplete, onError: onExportError, }); } else { yield (0, export_utils_1.exportClientData)(table, { format: 'csv', filename, onProgress: onExportProgress, onComplete: onExportComplete, onError: onExportError, }); } } catch (error) { onExportError === null || onExportError === void 0 ? void 0 : onExportError({ message: error.message || 'Export failed', code: 'EXPORT_ERROR', }); } finally { setExportController === null || setExportController === void 0 ? void 0 : setExportController(null); } }), exportExcel: (...args_1) => tslib_1.__awaiter(this, [...args_1], void 0, function* (options = {}) { var _a; const { filename = exportFilename } = options; try { const controller = new AbortController(); setExportController === null || setExportController === void 0 ? void 0 : setExportController(controller); if (dataMode === 'server' && onServerExport) { const currentFilters = { globalFilter, customColumnsFilter, sorting, pagination, columnOrder, columnPinning, }; yield (0, export_utils_1.exportServerData)(table, { format: 'excel', filename, fetchData: (filters, selection) => onServerExport(filters, selection), currentFilters, selection: (_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table), onProgress: onExportProgress, onComplete: onExportComplete, onError: onExportError, }); } else { yield (0, export_utils_1.exportClientData)(table, { format: 'excel', filename, onProgress: onExportProgress, onComplete: onExportComplete, onError: onExportError, }); } } catch (error) { onExportError === null || onExportError === void 0 ? void 0 : onExportError({ message: error.message || 'Export failed', code: 'EXPORT_ERROR', }); } finally { setExportController === null || setExportController === void 0 ? void 0 : setExportController(null); } }), exportServerData: (options) => tslib_1.__awaiter(this, void 0, void 0, function* () { var _a; const { format, filename = exportFilename, fetchData = onServerExport, } = options; if (!fetchData) { onExportError === null || onExportError === void 0 ? void 0 : onExportError({ message: 'No server export function provided', code: 'NO_SERVER_EXPORT', }); return; } try { const controller = new AbortController(); setExportController === null || setExportController === void 0 ? void 0 : setExportController(controller); const currentFilters = { globalFilter, customColumnsFilter, sorting, pagination, columnOrder, columnPinning, }; yield (0, export_utils_1.exportServerData)(table, { format, filename, fetchData: (filters, selection) => fetchData(filters, selection), currentFilters, selection: (_a = table.getSelectionState) === null || _a === void 0 ? void 0 : _a.call(table), onProgress: onExportProgress, onComplete: onExportComplete, onError: onExportError, }); } catch (error) { onExportError === null || onExportError === void 0 ? void 0 : onExportError({ message: error.message || 'Export failed', code: 'EXPORT_ERROR', }); } finally { setExportController === null || setExportController === void 0 ? void 0 : setExportController(null); } }), isExporting: () => isExporting || false, cancelExport: () => { exportController === null || exportController === void 0 ? void 0 : exportController.abort(); setExportController === null || setExportController === void 0 ? void 0 : setExportController(null); }, }, }), [ table, enhancedColumns, handleColumnFilterStateChange, customColumnsFilter, data, idKey, onDataStateChange, onFetchData, globalFilter, sorting, pagination, columnOrder, columnPinning, onDataChange, enableColumnPinning, enablePagination, initialPageIndex, initialPageSize, pageSize, exportFilename, onExportProgress, onExportComplete, onExportError, onServerExport, exportController, setExportController, isExporting, dataMode, selectMode, onSelectionChange, ]); }