Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
}

&.extra-small {
height: 30px;
height: 24px;
}

&.small {
Expand Down Expand Up @@ -98,6 +98,10 @@
&:hover {
background-color: $gray-1;
}

&.menu-with-background {
background-color: $gray-1;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { IconSize } from '../icon/icon-size';
import { SearchBoxDisplayMode } from '../search-box/search-box.component';
import { SelectOptionComponent } from '../select/select-option.component';
import { SelectSize } from '../select/select-size';
import { SelectTriggerDisplayMode } from '../select/select.component';
import { MultiSelectJustify } from './multi-select-justify';
@Component({
selector: 'ht-multi-select',
Expand Down Expand Up @@ -57,7 +58,8 @@ import { MultiSelectJustify } from './multi-select-justify';
this.triggerLabelDisplayMode,
this.popoverOpen ? 'open' : '',
this.size,
this.disabled ? 'disabled' : ''
this.disabled ? 'disabled' : '',
this.triggerDisplayMode
]"
#triggerContainer
>
Expand Down Expand Up @@ -171,6 +173,9 @@ export class MultiSelectComponent<V> implements ControlValueAccessor, AfterConte
@Input()
public justify: MultiSelectJustify = MultiSelectJustify.Left;

@Input()
public triggerDisplayMode?: SelectTriggerDisplayMode;

@Input()
public triggerLabelDisplayMode: TriggerLabelDisplayMode = TriggerLabelDisplayMode.Selection;

Expand Down Expand Up @@ -251,7 +256,7 @@ export class MultiSelectComponent<V> implements ControlValueAccessor, AfterConte
}

public isSelectedItem(item: SelectOptionComponent<V>): boolean {
return this.selected !== undefined && this.selected.filter(value => isEqual(value, item.value)).length > 0;
return Array.isArray(this.selected) && this.selected.filter(value => isEqual(value, item.value)).length > 0;
}

public preventClickDefault(event: Event): void {
Expand Down
23 changes: 21 additions & 2 deletions projects/components/src/select/select.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
width: 100%;
height: 36px;

&.extra-small {
height: 24px;
}

&.small {
height: 32px;
}
Expand Down Expand Up @@ -64,7 +68,7 @@
.trigger-content {
display: flex;
align-items: center;
padding: 0 8px;
padding-left: 8px;
height: 100%;

&.menu-with-border {
Expand All @@ -78,7 +82,7 @@
border-radius: 4px;

.trigger-label {
@include body-1-medium($gray-9);
@include body-2-medium();
}

.trigger-icon {
Expand Down Expand Up @@ -154,6 +158,8 @@
.select-content {
@include dropdown();
max-height: 204px;
display: flex;
flex-direction: column;

.select-option {
display: flex;
Expand Down Expand Up @@ -201,3 +207,16 @@
}
}
}

.search-bar {
display: flex;
height: 34px;
margin-top: 2px;
cursor: pointer;
font-size: 14px;
align-items: center;
}

.divider {
padding: 0 16px;
}
36 changes: 34 additions & 2 deletions projects/components/src/select/select.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ import {
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { IconType } from '@hypertrace/assets-library';
import { LoggerService, queryListAndChanges$, SubscriptionLifecycle, TypedSimpleChanges } from '@hypertrace/common';
import { isEqual } from 'lodash-es';
import { EMPTY, merge, Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { IconSize } from '../icon/icon-size';
import { SearchBoxDisplayMode } from '../search-box/search-box.component';
import { SelectControlOptionComponent, SelectControlOptionPosition } from './select-control-option.component';
import { SelectGroupPosition } from './select-group-position';
import { SelectJustify } from './select-justify';
Expand Down Expand Up @@ -115,12 +117,23 @@ import { SelectSize } from './select-size';
>
</ht-label
></ng-template>
<ht-icon class="trigger-icon" icon="${IconType.ChevronDown}" size="${IconSize.Small}"> </ht-icon>
<ht-icon class="trigger-icon" icon="${IconType.ChevronDown}" size="${IconSize.ExtraSmall}"> </ht-icon>
</div>
</div>
</ht-popover-trigger>
<ht-popover-content>
<div class="select-content" [ngStyle]="{ 'minWidth.px': triggerContainer.offsetWidth }">
<ng-container *ngIf="this.searchMode === '${SelectSearchMode.EmitOnly}'">
<ht-event-blocker event="click" [enabled]="true">
<ht-search-box
class="search-bar"
(valueChange)="this.searchOptions($event)"
[debounceTime]="200"
displayMode="${SearchBoxDisplayMode.NoBorder}"
></ht-search-box>
</ht-event-blocker>
<ht-divider class="divider"></ht-divider>
</ng-container>
<ng-container *htLetAsync="this.topControlItems$ as topControlItems">
<div *ngIf="topControlItems?.length !== 0">
<ng-container
Expand Down Expand Up @@ -206,9 +219,15 @@ export class SelectComponent<V> implements ControlValueAccessor, AfterContentIni
@Input()
public highlightSelected: boolean = true;

@Input()
public searchMode: SelectSearchMode = SelectSearchMode.Disabled;

@Output()
public readonly selectedChange: EventEmitter<V> = new EventEmitter<V>();

@Output()
public readonly searchValueChange: EventEmitter<string> = new EventEmitter<string>();

@ContentChildren(SelectOptionComponent)
public items?: QueryList<SelectOptionComponent<V>>;

Expand Down Expand Up @@ -258,14 +277,22 @@ export class SelectComponent<V> implements ControlValueAccessor, AfterContentIni
}

public isSelectedItem(item: SelectOptionComponent<V>): boolean {
return this.selected === item.value;
return isEqual(this.selected, item.value);
}

public updateGroupPosition(position: SelectGroupPosition): void {
this.groupPosition = position;
this.changeDetector.markForCheck();
}

public searchOptions(searchText: string): void {
if (this.searchMode === SelectSearchMode.Disabled) {
return;
}

this.searchValueChange.emit(searchText);
}

private buildObservableOfSelected(): Observable<SelectOption<V> | undefined> {
if (!this.items) {
return EMPTY;
Expand Down Expand Up @@ -339,3 +366,8 @@ export const enum SelectTriggerDisplayMode {
MenuWithBackground = 'menu-with-background',
Icon = 'icon'
}

export const enum SelectSearchMode {
Disabled = 'disabled', // Search is not available
EmitOnly = 'emit-only' // Current available values not filtered, but an emit still triggered
}
6 changes: 5 additions & 1 deletion projects/components/src/select/select.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MemoizeModule } from '@hypertrace/common';
import { DividerModule } from '../divider/divider.module';
import { EventBlockerModule } from '../event-blocker/event-blocker.module';
import { IconModule } from '../icon/icon.module';
import { LabelModule } from '../label/label.module';
import { LetAsyncModule } from '../let-async/let-async.module';
import { PopoverModule } from '../popover/popover.module';
import { TraceSearchBoxModule } from '../search-box/search-box.module';
import { TooltipModule } from '../tooltip/tooltip.module';
import { SelectOptionRendererDirective } from './directive/select-option-renderer.directive';
import { SelectControlOptionComponent } from './select-control-option.component';
Expand All @@ -24,7 +26,9 @@ import { SelectComponent } from './select.component';
PopoverModule,
TooltipModule,
DividerModule,
MemoizeModule
MemoizeModule,
TraceSearchBoxModule,
EventBlockerModule
],
declarations: [
SelectComponent,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { assertUnreachable } from '@hypertrace/common';
import { FieldFilter, FilterOperator, FilterValue, TableFilter } from '@hypertrace/components';
import { FieldFilter, Filter, FilterOperator, FilterValue, TableFilter } from '@hypertrace/components';
import { GraphQlArgumentValue } from '@hypertrace/graphql-client';
import { GraphQlFieldFilter } from '../../graphql/model/schema/filter/field/graphql-field-filter';
import { GraphQlFilter, GraphQlOperatorType } from '../../graphql/model/schema/filter/graphql-filter';
Expand All @@ -20,7 +20,7 @@ export class GraphQlFilterBuilderService {
}));
}

public buildGraphQlFieldFilters(filters: FieldFilter[]): GraphQlFieldFilter[] {
public buildGraphQlFieldFilters(filters: (Filter | FieldFilter)[]): GraphQlFieldFilter[] {
return filters.map(
filter =>
new GraphQlFieldFilter(
Expand Down