diff --git a/mediarepo-ui/src/api/models/SortKey.ts b/mediarepo-ui/src/api/models/SortKey.ts index 674237e..6ed1d57 100644 --- a/mediarepo-ui/src/api/models/SortKey.ts +++ b/mediarepo-ui/src/api/models/SortKey.ts @@ -69,13 +69,17 @@ export class SortKey { } } + public get rawData(): SortKeyData { + return this.data; + } + public static fromValues( sortType: SortType, sortDirection: SortDirection, namespaceName: string | undefined ) { let data; - + if (sortType === "Namespace") { data = { Namespace: { @@ -99,8 +103,4 @@ export class SortKey { return `${this.sortType} ${this.sortDirection}`; } } - - public rawData(): SortKeyData { - return this.data; - } } diff --git a/mediarepo-ui/src/api/models/SortingPreset.ts b/mediarepo-ui/src/api/models/SortingPreset.ts index 9eb258a..43bc7f3 100644 --- a/mediarepo-ui/src/api/models/SortingPreset.ts +++ b/mediarepo-ui/src/api/models/SortingPreset.ts @@ -1,20 +1,39 @@ import {SortKey} from "./SortKey"; import {SortingPresetData} from "../api-types/presets"; +import {mapNew} from "./adaptors"; export class SortingPreset { - private readonly _id: number; private keys: SortKey[]; constructor(presetData: SortingPresetData) { this._id = presetData.id; - this.keys = presetData.keys.map(SortKey.fromRawData); + this.keys = presetData.keys.map(mapNew(SortKey)); } + private _id: number; + public get id(): number { return this._id; } + public set id(value: number) { + this._id = value; + } + public get sortKeys(): SortKey[] { - return this.sortKeys; + return this.keys; + } + + public get rawData(): SortingPresetData { + return { + id: this._id, + keys: this.keys.map(k => k.rawData), + }; + } + + public static fromValues(id: number, keys: SortKey[]) { + let preset = new SortingPreset({ id, keys: [] }); + preset.keys = keys; + return preset; } } diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.html b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.html index e4de89f..f9e7f61 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.html +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.html @@ -35,7 +35,8 @@ - + diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts index 9737c2d..7c6f149 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/file-search.component.ts @@ -9,7 +9,6 @@ import { Output, ViewChild } from "@angular/core"; -import {SortKey} from "../../../../../api/models/SortKey"; import {MatDialog} from "@angular/material/dialog"; import {SortDialogComponent} from "./sort-dialog/sort-dialog.component"; import {LoggingService} from "../../../../services/logging/logging.service"; @@ -23,6 +22,7 @@ import {FileStatus, FilterExpression,} from "../../../../../api/api-types/files" import {filterExpressionToString} from "../../../../utils/filter-utils"; import {MatCheckboxChange} from "@angular/material/checkbox"; import * as deepEqual from "fast-deep-equal"; +import {SortingPreset} from "../../../../../api/models/SortingPreset"; @Component({ @@ -32,7 +32,7 @@ import * as deepEqual from "fast-deep-equal"; changeDetection: ChangeDetectionStrategy.OnPush }) export class FileSearchComponent implements AfterViewChecked, OnInit { - public sortExpression: SortKey[] = []; + public sortingPreset: SortingPreset = new SortingPreset({ id: -1, keys: [] }); public filters: SearchFilters = new SearchFilters([]); @Input() availableTags: Tag[] = []; @@ -68,7 +68,7 @@ export class FileSearchComponent implements AfterViewChecked, OnInit { this.filters = f; this.assignDisplayedFilters(); }); - this.state.sortKeys.subscribe(s => this.sortExpression = s); + this.state.sortingPreset.subscribe(s => this.sortingPreset = s); this.applyStatusFromFilters(); this.needsScroll = true; this.assignDisplayedFilters(); @@ -127,20 +127,18 @@ export class FileSearchComponent implements AfterViewChecked, OnInit { } public openSortDialog() { - const sortEntries = this.sortExpression.map( - key => JSON.parse(JSON.stringify(key.rawData()))).map( - data => new SortKey(data)); + const sortingPreset = new SortingPreset(JSON.parse(JSON.stringify(this.sortingPreset.rawData))); const openedDialog = this.dialog.open(SortDialogComponent, { minWidth: "40vw", data: { - sortEntries, + sortingPreset, }, disableClose: true, }); - openedDialog.afterClosed().subscribe(async (sortExpression) => { - if (sortExpression) { - this.sortExpression = sortExpression; - this.state.setSortKeys(this.sortExpression); + openedDialog.afterClosed().subscribe(async (sortingPreset) => { + if (sortingPreset) { + this.sortingPreset = sortingPreset; + this.state.setSortingPreset(this.sortingPreset); } }); } diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.html b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.html index c6fc105..a350274 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.html +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.html @@ -1,7 +1,7 @@

Sort Entries

-
+
@@ -21,14 +21,16 @@ Namespace Name - - + {{namespace.name}} @@ -37,16 +39,18 @@
Direction - + Ascending Descending - - diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.ts b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.ts index 4bd7271..76b65d7 100644 --- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.ts +++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.ts @@ -5,6 +5,7 @@ import {CdkDragDrop, moveItemInArray} from "@angular/cdk/drag-drop"; import {Namespace} from "../../../../../../api/models/Namespace"; import {TagService} from "../../../../../services/tag/tag.service"; import {compareSearchResults} from "../../../../../utils/compare-utils"; +import {SortingPreset} from "../../../../../../api/models/SortingPreset"; @Component({ selector: "app-sort-dialog", @@ -14,31 +15,34 @@ import {compareSearchResults} from "../../../../../utils/compare-utils"; }) export class SortDialogComponent { - public sortEntries: SortKey[] = []; + public sortingPreset: SortingPreset = SortingPreset.fromValues(-1, []); public suggestedNamespaces: Namespace[] = []; + private previousId: number = -1; private namespaces: Namespace[] = []; constructor(public tagService: TagService, public dialogRef: MatDialogRef, @Inject( MAT_DIALOG_DATA) data: any) { - this.sortEntries = data.sortEntries; - console.debug(this.sortEntries); + this.sortingPreset = data.sortingPreset; + console.debug(this.sortingPreset); tagService.namespaces.subscribe( namespaces => this.namespaces = namespaces); } addNewSortKey() { const sortKey = SortKey.fromValues("FileName", "Ascending", undefined); - this.sortEntries.push(sortKey); + this.handlePresetChange(); + this.sortingPreset.sortKeys.push(sortKey); } public removeSortKey(sortKey: SortKey): void { - const index = this.sortEntries.indexOf(sortKey); - this.sortEntries.splice(index, 1); + const index = this.sortingPreset.sortKeys.indexOf(sortKey); + this.handlePresetChange(); + this.sortingPreset.sortKeys.splice(index, 1); } public confirmSort(): void { - this.dialogRef.close(this.sortEntries); + this.dialogRef.close(this.sortingPreset); } public cancelSort(): void { @@ -46,7 +50,8 @@ export class SortDialogComponent { } public onSortEntryDrop(event: CdkDragDrop): void { - moveItemInArray(this.sortEntries, event.previousIndex, + this.handlePresetChange(); + moveItemInArray(this.sortingPreset.sortKeys, event.previousIndex, event.currentIndex ); } @@ -56,4 +61,11 @@ export class SortDialogComponent { (a, b) => compareSearchResults(value, a.name, b.name)) .slice(0, 50); } + + public handlePresetChange() { + if (this.sortingPreset.id >= 0) { + this.previousId = this.sortingPreset.id; + this.sortingPreset.id = -1; + } + } } diff --git a/mediarepo-ui/src/app/models/TabState.ts b/mediarepo-ui/src/app/models/TabState.ts index 2798640..fc75b1b 100644 --- a/mediarepo-ui/src/app/models/TabState.ts +++ b/mediarepo-ui/src/app/models/TabState.ts @@ -6,7 +6,7 @@ import {SortKey} from "../../api/models/SortKey"; import {debounceTime} from "rxjs/operators"; import {mapNew} from "../../api/models/adaptors"; import {SearchFilters} from "../../api/models/SearchFilters"; -import {SortKeyData} from "../../api/api-types/files"; +import {SortingPreset} from "../../api/models/SortingPreset"; export class TabState { public uuid: number; @@ -17,12 +17,14 @@ export class TabState { public files = new BehaviorSubject([]); public filters = new BehaviorSubject(new SearchFilters([])); - public sortKeys = new BehaviorSubject( + public sortingPreset = new BehaviorSubject(SortingPreset.fromValues( + -1, [SortKey.fromValues( "FileImportedTime", "Ascending", undefined - )]); + )] + )); private fileService: FileService; @@ -37,7 +39,7 @@ export class TabState { if (this.category === TabCategory.Files) { this.filters.pipe(debounceTime(500)) .subscribe(async () => await this.findFiles()); - this.sortKeys.pipe(debounceTime(100)) + this.sortingPreset.pipe(debounceTime(100)) .subscribe(async () => await this.findFiles()); } } @@ -51,9 +53,9 @@ export class TabState { dto.category, fileService ); - const sortKeys = dto.sortKeys.map((data: SortKeyData) => new SortKey(data)); + state.filters.next(new SearchFilters(dto.filters ?? [])); - state.sortKeys.next(sortKeys); + state.sortingPreset.next(new SortingPreset(dto.sortingPreset)); state.mode.next(dto.mode ?? "grid"); state.selectedCD.next(dto.selectedFileHash); state.files.next((dto.files ?? []).map(mapNew(File))); @@ -65,7 +67,7 @@ export class TabState { this.loading.next(true); const files = await this.fileService.findFiles( this.filters.value, - this.sortKeys.value + this.sortingPreset.value.sortKeys ); this.files.next(files); this.loading.next(false); @@ -75,8 +77,8 @@ export class TabState { this.filters.next(filters); } - public setSortKeys(keys: SortKey[]) { - this.sortKeys.next(keys); + public setSortingPreset(preset: SortingPreset) { + this.sortingPreset.next(preset); } public getDTO(): any { @@ -84,7 +86,7 @@ export class TabState { uuid: this.uuid, category: this.category, filters: this.filters.value.getFilters(), - sortKeys: this.sortKeys.value.map(key => key.rawData()), + sortingPreset: this.sortingPreset.value.rawData, mode: this.mode.value, selectedFileHash: this.selectedCD.value, files: this.category === TabCategory.Import ? this.files.value.map( diff --git a/mediarepo-ui/src/app/services/file/file.service.ts b/mediarepo-ui/src/app/services/file/file.service.ts index 4f2e549..ab783a9 100644 --- a/mediarepo-ui/src/app/services/file/file.service.ts +++ b/mediarepo-ui/src/app/services/file/file.service.ts @@ -26,7 +26,7 @@ export class FileService { return MediarepoApi.findFiles( { filters: filters.getFilters(), - sortBy: sortBy.map(k => k.rawData()) + sortBy: sortBy.map(k => k.rawData) }) .then(mapMany(mapNew(File))); } diff --git a/mediarepo-ui/src/app/services/state/state.service.ts b/mediarepo-ui/src/app/services/state/state.service.ts index 00a4738..3d2a0f7 100644 --- a/mediarepo-ui/src/app/services/state/state.service.ts +++ b/mediarepo-ui/src/app/services/state/state.service.ts @@ -59,6 +59,16 @@ export class StateService { this.state.next(state); } + /** + * Sets the state of the frontend + * @returns {Promise} + */ + public async saveState(): Promise { + if (this.repoService.selectedRepository.value) { + await MediarepoApi.setFrontendState({ state: this.state.value.serializeJson() }); + } + } + private subscribeToState(state: AppState) { state.tabs.subscribe(async tabs => { this.tabSubscriptions.forEach(s => s.unsubscribe()); @@ -70,7 +80,7 @@ export class StateService { private subscribeToTab(tab: TabState) { this.tabSubscriptions.push(tab.filters .subscribe(() => this.stateChange.next())); - this.tabSubscriptions.push(tab.sortKeys + this.tabSubscriptions.push(tab.sortingPreset .subscribe(() => this.stateChange.next())); this.tabSubscriptions.push( tab.selectedCD.subscribe(() => this.stateChange.next())); @@ -78,14 +88,4 @@ export class StateService { tab.mode.subscribe(() => this.stateChange.next())); this.tabSubscriptions.push(tab.files.subscribe(() => this.stateChange.next())); } - - /** - * Sets the state of the frontend - * @returns {Promise} - */ - public async saveState(): Promise { - if (this.repoService.selectedRepository.value) { - await MediarepoApi.setFrontendState({state: this.state.value.serializeJson()}); - } - } }