Skip to content

Commit cf7c36a

Browse files
authored
Fix: Enable search history by default for Search Box (#2566)
* make enable search history true by default * fix: debounceTime being shadowed (linting) * check for normal debounce time input * remove redundant comment * minimum debounce value for search history * remove search history debounce input * incorporate debounce time in test * added test for higher debounce time * search history default enabled test
1 parent d9db405 commit cf7c36a

File tree

2 files changed

+88
-11
lines changed

2 files changed

+88
-11
lines changed

projects/components/src/search-box/search-box.component.test.ts

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,21 @@ describe('Search box Component', () => {
119119
});
120120
}));
121121

122+
test('search history should be enabled by default', fakeAsync(() => {
123+
spectator = createHost(
124+
`<ht-search-box [placeholder]="placeholder" [debounceTime]="debounceTime" [searchMode]="searchMode"></ht-search-box>`,
125+
{
126+
hostProps: {
127+
placeholder: 'Test Placeholder',
128+
debounceTime: 200,
129+
searchMode: SearchBoxEmitMode.Incremental,
130+
},
131+
},
132+
);
133+
134+
expect(spectator.component.enableSearchHistory).toBe(true);
135+
}));
136+
122137
test('enabled search history should work as expected', fakeAsync(() => {
123138
spectator = createHost(
124139
`<ht-search-box [placeholder]="placeholder" [debounceTime]="debounceTime" [searchMode]="searchMode" [enableSearchHistory]="enableSearchHistory"></ht-search-box>`,
@@ -144,16 +159,61 @@ describe('Search box Component', () => {
144159
spectator.setInput({ value: 'test-value' });
145160
spectator.triggerEventHandler('input', 'input', 'test-value');
146161
expect(searchBoxELement).toHaveClass('has-value');
147-
spectator.tick(500);
162+
163+
spectator.tick(1500);
164+
165+
expect(spectator.inject(PopoverService).drawPopover).not.toHaveBeenCalled();
148166

149167
inputElement.blur();
150168
spectator.click('.icon.close');
151-
spectator.tick(500);
169+
spectator.tick(1500);
152170
expect(spectator.inject(PopoverService).drawPopover).toHaveBeenCalled();
153171

154172
flush();
155173
}));
156174

175+
test('enabled search history should work as expected for high debounce time', fakeAsync(() => {
176+
const debounceTime = 3000;
177+
spectator = createHost(
178+
`<ht-search-box [placeholder]="placeholder" [debounceTime]="debounceTime" [searchMode]="searchMode" [enableSearchHistory]="enableSearchHistory"></ht-search-box>`,
179+
{
180+
hostProps: {
181+
placeholder: 'Test Placeholder',
182+
debounceTime: debounceTime,
183+
searchMode: SearchBoxEmitMode.Incremental,
184+
enableSearchHistory: true,
185+
},
186+
},
187+
);
188+
189+
const searchBoxELement = spectator.query('.ht-search-box')!;
190+
expect(searchBoxELement).not.toHaveClass('has-value');
191+
expect(searchBoxELement).not.toHaveClass('focused');
192+
193+
spectator.click('.icon.search');
194+
expect(searchBoxELement).toHaveClass('focused');
195+
expect(spectator.inject(PopoverService).drawPopover).toHaveBeenCalledTimes(1);
196+
197+
const inputElement = spectator.query('input') as HTMLInputElement;
198+
spectator.setInput({ value: 'test-value' });
199+
spectator.triggerEventHandler('input', 'input', 'test-value');
200+
expect(searchBoxELement).toHaveClass('has-value');
201+
202+
// popover not called before debounce is over
203+
expect(spectator.inject(PopoverService).drawPopover).toHaveBeenCalledTimes(1);
204+
205+
spectator.tick(debounceTime + 100);
206+
207+
expect(spectator.inject(PopoverService).drawPopover).toHaveBeenCalledTimes(1);
208+
209+
inputElement.blur();
210+
spectator.click('.icon.close');
211+
spectator.tick(debounceTime + 100);
212+
expect(spectator.inject(PopoverService).drawPopover).toHaveBeenCalledTimes(2);
213+
214+
flush();
215+
}));
216+
157217
test('collapsable enabled should add collapsable class', () => {
158218
spectator = createHost(
159219
`<ht-search-box [placeholder]="placeholder" [debounceTime]="debounceTime" [searchMode]="searchMode" [enableSearchHistory]="enableSearchHistory" [collapsable]="collapsable"></ht-search-box>`,

projects/components/src/search-box/search-box.component.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
TypedSimpleChanges,
2222
} from '@hypertrace/common';
2323
import { combineLatest, Observable, Subject, timer } from 'rxjs';
24-
import { debounce, map } from 'rxjs/operators';
24+
import { debounce, debounceTime, map } from 'rxjs/operators';
2525
import { IconSize } from '../icon/icon-size';
2626
import { PopoverService } from '../popover/popover.service';
2727
import { PopoverRef } from '../popover/popover-ref';
@@ -111,7 +111,7 @@ export class SearchBoxComponent implements OnInit, OnChanges {
111111
public searchMode: SearchBoxEmitMode = SearchBoxEmitMode.Incremental;
112112

113113
@Input()
114-
public enableSearchHistory: boolean = false; // Experimental
114+
public enableSearchHistory: boolean = true;
115115

116116
@Input()
117117
public collapsable: boolean = false;
@@ -137,6 +137,8 @@ export class SearchBoxComponent implements OnInit, OnChanges {
137137

138138
public popover?: PopoverRef;
139139

140+
public defaultSearchHistoryDebounceTime = 1000;
141+
140142
public constructor(
141143
private readonly cdr: ChangeDetectorRef,
142144
private readonly host: ElementRef,
@@ -222,7 +224,7 @@ export class SearchBoxComponent implements OnInit, OnChanges {
222224
this.subscriptionLifecycle.unsubscribe();
223225
this.subscriptionLifecycle.add(
224226
combineLatest([this.debouncedValueSubject, this.getDebounceTime()])
225-
.pipe(debounce(([_, debounceTime]) => timer(debounceTime)))
227+
.pipe(debounce(([_, valueDebounceTime]) => timer(valueDebounceTime)))
226228
.subscribe(([value, _]) => this.valueChange.emit(value)),
227229
);
228230
}
@@ -260,12 +262,27 @@ export class SearchBoxComponent implements OnInit, OnChanges {
260262
}),
261263
);
262264

265+
// Use the default search history debounce time if the value debounce time is less than the default
266+
const searchHistoryDebounce =
267+
this.debounceTime && this.debounceTime > this.defaultSearchHistoryDebounceTime
268+
? 0
269+
: this.defaultSearchHistoryDebounceTime;
270+
263271
this.subscriptionLifecycle.add(
264-
this.valueChange.asObservable().subscribe(emittedValue => {
265-
if (!isEmpty(emittedValue)) {
266-
this.lastEmittedValues = [emittedValue, ...this.lastEmittedValues];
267-
}
268-
}),
272+
searchHistoryDebounce > 0
273+
? this.valueChange
274+
.asObservable()
275+
.pipe(debounceTime(searchHistoryDebounce))
276+
.subscribe(emittedValue => {
277+
if (!isEmpty(emittedValue)) {
278+
this.lastEmittedValues = [emittedValue, ...this.lastEmittedValues];
279+
}
280+
})
281+
: this.valueChange.asObservable().subscribe(emittedValue => {
282+
if (!isEmpty(emittedValue)) {
283+
this.lastEmittedValues = [emittedValue, ...this.lastEmittedValues];
284+
}
285+
}),
269286
);
270287
}
271288

@@ -296,7 +313,7 @@ export class SearchBoxComponent implements OnInit, OnChanges {
296313
}
297314

298315
private handleSearchHistoryOnInputBlur(): void {
299-
this.searchHistory = [...uniq(this.lastEmittedValues), ...this.searchHistory];
316+
this.searchHistory = uniq([...this.lastEmittedValues, ...this.searchHistory]);
300317
this.filteredSearchHistory = [...this.searchHistory];
301318
this.lastEmittedValues = [];
302319
}

0 commit comments

Comments
 (0)