|
|
@ -1,7 +1,7 @@
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
AfterViewChecked,
|
|
|
|
AfterViewChecked,
|
|
|
|
Component,
|
|
|
|
Component,
|
|
|
|
ElementRef, EventEmitter, Output,
|
|
|
|
ElementRef, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges,
|
|
|
|
ViewChild
|
|
|
|
ViewChild
|
|
|
|
} from '@angular/core';
|
|
|
|
} from '@angular/core';
|
|
|
|
import {TagService} from "../../services/tag/tag.service";
|
|
|
|
import {TagService} from "../../services/tag/tag.service";
|
|
|
@ -16,6 +16,7 @@ import {MatDialog} from "@angular/material/dialog";
|
|
|
|
import {FilterDialogComponent} from "./filter-dialog/filter-dialog.component";
|
|
|
|
import {FilterDialogComponent} from "./filter-dialog/filter-dialog.component";
|
|
|
|
import {ErrorBrokerService} from "../../services/error-broker/error-broker.service";
|
|
|
|
import {ErrorBrokerService} from "../../services/error-broker/error-broker.service";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
@Component({
|
|
|
|
selector: 'app-file-search',
|
|
|
|
selector: 'app-file-search',
|
|
|
|
templateUrl: './file-search.component.html',
|
|
|
|
templateUrl: './file-search.component.html',
|
|
|
@ -32,24 +33,29 @@ export class FileSearchComponent implements AfterViewChecked {
|
|
|
|
public searchTags: TagQuery[] = [];
|
|
|
|
public searchTags: TagQuery[] = [];
|
|
|
|
public suggestionTags: Observable<string[]>;
|
|
|
|
public suggestionTags: Observable<string[]>;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Input() validTags: string[] = [];
|
|
|
|
@Output() searchStartEvent = new EventEmitter<void>();
|
|
|
|
@Output() searchStartEvent = new EventEmitter<void>();
|
|
|
|
@Output() searchEndEvent = new EventEmitter<void>();
|
|
|
|
@Output() searchEndEvent = new EventEmitter<void>();
|
|
|
|
|
|
|
|
|
|
|
|
private allTags: string[] = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ViewChild("tagInput") tagInput!: ElementRef<HTMLInputElement>;
|
|
|
|
@ViewChild("tagInput") tagInput!: ElementRef<HTMLInputElement>;
|
|
|
|
@ViewChild("tagInputList") inputList!: ElementRef;
|
|
|
|
@ViewChild("tagInputList") inputList!: ElementRef;
|
|
|
|
|
|
|
|
|
|
|
|
constructor(private errorBroker: ErrorBrokerService, private tagService: TagService, private fileService: FileService, public dialog: MatDialog) {
|
|
|
|
constructor(private errorBroker: ErrorBrokerService, private tagService: TagService, private fileService: FileService, public dialog: MatDialog) {
|
|
|
|
this.tagService.tags.subscribe(
|
|
|
|
|
|
|
|
(tag) => this.allTags = tag.map(t => t.getNormalizedOutput()));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.suggestionTags = this.formControl.valueChanges.pipe(startWith(null),
|
|
|
|
this.suggestionTags = this.formControl.valueChanges.pipe(startWith(null),
|
|
|
|
map(
|
|
|
|
map(
|
|
|
|
(tag: string | null) => tag ? this.allTags.filter(
|
|
|
|
(tag: string | null) => tag ? this.filterSuggestionTag(
|
|
|
|
(t: string) => t.includes(tag.replace(/^-/g, '')))
|
|
|
|
tag) : this.validTags.slice(0, 20)));
|
|
|
|
.map((t) => tag.startsWith("-") ? "-" + t : t)
|
|
|
|
}
|
|
|
|
.slice(0, 20) : this.allTags.slice(0, 20)));
|
|
|
|
|
|
|
|
|
|
|
|
private filterSuggestionTag(tag: string) {
|
|
|
|
|
|
|
|
const negated = tag.startsWith("-");
|
|
|
|
|
|
|
|
const normalizedTag = tag.replace(/^-/, "");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return this.validTags.filter(
|
|
|
|
|
|
|
|
t => t.includes(normalizedTag) && this.searchTags.findIndex(
|
|
|
|
|
|
|
|
s => s.name === t) < 0)
|
|
|
|
|
|
|
|
.map(t => negated ? "-" + t : t)
|
|
|
|
|
|
|
|
.slice(0, 20);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public async searchForFiles() {
|
|
|
|
public async searchForFiles() {
|
|
|
@ -91,7 +97,7 @@ export class FileSearchComponent implements AfterViewChecked {
|
|
|
|
async addSearchTagByInput(event: KeyboardEvent) {
|
|
|
|
async addSearchTagByInput(event: KeyboardEvent) {
|
|
|
|
if (event.key === "Enter") {
|
|
|
|
if (event.key === "Enter") {
|
|
|
|
const tag = (this.formControl.value as string ?? "").trim();
|
|
|
|
const tag = (this.formControl.value as string ?? "").trim();
|
|
|
|
if (tag.length > 0 && this.allTags.includes(tag.replace(/-/g, ''))) {
|
|
|
|
if (tag.length > 0 && this.validTags.includes(tag.replace(/-/g, ''))) {
|
|
|
|
this.addSearchTag(tag);
|
|
|
|
this.addSearchTag(tag);
|
|
|
|
this.formControl.setValue(null);
|
|
|
|
this.formControl.setValue(null);
|
|
|
|
await this.searchForFiles();
|
|
|
|
await this.searchForFiles();
|
|
|
@ -108,7 +114,9 @@ export class FileSearchComponent implements AfterViewChecked {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
openSortDialog() {
|
|
|
|
openSortDialog() {
|
|
|
|
const sortEntries = this.sortExpression.map(key => JSON.parse(JSON.stringify(key))).map(key => new SortKey(key.sortType, key.sortDirection, key.namespaceName))
|
|
|
|
const sortEntries = this.sortExpression.map(
|
|
|
|
|
|
|
|
key => JSON.parse(JSON.stringify(key))).map(
|
|
|
|
|
|
|
|
key => new SortKey(key.sortType, key.sortDirection, key.namespaceName))
|
|
|
|
const openedDialog = this.dialog.open(FilterDialogComponent, {
|
|
|
|
const openedDialog = this.dialog.open(FilterDialogComponent, {
|
|
|
|
minWidth: "40vw",
|
|
|
|
minWidth: "40vw",
|
|
|
|
data: {
|
|
|
|
data: {
|
|
|
|