Add status filter checkboxes

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/4/head
trivernis 2 years ago
parent 582a6c0264
commit 918f4b3bb8

@ -27,16 +27,26 @@ export class SearchFilters {
return !!this.filters.find(f => deepEqual(f, expression));
}
public hasSubfilter(query: FilterQuery): boolean {
return !!this.filters.find(f => {
if ("OrExpression" in f) {
return !!f.OrExpression.find(q => deepEqual(q, query));
} else {
return deepEqual(f.Query, query);
}
});
}
public addFilterExpression(filter: FilterExpression) {
this.filters.push(filter);
this.processChangesToOrExpressions();
}
public addFilter(filter: FilterQuery, index: number) {
public addFilter(filter: FilterExpression, index: number) {
this.filters = [...this.filters.slice(
0,
index
), { Query: filter }, ...this.filters.slice(index)];
), filter, ...this.filters.slice(index)];
}
public appendFilter(filter: FilterQuery) {
@ -59,7 +69,7 @@ export class SearchFilters {
} else {
const otherQuery = expressionEntry["Query"]!;
let entry = expressionEntry as unknown as { OrExpression: FilterQuery[], Query: undefined };
entry["Query"] = undefined;
delete entry["Query"];
entry["OrExpression"] = [otherQuery, filter];
}
}
@ -70,10 +80,12 @@ export class SearchFilters {
return false;
} else {
f["OrExpression"] = f["OrExpression"]!.filter(q => !deepEqual(q, queryToRemove));
return (f["OrExpression"]!.length === 0);
return (!f["OrExpression"] || f["OrExpression"]!.length === 0);
}
});
this.filters.splice(index);
if (index >= 0) {
this.filters.splice(index, 1);
}
this.processChangesToOrExpressions();
}
@ -94,13 +106,13 @@ export class SearchFilters {
const filters_to_remove: FilterExpression[] = [];
for (const filter of this.filters) {
if ("OrExpression" in filter) {
if (filter.OrExpression.length === 1) {
if ("OrExpression" in filter && !("Query" in filter)) {
if (filter.OrExpression && filter.OrExpression.length === 1) {
const query = filter.OrExpression[0];
let newFilter = filter as unknown as FilterExpressionQuery & { OrExpression: undefined };
newFilter["OrExpression"] = undefined;
delete newFilter["OrExpression"];
newFilter.Query = query;
} else if (filter.OrExpression.length === 0) {
} else if (!filter.OrExpression || filter.OrExpression.length === 0) {
filters_to_remove.push(filter);
}
}

@ -167,9 +167,25 @@ export class FilterInputComponent implements OnChanges {
}
if (validComparators.length == 1) {
return validProperties.map(p => validComparators.map(c => this.propertyQueriesWithValues[p].map(v => `${p} ${c} ${v ?? value}`.trim())).flat()).flat();
return validProperties.map(p => validComparators.filter(c => this.filterComparatorsForProperty(
c,
p
)).map(c => this.propertyQueriesWithValues[p].map(v => `${p} ${c} ${v ?? value}`.trim())).flat()).flat();
} else {
return validProperties.map(p => validComparators.map(c => `${p} ${c} ${value}`.trim())).flat();
return validProperties.map(p => validComparators.filter((c) => this.filterComparatorsForProperty(c, p)).map(
c => `${p} ${c} ${value}`.trim())).flat();
}
}
private filterComparatorsForProperty(comparator: string, property: string): boolean {
console.log(comparator, property);
switch (property) {
case ".status":
case ".fileId":
case ".contentDescriptor":
return comparator === "=";
default:
return true;
}
}
}

@ -1,6 +1,13 @@
<div class="search-tab-inner" fxLayout="column">
<div id="file-search-input">
<div class="status-selector">
<mat-checkbox (change)="this.setDisplayImported($event)" [checked]="this.displayImported">Imported
</mat-checkbox>
<mat-checkbox (change)="this.setDisplayArchived($event)" [checked]="this.displayArchived">Archived
</mat-checkbox>
<mat-checkbox (change)="this.setDisplayDeleted($event)" [checked]="this.displayDeleted">Deleted
</mat-checkbox>
</div>
<div class="tag-input-list-and-actions">
<div #tagInputList class="tag-input-list">
<div class="tag-input-list-inner">

@ -123,3 +123,12 @@ mat-divider {
.file-tag-list {
position: relative;
}
.status-selector {
display: flex;
align-items: center;
justify-content: space-between;
width: calc(100% - 2em);
margin-left: 1em;
margin-right: 1em;
}

@ -9,8 +9,9 @@ import {clipboard} from "@tauri-apps/api";
import {TabState} from "../../../../models/TabState";
import {FilterQueryBuilder} from "../../../../../api/models/FilterQueryBuilder";
import {SearchFilters} from "../../../../../api/models/SearchFilters";
import {FilterExpression,} from "../../../../../api/api-types/files";
import {FileStatus, FilterExpression,} from "../../../../../api/api-types/files";
import {filterExpressionToString} from "../../../../utils/filter-utils";
import {MatCheckboxChange} from "@angular/material/checkbox";
@Component({
@ -36,6 +37,12 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public contextMenuFilter: FilterExpression | undefined = undefined;
public initialFilterInputValue: string | undefined;
public displayImported = true;
public displayArchived = true;
public displayDeleted = false;
private needsScroll = false;
constructor(
private errorBroker: ErrorBrokerService,
public dialog: MatDialog
@ -45,11 +52,14 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public async ngOnInit() {
this.state.filters.subscribe(f => this.filters = f);
this.state.sortKeys.subscribe(s => this.sortExpression = s);
this.applyStatusFromFilters();
await this.searchForFiles();
}
public ngAfterViewChecked(): void {
this.inputList.nativeElement.scrollLeft = this.inputList.nativeElement.scrollWidth;
if (this.needsScroll) {
this.inputList.nativeElement.scrollLeft = this.inputList.nativeElement.scrollWidth;
}
}
public async searchForFiles() {
@ -67,6 +77,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
this.filters.addFilterExpression(filter);
this.state.setTagFilters(this.filters);
this.needsScroll = true;
}
public addTagFilter(filterString: string) {
@ -93,6 +104,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public async removeFilterExpression(expr: FilterExpression) {
this.filters.removeFilter(expr);
this.state.setTagFilters(this.filters);
this.needsScroll = true;
}
public openSortDialog() {
@ -118,7 +130,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public openFilterDialog(): void {
const filterEntries = new SearchFilters(JSON.parse(JSON.stringify(this.filters.getFilters())));
const filterDialog = this.dialog.open(FilterDialogComponent, {
minWidth: "25vw",
maxHeight: "80vh",
@ -132,6 +144,8 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
if (filterExpression !== undefined || filterExpression?.length > 0) {
this.filters = filterExpression;
this.state.setTagFilters(this.filters);
this.applyStatusFromFilters();
this.needsScroll = true;
}
});
}
@ -143,4 +157,64 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public addFilterToInput(param: FilterExpression): void {
this.initialFilterInputValue = filterExpressionToString(param);
}
public setDisplayDeleted(event: MatCheckboxChange) {
this.displayDeleted = event.checked;
this.updateStatusFilters();
}
public setDisplayArchived(event: MatCheckboxChange) {
this.displayArchived = event.checked;
this.updateStatusFilters();
}
public setDisplayImported(event: MatCheckboxChange) {
this.displayImported = event.checked;
this.updateStatusFilters();
}
private applyStatusFromFilters() {
const filterImported = FilterQueryBuilder.status("Imported");
const filterArchived = FilterQueryBuilder.status("Archived");
const filterDeleted = FilterQueryBuilder.status("Deleted");
this.displayImported = this.filters.hasSubfilter(filterImported);
this.displayArchived = this.filters.hasSubfilter(filterArchived);
this.displayDeleted = this.filters.hasSubfilter(filterDeleted);
if (!this.displayImported && !this.displayDeleted && !this.displayArchived) {
this.displayImported = true;
this.displayArchived = true;
this.updateStatusFilters();
}
}
private updateStatusFilters() {
this.deleteAllStatusFilters();
const filter = this.buildFilterForDisplayProperty();
this.filters.addFilter(filter, 0);
this.state.setTagFilters(this.filters);
}
private deleteAllStatusFilters() {
for (const status of ["Imported", "Archived", "Deleted"]) {
const query = FilterQueryBuilder.status(status as FileStatus);
this.filters.removeSubfilter(query);
this.filters.removeFilter({ Query: query });
}
this.state.setTagFilters(this.filters);
}
private buildFilterForDisplayProperty(): FilterExpression {
const filters = [];
if (this.displayImported) {
filters.push(FilterQueryBuilder.status("Imported"));
}
if (this.displayArchived) {
filters.push(FilterQueryBuilder.status("Archived"));
}
if (this.displayDeleted) {
filters.push(FilterQueryBuilder.status("Deleted"));
}
return { OrExpression: filters };
}
}

Loading…
Cancel
Save