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]] [[package]]
name = "mediarepo-api" name = "mediarepo-api"
version = "0.10.0" version = "0.11.0"
source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=74380887a2349b1aa4fb72aa6bc0916961b54db9#74380887a2349b1aa4fb72aa6bc0916961b54db9" source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=6fbc72699a565b1ca3f76f58c3dafbe9790c758e#6fbc72699a565b1ca3f76f58c3dafbe9790c758e"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"chrono", "chrono",

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

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

@ -1,8 +1,8 @@
<div class="tag-input-list-and-actions"> <div class="tag-input-list-and-actions">
<div #tagInputList class="tag-input-list"> <div #tagInputList class="tag-input-list">
<div class="tag-input-list-inner"> <div class="tag-input-list-inner">
<div (click)="removeSearchTag(tag)" *ngFor="let tag of searchTags" class="tag-input-item" <div (click)="removeFilterExpression(filter)" *ngFor="let filter of filters" class="tag-input-item"
mat-ripple>{{tag.getNormalizedTag()}}</div> mat-ripple>{{filter.getDisplayName()}}</div>
</div> </div>
</div> </div>
<button (click)="removeAllSearchTags()" id="delete-all-tags-button" mat-icon-button> <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 {TagQuery} from "../../models/TagQuery";
import {SortKey} from "../../models/SortKey"; import {SortKey} from "../../models/SortKey";
import {MatDialog} from "@angular/material/dialog"; 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 {ErrorBrokerService} from "../../services/error-broker/error-broker.service";
import {
FilterExpression,
SingleFilterExpression
} from "../../models/FilterExpression";
@Component({ @Component({
@ -30,7 +34,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public sortExpression: SortKey[] = [new SortKey("FileImportedTime", public sortExpression: SortKey[] = [new SortKey("FileImportedTime",
"Ascending", undefined)]; "Ascending", undefined)];
public formControl = new FormControl(); public formControl = new FormControl();
public searchTags: TagQuery[] = []; public filters: FilterExpression[] = [];
public suggestionTags: Observable<string[]>; public suggestionTags: Observable<string[]>;
@Input() validTags: string[] = []; @Input() validTags: string[] = [];
@ -58,7 +62,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public async searchForFiles() { public async searchForFiles() {
this.searchStartEvent.emit(); this.searchStartEvent.emit();
try { try {
await this.fileService.findFiles(this.searchTags, this.sortExpression); await this.fileService.findFiles(this.filters, this.sortExpression);
} catch (err) { } catch (err) {
this.errorBroker.showError(err); this.errorBroker.showError(err);
} }
@ -68,25 +72,25 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
public addSearchTag(tag: string) { public addSearchTag(tag: string) {
if (tag.startsWith("-")) { if (tag.startsWith("-")) {
tag = tag.replace(/^-/g, ''); tag = tag.replace(/^-/g, '');
this.searchTags.push(new TagQuery(tag, true)); this.filters.push(new SingleFilterExpression(new TagQuery(tag, true)));
} else { } 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) { if (this.filters.filter(t => t.partiallyEq(tag)).length > 1) {
const index = this.searchTags.findIndex(t => t.name === tag); const index = this.filters.findIndex(t => t.partiallyEq(tag));
this.searchTags.splice(index, 1); this.filters.splice(index, 1);
} }
} }
async removeAllSearchTags() { async removeAllSearchTags() {
this.searchTags = []; this.filters = [];
await this.searchForFiles(); await this.searchForFiles();
} }
async removeSearchTag(tag: TagQuery) { async removeFilterExpression(expr: FilterExpression) {
const index = this.searchTags.indexOf(tag); const index = this.filters.indexOf(expr);
if (index >= 0) { if (index >= 0) {
this.searchTags.splice(index, 1); this.filters.splice(index, 1);
} }
await this.searchForFiles(); await this.searchForFiles();
} }
@ -114,7 +118,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
const sortEntries = this.sortExpression.map( const sortEntries = this.sortExpression.map(
key => JSON.parse(JSON.stringify(key))).map( key => JSON.parse(JSON.stringify(key))).map(
key => new SortKey(key.sortType, key.sortDirection, key.namespaceName)) key => new SortKey(key.sortType, key.sortDirection, key.namespaceName))
const openedDialog = this.dialog.open(FilterDialogComponent, { const openedDialog = this.dialog.open(SortDialogComponent, {
minWidth: "40vw", minWidth: "40vw",
data: { data: {
sortEntries, sortEntries,
@ -134,8 +138,8 @@ export class FileSearchComponent implements AfterViewChecked, OnInit {
const normalizedTag = tag.replace(/^-/, ""); const normalizedTag = tag.replace(/^-/, "");
return this.validTags.filter( return this.validTags.filter(
t => t.includes(normalizedTag) && this.searchTags.findIndex( t => t.includes(normalizedTag) && this.filters.findIndex(
s => s.getNormalizedTag() === t) < 0) f => f.eq(t)) < 0)
.map(t => negated ? "-" + t : t) .map(t => negated ? "-" + t : t)
.slice(0, 20); .slice(0, 20);
} }

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

@ -4,15 +4,15 @@ import {SortKey} from "../../../models/SortKey";
import {CdkDragDrop, moveItemInArray} from "@angular/cdk/drag-drop"; import {CdkDragDrop, moveItemInArray} from "@angular/cdk/drag-drop";
@Component({ @Component({
selector: 'app-filter-dialog', selector: 'app-sort-dialog',
templateUrl: './filter-dialog.component.html', templateUrl: './sort-dialog.component.html',
styleUrls: ['./filter-dialog.component.scss'] styleUrls: ['./sort-dialog.component.scss']
}) })
export class FilterDialogComponent { export class SortDialogComponent {
public sortEntries: SortKey[] = [] public sortEntries: SortKey[] = []
constructor(public dialogRef: MatDialogRef<FilterDialogComponent>, @Inject( constructor(public dialogRef: MatDialogRef<SortDialogComponent>, @Inject(
MAT_DIALOG_DATA) data: any) { MAT_DIALOG_DATA) data: any) {
this.sortEntries = data.sortEntries; 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 { export class TagQuery {
constructor(public name: string, public negate: boolean) { constructor(public tag: string, public negate: boolean) {
} }
public getNormalizedTag(): string { 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 {TagQuery} from "../../models/TagQuery";
import {SortKey} from "../../models/SortKey"; import {SortKey} from "../../models/SortKey";
import {RepositoryService} from "../repository/repository.service"; import {RepositoryService} from "../repository/repository.service";
import {FilterExpression} from "../../models/FilterExpression";
@Injectable({ @Injectable({
providedIn: 'root' providedIn: 'root'
@ -29,9 +30,10 @@ export class FileService {
this.displayedFiles.next(all_files); 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", 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); this.displayedFiles.next(files);
} }

Loading…
Cancel
Save