Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 98 additions & 0 deletions packages/iris-grid/src/IrisGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import IrisGrid from './IrisGrid';
import IrisGridTestUtils from './IrisGridTestUtils';
import type IrisGridProxyModel from './IrisGridProxyModel';
import { isPartitionedGridModel } from './PartitionedGridModel';
import { type ReadonlyQuickFilterMap } from './CommonTypes';

jest.mock('@deephaven/grid', () => ({
...jest.requireActual('@deephaven/grid'),
Expand Down Expand Up @@ -650,3 +651,100 @@ describe('Advanced Filter', () => {
}
);
});

describe('updateQuickFilters', () => {
it('stores the map reference directly (no cloning) when called with a map', () => {
const component = makeComponent();
const filterMap: ReadonlyQuickFilterMap = new Map([
[0, { text: 'foo', filter: null }],
]);
act(() => {
component.updateQuickFilters(filterMap);
});
expect(component.state.quickFilters).toBe(filterMap);
});

it('stores EMPTY_MAP when called with null', () => {
const component = makeComponent();
// Seed a non-empty map first so we can confirm it is replaced
act(() => {
component.updateQuickFilters(
new Map([[0, { text: 'foo', filter: null }]])
);
});
act(() => {
component.updateQuickFilters(null);
});
expect(component.state.quickFilters.size).toBe(0);
});

it('re-applies quickFilters when the prop reference changes', () => {
const model = irisGridTestUtils.makeModel();
const ref = React.createRef<IrisGrid>();
const filter1: ReadonlyQuickFilterMap = new Map([
[0, { text: 'a', filter: null }],
]);
const filter2: ReadonlyQuickFilterMap = new Map([
[0, { text: 'b', filter: null }],
]);

const { rerender } = render(
<IrisGrid
ref={ref}
model={model}
settings={DEFAULT_SETTINGS}
quickFilters={filter1}
/>
);

act(() => undefined); // flush

// Swap to a new reference — componentDidUpdate should call updateQuickFilters
jest.spyOn(ref.current!, 'updateQuickFilters');

rerender(
<IrisGrid
ref={ref}
model={model}
settings={DEFAULT_SETTINGS}
quickFilters={filter2}
/>
);

expect(ref.current!.updateQuickFilters).toHaveBeenCalledWith(filter2);
expect(ref.current!.state.quickFilters).toBe(filter2);
});

it('does NOT re-apply quickFilters when the same reference is passed again', () => {
const model = irisGridTestUtils.makeModel();
const ref = React.createRef<IrisGrid>();
const filter: ReadonlyQuickFilterMap = new Map([
[0, { text: 'a', filter: null }],
]);

const { rerender } = render(
<IrisGrid
ref={ref}
model={model}
settings={DEFAULT_SETTINGS}
quickFilters={filter}
/>
);

act(() => undefined);

jest.spyOn(ref.current!, 'updateQuickFilters');

// Re-render with the exact same reference — should be a no-op
rerender(
<IrisGrid
ref={ref}
model={model}
settings={DEFAULT_SETTINGS}
quickFilters={filter}
/>
);

expect(ref.current!.updateQuickFilters).not.toHaveBeenCalled();
});
});
19 changes: 19 additions & 0 deletions packages/iris-grid/src/IrisGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1001,6 +1001,7 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
settings,
model,
customFilters,
quickFilters,
sorts,
getMetricCalculator,
} = this.props;
Expand Down Expand Up @@ -1058,6 +1059,9 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
if (sorts !== prevProps.sorts) {
this.updateSorts(sorts);
}
if (quickFilters !== prevProps.quickFilters) {
this.updateQuickFilters(quickFilters);
}
const { loadingScrimStartTime, loadingScrimFinishTime } = this;
if (loadingScrimStartTime != null && loadingScrimFinishTime != null) {
window.requestAnimationFrame(() => {
Expand Down Expand Up @@ -3016,6 +3020,21 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
this.grid?.forceUpdate();
}

updateQuickFilters(quickFilters: ReadonlyQuickFilterMap | null): void {
const { quickFilters: currentQuickFilters } = this.state;
if (quickFilters == null) {
if (currentQuickFilters.size === 0) {
return;
}
} else if (quickFilters === currentQuickFilters) {
return;
}

this.startLoading('Filtering...', { resetRanges: true });
this.setState({ quickFilters: quickFilters ?? EMPTY_MAP });
this.grid?.forceUpdate();
}

sortColumn(
modelColumn: ModelIndex,
direction: SortDirection = TableUtils.sortDirection.none,
Expand Down
Loading