Fix scaling of filter dialog height

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 3 years ago
parent bade6214a0
commit 2fefc65d29

@ -9,20 +9,9 @@
<mat-icon>delete-sweep</mat-icon>
</button>
</div>
<mat-form-field appearance="fill" class="full-width">
<mat-label>Enter tags to filter for</mat-label>
<input #tagInput
(keydown)="addSearchTagByInput($event)"
[formControl]="formControl"
[matAutocomplete]="auto"
matInput/>
<app-tag-input class="full-width" [allowNegation]="true" [availableTags]="getValidSearchTags()" (tagAdded)="addSearchTag($event); searchForFiles()">
<button mat-button class="filter-dialog-button" (click)="openFilterDialog()">
<mat-icon>filter_alt</mat-icon>
</button>
<mat-autocomplete #auto (optionSelected)="addSearchTagByAutocomplete($event)">
<mat-option *ngFor="let tag of suggestionTags | async" [value]="tag">
{{tag}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</app-tag-input>
<button (click)="openSortDialog()" id="sort-button" mat-flat-button>Sort: {{sortExpression.join(", ")}}</button>

@ -8,12 +8,7 @@ import {
Output,
ViewChild
} from '@angular/core';
import {TagService} from "../../services/tag/tag.service";
import {FileService} from "../../services/file/file.service";
import {FormControl} from "@angular/forms";
import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
import {map, startWith} from "rxjs/operators";
import {Observable} from "rxjs";
import {TagQuery} from "../../models/TagQuery";
import {SortKey} from "../../models/SortKey";
import {MatDialog} from "@angular/material/dialog";
@ -35,24 +30,20 @@ import {Tag} from "../../models/Tag";
export class FileSearchComponent implements AfterViewChecked, OnInit {
public sortExpression: SortKey[] = [new SortKey("FileImportedTime",
"Ascending", undefined)];
public formControl = new FormControl();
public filters: FilterExpression[] = [];
public suggestionTags: Observable<string[]>;
@Input() availableTags: Tag[] = [];
@Input() validTags: string[] = [];
@Output() searchStartEvent = new EventEmitter<void>();
@Output() searchEndEvent = new EventEmitter<void>();
@ViewChild("tagInput") tagInput!: ElementRef<HTMLInputElement>;
@ViewChild("tagInputList") inputList!: ElementRef;
constructor(private errorBroker: ErrorBrokerService, private tagService: TagService, private fileService: FileService, public dialog: MatDialog) {
this.suggestionTags = this.formControl.valueChanges.pipe(startWith(null),
map(
(tag: string | null) => tag ? this.filterSuggestionTag(
tag) : this.validTags.slice(0, 20)));
}
constructor(
private errorBroker: ErrorBrokerService,
private fileService: FileService,
public dialog: MatDialog
) {}
public async ngOnInit() {
await this.searchForFiles();
@ -82,12 +73,16 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
}
}
async removeAllSearchTags() {
public getValidSearchTags(): Tag[] {
return this.availableTags.filter(t => this.filters.findIndex(f => f.partiallyEq(t.getNormalizedOutput())) < 0);
}
public async removeAllSearchTags() {
this.filters = [];
await this.searchForFiles();
}
async removeFilterExpression(expr: FilterExpression) {
public async removeFilterExpression(expr: FilterExpression) {
const index = this.filters.indexOf(expr);
if (index >= 0) {
this.filters.splice(index, 1);
@ -95,26 +90,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
await this.searchForFiles();
}
async addSearchTagByInput(event: KeyboardEvent) {
if (event.key === "Enter") {
const tag = (this.formControl.value as string ?? "").trim();
if (tag.length > 0 && this.validTags.includes(tag.replace(/-/g, ''))) {
this.addSearchTag(tag);
this.formControl.setValue(null);
await this.searchForFiles();
}
}
}
async addSearchTagByAutocomplete(event: MatAutocompleteSelectedEvent) {
const tag = event.option.viewValue;
this.addSearchTag(tag);
this.formControl.setValue(null);
this.tagInput.nativeElement.value = '';
await this.searchForFiles();
}
openSortDialog() {
public openSortDialog() {
const sortEntries = this.sortExpression.map(
key => JSON.parse(JSON.stringify(key))).map(
key => new SortKey(key.sortType, key.sortDirection, key.namespaceName))
@ -133,22 +109,11 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
});
}
private filterSuggestionTag(tag: string) {
const negated = tag.startsWith("-");
const normalizedTag = tag.replace(/^-/, "");
return this.validTags.filter(
t => t.includes(normalizedTag) && this.filters.findIndex(
f => f.eq(t)) < 0)
.map(t => negated ? "-" + t : t)
.slice(0, 20);
}
public openFilterDialog(): void {
const filterEntries = this.filters.map(f => f.clone());
const filterDialog = this.dialog.open(FilterDialogComponent, {
minWidth: "25vw",
height: "80vh",
maxHeight: "80vh",
data: {
filterEntries,
availableTags: this.availableTags,

@ -1,15 +1,18 @@
<h1 mat-dialog-title>Filters</h1>
<div mat-dialog-content fxLayout="column" class="filter-dialog-content">
<div fxFlex fxFlexFill class="filter-dialog-list">
<mat-list>
<div mat-dialog-content class="filter-dialog-content">
<div class="filter-dialog-list">
<mat-list class="mat-filter-dialog-list">
<mat-list-item class="filter-list-item" *ngFor="let expression of filters" [class.selected]="expression.selected">
<app-tag-filter-list-item (querySelect)="this.addToSelection($event)" (queryUnselect)="this.removeFromSelection($event)" (removeClicked)="this.removeFilter($event)"
(contextmenu)="contextMenu.onContextMenu($event)" [expression]="expression"></app-tag-filter-list-item>
<app-tag-filter-list-item (querySelect)="this.addToSelection($event)"
(queryUnselect)="this.removeFromSelection($event)"
(removeClicked)="this.removeFilter($event)"
(contextmenu)="contextMenu.onContextMenu($event)"
[expression]="expression"></app-tag-filter-list-item>
</mat-list-item>
</mat-list>
</div>
<mat-divider fxFlex="10px"></mat-divider>
<app-tag-input fxFlex="5em" class="tag-input" [allowNegation]="true" [availableTags]="this.availableTags"
<mat-divider></mat-divider>
<app-tag-input class="tag-input" [allowNegation]="true" [availableTags]="this.availableTags"
(tagAdded)="this.addFilter($event)"></app-tag-input>
</div>
<div class="dialog-actions" mat-dialog-actions>

@ -10,6 +10,7 @@
.tag-input {
width: 100%;
height: 5em;
}
mat-list-item.filter-list-item {
@ -29,13 +30,16 @@ app-tag-filter-list-item {
.filter-dialog-content {
overflow: hidden;
height: 100%;
width: 100%;
margin: 0;
max-height: 60vh;
}
.filter-dialog-list {
max-height: calc(60vh - 5em);
overflow-y: auto;
height: 100%;
width: 100%;
}
mat-list.mat-filter-dialog-list {
padding: 0;
}

@ -1,4 +1,4 @@
<mat-form-field>
<mat-form-field appearance="fill">
<mat-label>
Enter a tag
</mat-label>
@ -7,6 +7,7 @@
matInput
(keydown.enter)="addTagByInput($event)"
[matAutocomplete]="auto">
<ng-content></ng-content>
<mat-autocomplete #auto (optionSelected)="addTagByAutocomplete($event)">
<mat-option *ngFor="let tag of autosuggestTags | async" [value]="tag">
{{tag}}

@ -5,7 +5,6 @@
<div id="file-search-input">
<app-file-search #filesearch (searchEndEvent)="this.searchEndEvent.emit()"
(searchStartEvent)="this.searchStartEvent.emit()"
[validTags]="this.getValidTagsForSearch()"
[availableTags]="this.allTags"></app-file-search>
</div>
<mat-divider fxFlex="1em"></mat-divider>

@ -74,10 +74,6 @@ export class FilesTabSidebarComponent implements OnInit, OnChanges {
await this.fileSearch.searchForFiles();
}
getValidTagsForSearch(): string[] {
return this.tagsOfFiles.map(t => t.getNormalizedOutput())
}
async showFileDetails(files: File[]) {
this.tagsOfSelection = await this.tagService.getTagsForFiles(files.map(f => f.hash))
this.tagsOfSelection = this.tagsOfSelection.sort(

Loading…
Cancel
Save