Update plugin and rename filter dialog to sort dialog

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

@ -1580,8 +1580,8 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "mediarepo-api"
version = "0.10.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=74380887a2349b1aa4fb72aa6bc0916961b54db9#74380887a2349b1aa4fb72aa6bc0916961b54db9"
version = "0.11.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=6fbc72699a565b1ca3f76f58c3dafbe9790c758e#6fbc72699a565b1ca3f76f58c3dafbe9790c758e"
dependencies = [
"async-trait",
"chrono",

@ -30,7 +30,7 @@ features = ["env-filter"]
[dependencies.mediarepo-api]
git = "https://github.com/Trivernis/mediarepo-api.git"
rev = "74380887a2349b1aa4fb72aa6bc0916961b54db9"
rev = "6fbc72699a565b1ca3f76f58c3dafbe9790c758e"
features = ["tauri-plugin"]
[features]

@ -30,7 +30,7 @@ import {MatTabsModule} from "@angular/material/tabs";
import {FilesTabComponent} from './pages/home/files-tab/files-tab.component';
import {FlexModule, GridModule} from "@angular/flex-layout";
import {MatRippleModule} from "@angular/material/core";
import {FilterDialogComponent} from './components/file-search/filter-dialog/filter-dialog.component';
import {SortDialogComponent} from './components/file-search/sort-dialog/sort-dialog.component';
import {MatDialogModule} from "@angular/material/dialog";
import {MatSelectModule} from "@angular/material/select";
import {FileGalleryComponent} from './components/file-gallery/file-gallery.component';
@ -65,7 +65,7 @@ import {MatCheckboxModule} from "@angular/material/checkbox";
FileGridEntryComponent,
FileSearchComponent,
FilesTabComponent,
FilterDialogComponent,
SortDialogComponent,
FileGalleryComponent,
FileGalleryEntryComponent,
ContentAwareImageComponent,

@ -1,8 +1,8 @@
<div class="tag-input-list-and-actions">
<div #tagInputList class="tag-input-list">
<div class="tag-input-list-inner">
<div (click)="removeSearchTag(tag)" *ngFor="let tag of searchTags" class="tag-input-item"
mat-ripple>{{tag.getNormalizedTag()}}</div>
<div (click)="removeFilterExpression(filter)" *ngFor="let filter of filters" class="tag-input-item"
mat-ripple>{{filter.getDisplayName()}}</div>
</div>
</div>
<button (click)="removeAllSearchTags()" id="delete-all-tags-button" mat-icon-button>

@ -17,8 +17,12 @@ import {Observable} from "rxjs";
import {TagQuery} from "../../models/TagQuery";
import {SortKey} from "../../models/SortKey";
import {MatDialog} from "@angular/material/dialog";
import {FilterDialogComponent} from "./filter-dialog/filter-dialog.component";
import {SortDialogComponent} from "./sort-dialog/sort-dialog.component";
import {ErrorBrokerService} from "../../services/error-broker/error-broker.service";
import {
FilterExpression,
SingleFilterExpression
} from "../../models/FilterExpression";
@Component({
@ -30,7 +34,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public sortExpression: SortKey[] = [new SortKey("FileImportedTime",
"Ascending", undefined)];
public formControl = new FormControl();
public searchTags: TagQuery[] = [];
public filters: FilterExpression[] = [];
public suggestionTags: Observable<string[]>;
@Input() validTags: string[] = [];
@ -58,7 +62,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public async searchForFiles() {
this.searchStartEvent.emit();
try {
await this.fileService.findFiles(this.searchTags, this.sortExpression);
await this.fileService.findFiles(this.filters, this.sortExpression);
} catch (err) {
this.errorBroker.showError(err);
}
@ -68,25 +72,25 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public addSearchTag(tag: string) {
if (tag.startsWith("-")) {
tag = tag.replace(/^-/g, '');
this.searchTags.push(new TagQuery(tag, true));
this.filters.push(new SingleFilterExpression(new TagQuery(tag, true)));
} else {
this.searchTags.push(new TagQuery(tag, false));
this.filters.push(new SingleFilterExpression(new TagQuery(tag, false)));
}
if (this.searchTags.filter(t => t.name === tag).length > 1) {
const index = this.searchTags.findIndex(t => t.name === tag);
this.searchTags.splice(index, 1);
if (this.filters.filter(t => t.partiallyEq(tag)).length > 1) {
const index = this.filters.findIndex(t => t.partiallyEq(tag));
this.filters.splice(index, 1);
}
}
async removeAllSearchTags() {
this.searchTags = [];
this.filters = [];
await this.searchForFiles();
}
async removeSearchTag(tag: TagQuery) {
const index = this.searchTags.indexOf(tag);
async removeFilterExpression(expr: FilterExpression) {
const index = this.filters.indexOf(expr);
if (index >= 0) {
this.searchTags.splice(index, 1);
this.filters.splice(index, 1);
}
await this.searchForFiles();
}
@ -114,7 +118,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
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(SortDialogComponent, {
minWidth: "40vw",
data: {
sortEntries,
@ -134,8 +138,8 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
const normalizedTag = tag.replace(/^-/, "");
return this.validTags.filter(
t => t.includes(normalizedTag) && this.searchTags.findIndex(
s => s.getNormalizedTag() === t) < 0)
t => t.includes(normalizedTag) && this.filters.findIndex(
f => f.eq(t)) < 0)
.map(t => negated ? "-" + t : t)
.slice(0, 20);
}

@ -1,20 +1,20 @@
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {FilterDialogComponent} from './filter-dialog.component';
import {SortDialogComponent} from './sort-dialog.component';
describe('FilterDialogComponent', () => {
let component: FilterDialogComponent;
let fixture: ComponentFixture<FilterDialogComponent>;
let component: SortDialogComponent;
let fixture: ComponentFixture<SortDialogComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [FilterDialogComponent]
declarations: [SortDialogComponent]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(FilterDialogComponent);
fixture = TestBed.createComponent(SortDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

@ -4,15 +4,15 @@ import {SortKey} from "../../../models/SortKey";
import {CdkDragDrop, moveItemInArray} from "@angular/cdk/drag-drop";
@Component({
selector: 'app-filter-dialog',
templateUrl: './filter-dialog.component.html',
styleUrls: ['./filter-dialog.component.scss']
selector: 'app-sort-dialog',
templateUrl: './sort-dialog.component.html',
styleUrls: ['./sort-dialog.component.scss']
})
export class FilterDialogComponent {
export class SortDialogComponent {
public sortEntries: SortKey[] = []
constructor(public dialogRef: MatDialogRef<FilterDialogComponent>, @Inject(
constructor(public dialogRef: MatDialogRef<SortDialogComponent>, @Inject(
MAT_DIALOG_DATA) data: any) {
this.sortEntries = data.sortEntries;
}

@ -0,0 +1,54 @@
import {TagQuery} from "./TagQuery";
export interface FilterExpression {
filter_type: "OrExpression" | "Query";
filter: TagQuery[] | TagQuery;
eq(value: any): boolean;
partiallyEq(value: any): boolean;
getDisplayName(): string;
}
export class OrFilterExpression implements FilterExpression{
public filter_type: "OrExpression" = "OrExpression";
public filter: TagQuery[] = [];
constructor(tags: TagQuery[]) {
this.filter = tags;
}
public eq(value: any): boolean {
return this == value
}
public partiallyEq(value: any): boolean {
return this == value;
}
public getDisplayName(): string {
return this.filter.map(t => t.getNormalizedTag()).join(" OR ");
}
}
export class SingleFilterExpression implements FilterExpression {
public filter_type: "Query" = "Query";
public filter: TagQuery;
constructor(tag: TagQuery) {
this.filter = tag;
}
public eq(value: any): boolean {
return (this.filter.tag === value?.name && this.filter.negate === value?.negate) || this.filter.getNormalizedTag() === value;
}
public partiallyEq(value: any): boolean {
return this.filter.tag === value || this.filter.tag === value?.name;
}
public getDisplayName(): string {
return this.filter.getNormalizedTag();
}
}

@ -1,8 +1,8 @@
export class TagQuery {
constructor(public name: string, public negate: boolean) {
constructor(public tag: string, public negate: boolean) {
}
public getNormalizedTag(): string {
return this.negate ? "-" + this.name : this.name;
return this.negate ? "-" + this.tag : this.tag;
}
}

@ -7,6 +7,7 @@ import {Thumbnail} from "../../models/Thumbnail";
import {TagQuery} from "../../models/TagQuery";
import {SortKey} from "../../models/SortKey";
import {RepositoryService} from "../repository/repository.service";
import {FilterExpression} from "../../models/FilterExpression";
@Injectable({
providedIn: 'root'
@ -29,9 +30,10 @@ export class FileService {
this.displayedFiles.next(all_files);
}
public async findFiles(tags: TagQuery[], sortBy: SortKey[]) {
public async findFiles(filters: FilterExpression[], sortBy: SortKey[]) {
console.log(filters);
let files = await invoke<File[]>("plugin:mediarepo|find_files",
{tags, sortBy: sortBy.map(k => k.toBackendType())});
{filters, sortBy: sortBy.map(k => k.toBackendType())});
this.displayedFiles.next(files);
}

Loading…
Cancel
Save