From 4a8c1cd25a8fc8d8bc2a734d2ed710bb3d91b790 Mon Sep 17 00:00:00 2001 From: Jamie Rees Date: Mon, 4 May 2020 22:11:43 +0100 Subject: [PATCH] Added filtering on status to the requests page --- .gitignore | 1 + src/Ombi.Core/Engine/MovieRequestEngine.cs | 15 +-- src/Ombi.Store/Context/OmbiContext.cs | 7 +- .../movies-grid/movies-grid.component.html | 124 ++++++++++-------- .../movies-grid/movies-grid.component.ts | 44 +++++-- .../requests-list/models/RequestFilterType.ts | 7 + .../src/app/services/requestV2.service.ts | 16 +++ .../src/app/settings/ombi/ombi.component.html | 4 +- src/Ombi/Controllers/V2/RequestsController.cs | 3 +- src/Ombi/wwwroot/translations/en.json | 7 +- 10 files changed, 150 insertions(+), 78 deletions(-) create mode 100644 src/Ombi/ClientApp/src/app/requests-list/models/RequestFilterType.ts diff --git a/.gitignore b/.gitignore index 1a2574bf5..1a1a229b8 100644 --- a/.gitignore +++ b/.gitignore @@ -248,3 +248,4 @@ _Pvt_Extensions *.vscode /src/Ombi/database.json /src/Ombi/healthchecksdb +/src/Ombi/ClientApp/package-lock.json diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index 08c2f1a9f..79211c5ce 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -267,10 +267,10 @@ namespace Ombi.Core.Engine allRequests = allRequests.Where(x => x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value)); break; case RequestStatus.Available: - allRequests = allRequests.Where(x => x.Available && (!x.Denied.HasValue || !x.Denied.Value)); + allRequests = allRequests.Where(x => x.Available); break; case RequestStatus.Denied: - allRequests = allRequests.Where(x => x.Denied.HasValue && x.Denied.Value); + allRequests = allRequests.Where(x => x.Denied.HasValue && x.Denied.Value && !x.Available); break; default: break; @@ -332,12 +332,11 @@ namespace Ombi.Core.Engine //var secondProp = TypeDescriptor.GetProperties(propType).Find(properties[1], true); } - allRequests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase) - ? allRequests.OrderBy(x => prop.GetValue(x)) - : allRequests.OrderByDescending(x => prop.GetValue(x)); - var total = await allRequests.CountAsync(); - var requests = await allRequests.Skip(position).Take(count) - .ToListAsync(); + var requests = (sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase) + ? allRequests.ToList().OrderBy(x => prop.GetValue(x)) + : allRequests.ToList().OrderByDescending(x => prop.GetValue(x))).ToList(); + var total = requests.Count(); + requests = requests.Skip(position).Take(count).ToList(); await CheckForSubscription(shouldHide, requests); return new RequestsViewModel diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 6e307b47b..2d06d4553 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -93,7 +93,7 @@ namespace Ombi.Store.Context } needToSave = true; - NotificationTemplates notificationToAdd; + NotificationTemplates notificationToAdd = null; switch (notificationType) { case NotificationType.NewRequest: @@ -207,7 +207,10 @@ namespace Ombi.Store.Context default: throw new ArgumentOutOfRangeException(); } - NotificationTemplates.Add(notificationToAdd); + if (notificationToAdd != null) + { + NotificationTemplates.Add(notificationToAdd); + } } } diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html index 228ae9cdb..079a1a081 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html @@ -1,57 +1,73 @@
- - - 10 - 15 - 30 - 100 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Requested By {{element.requestedUser?.userAlias}} Title {{element.title}} ({{element.releaseDate | amLocal | amDateFormat: - 'YYYY'}}) Request Date {{element.requestedDate | amLocal | amDateFormat: 'LL'}} Status {{element.status}} Request Status {{element.requestStatus | translate}} - - -
- - -
+ + +
+
+ + + + + +
+
+ +
+
+ + + 10 + 15 + 30 + 100 + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Requested By {{element.requestedUser?.userAlias}} Title {{element.title}} ({{element.releaseDate | amLocal | amDateFormat: 'YYYY'}}) Request Date {{element.requestedDate | amLocal | amDateFormat: 'LL'}} Status {{element.status}} Request Status {{element.requestStatus | translate}} + + +
+ + + \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts index e31e7ed66..340a85445 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts @@ -7,6 +7,7 @@ import { catchError, map, startWith, switchMap } from 'rxjs/operators'; import { RequestServiceV2 } from "../../../services/requestV2.service"; import { AuthService } from "../../../auth/auth.service"; import { StorageService } from "../../../shared/storage/storage-service"; +import { RequestFilterType } from "../../models/RequestFilterType"; @Component({ templateUrl: "./movies-grid.component.html", @@ -19,14 +20,19 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { public isLoadingResults = true; public displayedColumns: string[] = ['requestedUser.requestedBy', 'title', 'requestedDate', 'status', 'requestStatus', 'actions']; public gridCount: string = "15"; - public showUnavailableRequests: boolean; public isAdmin: boolean; public defaultSort: string = "requestedDate"; public defaultOrder: string = "desc"; + public RequestFilter = RequestFilterType; + + private currentFilter: RequestFilterType = RequestFilterType.All; + private storageKey = "Movie_DefaultRequestListSort"; private storageKeyOrder = "Movie_DefaultRequestListSortOrder"; private storageKeyGridCount = "Movie_DefaultGridCount"; + private storageKeyCurrentFilter = "Movie_DefaultFilter"; + private $data: Observable; @Output() public onOpenOptions = new EventEmitter<{ request: any, filter: any, onChange: any }>(); @@ -38,19 +44,25 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { } - public ngOnInit() { + public ngOnInit() { + this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser"); + const defaultCount = this.storageService.get(this.storageKeyGridCount); const defaultSort = this.storageService.get(this.storageKey); const defaultOrder = this.storageService.get(this.storageKeyOrder); + const defaultFilter = +this.storageService.get(this.storageKeyCurrentFilter); if (defaultSort) { this.defaultSort = defaultSort; } if (defaultOrder) { this.defaultOrder = defaultOrder; } - if(defaultCount) { + if (defaultCount) { this.gridCount = defaultCount; } + if (defaultFilter) { + this.currentFilter = defaultFilter; + } } public async ngAfterViewInit() { @@ -60,13 +72,12 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { // this.resultsLength = results.total; this.storageService.save(this.storageKeyGridCount, this.gridCount); - - this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser"); + this.storageService.save(this.storageKeyCurrentFilter, (+this.currentFilter).toString()); // If the user changes the sort order, reset back to the first page. this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0); - merge(this.sort.sortChange, this.paginator.page) + merge(this.sort.sortChange, this.paginator.page, this.currentFilter) .pipe( startWith({}), switchMap((value: any) => { @@ -92,11 +103,19 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { } public loadData(): Observable> { - if (this.showUnavailableRequests) { - return this.requestService.getMovieUnavailableRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); - } else { - return this.requestService.getMovieRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); + switch(RequestFilterType[RequestFilterType[this.currentFilter]]) { + case RequestFilterType.All: + return this.requestService.getMovieRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); + case RequestFilterType.Pending: + return this.requestService.getMoviePendingRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); + case RequestFilterType.Available: + return this.requestService.getMovieAvailableRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); + case RequestFilterType.Processing: + return this.requestService.getMovieProcessingRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); + case RequestFilterType.Denied: + return this.requestService.getMovieDeniedRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); } + } public openOptions(request: IMovieRequests) { @@ -112,4 +131,9 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { this.onOpenOptions.emit({ request: request, filter: filter, onChange: onChange }); } + + public switchFilter(type: RequestFilterType) { + this.currentFilter = type; + this.ngAfterViewInit(); + } } diff --git a/src/Ombi/ClientApp/src/app/requests-list/models/RequestFilterType.ts b/src/Ombi/ClientApp/src/app/requests-list/models/RequestFilterType.ts new file mode 100644 index 000000000..6c39b07af --- /dev/null +++ b/src/Ombi/ClientApp/src/app/requests-list/models/RequestFilterType.ts @@ -0,0 +1,7 @@ +export enum RequestFilterType { + All, + Pending, + Processing, + Available, + Denied +} diff --git a/src/Ombi/ClientApp/src/app/services/requestV2.service.ts b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts index a7dca2a19..a6c800f32 100644 --- a/src/Ombi/ClientApp/src/app/services/requestV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts @@ -17,6 +17,22 @@ export class RequestServiceV2 extends ServiceHelpers { return this.http.get>(`${this.url}movie/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); } + public getMovieAvailableRequests(count: number, position: number, sortProperty: string , order: string): Observable> { + return this.http.get>(`${this.url}movie/available/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); + } + + public getMovieProcessingRequests(count: number, position: number, sortProperty: string , order: string): Observable> { + return this.http.get>(`${this.url}movie/processing/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); + } + + public getMoviePendingRequests(count: number, position: number, sortProperty: string , order: string): Observable> { + return this.http.get>(`${this.url}movie/pending/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); + } + + public getMovieDeniedRequests(count: number, position: number, sortProperty: string , order: string): Observable> { + return this.http.get>(`${this.url}movie/denied/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); + } + public getTvRequests(count: number, position: number, sortProperty: string , order: string): Observable> { return this.http.get>(`${this.url}tv/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); } diff --git a/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.html b/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.html index 788b6e9b5..a3b34dd76 100644 --- a/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.html +++ b/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.html @@ -40,7 +40,7 @@
- Ignore any certificate errors + Ignore any certificate errors (Please restart after changing)
@@ -71,4 +71,4 @@
- + \ No newline at end of file diff --git a/src/Ombi/Controllers/V2/RequestsController.cs b/src/Ombi/Controllers/V2/RequestsController.cs index ec6745721..f78cfac21 100644 --- a/src/Ombi/Controllers/V2/RequestsController.cs +++ b/src/Ombi/Controllers/V2/RequestsController.cs @@ -35,8 +35,9 @@ namespace Ombi.Controllers.V2 { return await _movieRequestEngine.GetRequests(count, position, sort, sortOrder); } - + [HttpGet("movie/availble/{count:int}/{position:int}/{sort}/{sortOrder}")] + [HttpGet("movie/available/{count:int}/{position:int}/{sort}/{sortOrder}")] public async Task> GetAvailableRequests(int count, int position, string sort, string sortOrder) { return await _movieRequestEngine.GetRequestsByStatus(count, position, sort, sortOrder, RequestStatus.Available); diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index abc6eb2f6..23dc79a50 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -153,7 +153,12 @@ "NextHours": "Another request will be added in {{time}} hours", "NextMinutes": "Another request will be added in {{time}} minutes", "NextMinute": "Another request will be added in {{time}} minute" - } + }, + "AllRequests": "All Requests", + "PendingRequests": "Pending Requests", + "ProcessingRequests": "Processing Requests", + "AvailableRequests": "Available Requests", + "DeniedRequests": "Denied Requests" }, "Issues": { "Title": "Issues",