diff --git a/mediarepo-ui/src/api/api-types/requests.ts b/mediarepo-ui/src/api/api-types/requests.ts
index e58e50c..f0bec62 100644
--- a/mediarepo-ui/src/api/api-types/requests.ts
+++ b/mediarepo-ui/src/api/api-types/requests.ts
@@ -110,7 +110,7 @@ export type RunJobRequest = {
};
export type AddSortingPresetRequest = {
- sort_keys: SortKeyData[]
+ sortKeys: SortKeyData[]
};
export type DeleteSortingPresetRequest = {
diff --git a/mediarepo-ui/src/api/models/SortKey.ts b/mediarepo-ui/src/api/models/SortKey.ts
index 6ed1d57..bf85cb4 100644
--- a/mediarepo-ui/src/api/models/SortKey.ts
+++ b/mediarepo-ui/src/api/models/SortKey.ts
@@ -98,9 +98,13 @@ export class SortKey {
public toString(): string {
if (this.sortType == "Namespace") {
- return `${this.sortType} '${this.namespaceName}' ${this.sortDirection}`;
+ return `${this.sortType} '${this.namespaceName}' ${this.getDirectionString()}`;
} else {
- return `${this.sortType} ${this.sortDirection}`;
+ return `${this.sortType} ${this.getDirectionString()}`;
}
}
+
+ private getDirectionString(): string {
+ return this.sortDirection === "Ascending" ? "▲" : "▼";
+ }
}
diff --git a/mediarepo-ui/src/api/models/SortingPreset.ts b/mediarepo-ui/src/api/models/SortingPreset.ts
index 5fe3d28..1b0dc9b 100644
--- a/mediarepo-ui/src/api/models/SortingPreset.ts
+++ b/mediarepo-ui/src/api/models/SortingPreset.ts
@@ -37,6 +37,11 @@ export class SortingPreset {
return preset;
}
+ public setData(data: SortingPresetData) {
+ this._id = data.id;
+ this.keys = data.keys.map(mapNew(SortKey));
+ }
+
public toString(): string {
return this.sortKeys.join(", ");
}
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.html b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.html
index 5bfa0a4..74c859c 100644
--- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.html
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.html
@@ -4,11 +4,5 @@
class="sort-button"
mat-flat-button>
Sort:
-
- {{key.sortType}}
- {{key.namespaceName}}
-
-
- |
-
+
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss
index 1fad7f8..4448aea 100644
--- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-button/sort-button.component.scss
@@ -7,21 +7,3 @@
text-overflow: ellipsis;
overflow: hidden;
}
-
-.sort-key-direction {
- font-size: 1.5em;
- vertical-align: bottom;
- margin-bottom: 0.6em;
-}
-
-.sort-key-type {
- color: $primary-lighter-50
-}
-
-.sort-key-namespace {
- color: $accent-lighter-10;
-}
-
-.sort-key:last-child .key-divider {
- display: none;
-}
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 a350274..9d0c74b 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,5 +1,19 @@
-
+
0" class="preset-selection">
+ Preset
+
+
+
+ {{preset.toString()}}
+
+
+
-
+
+
+
+
+
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.scss b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.scss
index 03a3540..81d185d 100644
--- a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.scss
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-dialog/sort-dialog.component.scss
@@ -18,12 +18,17 @@ mat-form-field, .filler, .drag-handle {
}
.dialog-actions {
- display: flex;
- flex-direction: row-reverse;
width: 100%;
+ display: block;
button {
margin-left: 1em;
+ float: right;
+ }
+
+ button.button-left {
+ float: left;
+ margin-right: 1em;
}
}
@@ -57,3 +62,9 @@ mat-form-field, .filler, .drag-handle {
background-color: darken(dimgrey, 20);
border-radius: 1em;
}
+
+.preset-selection {
+ width: calc(100% - 2em);
+ display: block;
+ font-size: 1em;
+}
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 76b65d7..fb9fdfc 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
@@ -1,4 +1,4 @@
-import {ChangeDetectionStrategy, Component, Inject} from "@angular/core";
+import {ChangeDetectionStrategy, ChangeDetectorRef, Component, Inject, OnInit} from "@angular/core";
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
import {SortKey} from "../../../../../../api/models/SortKey";
import {CdkDragDrop, moveItemInArray} from "@angular/cdk/drag-drop";
@@ -6,6 +6,8 @@ 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";
+import {PresetService} from "../../../../../services/preset/preset.service";
+import {LoggingService} from "../../../../../services/logging/logging.service";
@Component({
selector: "app-sort-dialog",
@@ -13,22 +15,36 @@ import {SortingPreset} from "../../../../../../api/models/SortingPreset";
styleUrls: ["./sort-dialog.component.scss"],
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class SortDialogComponent {
+export class SortDialogComponent implements OnInit {
public sortingPreset: SortingPreset = SortingPreset.fromValues(-1, []);
+ public availablePresets: SortingPreset[] = [];
public suggestedNamespaces: Namespace[] = [];
+ public emptyPreset = SortingPreset.fromValues(-1, []);
- private previousId: number = -1;
+ public previousId: number = -1;
private namespaces: Namespace[] = [];
- constructor(public tagService: TagService, public dialogRef: MatDialogRef
, @Inject(
- MAT_DIALOG_DATA) data: any) {
+ constructor(
+ public logger: LoggingService,
+ public tagService: TagService,
+ public presetService: PresetService,
+ public changeDetector: ChangeDetectorRef,
+ public dialogRef: MatDialogRef,
+ @Inject(
+ MAT_DIALOG_DATA) data: any
+ ) {
this.sortingPreset = data.sortingPreset;
+ this.previousId = this.sortingPreset.id;
console.debug(this.sortingPreset);
tagService.namespaces.subscribe(
namespaces => this.namespaces = namespaces);
}
+ public async ngOnInit() {
+ this.availablePresets = await this.presetService.getAllSortingPresets();
+ }
+
addNewSortKey() {
const sortKey = SortKey.fromValues("FileName", "Ascending", undefined);
this.handlePresetChange();
@@ -68,4 +84,43 @@ export class SortDialogComponent {
this.sortingPreset.id = -1;
}
}
+
+ public async savePreset() {
+ await this.deletePreset();
+ await this.saveNewPreset();
+ }
+
+ public async saveNewPreset() {
+ let newPreset = await this.logger.try(() => this.presetService.addSortingPreset(this.sortingPreset.sortKeys));
+ if (newPreset) {
+ this.sortingPreset.setData(newPreset.rawData);
+ this.previousId = this.sortingPreset.id;
+ this.availablePresets.push(new SortingPreset(JSON.parse(JSON.stringify(newPreset.rawData))));
+ this.changeDetector.detectChanges();
+ }
+ }
+
+ public async deletePreset() {
+ if (this.previousId >= 0) {
+ const index = this.availablePresets.findIndex(p => p.id == this.previousId);
+ if (index >= 0) {
+ this.availablePresets.splice(index, 1);
+ this.changeDetector.detectChanges();
+ }
+ try {
+ await this.presetService.deleteSortingPreset(this.previousId);
+ } catch (err: any) {
+ this.logger.warn(`Could not delete previous preset: ${err.message}`);
+ }
+ }
+ }
+
+ public selectPreset(presetId: number): void {
+ const preset = this.availablePresets.find(p => p.id == presetId);
+
+ if (preset) {
+ this.sortingPreset.setData(JSON.parse(JSON.stringify(preset.rawData)));
+ this.previousId = preset.id;
+ }
+ }
}
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.html b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.html
new file mode 100644
index 0000000..7300b4e
--- /dev/null
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.html
@@ -0,0 +1,7 @@
+
+ {{key.sortType}}
+ {{key.namespaceName}}
+
+
+ |
+
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.scss b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.scss
new file mode 100644
index 0000000..667f8ea
--- /dev/null
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.scss
@@ -0,0 +1,20 @@
+@import "src/colors";
+
+
+.sort-key-direction {
+ font-size: 1.5em;
+ vertical-align: bottom;
+ margin-bottom: 0.6em;
+}
+
+.sort-key-type {
+ color: $primary-lighter-50
+}
+
+.sort-key-namespace {
+ color: $accent-lighter-10;
+}
+
+.sort-key:last-child .key-divider {
+ display: none;
+}
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.spec.ts b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.spec.ts
new file mode 100644
index 0000000..1756cd3
--- /dev/null
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.spec.ts
@@ -0,0 +1,25 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { SortPresetItemComponent } from './sort-preset-item.component';
+
+describe('SortPresetItemComponent', () => {
+ let component: SortPresetItemComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [ SortPresetItemComponent ]
+ })
+ .compileComponents();
+ });
+
+ beforeEach(() => {
+ fixture = TestBed.createComponent(SortPresetItemComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.ts b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.ts
new file mode 100644
index 0000000..7e18532
--- /dev/null
+++ b/mediarepo-ui/src/app/components/shared/sidebar/file-search/sort-preset-item/sort-preset-item.component.ts
@@ -0,0 +1,16 @@
+import {ChangeDetectionStrategy, Component, Input} from "@angular/core";
+import {SortingPreset} from "../../../../../../api/models/SortingPreset";
+
+@Component({
+ selector: "app-sort-preset-item",
+ templateUrl: "./sort-preset-item.component.html",
+ styleUrls: ["./sort-preset-item.component.scss"],
+ changeDetection: ChangeDetectionStrategy.OnPush
+})
+export class SortPresetItemComponent {
+
+ @Input() preset!: SortingPreset;
+
+ constructor() {
+ }
+}
diff --git a/mediarepo-ui/src/app/components/shared/sidebar/sidebar.module.ts b/mediarepo-ui/src/app/components/shared/sidebar/sidebar.module.ts
index 57b8de1..211fb91 100644
--- a/mediarepo-ui/src/app/components/shared/sidebar/sidebar.module.ts
+++ b/mediarepo-ui/src/app/components/shared/sidebar/sidebar.module.ts
@@ -52,6 +52,7 @@ import {GetTagQueryPipe} from "./file-search/filter-pipes/get-tag-query.pipe";
import {GetPropertyQueryPipe} from "./file-search/filter-pipes/get-property-query.pipe";
import {SortButtonComponent} from "./file-search/sort-button/sort-button.component";
import {MatTooltipModule} from "@angular/material/tooltip";
+import { SortPresetItemComponent } from './file-search/sort-preset-item/sort-preset-item.component';
@NgModule({
@@ -71,6 +72,7 @@ import {MatTooltipModule} from "@angular/material/tooltip";
GetTagQueryPipe,
GetPropertyQueryPipe,
SortButtonComponent,
+ SortPresetItemComponent,
],
exports: [
TagEditComponent,
diff --git a/mediarepo-ui/src/app/services/preset/preset.service.ts b/mediarepo-ui/src/app/services/preset/preset.service.ts
index 32fb28b..1b41688 100644
--- a/mediarepo-ui/src/app/services/preset/preset.service.ts
+++ b/mediarepo-ui/src/app/services/preset/preset.service.ts
@@ -2,6 +2,7 @@ import {Injectable} from "@angular/core";
import {SortingPreset} from "../../../api/models/SortingPreset";
import {MediarepoApi} from "../../../api/Api";
import {mapMany, mapNew} from "../../../api/models/adaptors";
+import {SortKey} from "../../../api/models/SortKey";
@Injectable({
providedIn: "root"
@@ -14,4 +15,12 @@ export class PresetService {
public async getAllSortingPresets(): Promise {
return MediarepoApi.getAllSortingPresets().then(mapMany(mapNew(SortingPreset)));
}
+
+ public async addSortingPreset(keys: SortKey[]): Promise {
+ return MediarepoApi.addSortingPreset({ sortKeys: keys.map(k => k.rawData) }).then(mapNew(SortingPreset));
+ }
+
+ public async deleteSortingPreset(id: number): Promise {
+ return MediarepoApi.deleteSortingPreset({ id });
+ }
}