Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions projects/components/src/combo-box/combo-box.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export class ComboBoxComponent<TValue = string> implements AfterViewInit, OnChan
public onOptionClick(option: ComboBoxOption<TValue>): void {
this.setText(option.text);
this.hidePopover();
this.input.nativeElement.focus();
this.focus();
this.selection.emit(this.buildResult());
}

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

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

public focus(): void {
this.input.nativeElement.focus();
}

private buildResult(): ComboBoxResult<TValue> {
return { text: this.text, option: this.findOption(this.text) };
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
Input,
OnChanges,
Expand All @@ -13,13 +12,15 @@ import {
} from '@angular/core';
import { IconType } from '@hypertrace/assets-library';
import { TypedSimpleChanges } from '@hypertrace/common';
import { isEqual } from 'lodash-es';
import { BehaviorSubject, Observable, Subscription } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
import { distinctUntilChanged, switchMap } from 'rxjs/operators';
import { IconSize } from '../../icon/icon-size';
import { Filter } from '../filter/filter';
import { FilterAttribute } from '../filter/filter-attribute';
import { FilterUrlService } from '../filter/filter-url.service';
import { FilterBarService } from './filter-bar.service';
import { FilterChipComponent } from './filter-chip/filter-chip.component';

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

@ViewChild('filterInput', { read: ElementRef })
public readonly filterInput!: ElementRef;
@ViewChild('filterInput')
public readonly filterInput?: FilterChipComponent;

public isFocused: boolean = false;

private readonly attributeSubject$: BehaviorSubject<FilterAttribute[]> = new BehaviorSubject<FilterAttribute[]>([]);
private readonly internalFiltersSubject$: BehaviorSubject<Filter[]> = new BehaviorSubject<Filter[]>([]);
public readonly internalFilters$: Observable<Filter[]> = this.internalFiltersSubject$.asObservable();
public readonly internalFilters$: Observable<Filter[]> = this.internalFiltersSubject$
.asObservable()
.pipe(distinctUntilChanged(isEqual));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optimization, but sometimes multiple things (such as a url change and a child output) cause a filter change to be picked up, and we want to dedupe.


private subscription?: Subscription;

Expand Down Expand Up @@ -123,7 +126,7 @@ export class FilterBarComponent implements OnChanges, OnInit, OnDestroy {

private subscribeToUrlFilterChanges(): void {
this.subscription = this.attributeSubject$
.pipe(mergeMap(attributes => this.filterUrlService.getUrlFiltersChanges$(attributes)))
.pipe(switchMap(attributes => this.filterUrlService.getUrlFiltersChanges$(attributes)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When attributes come after load, a mergemap led to multiple subscriptions

.subscribe(filters => this.onFiltersChanged(filters, true, false));
}

Expand Down Expand Up @@ -168,7 +171,7 @@ export class FilterBarComponent implements OnChanges, OnInit, OnDestroy {
}

private resetFocus(): void {
this.filterInput?.nativeElement.focus();
this.filterInput?.focus();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was the main change. We don't want to focus on the filter chip, we want to focus on the input inside it. Exposed focus method down the component stack.

}

private updateFilter(oldFilter: Filter, newFilter: Filter): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import {
ChangeDetectionStrategy,
Component,
EventEmitter,
Input,
OnChanges,
OnInit,
Output,
ViewChild
} from '@angular/core';
import { TypedSimpleChanges } from '@hypertrace/common';
import { ComboBoxMode, ComboBoxOption, ComboBoxResult } from '../../../combo-box/combo-box-api';
import { ComboBoxComponent } from '../../../combo-box/combo-box.component';
import { Filter, IncompleteFilter } from '../../filter/filter';
import { FilterAttribute } from '../../filter/filter-attribute';
import { FilterChipService } from './filter-chip.service';
Expand Down Expand Up @@ -43,6 +53,9 @@ export class FilterChipComponent implements OnInit, OnChanges {
@Output()
public readonly clear: EventEmitter<void> = new EventEmitter();

@ViewChild(ComboBoxComponent)
public readonly comboBox?: ComboBoxComponent;

public text?: string;
public options?: ComboBoxOption<IncompleteFilter>[];

Expand Down Expand Up @@ -86,6 +99,10 @@ export class FilterChipComponent implements OnInit, OnChanges {
this.clear.emit();
}

public focus(): void {
this.comboBox?.focus();
}

private isValidFilter(result: ComboBoxResult<IncompleteFilter>): result is ComboBoxResult<Filter> {
return result.option?.value !== undefined && result.option?.value.value !== undefined;
}
Expand Down