Skip to content
This repository was archived by the owner on Nov 14, 2023. It is now read-only.

Commit 88a46a9

Browse files
aaron-steinfeldjaywalker21
authored andcommitted
fix: incorrect focus on editing filter chips (hypertrace#1227)
1 parent 8dc3038 commit 88a46a9

File tree

3 files changed

+34
-10
lines changed

3 files changed

+34
-10
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
255255
public onOptionClick(option: ComboBoxOption<TValue>): void {
256256
this.setText(option.text);
257257
this.hidePopover();
258-
this.input.nativeElement.focus();
258+
this.focus();
259259
this.selection.emit(this.buildResult());
260260
}
261261

@@ -325,7 +325,7 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
325325
* This might just be a mac or browser specific thing, but when an input box gets tabbed into it doesn't
326326
* get focus, but the entire text content is selected. Let's use that to give ourselves focus as well.
327327
*/
328-
this.input.nativeElement.focus();
328+
this.focus();
329329
}
330330

331331
public onEscape(): void {
@@ -369,6 +369,10 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
369369
return this.createOption !== undefined && !isNil(this.text);
370370
}
371371

372+
public focus(): void {
373+
this.input.nativeElement.focus();
374+
}
375+
372376
private buildResult(): ComboBoxResult<TValue> {
373377
return { text: this.text, option: this.findOption(this.text) };
374378
}

projects/components/src/filtering/filter-bar/filter-bar.component.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import {
22
ChangeDetectionStrategy,
33
ChangeDetectorRef,
44
Component,
5-
ElementRef,
65
EventEmitter,
76
Input,
87
OnChanges,
@@ -13,13 +12,15 @@ import {
1312
} from '@angular/core';
1413
import { IconType } from '@hypertrace/assets-library';
1514
import { TypedSimpleChanges } from '@hypertrace/common';
15+
import { isEqual } from 'lodash-es';
1616
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
17-
import { mergeMap } from 'rxjs/operators';
17+
import { distinctUntilChanged, switchMap } from 'rxjs/operators';
1818
import { IconSize } from '../../icon/icon-size';
1919
import { Filter } from '../filter/filter';
2020
import { FilterAttribute } from '../filter/filter-attribute';
2121
import { FilterUrlService } from '../filter/filter-url.service';
2222
import { FilterBarService } from './filter-bar.service';
23+
import { FilterChipComponent } from './filter-chip/filter-chip.component';
2324

2425
@Component({
2526
selector: 'ht-filter-bar',
@@ -83,14 +84,16 @@ export class FilterBarComponent implements OnChanges, OnInit, OnDestroy {
8384
@Output()
8485
public readonly filtersChange: EventEmitter<Filter[]> = new EventEmitter();
8586

86-
@ViewChild('filterInput', { read: ElementRef })
87-
public readonly filterInput!: ElementRef;
87+
@ViewChild('filterInput')
88+
public readonly filterInput?: FilterChipComponent;
8889

8990
public isFocused: boolean = false;
9091

9192
private readonly attributeSubject$: BehaviorSubject<FilterAttribute[]> = new BehaviorSubject<FilterAttribute[]>([]);
9293
private readonly internalFiltersSubject$: BehaviorSubject<Filter[]> = new BehaviorSubject<Filter[]>([]);
93-
public readonly internalFilters$: Observable<Filter[]> = this.internalFiltersSubject$.asObservable();
94+
public readonly internalFilters$: Observable<Filter[]> = this.internalFiltersSubject$
95+
.asObservable()
96+
.pipe(distinctUntilChanged(isEqual));
9497

9598
private subscription?: Subscription;
9699

@@ -123,7 +126,7 @@ export class FilterBarComponent implements OnChanges, OnInit, OnDestroy {
123126

124127
private subscribeToUrlFilterChanges(): void {
125128
this.subscription = this.attributeSubject$
126-
.pipe(mergeMap(attributes => this.filterUrlService.getUrlFiltersChanges$(attributes)))
129+
.pipe(switchMap(attributes => this.filterUrlService.getUrlFiltersChanges$(attributes)))
127130
.subscribe(filters => this.onFiltersChanged(filters, true, false));
128131
}
129132

@@ -168,7 +171,7 @@ export class FilterBarComponent implements OnChanges, OnInit, OnDestroy {
168171
}
169172

170173
private resetFocus(): void {
171-
this.filterInput?.nativeElement.focus();
174+
this.filterInput?.focus();
172175
}
173176

174177
private updateFilter(oldFilter: Filter, newFilter: Filter): void {

projects/components/src/filtering/filter-bar/filter-chip/filter-chip.component.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
1-
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
1+
import {
2+
ChangeDetectionStrategy,
3+
Component,
4+
EventEmitter,
5+
Input,
6+
OnChanges,
7+
OnInit,
8+
Output,
9+
ViewChild
10+
} from '@angular/core';
211
import { TypedSimpleChanges } from '@hypertrace/common';
312
import { ComboBoxMode, ComboBoxOption, ComboBoxResult } from '../../../combo-box/combo-box-api';
13+
import { ComboBoxComponent } from '../../../combo-box/combo-box.component';
414
import { Filter, IncompleteFilter } from '../../filter/filter';
515
import { FilterAttribute } from '../../filter/filter-attribute';
616
import { FilterChipService } from './filter-chip.service';
@@ -43,6 +53,9 @@ export class FilterChipComponent implements OnInit, OnChanges {
4353
@Output()
4454
public readonly clear: EventEmitter<void> = new EventEmitter();
4555

56+
@ViewChild(ComboBoxComponent)
57+
public readonly comboBox?: ComboBoxComponent;
58+
4659
public text?: string;
4760
public options?: ComboBoxOption<IncompleteFilter>[];
4861

@@ -86,6 +99,10 @@ export class FilterChipComponent implements OnInit, OnChanges {
8699
this.clear.emit();
87100
}
88101

102+
public focus(): void {
103+
this.comboBox?.focus();
104+
}
105+
89106
private isValidFilter(result: ComboBoxResult<IncompleteFilter>): result is ComboBoxResult<Filter> {
90107
return result.option?.value !== undefined && result.option?.value.value !== undefined;
91108
}

0 commit comments

Comments
 (0)