From d5ec4298931441133bce080dfb27bb16ddebdf37 Mon Sep 17 00:00:00 2001 From: "Jamie.Rees" Date: Fri, 2 Jun 2017 15:09:57 +0100 Subject: [PATCH] Request Grid test --- .../Engine/MovieRequestEngineTests.cs | 131 ++++++++++++++++++ .../Engine/TvRequestEngineTests.cs | 130 +++++++++++++++++ .../Rule/AutoApproveRuleTests.cs | 8 +- .../Rule/CanRequestRuleTests.cs | 8 +- .../Engine/Interfaces/IMovieRequestEngine.cs | 15 +- .../Engine/Interfaces/IRequestEngine.cs | 17 +++ .../Engine/Interfaces/ITvRequestEngine.cs | 13 +- src/Ombi.Core/Engine/MovieRequestEngine.cs | 27 +++- src/Ombi.Core/Engine/TvRequestEngine.cs | 31 ++++- src/Ombi/Controllers/RequestController.cs | 73 +++++++--- src/Ombi/Models/RequestGridModel.cs | 12 ++ src/Ombi/Ombi.csproj | 30 ++++ src/Ombi/Styles/_imports.scss | 1 + src/Ombi/gulpfile.js | 9 +- src/Ombi/package.json | 1 + src/Ombi/wwwroot/app/app.module.ts | 29 ++-- .../wwwroot/app/interfaces/IRequestModel.ts | 6 + .../app/requests/request-card.component.html | 3 + .../app/requests/request-card.component.ts | 12 ++ .../app/requests/request-grid.component.html | 39 ++++++ .../app/requests/request-grid.component.ts | 37 +++++ .../wwwroot/app/services/request.service.ts | 10 +- .../app/settings/radarr/radarr.component.html | 6 +- .../app/settings/sonarr/sonarr.component.html | 6 +- 24 files changed, 583 insertions(+), 71 deletions(-) create mode 100644 src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs create mode 100644 src/Ombi.Core.Tests/Engine/TvRequestEngineTests.cs create mode 100644 src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs create mode 100644 src/Ombi/Models/RequestGridModel.cs create mode 100644 src/Ombi/wwwroot/app/requests/request-card.component.html create mode 100644 src/Ombi/wwwroot/app/requests/request-card.component.ts create mode 100644 src/Ombi/wwwroot/app/requests/request-grid.component.html create mode 100644 src/Ombi/wwwroot/app/requests/request-grid.component.ts diff --git a/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs b/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs new file mode 100644 index 000000000..801472f4f --- /dev/null +++ b/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs @@ -0,0 +1,131 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Moq; +using Ombi.Core.Engine; +using Ombi.Core.Models.Requests; +using Ombi.Core.Models.Requests.Movie; +using Ombi.Core.Requests.Models; +using Xunit; + +namespace Ombi.Core.Tests.Engine +{ + public class MovieRequestEngineTests + { + public MovieRequestEngineTests() + { + RequestService = new Mock>(); + var requestService = new RequestService(null, RequestService.Object); + Engine = new MovieRequestEngine(null, requestService, null, null, null); + } + + private MovieRequestEngine Engine { get; } + private Mock> RequestService { get; } + + [Fact] + public async Task GetNewRequests_Should_ReturnEmpty_WhenThereAreNoNewRequests() + { + var requests = new List + { + new MovieRequestModel { Available = true }, + new MovieRequestModel { Approved = true }, + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetNewRequests(); + + Assert.False(result.Any()); + } + + [Fact] + public async Task GetNewRequests_Should_ReturnOnlyNewRequests_WhenThereAreMultipleRequests() + { + var requests = new List + { + new MovieRequestModel { Available = true }, + new MovieRequestModel { Approved = true }, + new MovieRequestModel(), + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetNewRequests(); + + Assert.Equal(result.Count(), 1); + Assert.All(result, x => + { + Assert.Equal(x.Available, false); + Assert.Equal(x.Approved, false); + }); + } + + [Fact] + public async Task GetApprovedRequests_Should_ReturnEmpty_WhenThereAreNoApprovedRequests() + { + var requests = new List + { + new MovieRequestModel { Available = true }, + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetApprovedRequests(); + + Assert.False(result.Any()); + } + + [Fact] + public async Task GetApprovedRequests_Should_ReturnOnlyApprovedRequests_WhenThereAreMultipleRequests() + { + var requests = new List + { + new MovieRequestModel { Available = true }, + new MovieRequestModel { Approved = true }, + new MovieRequestModel(), + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetApprovedRequests(); + + Assert.Equal(result.Count(), 1); + Assert.All(result, x => + { + Assert.Equal(x.Available, false); + Assert.Equal(x.Approved, true); + }); + } + + [Fact] + public async Task GetAvailableRequests_Should_ReturnEmpty_WhenThereAreNoAvailableRequests() + { + var requests = new List + { + new MovieRequestModel { Approved = true }, + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetAvailableRequests(); + + Assert.False(result.Any()); + } + + [Fact] + public async Task GetAvailableRequests_Should_ReturnOnlyAvailableRequests_WhenThereAreMultipleRequests() + { + var requests = new List + { + new MovieRequestModel { Available = true }, + new MovieRequestModel { Approved = true }, + new MovieRequestModel(), + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetAvailableRequests(); + + Assert.Equal(result.Count(), 1); + Assert.All(result, x => + { + Assert.Equal(x.Available, true); + Assert.Equal(x.Approved, false); + }); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Core.Tests/Engine/TvRequestEngineTests.cs b/src/Ombi.Core.Tests/Engine/TvRequestEngineTests.cs new file mode 100644 index 000000000..66a31d142 --- /dev/null +++ b/src/Ombi.Core.Tests/Engine/TvRequestEngineTests.cs @@ -0,0 +1,130 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Moq; +using Ombi.Core.Engine; +using Ombi.Core.Models.Requests; +using Ombi.Core.Requests.Models; +using Xunit; + +namespace Ombi.Core.Tests.Engine +{ + public class TvRequestEngineTests + { + public TvRequestEngineTests() + { + RequestService = new Mock>(); + var requestService = new RequestService(RequestService.Object, null); + Engine = new TvRequestEngine(null, requestService, null, null, null, null); + } + + private TvRequestEngine Engine { get; } + private Mock> RequestService { get; } + + [Fact] + public async Task GetNewRequests_Should_ReturnEmpty_WhenThereAreNoNewRequests() + { + var requests = new List + { + new TvRequestModel { Available = true }, + new TvRequestModel { Approved = true }, + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetNewRequests(); + + Assert.False(result.Any()); + } + + [Fact] + public async Task GetNewRequests_Should_ReturnOnlyNewRequests_WhenThereAreMultipleRequests() + { + var requests = new List + { + new TvRequestModel { Available = true }, + new TvRequestModel { Approved = true }, + new TvRequestModel(), + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetNewRequests(); + + Assert.Equal(result.Count(), 1); + Assert.All(result, x => + { + Assert.Equal(x.Available, false); + Assert.Equal(x.Approved, false); + }); + } + + [Fact] + public async Task GetApprovedRequests_Should_ReturnEmpty_WhenThereAreNoApprovedRequests() + { + var requests = new List + { + new TvRequestModel { Available = true }, + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetApprovedRequests(); + + Assert.False(result.Any()); + } + + [Fact] + public async Task GetApprovedRequests_Should_ReturnOnlyApprovedRequests_WhenThereAreMultipleRequests() + { + var requests = new List + { + new TvRequestModel { Available = true }, + new TvRequestModel { Approved = true }, + new TvRequestModel(), + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetApprovedRequests(); + + Assert.Equal(result.Count(), 1); + Assert.All(result, x => + { + Assert.Equal(x.Available, false); + Assert.Equal(x.Approved, true); + }); + } + + [Fact] + public async Task GetAvailableRequests_Should_ReturnEmpty_WhenThereAreNoAvailableRequests() + { + var requests = new List + { + new TvRequestModel { Approved = true }, + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetAvailableRequests(); + + Assert.False(result.Any()); + } + + [Fact] + public async Task GetAvailableRequests_Should_ReturnOnlyAvailableRequests_WhenThereAreMultipleRequests() + { + var requests = new List + { + new TvRequestModel { Available = true }, + new TvRequestModel { Approved = true }, + new TvRequestModel(), + }; + RequestService.Setup(x => x.GetAllAsync()).ReturnsAsync(requests); + + var result = await Engine.GetAvailableRequests(); + + Assert.Equal(result.Count(), 1); + Assert.All(result, x => + { + Assert.Equal(x.Available, true); + Assert.Equal(x.Approved, false); + }); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Core.Tests/Rule/AutoApproveRuleTests.cs b/src/Ombi.Core.Tests/Rule/AutoApproveRuleTests.cs index 7f7202e3e..07d438278 100644 --- a/src/Ombi.Core.Tests/Rule/AutoApproveRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/AutoApproveRuleTests.cs @@ -1,11 +1,11 @@ -using Ombi.Core.Rule.Rules; -using Xunit; using System.Security.Principal; using Moq; -using Ombi.Core.Models.Requests; using Ombi.Core.Claims; +using Ombi.Core.Models.Requests; +using Ombi.Core.Rule.Rules; +using Xunit; -namespace Ombi.Core.Tests +namespace Ombi.Core.Tests.Rule { public class AutoApproveRuleTests { diff --git a/src/Ombi.Core.Tests/Rule/CanRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/CanRequestRuleTests.cs index e7e8d11e3..3ef88f03e 100644 --- a/src/Ombi.Core.Tests/Rule/CanRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/CanRequestRuleTests.cs @@ -1,11 +1,11 @@ -using Ombi.Core.Rule.Rules; -using Xunit; using System.Security.Principal; using Moq; -using Ombi.Core.Models.Requests; using Ombi.Core.Claims; +using Ombi.Core.Models.Requests; +using Ombi.Core.Rule.Rules; +using Xunit; -namespace Ombi.Core.Tests +namespace Ombi.Core.Tests.Rule { public class CanRequestRuleTests { diff --git a/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs index a9f3a5a52..730cac9b3 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs @@ -1,26 +1,23 @@ -using Ombi.Core.Models.Requests; +using System.Collections.Generic; +using System.Threading.Tasks; +using Ombi.Core.Models.Requests; using Ombi.Core.Models.Requests.Movie; using Ombi.Core.Models.Search; using Ombi.Store.Entities; -using System.Collections.Generic; -using System.Threading.Tasks; -namespace Ombi.Core.Engine +namespace Ombi.Core.Engine.Interfaces { - public interface IMovieRequestEngine + public interface IMovieRequestEngine : IRequestEngine { Task RequestMovie(SearchMovieViewModel model); bool ShouldAutoApprove(RequestType requestType); - - Task> GetMovieRequests(int count, int position); + Task> SearchMovieRequest(string search); Task RemoveMovieRequest(int requestId); Task UpdateMovieRequest(MovieRequestModel request); - - RequestCountModel RequestCount(); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs new file mode 100644 index 000000000..2a9598634 --- /dev/null +++ b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Ombi.Core.Models.Requests; + +namespace Ombi.Core.Engine.Interfaces +{ + public interface IRequestEngine + { + + Task> GetApprovedRequests(); + Task> GetNewRequests(); + Task> GetAvailableRequests(); + RequestCountModel RequestCount(); + Task> GetRequests(int count, int position); + Task> GetRequests(); + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs index 1adcf556c..027f36907 100644 --- a/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs @@ -1,13 +1,12 @@ -using Ombi.Core.Models.Requests; -using Ombi.Core.Models.Search; -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading.Tasks; +using Ombi.Core.Models.Requests; +using Ombi.Core.Models.Search; -namespace Ombi.Core.Engine +namespace Ombi.Core.Engine.Interfaces { - public interface ITvRequestEngine + public interface ITvRequestEngine : IRequestEngine { - Task> GetTvRequests(int count, int position); Task RemoveTvRequest(int requestId); @@ -16,7 +15,5 @@ namespace Ombi.Core.Engine Task> SearchTvRequest(string search); Task UpdateTvRequest(TvRequestModel request); - - RequestCountModel RequestCount(); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index a09885174..108fae8f8 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -14,6 +14,7 @@ using System.Globalization; using System.Linq; using System.Security.Principal; using System.Threading.Tasks; +using Ombi.Core.Engine.Interfaces; namespace Ombi.Core.Engine { @@ -160,12 +161,18 @@ namespace Ombi.Core.Engine return null; } - public async Task> GetMovieRequests(int count, int position) + public async Task> GetRequests(int count, int position) { var allRequests = await MovieRequestService.GetAllAsync(count, position); return allRequests; } + public async Task> GetRequests() + { + var allRequests = await MovieRequestService.GetAllAsync(); + return allRequests; + } + public async Task> SearchMovieRequest(string search) { var allRequests = await MovieRequestService.GetAllAsync(); @@ -256,5 +263,23 @@ namespace Ombi.Core.Engine return new RequestEngineResult {RequestAdded = true}; } + + public async Task> GetApprovedRequests() + { + var allRequests = await MovieRequestService.GetAllAsync(); + return allRequests.Where(x => x.Approved && !x.Available); + } + + public async Task> GetNewRequests() + { + var allRequests = await MovieRequestService.GetAllAsync(); + return allRequests.Where(x => !x.Approved && !x.Available); + } + + public async Task> GetAvailableRequests() + { + var allRequests = await MovieRequestService.GetAllAsync(); + return allRequests.Where(x => !x.Approved && x.Available); + } } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index 3d19f0933..593f77d65 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -14,6 +14,7 @@ using System.Globalization; using System.Linq; using System.Security.Principal; using System.Threading.Tasks; +using Ombi.Core.Engine.Interfaces; namespace Ombi.Core.Engine { @@ -51,7 +52,7 @@ namespace Ombi.Core.Engine Status = showInfo.status, RequestedDate = DateTime.UtcNow, Approved = false, - RequestedUsers = new List {Username}, + RequestedUsers = new List { Username }, Issues = IssueState.None, ProviderId = tv.Id, RequestAll = tv.RequestAll, @@ -124,12 +125,18 @@ namespace Ombi.Core.Engine return await AddRequest(model); } - public async Task> GetTvRequests(int count, int position) + public async Task> GetRequests(int count, int position) { var allRequests = await TvRequestService.GetAllAsync(count, position); return allRequests; } + public async Task> GetRequests() + { + var allRequests = await TvRequestService.GetAllAsync(); + return allRequests; + } + public async Task> SearchTvRequest(string search) { var allRequests = await TvRequestService.GetAllAsync(); @@ -234,7 +241,25 @@ namespace Ombi.Core.Engine // await RequestLimitRepo.UpdateAsync(usersLimit); //} - return new RequestEngineResult {RequestAdded = true}; + return new RequestEngineResult { RequestAdded = true }; + } + + public async Task> GetApprovedRequests() + { + var allRequests = await TvRequestService.GetAllAsync(); + return allRequests.Where(x => x.Approved && !x.Available); + } + + public async Task> GetNewRequests() + { + var allRequests = await TvRequestService.GetAllAsync(); + return allRequests.Where(x => !x.Approved && !x.Available); + } + + public async Task> GetAvailableRequests() + { + var allRequests = await TvRequestService.GetAllAsync(); + return allRequests.Where(x => x.Available); } } } \ No newline at end of file diff --git a/src/Ombi/Controllers/RequestController.cs b/src/Ombi/Controllers/RequestController.cs index 56e612366..14eb06b90 100644 --- a/src/Ombi/Controllers/RequestController.cs +++ b/src/Ombi/Controllers/RequestController.cs @@ -1,12 +1,14 @@ -using System; -using System.Collections.Generic; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Ombi.Core.Engine; +using Ombi.Core.Engine.Interfaces; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Requests.Movie; using Ombi.Core.Models.Search; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Ombi.Models; namespace Ombi.Controllers { @@ -22,15 +24,20 @@ namespace Ombi.Controllers private IMovieRequestEngine MovieRequestEngine { get; } private ITvRequestEngine TvRequestEngine { get; } - [HttpGet("movie/{count:int}/{position:int}")] public async Task> GetRequests(int count, int position) { - return await MovieRequestEngine.GetMovieRequests(count, position); + return await MovieRequestEngine.GetRequests(count, position); + } + + [HttpGet("movie")] + public async Task> GetRequests() + { + return await MovieRequestEngine.GetRequests(); } [HttpPost("movie")] - public async Task RequestMovie([FromBody]SearchMovieViewModel movie) + public async Task RequestMovie([FromBody] SearchMovieViewModel movie) { return await MovieRequestEngine.RequestMovie(movie); } @@ -38,7 +45,6 @@ namespace Ombi.Controllers [HttpGet("movie/search/{searchTerm}")] public async Task> Search(string searchTerm) { - return await MovieRequestEngine.SearchMovieRequest(searchTerm); } @@ -49,7 +55,7 @@ namespace Ombi.Controllers } [HttpPut("movie")] - public async Task UpdateRequest([FromBody]MovieRequestModel model) + public async Task UpdateRequest([FromBody] MovieRequestModel model) { return await MovieRequestEngine.UpdateMovieRequest(model); } @@ -57,28 +63,24 @@ namespace Ombi.Controllers [HttpGet("tv/{count:int}/{position:int}")] public async Task> GetTvRequests(int count, int position) { - try - { - return await TvRequestEngine.GetTvRequests(count, position); - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } + return await TvRequestEngine.GetRequests(count, position); + } + + [HttpGet("tv")] + public async Task> GetTvRequests() + { + return await TvRequestEngine.GetRequests(); } [HttpPost("tv")] - public async Task RequestTv([FromBody]SearchTvShowViewModel tv) + public async Task RequestTv([FromBody] SearchTvShowViewModel tv) { return await TvRequestEngine.RequestTvShow(tv); } - [HttpGet("tv/search/{searchTerm}")] public async Task> SearchTv(string searchTerm) { - return await TvRequestEngine.SearchTvRequest(searchTerm); } @@ -89,7 +91,7 @@ namespace Ombi.Controllers } [HttpPut("tv")] - public async Task UpdateRequest([FromBody]TvRequestModel model) + public async Task UpdateRequest([FromBody] TvRequestModel model) { return await TvRequestEngine.UpdateTvRequest(model); } @@ -101,5 +103,30 @@ namespace Ombi.Controllers // Doesn't matter if we use the TvEngine or MovieEngine, this method is in the base class return TvRequestEngine.RequestCount(); } + + [HttpGet("tv/grid")] + public async Task> GetTvRequestsGrid() + { + return await GetGrid(TvRequestEngine); + } + + [HttpGet("movie/grid")] + public async Task> GetMovieRequestsGrid() + { + return await GetGrid(MovieRequestEngine); + } + + private async Task> GetGrid(IRequestEngine engine) where T : BaseRequestModel + { + var allRequests = await engine.GetRequests(); + var r = allRequests.ToList(); + var model = new RequestGridModel + { + Available = r.Where(x => x.Available && !x.Approved), + Approved = r.Where(x => x.Approved && !x.Available), + New = r.Where(x => !x.Available && !x.Approved) + }; + return model; + } } -} +} \ No newline at end of file diff --git a/src/Ombi/Models/RequestGridModel.cs b/src/Ombi/Models/RequestGridModel.cs new file mode 100644 index 000000000..fe23a44bb --- /dev/null +++ b/src/Ombi/Models/RequestGridModel.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Ombi.Core.Models.Requests; + +namespace Ombi.Models +{ + public class RequestGridModel where T : BaseRequestModel + { + public IEnumerable Available { get; set; } + public IEnumerable New { get; set; } + public IEnumerable Approved { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi/Ombi.csproj b/src/Ombi/Ombi.csproj index 03f67528b..ae8743dc0 100644 --- a/src/Ombi/Ombi.csproj +++ b/src/Ombi/Ombi.csproj @@ -64,6 +64,36 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + request-card.component.ts + + + request-grid - Copy.component.ts + PreserveNewest + + + request-card.component.js + + + request-grid - Copy.component.js + PreserveNewest + + + request-grid - Copy.component.html + PreserveNewest + PreserveNewest diff --git a/src/Ombi/Styles/_imports.scss b/src/Ombi/Styles/_imports.scss index 5ea7ab9d4..e3a1cd214 100644 --- a/src/Ombi/Styles/_imports.scss +++ b/src/Ombi/Styles/_imports.scss @@ -1,6 +1,7 @@ @import "./bootstrap.css"; //@import "./lib/tether.css"; @import "../node_modules/primeng/resources/themes/omega/theme.scss"; +@import "../node_modules/@angular/material/prebuilt-themes/deeppurple-amber"; @import "./lib/primeng.css"; $fa-font-path: "../fonts/lib"; diff --git a/src/Ombi/gulpfile.js b/src/Ombi/gulpfile.js index fb2e8d15c..67c31d563 100644 --- a/src/Ombi/gulpfile.js +++ b/src/Ombi/gulpfile.js @@ -57,7 +57,8 @@ var paths = { './bower_components/PACE/pace.js', './node_modules/bootstrap/dist/js/bootstrap.js', './node_modules/tether/dist/js/tether.js', - './node_modules/angular2-jwt/angular2-jwt.js' + './node_modules/angular2-jwt/angular2-jwt.js', + ], dest: './lib/' }, @@ -74,6 +75,7 @@ var paths = { './node_modules/primeng/resources/primeng.css', './node_modules/tether/dist/css/tether.css', './node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css', + './node_modules/dragula/dist/dragula.css' ], dest: './css/lib/' }, @@ -125,6 +127,11 @@ var paths = { name: 'primeng', src: './node_modules/primeng/**/*.js', dest: './lib/primeng/' + }, + { + name: 'ng2-dragula', + src: './node_modules/ng2-dragula/**/*.js', + dest: './lib/ng2-dragula/' } ], sass: // Simple sass->css compilation diff --git a/src/Ombi/package.json b/src/Ombi/package.json index 92bd942fe..0f7d38f6b 100644 --- a/src/Ombi/package.json +++ b/src/Ombi/package.json @@ -37,6 +37,7 @@ "jquery": "2.2.1", "merge-stream": "^1.0.1", "nanoscroller": "^0.8.7", + "ng2-dragula": "^1.3.1", "ngx-infinite-scroll": "^0.4.1", "primeng": "^2.0.5", "run-sequence": "^1.2.2", diff --git a/src/Ombi/wwwroot/app/app.module.ts b/src/Ombi/wwwroot/app/app.module.ts index cd52a0c29..a20155ca2 100644 --- a/src/Ombi/wwwroot/app/app.module.ts +++ b/src/Ombi/wwwroot/app/app.module.ts @@ -2,17 +2,20 @@ import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { FormsModule } from '@angular/forms'; -import { MdButtonModule } from '@angular/material'; -import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; - -import { AppComponent } from './app.component'; - +import { MdButtonModule, MdCardModule } from '@angular/material'; import { RouterModule, Routes } from '@angular/router'; import { HttpModule } from '@angular/http'; -import { InfiniteScrollModule } from 'ngx-infinite-scroll' +// Third Party +import { ButtonModule, DialogModule } from 'primeng/primeng'; +import { GrowlModule } from 'primeng/components/growl/growl'; +import { DataTableModule, SharedModule } from 'primeng/primeng'; +import { InfiniteScrollModule } from 'ngx-infinite-scroll'; +import { DragulaModule, DragulaService } from 'ng2-dragula/ng2-dragula'; +import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; // Components +import { AppComponent } from './app.component'; // Search import { SearchComponent } from './search/search.component'; import { MovieSearchComponent } from './search/moviesearch.component'; @@ -23,6 +26,8 @@ import { SeriesInformationComponent } from './search/seriesinformation.component import { RequestComponent } from './requests/request.component'; import { MovieRequestsComponent } from './requests/movierequests.component'; import { TvRequestsComponent } from './requests/tvrequests.component'; +import { RequestGridComponent } from './requests/request-grid.component'; +import { RequestCardComponent } from './requests/request-card.component'; import { LoginComponent } from './login/login.component'; import { LandingPageComponent } from './landingpage/landingpage.component'; @@ -45,16 +50,13 @@ import { StatusService } from './services/status.service'; import { SettingsModule } from './settings/settings.module'; import { WizardModule } from './wizard/wizard.module'; -import { ButtonModule, DialogModule } from 'primeng/primeng'; -import { GrowlModule } from 'primeng/components/growl/growl'; -import { DataTableModule, SharedModule } from 'primeng/primeng'; - const routes: Routes = [ { path: '*', component: PageNotFoundComponent }, { path: '', redirectTo: '/search', pathMatch: 'full' }, { path: 'search', component: SearchComponent, canActivate: [AuthGuard] }, { path: 'search/show/:id', component: SeriesInformationComponent, canActivate: [AuthGuard] }, { path: 'requests', component: RequestComponent, canActivate: [AuthGuard] }, + { path: 'requests-grid', component: RequestGridComponent }, { path: 'login', component: LoginComponent }, { path: 'landingpage', component: LandingPageComponent }, { path: 'usermanagement', component: UserManagementComponent, canActivate: [AuthGuard] }, @@ -78,6 +80,8 @@ const routes: Routes = [ DialogModule, MdButtonModule, NgbModule.forRoot(), + DragulaModule, + MdCardModule ], declarations: [ AppComponent, @@ -92,6 +96,8 @@ const routes: Routes = [ MovieRequestsComponent, TvRequestsComponent, SeriesInformationComponent, + RequestGridComponent, + RequestCardComponent, ], providers: [ SearchService, @@ -101,7 +107,8 @@ const routes: Routes = [ AuthGuard, SettingsService, IdentityService, - StatusService + StatusService, + DragulaService ], bootstrap: [AppComponent] }) diff --git a/src/Ombi/wwwroot/app/interfaces/IRequestModel.ts b/src/Ombi/wwwroot/app/interfaces/IRequestModel.ts index 52a35dc8e..75ad6ee4d 100644 --- a/src/Ombi/wwwroot/app/interfaces/IRequestModel.ts +++ b/src/Ombi/wwwroot/app/interfaces/IRequestModel.ts @@ -68,4 +68,10 @@ export enum RequestType { export interface IRequestsPageScroll { count: number, position: number +} + +export interface IRequestGrid { + available: T[], + new: T[], + approved:T[] } \ No newline at end of file diff --git a/src/Ombi/wwwroot/app/requests/request-card.component.html b/src/Ombi/wwwroot/app/requests/request-card.component.html new file mode 100644 index 000000000..bc92892a1 --- /dev/null +++ b/src/Ombi/wwwroot/app/requests/request-card.component.html @@ -0,0 +1,3 @@ +
+ {{request.title}} +
\ No newline at end of file diff --git a/src/Ombi/wwwroot/app/requests/request-card.component.ts b/src/Ombi/wwwroot/app/requests/request-card.component.ts new file mode 100644 index 000000000..241308afa --- /dev/null +++ b/src/Ombi/wwwroot/app/requests/request-card.component.ts @@ -0,0 +1,12 @@ +import { Component, Input } from '@angular/core'; + +import { IMediaBase } from '../interfaces/IRequestModel'; + +@Component({ + selector: 'request-card', + moduleId: module.id, + templateUrl: './request-card.component.html' +}) +export class RequestCardComponent { + @Input() request: IMediaBase; +} diff --git a/src/Ombi/wwwroot/app/requests/request-grid.component.html b/src/Ombi/wwwroot/app/requests/request-grid.component.html new file mode 100644 index 000000000..93f4518a1 --- /dev/null +++ b/src/Ombi/wwwroot/app/requests/request-grid.component.html @@ -0,0 +1,39 @@ + + + +
+
+ + Title +
+
+
+ +
+
+
+ +
+ + Title +
+
+
+ +
+
+
+ +
+ + Title +
+
+
+
+ +
+
+
+
+
diff --git a/src/Ombi/wwwroot/app/requests/request-grid.component.ts b/src/Ombi/wwwroot/app/requests/request-grid.component.ts new file mode 100644 index 000000000..2945a60fd --- /dev/null +++ b/src/Ombi/wwwroot/app/requests/request-grid.component.ts @@ -0,0 +1,37 @@ +import { Component, OnInit } from '@angular/core'; +import { DragulaService } from 'ng2-dragula/ng2-dragula'; +import { RequestService } from '../services/request.service'; +import { ITvRequestModel, IMovieRequestModel, IRequestGrid } from '../interfaces/IRequestModel'; + +@Component({ + moduleId: module.id, + templateUrl: './request-grid.component.html' +}) +export class RequestGridComponent implements OnInit { + + constructor(private dragulaService: DragulaService, private requestService: RequestService) { + this.dragulaService.setOptions('requests', { + removeOnSpill: false, + + }); + + this.dragulaService.drop.subscribe((value: any) => { + + }); + } + + + ngOnInit(): void { + this.requestService.getMovieGrid().subscribe(x => { + this.movieRequests = x; + }); + this.requestService.getTvGrid().subscribe(x => { + this.tvRequests = x; + }); + } + + + movieRequests: IRequestGrid; + tvRequests: IRequestGrid; + +} \ No newline at end of file diff --git a/src/Ombi/wwwroot/app/services/request.service.ts b/src/Ombi/wwwroot/app/services/request.service.ts index eade30273..eacaa8082 100644 --- a/src/Ombi/wwwroot/app/services/request.service.ts +++ b/src/Ombi/wwwroot/app/services/request.service.ts @@ -7,7 +7,7 @@ import { ServiceAuthHelpers } from './service.helpers'; import { IRequestEngineResult } from '../interfaces/IRequestEngineResult'; import { ISearchMovieResult } from '../interfaces/ISearchMovieResult'; import { ISearchTvResult } from '../interfaces/ISearchTvResult'; -import { IMovieRequestModel, ITvRequestModel, IRequestCountModel } from '../interfaces/IRequestModel'; +import { IMovieRequestModel, ITvRequestModel, IRequestCountModel, IRequestGrid } from '../interfaces/IRequestModel'; @Injectable() export class RequestService extends ServiceAuthHelpers { @@ -58,4 +58,12 @@ export class RequestService extends ServiceAuthHelpers { getRequestsCount(): Observable { return this.basicHttp.get(`${this.url}count`).map(this.extractData); } + + getMovieGrid(): Observable> { + return this.http.get(`${this.url}movie/grid`).map(this.extractData); + } + + getTvGrid(): Observable> { + return this.http.get(`${this.url}tv/grid`).map(this.extractData); + } } \ No newline at end of file diff --git a/src/Ombi/wwwroot/app/settings/radarr/radarr.component.html b/src/Ombi/wwwroot/app/settings/radarr/radarr.component.html index 62adab4cd..37ad28645 100644 --- a/src/Ombi/wwwroot/app/settings/radarr/radarr.component.html +++ b/src/Ombi/wwwroot/app/settings/radarr/radarr.component.html @@ -51,7 +51,7 @@
- +
@@ -65,7 +65,7 @@
- +
@@ -89,7 +89,7 @@
- +
diff --git a/src/Ombi/wwwroot/app/settings/sonarr/sonarr.component.html b/src/Ombi/wwwroot/app/settings/sonarr/sonarr.component.html index 9c6df9826..0609aaae7 100644 --- a/src/Ombi/wwwroot/app/settings/sonarr/sonarr.component.html +++ b/src/Ombi/wwwroot/app/settings/sonarr/sonarr.component.html @@ -51,7 +51,7 @@
- +
@@ -65,7 +65,7 @@
- +
@@ -89,7 +89,7 @@
- +