Skip to content

Commit 4baa67e

Browse files
Ethan Alvizoethanalvizo
authored andcommitted
feat: add contains ignore case in go to row
1 parent 02215b6 commit 4baa67e

4 files changed

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

packages/iris-grid/src/GotoRow.tsx

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

89-
const res = 'Row number';
90-
9189
const { rowCount } = model;
9290

9391
const handleGotoValueNumberKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
@@ -193,6 +191,7 @@ function GotoRow({
193191
);
194192
}}
195193
value={gotoValueFilter}
194+
data-testid="filter-type-select"
196195
>
197196
<option key={FilterType.eq} value={FilterType.eq}>
198197
Equals
@@ -204,7 +203,13 @@ function GotoRow({
204203
key={FilterType.eqIgnoreCase}
205204
value={FilterType.eqIgnoreCase}
206205
>
207-
EqIgnoreCase
206+
Equals (ignore case)
207+
</option>
208+
<option
209+
key={FilterType.containsIgnoreCase}
210+
value={FilterType.containsIgnoreCase}
211+
>
212+
Contains (ignore case)
208213
</option>
209214
</select>
210215
</div>
@@ -283,6 +288,7 @@ function GotoRow({
283288
<div className="goto-row-input">
284289
<input
285290
ref={gotoRowInputRef}
291+
data-testid="goto-row-input"
286292
type="number"
287293
onKeyDown={e => {
288294
if (e.key === 'Enter') {
@@ -294,7 +300,7 @@ function GotoRow({
294300
className={classNames('form-control', {
295301
'is-invalid': gotoRowError !== '',
296302
})}
297-
placeholder={res}
303+
placeholder="Row number"
298304
onChange={event => {
299305
onGotoRowNumberChanged(event);
300306
}}
@@ -331,6 +337,7 @@ function GotoRow({
331337
onGotoValueSelectedColumnNameChanged(columnName);
332338
}}
333339
value={gotoValueSelectedColumnName}
340+
data-testid="column-name-select"
334341
>
335342
{columns.map(column => (
336343
<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
@@ -3339,10 +3339,12 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
33393339
searchFromRow = 0;
33403340
}
33413341

3342-
const isContains = gotoValueSelectedFilter === FilterType.contains;
3343-
const isEquals =
3344-
gotoValueSelectedFilter === FilterType.eq ||
3345-
gotoValueSelectedFilter === FilterType.eqIgnoreCase;
3342+
const isContains =
3343+
gotoValueSelectedFilter === FilterType.contains ||
3344+
gotoValueSelectedFilter === FilterType.containsIgnoreCase;
3345+
const isIgnoreCase =
3346+
gotoValueSelectedFilter === FilterType.eqIgnoreCase ||
3347+
gotoValueSelectedFilter === FilterType.containsIgnoreCase;
33463348

33473349
try {
33483350
const { formatter } = model;
@@ -3358,7 +3360,7 @@ export class IrisGrid extends Component<IrisGridProps, IrisGridState> {
33583360
selectedColumn,
33593361
dh.ValueType.STRING,
33603362
inputString,
3361-
isEquals,
3363+
isIgnoreCase,
33623364
isContains,
33633365
isBackwards ?? false
33643366
);

0 commit comments

Comments
 (0)