blob: 36f77cbcfbd32e777f239d48b2d0f29350cb36a7 [file]
/*
* Copyright (C) 2024 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {Component, EventEmitter, Input, Output} from '@angular/core';
import {assertDefined} from 'common/assert_utils';
import {FilterFlag} from 'common/filter_flag';
import {TextFilter} from 'viewers/common/text_filter';
@Component({
selector: 'search-box',
template: `
<mat-form-field
*ngIf="textFilter"
[class]="getFormFieldClasses()"
[appearance]="appearance"
[style.height]="height"
(keydown.esc)="$event.target.blur()"
(keydown.enter)="$event.target.blur()">
<mat-label>{{ label }}</mat-label>
<input
matInput
[(ngModel)]="textFilter.filterString"
(ngModelChange)="onFilterChange()"
[name]="filterName" />
<div class="field-suffix" matSuffix>
<button
mat-icon-button
matTooltip="Match case"
[color]="hasFlag(FilterFlag.MATCH_CASE) ? 'primary' : undefined"
(click)="onFilterFlagClick($event, FilterFlag.MATCH_CASE)">
<mat-icon class="material-symbols-outlined">match_case</mat-icon>
</button>
<button
mat-icon-button
matTooltip="Match whole word"
[color]="hasFlag(FilterFlag.MATCH_WORD) ? 'primary' : undefined"
(click)="onFilterFlagClick($event, FilterFlag.MATCH_WORD)">
<mat-icon class="material-symbols-outlined">match_word</mat-icon>
</button>
<button
mat-icon-button
matTooltip="Use regex"
[color]="hasFlag(FilterFlag.USE_REGEX) ? 'primary' : undefined"
(click)="onFilterFlagClick($event, FilterFlag.USE_REGEX)">
<mat-icon class="material-symbols-outlined">regular_expression</mat-icon>
</button>
</div>
</mat-form-field>
`,
styles: [
`
.search-box {
font-size: 14px;
margin-top: 4px;
}
.search-box .mat-icon {
font-size: 18px;
}
.wide-field {
width: 100%;
}
`,
],
})
export class SearchBoxComponent {
FilterFlag = FilterFlag;
@Input() textFilter: TextFilter | undefined = new TextFilter();
@Input() label = 'Search';
@Input() filterName = 'filter';
@Input() appearance = '';
@Input() formFieldClass = '';
@Input() height = '48px';
@Output() readonly filterChange = new EventEmitter<TextFilter>();
hasFlag(flag: FilterFlag): boolean {
return assertDefined(this.textFilter).flags.includes(flag) ?? false;
}
onFilterFlagClick(event: MouseEvent, flag: FilterFlag) {
event.stopPropagation();
const filter = assertDefined(this.textFilter);
if (this.hasFlag(flag)) {
filter.flags = filter.flags.filter((f) => f !== flag);
} else {
filter.flags = filter.flags.concat(flag);
}
this.onFilterChange();
}
onFilterChange() {
this.filterChange.emit(this.textFilter);
}
getFormFieldClasses(): string {
return (
'search-box ' +
((this.textFilter?.filterString.length ?? 0) > 0 ? 'highlighted ' : '') +
this.formFieldClass
);
}
}