UNPKG

@ackplus/react-tanstack-data-table

Version:

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

248 lines (247 loc) 11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCombinedFilteredRowModel = exports.CustomColumnFilterFeature = void 0; exports.matchesCustomColumnFilters = matchesCustomColumnFilters; const tslib_1 = require("tslib"); const react_table_1 = require("@tanstack/react-table"); const moment_1 = tslib_1.__importDefault(require("moment")); exports.CustomColumnFilterFeature = { getInitialState: (state) => { return Object.assign({ customColumnFilter: { filters: [], logic: 'AND', pendingFilters: [], pendingLogic: 'AND', } }, state); }, getDefaultOptions: (table) => { return { enableCustomColumnFilter: true, onCustomColumnFilterChange: (0, react_table_1.makeStateUpdater)('customColumnFilter', table), onCustomColumnFilterApply: (state) => { }, }; }, createTable: (table) => { table.setCustomColumnFilter = (updater) => { var _a, _b; const safeUpdater = (old) => { const newState = (0, react_table_1.functionalUpdate)(updater, old); return newState; }; return (_b = (_a = table.options).onCustomColumnFilterChange) === null || _b === void 0 ? void 0 : _b.call(_a, safeUpdater); }; table.addPendingColumnFilter = (columnId, operator, value) => { table.setCustomColumnFilter((old) => { const newFilter = { id: `filter_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`, columnId, operator, value, }; return Object.assign(Object.assign({}, old), { pendingFilters: [...old.pendingFilters, newFilter] }); }); }; table.updatePendingColumnFilter = (filterId, updates) => { table.setCustomColumnFilter((old) => { const updatedFilters = old.pendingFilters.map((filter) => filter.id === filterId ? Object.assign(Object.assign({}, filter), updates) : filter); return Object.assign(Object.assign({}, old), { pendingFilters: updatedFilters }); }); }; table.removePendingColumnFilter = (filterId) => { table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { pendingFilters: old.pendingFilters.filter((filter) => filter.id !== filterId) }))); }; table.clearAllPendingColumnFilters = () => { table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { pendingFilters: [] }))); }; table.setPendingFilterLogic = (logic) => { table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { pendingLogic: logic }))); }; table.applyPendingColumnFilters = () => { table.setCustomColumnFilter((old) => { const newState = Object.assign(Object.assign({}, old), { filters: [...old.pendingFilters], logic: old.pendingLogic }); setTimeout(() => { var _a, _b; (_b = (_a = table.options).onCustomColumnFilterApply) === null || _b === void 0 ? void 0 : _b.call(_a, newState); }, 0); return newState; }); }; table.addColumnFilter = (columnId, operator, value) => { table.setCustomColumnFilter((old) => { const newFilter = { id: `filter_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`, columnId, operator, value, }; return Object.assign(Object.assign({}, old), { filters: [...old.filters, newFilter] }); }); }; table.updateColumnFilter = (filterId, updates) => { table.setCustomColumnFilter((old) => { const updatedFilters = old.filters.map((filter) => filter.id === filterId ? Object.assign(Object.assign({}, filter), updates) : filter); return Object.assign(Object.assign({}, old), { filters: updatedFilters }); }); }; table.removeColumnFilter = (filterId) => { table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { filters: old.filters.filter((filter) => filter.id !== filterId) }))); }; table.clearAllColumnFilters = () => { table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { filters: [] }))); }; table.setFilterLogic = (logic) => { table.setCustomColumnFilter((old) => (Object.assign(Object.assign({}, old), { logic }))); }; table.getActiveColumnFilters = () => { const state = table.getState().customColumnFilter; return state.filters.filter((f) => f.columnId && f.operator); }; table.getPendingColumnFilters = () => { const state = table.getState().customColumnFilter; return state.pendingFilters.filter((f) => f.columnId && f.operator); }; table.getCustomColumnFilterState = () => { return table.getState().customColumnFilter; }; }, }; function matchesCustomColumnFilters(row, filters, logic = 'AND') { if (filters.length === 0) return true; const activeFilters = filters.filter((f) => f.columnId && f.operator); if (activeFilters.length === 0) return true; const results = activeFilters.map((filter) => { var _a; let columnValue; let columnType = filter.columnType || 'text'; try { const column = row.getAllCells().find((cell) => cell.column.id === filter.columnId); if (column) { columnValue = column.getValue(); if (!filter.columnType && column.column.columnDef && column.column.columnDef.type) { columnType = column.column.columnDef.type; } } } catch (error) { console.warn(`Error getting value for column ${filter.columnId}:`, error); columnValue = ((_a = row.original) === null || _a === void 0 ? void 0 : _a[filter.columnId]) || ''; } return evaluateFilterCondition(columnValue, filter.operator, filter.value, columnType); }); return logic === 'AND' ? results.every(Boolean) : results.some(Boolean); } const getCombinedFilteredRowModel = () => { return (table) => () => { var _a; const baseFilteredModel = (0, react_table_1.getFilteredRowModel)()(table)(); const { filters, logic } = (_a = table.getState().customColumnFilter) !== null && _a !== void 0 ? _a : { filters: [], logic: 'AND', }; if (!filters.length) return baseFilteredModel; const filteredRows = baseFilteredModel.rows.filter(row => matchesCustomColumnFilters(row, filters, logic)); const flatRows = []; const rowsById = {}; const addRow = (row) => { var _a; flatRows.push(row); rowsById[row.id] = row; (_a = row.subRows) === null || _a === void 0 ? void 0 : _a.forEach(addRow); }; filteredRows.forEach(addRow); return { rows: filteredRows, flatRows, rowsById, }; }; }; exports.getCombinedFilteredRowModel = getCombinedFilteredRowModel; function evaluateFilterCondition(columnValue, operator, filterValue, type = 'text') { function toMoment(val) { if (!val) return null; const m = (0, moment_1.default)(val); return m.isValid() ? m : null; } if (type === 'date') { const mCol = toMoment(columnValue); const mFilter = toMoment(filterValue); if (!mCol || !mFilter) return false; switch (operator) { case 'equals': return mCol.isSame(mFilter, 'day'); case 'notEquals': return !mCol.isSame(mFilter, 'day'); case 'after': return mCol.isAfter(mFilter, 'day'); case 'before': return mCol.isBefore(mFilter, 'day'); case 'isEmpty': return !columnValue; case 'isNotEmpty': return !!columnValue; default: return true; } } if (type === 'boolean') { switch (operator) { case 'is': if (filterValue === 'any') return true; if (filterValue === 'true') return (columnValue === true || columnValue === 'true' || columnValue === 1 || columnValue === '1' || columnValue === 'Yes' || columnValue === 'yes'); if (filterValue === 'false') return (columnValue === false || columnValue === 'false' || columnValue === 0 || columnValue === '0' || columnValue === 'No' || columnValue === 'no'); return false; default: return true; } } if (type === 'select') { if (operator === 'in' || operator === 'notIn') { if (Array.isArray(filterValue)) { if (operator === 'in') return filterValue.includes(columnValue); if (operator === 'notIn') return !filterValue.includes(columnValue); } return false; } if (operator === 'equals' || operator === 'notEquals') { return operator === 'equals' ? columnValue === filterValue : columnValue !== filterValue; } } switch (operator) { case 'contains': return String(columnValue).toLowerCase().includes(String(filterValue).toLowerCase()); case 'notContains': return !String(columnValue).toLowerCase().includes(String(filterValue).toLowerCase()); case 'startsWith': return String(columnValue).toLowerCase().startsWith(String(filterValue).toLowerCase()); case 'endsWith': return String(columnValue).toLowerCase().endsWith(String(filterValue).toLowerCase()); case 'isEmpty': return columnValue === null || columnValue === undefined || columnValue === ''; case 'isNotEmpty': return columnValue !== null && columnValue !== undefined && columnValue !== ''; case 'greaterThan': return Number(columnValue) > Number(filterValue); case 'greaterThanOrEqual': return Number(columnValue) >= Number(filterValue); case 'lessThan': return Number(columnValue) < Number(filterValue); case 'lessThanOrEqual': return Number(columnValue) <= Number(filterValue); default: return true; } }