diff --git a/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs index 6e4c9dd89..bc1fa68d1 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Ombi.Core.Models.Requests; +using Ombi.Core.Models.UI; using Ombi.Store.Entities.Requests; namespace Ombi.Core.Engine.Interfaces @@ -18,5 +19,6 @@ namespace Ombi.Core.Engine.Interfaces Task ApproveMovie(MovieRequests request); Task ApproveMovieById(int requestId); Task DenyMovieById(int modelId, string denyReason); + Task> GetRequests(int count, int position, string sortProperty, string sortOrder); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index b43e516de..231c1d062 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -4,6 +4,7 @@ using Ombi.Helpers; using Ombi.Store.Entities; using System; using System.Collections.Generic; +using System.ComponentModel; using System.Globalization; using System.Linq; using System.Security.Principal; @@ -200,6 +201,54 @@ namespace Ombi.Core.Engine }; } + public async Task> GetRequests(int count, int position, string sortProperty, string sortOrder) + { + var shouldHide = await HideFromOtherUsers(); + IQueryable allRequests; + if (shouldHide.Hide) + { + allRequests = + MovieRepository.GetWithUser(shouldHide + .UserId); + } + else + { + allRequests = + MovieRepository + .GetWithUser(); + } + + var prop = TypeDescriptor.GetProperties(typeof(MovieRequests)).Find(sortProperty, true); + + if (sortProperty.Contains('.')) + { + // This is a navigation property currently not supported + prop = TypeDescriptor.GetProperties(typeof(MovieRequests)).Find("RequestedDate", true); + //var properties = sortProperty.Split(new []{'.'}, StringSplitOptions.RemoveEmptyEntries); + //var firstProp = TypeDescriptor.GetProperties(typeof(MovieRequests)).Find(properties[0], true); + //var propType = firstProp.PropertyType; + //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(); + requests.ForEach(async x => + { + x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath); + await CheckForSubscription(shouldHide, x); + }); + return new RequestsViewModel + { + Collection = requests, + Total = total + }; + + } + private IQueryable OrderMovies(IQueryable allRequests, OrderType type) { switch (type) diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/index.ts b/src/Ombi/ClientApp/src/app/requests-list/components/index.ts index fd3f7445c..9fee1c6d6 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/index.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/index.ts @@ -1,8 +1,16 @@ import { RequestsListComponent } from "./requests-list.component"; import { MoviesGridComponent } from "./movies-grid/movies-grid.component"; +import { RequestServiceV2 } from "../../services/requestV2.service"; +import { RequestService } from "../../services"; + export const components: any[] = [ RequestsListComponent, MoviesGridComponent, ]; + +export const providers: any[] = [ + RequestService, + RequestServiceV2, +]; 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 0ae9b89c8..2a9acf5b9 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,14 +1,25 @@ -
-
- +
+
+
+ +
+ + + 10 + 15 + 30 + 100 + + + - - + + @@ -24,13 +35,13 @@ - + - + - +
Requested By Requested By {{element.requestedUser?.userAlias}} Status Status {{element.status}} Request Status Request Status
{{'Common.ProcessingRequest' | translate}}
{{'Common.PendingApproval' | @@ -49,9 +60,9 @@
- +
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 29b86112e..60c0d0604 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 @@ -1,10 +1,11 @@ import { Component, AfterViewInit, ViewChild } from "@angular/core"; -import { RequestService } from "../../../services"; import { IMovieRequests, OrderType, FilterType, IRequestsViewModel } from "../../../interfaces"; import { MatPaginator, MatSort } from "@angular/material"; import { merge, Observable, of as observableOf } from 'rxjs'; import { catchError, map, startWith, switchMap } from 'rxjs/operators'; +import { RequestServiceV2 } from "../../../services/requestV2.service"; + @Component({ templateUrl: "./movies-grid.component.html", selector: "movies-grid", @@ -14,13 +15,13 @@ export class MoviesGridComponent implements AfterViewInit { public dataSource: IMovieRequests[] = []; public resultsLength: number; public isLoadingResults = true; - public displayedColumns: string[] = ['requestedBy', 'title', 'requestedDate', 'status', 'requestStatus', 'actions']; - public gridCount = 30; + public displayedColumns: string[] = ['requestedUser.requestedBy', 'title', 'requestedDate', 'status', 'requestStatus', 'actions']; + public gridCount: string = "15"; @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; - constructor(private requestService: RequestService) { + constructor(private requestService: RequestServiceV2) { } @@ -40,8 +41,7 @@ export class MoviesGridComponent implements AfterViewInit { this.isLoadingResults = true; // eturn this.exampleDatabase!.getRepoIssues( // this.sort.active, this.sort.direction, this.paginator.pageIndex); - return this.requestService.getMovieRequests(this.gridCount, this.paginator.pageIndex * this.gridCount, OrderType.RequestedDateDesc, - { availabilityFilter: FilterType.None, statusFilter: FilterType.None}); + return this.requestService.getMovieRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); }), map((data: IRequestsViewModel) => { // Flip flag to show that loading has finished. diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.scss b/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.scss index 041f7e285..1d1ce17cf 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.scss +++ b/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.scss @@ -5,14 +5,9 @@ .table { width: 100%; + height:100%; } -.example-table-container { - position: relative; - max-height: 400px; - overflow: auto; - } - -.example-loading-shade { +.loading-shade { position: absolute; top: 0; left: 0; diff --git a/src/Ombi/ClientApp/src/app/requests-list/requests-list.module.ts b/src/Ombi/ClientApp/src/app/requests-list/requests-list.module.ts index 26c04d32a..c6d7157c8 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/requests-list.module.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/requests-list.module.ts @@ -1,7 +1,6 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; -import { RequestService } from "../services"; import { SharedModule } from "../shared/shared.module"; import { PipeModule } from "../pipes/pipe.module"; @@ -22,15 +21,15 @@ const routes: Routes = [ ], declarations: [ ...fromComponents.components - ], + ], exports: [ RouterModule, ], entryComponents: [ ], providers: [ - RequestService, - ], + ...fromComponents.providers + ], }) export class RequestsListModule { } diff --git a/src/Ombi/ClientApp/src/app/services/requestV2.service.ts b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts new file mode 100644 index 000000000..3c439214f --- /dev/null +++ b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts @@ -0,0 +1,20 @@ +import { PlatformLocation } from "@angular/common"; +import { Injectable } from "@angular/core"; + +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; +import { ServiceHelpers } from "./service.helpers"; +import { IRequestsViewModel, IMovieRequests } from "../interfaces"; + + +@Injectable() +export class RequestServiceV2 extends ServiceHelpers { + constructor(http: HttpClient, public platformLocation: PlatformLocation) { + super(http, "/api/v2/Requests/", platformLocation); + } + + public getMovieRequests(count: number, position: number, sortProperty: string , order: string): Observable> { + return this.http.get>(`${this.url}movie/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); + } + +} diff --git a/src/Ombi/Controllers/V2/RequestsController.cs b/src/Ombi/Controllers/V2/RequestsController.cs new file mode 100644 index 000000000..5d351f752 --- /dev/null +++ b/src/Ombi/Controllers/V2/RequestsController.cs @@ -0,0 +1,38 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; + +using System.Threading.Tasks; + +using Ombi.Core; +using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Models.UI; +using Ombi.Store.Entities.Requests; + +namespace Ombi.Controllers.V2 +{ + [ApiV2] + [Authorize] + [ApiController] + public class RequestsController : ControllerBase + { + public RequestsController(IMovieRequestEngine movieRequestEngine) + { + _movieRequestEngine = movieRequestEngine; + } + + private readonly IMovieRequestEngine _movieRequestEngine; + + /// + /// Gets movie requests. + /// + /// The count of items you want to return. e.g. 30 + /// The position. e.g. position 60 for a 2nd page (since we have already got the first 30 items) + /// The item to sort on e.g. "requestDate" + /// asc or desc + [HttpGet("movie/{count:int}/{position:int}/{sort}/{sortOrder}")] + public async Task> GetRequests(int count, int position, string sort, string sortOrder) + { + return await _movieRequestEngine.GetRequests(count, position, sort, sortOrder); + } + } +} \ No newline at end of file