diff --git a/mediarepo-ui/src-tauri/Cargo.lock b/mediarepo-ui/src-tauri/Cargo.lock
index 6097b35..df284a3 100644
--- a/mediarepo-ui/src-tauri/Cargo.lock
+++ b/mediarepo-ui/src-tauri/Cargo.lock
@@ -1581,7 +1581,7 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
[[package]]
name = "mediarepo-api"
version = "0.1.0"
-source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=2b6a968e6d5343326e20c73f4fcbbb88848b0c35#2b6a968e6d5343326e20c73f4fcbbb88848b0c35"
+source = "git+https://github.com/Trivernis/mediarepo-api.git?rev=4600810fca96bf6b457adc39667245a46127e5e8#4600810fca96bf6b457adc39667245a46127e5e8"
dependencies = [
"async-trait",
"chrono",
diff --git a/mediarepo-ui/src-tauri/Cargo.toml b/mediarepo-ui/src-tauri/Cargo.toml
index 30c2c17..cf835ff 100644
--- a/mediarepo-ui/src-tauri/Cargo.toml
+++ b/mediarepo-ui/src-tauri/Cargo.toml
@@ -30,7 +30,7 @@ features = ["env-filter"]
[dependencies.mediarepo-api]
git = "https://github.com/Trivernis/mediarepo-api.git"
-rev = "2b6a968e6d5343326e20c73f4fcbbb88848b0c35"
+rev = "4600810fca96bf6b457adc39667245a46127e5e8"
features = ["tauri-plugin"]
[features]
diff --git a/mediarepo-ui/src/app/app.module.ts b/mediarepo-ui/src/app/app.module.ts
index 3045b44..f2189e5 100644
--- a/mediarepo-ui/src/app/app.module.ts
+++ b/mediarepo-ui/src/app/app.module.ts
@@ -26,6 +26,8 @@ import {ScrollingModule} from "@angular/cdk/scrolling";
import {LightboxModule} from "ngx-lightbox";
import {MatChipsModule} from "@angular/material/chips";
import {MatIconModule} from "@angular/material/icon";
+import {MatAutocompleteModule} from "@angular/material/autocomplete";
+import { FileSearchComponent } from './components/file-search/file-search.component';
@NgModule({
declarations: [
@@ -36,28 +38,30 @@ import {MatIconModule} from "@angular/material/icon";
RepoFormComponent,
FileGridComponent,
FileGridEntryComponent,
+ FileSearchComponent,
],
- imports: [
- BrowserModule,
- AppRoutingModule,
- BrowserAnimationsModule,
- MatCardModule,
- MatListModule,
- MatButtonModule,
- MatToolbarModule,
- MatSnackBarModule,
- MatFormFieldModule,
- MatInputModule,
- ReactiveFormsModule,
- MatSidenavModule,
- MatGridListModule,
- MatProgressBarModule,
- MatPaginatorModule,
- ScrollingModule,
- LightboxModule,
- MatChipsModule,
- MatIconModule
- ],
+ imports: [
+ BrowserModule,
+ AppRoutingModule,
+ BrowserAnimationsModule,
+ MatCardModule,
+ MatListModule,
+ MatButtonModule,
+ MatToolbarModule,
+ MatSnackBarModule,
+ MatFormFieldModule,
+ MatInputModule,
+ ReactiveFormsModule,
+ MatSidenavModule,
+ MatGridListModule,
+ MatProgressBarModule,
+ MatPaginatorModule,
+ ScrollingModule,
+ LightboxModule,
+ MatChipsModule,
+ MatIconModule,
+ MatAutocompleteModule
+ ],
providers: [],
bootstrap: [AppComponent]
})
diff --git a/mediarepo-ui/src/app/components/file-search/file-search.component.html b/mediarepo-ui/src/app/components/file-search/file-search.component.html
new file mode 100644
index 0000000..a74f731
--- /dev/null
+++ b/mediarepo-ui/src/app/components/file-search/file-search.component.html
@@ -0,0 +1,23 @@
+
+
+
+ {{tag}}
+
+
+
+
+
+
+ {{tag}}
+
+
+
diff --git a/mediarepo-ui/src/app/components/file-search/file-search.component.scss b/mediarepo-ui/src/app/components/file-search/file-search.component.scss
new file mode 100644
index 0000000..47109f6
--- /dev/null
+++ b/mediarepo-ui/src/app/components/file-search/file-search.component.scss
@@ -0,0 +1,7 @@
+#tag-search {
+ width: 100%;
+}
+
+.full-width {
+ width: 100%;
+}
diff --git a/mediarepo-ui/src/app/components/file-search/file-search.component.spec.ts b/mediarepo-ui/src/app/components/file-search/file-search.component.spec.ts
new file mode 100644
index 0000000..c2d77de
--- /dev/null
+++ b/mediarepo-ui/src/app/components/file-search/file-search.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { FileSearchComponent } from './file-search.component';
+
+describe('FileSearchComponent', () => {
+ let component: FileSearchComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ FileSearchComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(FileSearchComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/mediarepo-ui/src/app/components/file-search/file-search.component.ts b/mediarepo-ui/src/app/components/file-search/file-search.component.ts
new file mode 100644
index 0000000..7240fcd
--- /dev/null
+++ b/mediarepo-ui/src/app/components/file-search/file-search.component.ts
@@ -0,0 +1,66 @@
+import {Component, ElementRef, OnInit, ViewChild} from '@angular/core';
+import {TagService} from "../../services/tag/tag.service";
+import {FileService} from "../../services/file/file.service";
+import {FormControl} from "@angular/forms";
+import {COMMA, ENTER} from "@angular/cdk/keycodes";
+import {MatChipInputEvent} from "@angular/material/chips";
+import {MatAutocompleteSelectedEvent} from "@angular/material/autocomplete";
+import {map, startWith} from "rxjs/operators";
+import {Observable} from "rxjs";
+
+@Component({
+ selector: 'app-file-search',
+ templateUrl: './file-search.component.html',
+ styleUrls: ['./file-search.component.scss']
+})
+export class FileSearchComponent {
+
+ public searchInputSeparators = [ENTER, COMMA];
+ public formControl = new FormControl();
+ public searchTags: string[] = [];
+ public suggestionTags: Observable;
+ private allTags: string[] = [];
+
+ @ViewChild('tagInput') tagInput!: ElementRef;
+
+ constructor(private tagService: TagService, private fileService: FileService) {
+ this.tagService.tags.subscribe(
+ (tag) => this.allTags = tag.map(t => t.getNormalizedOutput()));
+
+ this.suggestionTags = this.formControl.valueChanges.pipe(startWith(null), map(
+ (tag: string | null) => tag ? this.allTags.filter(
+ (t: string) => t.includes(tag)).slice(0, 20) : this.allTags.slice(0, 20)));
+ }
+
+ public async searchForFiles() {
+ await this.fileService.findFiles(this.searchTags);
+ }
+
+ public addSearchTag(tag: string) {
+ this.searchTags.push(tag);
+ }
+
+ async removeSearchTag(tag: string) {
+ const index = this.searchTags.indexOf(tag);
+ if (index >= 0) {
+ this.searchTags.splice(index, 1);
+ }
+ await this.searchForFiles();
+ }
+
+ async addSearchTagByChip(event: MatChipInputEvent) {
+ const tag = event.value.trim();
+ if (tag.length > 0 && this.allTags.includes(tag)) {
+ this.searchTags.push(tag);
+ event.chipInput?.clear();
+ this.formControl.setValue(null);
+ await this.searchForFiles(); }
+ }
+
+ async addSearchTagByAutocomplete(event: MatAutocompleteSelectedEvent) {
+ const tag = event.option.viewValue;
+ this.searchTags.push(tag);
+ this.formControl.setValue(null);
+ this.tagInput.nativeElement.value = '';
+ await this.searchForFiles(); }
+}
diff --git a/mediarepo-ui/src/app/pages/home/home.component.html b/mediarepo-ui/src/app/pages/home/home.component.html
index e9ad88f..f01c3a8 100644
--- a/mediarepo-ui/src/app/pages/home/home.component.html
+++ b/mediarepo-ui/src/app/pages/home/home.component.html
@@ -5,22 +5,7 @@