Skip to content

Commit 87b2c33

Browse files
authored
fix: DH-22099: stop loading when input filter change has no effect on… (#2643)
… grid filters (#2639) - When Ctrl+E clears all filters, the grid's `clearAllFilters()` removes quick filters and stops loading. However, the input filter's debounced clear arrives later, triggering `startLoading('Filtering...')` in `componentDidUpdate`. Since the filters were already cleared, `applyInputFilters()` finds no changes, never calls `setState`, and the model update/stopLoading never fires - leaving the grid stuck. - Fix: make `applyInputFilters()` return whether filters actually changed. If no change occurred, immediately call `stopLoading()` to cancel the loading state that was optimistically started. - Add e2e test for Ctrl+E clear filters with input filter stuck in Filtering state - Manually tested in Core to verify fix - Cherry-picked from the fix for DH-22062 on main
1 parent 4e2a7d0 commit 87b2c33

2 files changed

Lines changed: 61 additions & 3 deletions

File tree

packages/iris-grid/src/IrisGrid.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -940,8 +940,13 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
940940
this.clearGridInputField();
941941
this.clearCrossColumSearch();
942942
}
943-
this.startLoading('Filtering...', { resetRanges: true });
944-
this.applyInputFilters(changedInputFilters, replaceExistingFilters);
943+
const isChanged = this.applyInputFilters(
944+
changedInputFilters,
945+
replaceExistingFilters
946+
);
947+
if (isChanged) {
948+
this.startLoading('Filtering...', { resetRanges: true });
949+
}
945950
}
946951

947952
if (isSelectingColumn !== prevProps.isSelectingColumn) {
@@ -1617,11 +1622,12 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
16171622
* and clears any existing quickFilters or advancedFilters on that column
16181623
* @param inputFilters Array of input filters to apply
16191624
* @param replaceExisting If true, new filters will replace the existing ones, instead of merging
1625+
* @returns True if any filters were changed as a result of this operation
16201626
*/
16211627
applyInputFilters(
16221628
inputFilters: InputFilter[],
16231629
replaceExisting = false
1624-
): void {
1630+
): boolean {
16251631
const { model } = this.props;
16261632
const { advancedFilters, quickFilters } = this.state;
16271633
const newAdvancedFilters = replaceExisting
@@ -1650,6 +1656,7 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
16501656
advancedFilters: newAdvancedFilters,
16511657
});
16521658
}
1659+
return isChanged;
16531660
}
16541661

16551662
/**

tests/table-clear-filter.spec.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { test, expect } from '@playwright/test';
2+
import {
3+
dragComponent,
4+
waitForLoadingDone,
5+
openTable,
6+
gotoPage,
7+
} from './utils';
8+
9+
test('ctrl+e clears input filter without getting stuck in Filtering state', async ({
10+
page,
11+
}) => {
12+
await gotoPage(page, '');
13+
14+
await openTable(page, 'all_types');
15+
16+
await test.step('add input filter', async () => {
17+
await page.getByRole('button', { name: 'Controls' }).click();
18+
19+
const inputFilter = page.getByRole('button', { name: 'Input Filter' });
20+
const target = page.getByText('Command History');
21+
const dropIndicator = page.locator('.lm_dragProxy');
22+
await dragComponent(inputFilter, target, dropIndicator);
23+
});
24+
25+
await test.step('configure input filter for Int column', async () => {
26+
await page.getByRole('combobox').selectOption({ label: 'Int' });
27+
await page.getByRole('button', { name: 'Save' }).click();
28+
await expect(page.getByPlaceholder('Enter value...')).toHaveCount(1);
29+
});
30+
31+
await test.step('set input filter value', async () => {
32+
await page.getByPlaceholder('Enter value...').click();
33+
await page.keyboard.type('>1000');
34+
await expect(page.getByPlaceholder('Enter value...')).toHaveValue('>1000');
35+
36+
await waitForLoadingDone(page);
37+
});
38+
39+
await test.step('clear all filters with Ctrl+E', async () => {
40+
// Click on the grid to ensure it has focus for the keyboard shortcut
41+
await page.locator('.iris-grid .grid-wrapper').click();
42+
43+
await page.keyboard.press('ControlOrMeta+e');
44+
45+
// Wait for any debounced updates to process (input filter debounce is ~400ms total)
46+
await page.waitForTimeout(1000);
47+
48+
// The table should NOT be stuck in a loading/filtering state
49+
await waitForLoadingDone(page);
50+
});
51+
});

0 commit comments

Comments
 (0)