Tighten Soma table filter and pinning state

active-uix
dev 5 months ago
parent 108c7ceb95
commit d52a1919c6

@ -123,6 +123,40 @@ describe('createTable', () => {
}
});
it('resets pagination when filters are removed or cleared', () => {
const { table, cleanup } = withTable<Person>({
data: () => people,
columns,
getRowId: (row) => row.id,
filtering: { enabled: true },
pagination: { enabled: true, pageSize: 1 }
});
try {
table.setColumnFilter('status', 'active');
flushSync();
table.setPageIndex(1);
flushSync();
expect(table.pagination.pageIndex).toBe(1);
table.removeColumnFilter('status');
flushSync();
expect(table.pagination.pageIndex).toBe(0);
table.setGlobalFilter('a');
flushSync();
table.setPageIndex(1);
flushSync();
expect(table.pagination.pageIndex).toBe(1);
table.clearFilters();
flushSync();
expect(table.pagination.pageIndex).toBe(0);
} finally {
cleanup();
}
});
it('paginates and clamps page navigation', () => {
const { table, cleanup } = withTable<Person>({
data: () => people,
@ -209,12 +243,13 @@ describe('createTable', () => {
data: () => people,
columns,
getRowId: (row) => row.id,
initialColumnPinning: { left: ['name'], right: ['age'] }
initialColumnPinning: { left: ['name', 'status'], right: ['age'] }
});
try {
expect(table.headers.map((header) => header.id)).toEqual(['name', 'status', 'score', 'age']);
expect(table.getPinnedOffset('name')).toBe(0);
expect(table.getIsColumnPinned('status')).toBe(false);
table.pinColumn('status', 'left');
flushSync();

@ -545,6 +545,12 @@ export function createTable<TData>(config: TableConfig<TData>): TableInstance<TD
// ── Filtering actions ────────────────────────────────────────────────
function resetPageForDataChange() {
if (!config.pagination?.enabled) return;
pagination = { ...pagination, pageIndex: 0 };
config.onPaginationChange?.(pagination);
}
function setColumnFilter(columnId: string, value: unknown) {
const existing = columnFilters.findIndex((f) => f.id === columnId);
if (existing >= 0) {
@ -553,25 +559,19 @@ export function createTable<TData>(config: TableConfig<TData>): TableInstance<TD
columnFilters = [...columnFilters, { id: columnId, value }];
}
config.onColumnFiltersChange?.(columnFilters);
// Reset to first page when filters change
if (config.pagination?.enabled) {
pagination = { ...pagination, pageIndex: 0 };
config.onPaginationChange?.(pagination);
}
resetPageForDataChange();
}
function removeColumnFilter(columnId: string) {
columnFilters = columnFilters.filter((f) => f.id !== columnId);
config.onColumnFiltersChange?.(columnFilters);
resetPageForDataChange();
}
function setGlobalFilter(value: string) {
globalFilter = value;
config.onGlobalFilterChange?.(value);
if (config.pagination?.enabled) {
pagination = { ...pagination, pageIndex: 0 };
config.onPaginationChange?.(pagination);
}
resetPageForDataChange();
}
function clearFilters() {
@ -579,6 +579,7 @@ export function createTable<TData>(config: TableConfig<TData>): TableInstance<TD
globalFilter = '';
config.onColumnFiltersChange?.([]);
config.onGlobalFilterChange?.('');
resetPageForDataChange();
}
function getColumnFilterValue(columnId: string): unknown {
@ -748,9 +749,12 @@ export function createTable<TData>(config: TableConfig<TData>): TableInstance<TD
// ── Column pinning actions ──────────────────────────────────────────
function getCanPin(columnId: string): boolean {
return resolvedColumns.find((c) => c.id === columnId)?.def.enablePinning === true;
}
function pinColumn(columnId: string, position: ColumnPinningPosition) {
const col = resolvedColumns.find((c) => c.id === columnId);
if (!col || col.def.enablePinning !== true) return;
if (!getCanPin(columnId)) return;
const left = (columnPinning.left ?? []).filter((id) => id !== columnId);
const right = (columnPinning.right ?? []).filter((id) => id !== columnId);
if (position === 'left') {
@ -770,6 +774,7 @@ export function createTable<TData>(config: TableConfig<TData>): TableInstance<TD
}
function getIsColumnPinned(columnId: string): false | ColumnPinningPosition {
if (!getCanPin(columnId)) return false;
if (columnPinning.left?.includes(columnId)) return 'left';
if (columnPinning.right?.includes(columnId)) return 'right';
return false;
@ -778,17 +783,23 @@ export function createTable<TData>(config: TableConfig<TData>): TableInstance<TD
function getLeftPinnedColumns(): ResolvedColumn<TData>[] {
return (columnPinning.left ?? [])
.map((id) => resolvedColumns.find((c) => c.id === id))
.filter((c): c is ResolvedColumn<TData> => !!c && getIsColumnVisible(c.id));
.filter(
(c): c is ResolvedColumn<TData> => !!c && getCanPin(c.id) && getIsColumnVisible(c.id)
);
}
function getRightPinnedColumns(): ResolvedColumn<TData>[] {
return (columnPinning.right ?? [])
.map((id) => resolvedColumns.find((c) => c.id === id))
.filter((c): c is ResolvedColumn<TData> => !!c && getIsColumnVisible(c.id));
.filter(
(c): c is ResolvedColumn<TData> => !!c && getCanPin(c.id) && getIsColumnVisible(c.id)
);
}
function getCenterColumns(): ResolvedColumn<TData>[] {
const pinned = new Set([...(columnPinning.left ?? []), ...(columnPinning.right ?? [])]);
const pinned = new Set(
[...(columnPinning.left ?? []), ...(columnPinning.right ?? [])].filter((id) => getCanPin(id))
);
return getVisibleColumns().filter((c) => !pinned.has(c.id));
}

Loading…
Cancel
Save

Powered by TurnKey Linux.