Skip to content

Commit 2ba0f6c

Browse files
Ethan Alvizoethanalvizo
authored andcommitted
feat: add contains ignore case in go to row
1 parent 87fa2ef commit 2ba0f6c

4 files changed

Lines changed: 185 additions & 9 deletions

File tree

packages/filters/src/Type.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ export class Type {
3636

3737
static readonly notContains = 'notContains';
3838

39+
static readonly containsIgnoreCase = 'containsIgnoreCase';
40+
3941
static readonly startsWith = 'startsWith';
4042

4143
static readonly endsWith = 'endsWith';
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
import React from 'react';
2+
import { render, screen } from '@testing-library/react';
3+
import userEvent from '@testing-library/user-event';
4+
import {
5+
Type as FilterType,
6+
TypeValue as FilterTypeValue,
7+
} from '@deephaven/filters';
8+
import { TableUtils } from '@deephaven/jsapi-utils';
9+
import { IrisGridTestUtils } from '@deephaven/iris-grid';
10+
import GotoRow from './GotoRow';
11+
12+
function makeGotoRow({
13+
gotoRow = '',
14+
gotoRowError = '',
15+
gotoValueError = '',
16+
onGotoRowSubmit = jest.fn(),
17+
model = IrisGridTestUtils.makeModel(),
18+
onGotoRowNumberChanged = jest.fn(),
19+
onClose = jest.fn(),
20+
isShown = true,
21+
onEntering = jest.fn(),
22+
onEntered = jest.fn(),
23+
onExiting = jest.fn(),
24+
onExited = jest.fn(),
25+
gotoValueSelectedColumnName = '',
26+
gotoValue = '',
27+
gotoValueFilter = FilterType.eq,
28+
onGotoValueSelectedColumnNameChanged = jest.fn(),
29+
onGotoValueSelectedFilterChanged = jest.fn(),
30+
onGotoValueChanged = jest.fn(),
31+
onGotoValueSubmit = jest.fn(),
32+
} = {}) {
33+
return render(
34+
<GotoRow
35+
gotoRow={gotoRow}
36+
gotoRowError={gotoRowError}
37+
gotoValueError={gotoValueError}
38+
onGotoRowSubmit={onGotoRowSubmit}
39+
model={model}
40+
onGotoRowNumberChanged={onGotoRowNumberChanged}
41+
onClose={onClose}
42+
isShown={isShown}
43+
onEntering={onEntering}
44+
onEntered={onEntered}
45+
onExiting={onExiting}
46+
onExited={onExited}
47+
gotoValueSelectedColumnName={gotoValueSelectedColumnName}
48+
gotoValue={gotoValue}
49+
gotoValueFilter={gotoValueFilter as FilterTypeValue}
50+
onGotoValueSelectedColumnNameChanged={
51+
onGotoValueSelectedColumnNameChanged
52+
}
53+
onGotoValueSelectedFilterChanged={onGotoValueSelectedFilterChanged}
54+
onGotoValueChanged={onGotoValueChanged}
55+
onGotoValueSubmit={onGotoValueSubmit}
56+
/>
57+
);
58+
}
59+
60+
beforeEach(() => {
61+
jest.useFakeTimers();
62+
});
63+
64+
afterEach(() => {
65+
jest.useRealTimers();
66+
});
67+
68+
it('mounts and unmounts properly', () => {
69+
makeGotoRow();
70+
});
71+
72+
describe('Go to row', () => {
73+
it('calls onGotoRowSubmit on Enter key press', async () => {
74+
const user = userEvent.setup({ delay: null });
75+
const onGotoRowSubmitMock = jest.fn();
76+
const component = makeGotoRow({ onGotoRowSubmit: onGotoRowSubmitMock });
77+
78+
const inputElement = screen.getByRole('spinbutton');
79+
await user.type(inputElement, '{Enter}');
80+
81+
expect(onGotoRowSubmitMock).toHaveBeenCalledTimes(1);
82+
83+
component.unmount();
84+
});
85+
86+
it('does not call onGotoRowSubmit on non-Enter key press', async () => {
87+
const user = userEvent.setup({ delay: null });
88+
const onGotoRowSubmitMock = jest.fn();
89+
const component = makeGotoRow({ onGotoRowSubmit: onGotoRowSubmitMock });
90+
91+
const inputElement = screen.getByRole('spinbutton');
92+
await user.type(inputElement, 'a1`');
93+
94+
expect(onGotoRowSubmitMock).not.toHaveBeenCalled();
95+
96+
component.unmount();
97+
});
98+
99+
it('calls onGotoRowNumberChanged on number key press', async () => {
100+
const user = userEvent.setup({ delay: null });
101+
const onGotoRowNumberChangedMock = jest.fn();
102+
const component = makeGotoRow({
103+
onGotoRowNumberChanged: onGotoRowNumberChangedMock,
104+
});
105+
106+
const inputElement = screen.getByRole('spinbutton');
107+
await user.type(inputElement, '1');
108+
109+
expect(onGotoRowNumberChangedMock).toHaveBeenCalledTimes(1);
110+
111+
component.unmount();
112+
});
113+
});
114+
115+
describe('Go to value', () => {
116+
it('calls onGotoValueInputChanged when input value changes', async () => {
117+
const user = userEvent.setup({ delay: null });
118+
const onGotoValueInputChangedMock = jest.fn();
119+
const component = makeGotoRow({
120+
onGotoValueChanged: onGotoValueInputChangedMock,
121+
});
122+
123+
const inputElement = screen.getByPlaceholderText('value');
124+
await user.type(inputElement, 'a');
125+
126+
expect(onGotoValueInputChangedMock).toHaveBeenCalledTimes(1);
127+
128+
component.unmount();
129+
});
130+
131+
it('calls onGotoValueSelectedFilterChanged when select value changes', async () => {
132+
const user = userEvent.setup({ delay: null });
133+
const onGotoValueSelectedFilterChangedMock = jest.fn();
134+
135+
jest
136+
.spyOn(TableUtils, 'getNormalizedType')
137+
.mockImplementation(() => TableUtils.dataType.STRING);
138+
139+
const component = makeGotoRow({
140+
onGotoValueSelectedFilterChanged: onGotoValueSelectedFilterChangedMock,
141+
});
142+
143+
const inputElement = screen.getByTestId('filter-type-select');
144+
await user.selectOptions(inputElement, [FilterType.contains]);
145+
146+
expect(onGotoValueSelectedFilterChangedMock).toHaveBeenCalledTimes(1);
147+
148+
component.unmount();
149+
});
150+
151+
it('calls onGotoValueSelectedColumnNameChanged when select value changes', async () => {
152+
const user = userEvent.setup({ delay: null });
153+
const onGotoValueSelectedColumnNameChangedMock = jest.fn();
154+
const component = makeGotoRow({
155+
onGotoValueSelectedColumnNameChanged: onGotoValueSelectedColumnNameChangedMock,
156+
});
157+
158+
const inputElement = screen.getByTestId('column-name-select');
159+
await user.selectOptions(inputElement, ['1']);
160+
161+
expect(onGotoValueSelectedColumnNameChangedMock).toHaveBeenCalledTimes(1);
162+
163+
component.unmount();
164+
});
165+
});

packages/iris-grid/src/GotoRow.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,6 @@ function GotoRow({
8484
({ columns } = model.table);
8585
}
8686

87-
const res = 'Row number';
88-
8987
const { rowCount } = model;
9088

9189
const handleGotoValueNumberKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
@@ -191,6 +189,7 @@ function GotoRow({
191189
);
192190
}}
193191
value={gotoValueFilter}
192+
data-testid="filter-type-select"
194193
>
195194
<option key={FilterType.eq} value={FilterType.eq}>
196195
Equals
@@ -202,7 +201,13 @@ function GotoRow({
202201
key={FilterType.eqIgnoreCase}
203202
value={FilterType.eqIgnoreCase}
204203
>
205-
EqIgnoreCase
204+
Equals (ignore case)
205+
</option>
206+
<option
207+
key={FilterType.containsIgnoreCase}
208+
value={FilterType.containsIgnoreCase}
209+
>
210+
Contains (ignore case)
206211
</option>
207212
</select>
208213
</div>
@@ -281,6 +286,7 @@ function GotoRow({
281286
<div className="goto-row-input">
282287
<input
283288
ref={gotoRowInputRef}
289+
data-testid="goto-row-input"
284290
type="number"
285291
onKeyDown={e => {
286292
if (e.key === 'Enter') {
@@ -292,7 +298,7 @@ function GotoRow({
292298
className={classNames('form-control', {
293299
'is-invalid': gotoRowError !== '',
294300
})}
295-
placeholder={res}
301+
placeholder="Row number"
296302
onChange={event => {
297303
onGotoRowNumberChanged(event);
298304
}}
@@ -329,6 +335,7 @@ function GotoRow({
329335
onGotoValueSelectedColumnNameChanged(columnName);
330336
}}
331337
value={gotoValueSelectedColumnName}
338+
data-testid="column-name-select"
332339
>
333340
{columns.map(column => (
334341
<option key={column.name} value={column.name}>

packages/iris-grid/src/IrisGrid.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3315,10 +3315,12 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
33153315
searchFromRow = 0;
33163316
}
33173317

3318-
const isContains = gotoValueSelectedFilter === FilterType.contains;
3319-
const isEquals =
3320-
gotoValueSelectedFilter === FilterType.eq ||
3321-
gotoValueSelectedFilter === FilterType.eqIgnoreCase;
3318+
const isContains =
3319+
gotoValueSelectedFilter === FilterType.contains ||
3320+
gotoValueSelectedFilter === FilterType.containsIgnoreCase;
3321+
const isIgnoreCase =
3322+
gotoValueSelectedFilter === FilterType.eqIgnoreCase ||
3323+
gotoValueSelectedFilter === FilterType.containsIgnoreCase;
33223324

33233325
try {
33243326
const { formatter } = model;
@@ -3334,7 +3336,7 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
33343336
selectedColumn,
33353337
dh.ValueType.STRING,
33363338
inputString,
3337-
isEquals,
3339+
isIgnoreCase,
33383340
isContains,
33393341
isBackwards ?? false
33403342
);

0 commit comments

Comments
 (0)