More work around the advanced options

This commit is contained in:
tidusjar 2019-05-19 00:34:13 +01:00
parent e5b74d32d0
commit 10f503ae2c
18 changed files with 111 additions and 32 deletions

View file

@ -20,5 +20,6 @@ namespace Ombi.Core.Engine.Interfaces
Task<RequestEngineResult> ApproveMovieById(int requestId); Task<RequestEngineResult> ApproveMovieById(int requestId);
Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason); Task<RequestEngineResult> DenyMovieById(int modelId, string denyReason);
Task<RequestsViewModel<MovieRequests>> GetRequests(int count, int position, string sortProperty, string sortOrder); Task<RequestsViewModel<MovieRequests>> GetRequests(int count, int position, string sortProperty, string sortOrder);
Task<RequestEngineResult> UpdateAdvancedOptions(MovieAdvancedOptions options);
} }
} }

View file

@ -249,6 +249,29 @@ namespace Ombi.Core.Engine
} }
public async Task<RequestEngineResult> UpdateAdvancedOptions(MovieAdvancedOptions options)
{
var request = await MovieRepository.Find(options.RequestId);
if (request == null)
{
return new RequestEngineResult
{
Result = false,
ErrorMessage = "Request does not exist"
};
}
request.QualityOverride = options.QualityOverride;
request.RootPathOverride = options.RootPathOverride;
await MovieRepository.Update(request);
return new RequestEngineResult
{
Result = true
};
}
private IQueryable<MovieRequests> OrderMovies(IQueryable<MovieRequests> allRequests, OrderType type) private IQueryable<MovieRequests> OrderMovies(IQueryable<MovieRequests> allRequests, OrderType type)
{ {
switch (type) switch (type)

View file

@ -0,0 +1,9 @@
namespace Ombi.Core.Models.Requests
{
public class MovieAdvancedOptions
{
public int RequestId { get; set; }
public int RootPathOverride { get; set; }
public int QualityOverride { get; set; }
}
}

View file

@ -17,13 +17,11 @@ export interface IMinimumAvailability {
value: string; value: string;
name: string; name: string;
} }
export interface IAdvancedModel {
profile: IRadarrProfile;
rootFolder: IRadarrRootFolder;
}
export interface IAdvancedData { export interface IAdvancedData {
profile: IRadarrProfile;
profiles: IRadarrProfile[]; profiles: IRadarrProfile[];
profileId: number;
rootFolder: IRadarrRootFolder;
rootFolders: IRadarrRootFolder[]; rootFolders: IRadarrRootFolder[];
rootFolderId: number;
} }

View file

@ -21,6 +21,12 @@ export interface IMovieRequests extends IFullBaseRequest {
qualityOverrideTitle: string; qualityOverrideTitle: string;
} }
export interface IMovieAdvancedOptions {
requestId: number;
qualityOverride: number;
rootPathOverride: number;
}
export interface IAlbumRequest extends IBaseRequest { export interface IAlbumRequest extends IBaseRequest {
foreignAlbumId: string; foreignAlbumId: string;
foreignArtistId: string; foreignArtistId: string;

View file

@ -11,6 +11,8 @@ import { DenyDialogComponent } from "./shared/deny-dialog/deny-dialog.component"
import { TvRequestsPanelComponent } from "./tv/panels/tv-requests/tv-requests-panel.component"; import { TvRequestsPanelComponent } from "./tv/panels/tv-requests/tv-requests-panel.component";
import { MovieAdminPanelComponent } from "./movie/panels/movie-admin-panel/movie-admin-panel.component"; import { MovieAdminPanelComponent } from "./movie/panels/movie-admin-panel/movie-admin-panel.component";
import { MovieAdvancedOptionsComponent } from "./movie/panels/movie-advanced-options/movie-advanced-options.component"; import { MovieAdvancedOptionsComponent } from "./movie/panels/movie-advanced-options/movie-advanced-options.component";
import { SearchService, RequestService, RadarrService } from "../../services";
import { RequestServiceV2 } from "../../services/requestV2.service";
export const components: any[] = [ export const components: any[] = [
MovieDetailsComponent, MovieDetailsComponent,
@ -28,10 +30,15 @@ export const components: any[] = [
MovieAdvancedOptionsComponent MovieAdvancedOptionsComponent
]; ];
export const entryComponents: any[] = [ export const entryComponents: any[] = [
YoutubeTrailerComponent, YoutubeTrailerComponent,
DenyDialogComponent, DenyDialogComponent,
MovieAdvancedOptionsComponent, MovieAdvancedOptionsComponent,
]; ];
export const providers: any[] = [
SearchService,
RequestService,
RadarrService,
RequestServiceV2,
];

View file

@ -82,13 +82,13 @@
<mat-card class="mat-elevation-z8 spacing-below" *ngIf="isAdmin && movieRequest"> <mat-card class="mat-elevation-z8 spacing-below" *ngIf="isAdmin && movieRequest">
<mat-card-content class="medium-font"> <mat-card-content class="medium-font">
<movie-admin-panel [movie]="movieRequest"></movie-admin-panel> <movie-admin-panel [movie]="movieRequest" (advancedOptionsChange)="setAdvancedOptions($event)"></movie-admin-panel>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>
<mat-card class="mat-elevation-z8"> <mat-card class="mat-elevation-z8">
<mat-card-content class="medium-font"> <mat-card-content class="medium-font">
<movie-information-panel [movie]="movie"></movie-information-panel> <movie-information-panel [movie]="movie" [advancedOptions]="advancedOptions"></movie-information-panel>
</mat-card-content> </mat-card-content>
</mat-card> </mat-card>

View file

@ -6,7 +6,7 @@ import { ISearchMovieResultV2 } from "../../../interfaces/ISearchMovieResultV2";
import { MatDialog } from "@angular/material"; import { MatDialog } from "@angular/material";
import { YoutubeTrailerComponent } from "../shared/youtube-trailer.component"; import { YoutubeTrailerComponent } from "../shared/youtube-trailer.component";
import { AuthService } from "../../../auth/auth.service"; import { AuthService } from "../../../auth/auth.service";
import { IMovieRequests, RequestType } from "../../../interfaces"; import { IMovieRequests, RequestType, IAdvancedData } from "../../../interfaces";
import { DenyDialogComponent } from "../shared/deny-dialog/deny-dialog.component"; import { DenyDialogComponent } from "../shared/deny-dialog/deny-dialog.component";
@Component({ @Component({
@ -19,6 +19,7 @@ export class MovieDetailsComponent {
public hasRequest: boolean; public hasRequest: boolean;
public movieRequest: IMovieRequests; public movieRequest: IMovieRequests;
public isAdmin: boolean; public isAdmin: boolean;
public advancedOptions: IAdvancedData;
private theMovidDbId: number; private theMovidDbId: number;
@ -100,4 +101,8 @@ export class MovieDetailsComponent {
this.messageService.send(result.errorMessage, "Ok"); this.messageService.send(result.errorMessage, "Ok");
} }
} }
public setAdvancedOptions(data: any) {
this.advancedOptions = data;
}
} }

View file

@ -1,3 +1,3 @@
<div *ngIf="movie"> <div *ngIf="movie && radarrEnabled">
<button mat-raised-button color="warn" class="text-center" (click)="openAdvancedOptions();">Advanced Options</button> <button mat-raised-button color="warn" class="text-center" (click)="openAdvancedOptions();">Advanced Options</button>
</div> </div>

View file

@ -1,8 +1,9 @@
import { Component, Input, OnInit } from "@angular/core"; import { Component, Input, OnInit, EventEmitter, Output } from "@angular/core";
import { RadarrService } from "../../../../../services"; import { RadarrService } from "../../../../../services";
import { IRadarrProfile, IRadarrRootFolder, IMovieRequests, IAdvancedData } from "../../../../../interfaces"; import { IRadarrProfile, IRadarrRootFolder, IMovieRequests, IAdvancedData } from "../../../../../interfaces";
import { MatDialog } from "@angular/material"; import { MatDialog } from "@angular/material";
import { MovieAdvancedOptionsComponent } from "../movie-advanced-options/movie-advanced-options.component"; import { MovieAdvancedOptionsComponent } from "../movie-advanced-options/movie-advanced-options.component";
import { RequestServiceV2 } from "../../../../../services/requestV2.service";
@Component({ @Component({
templateUrl: "./movie-admin-panel.component.html", templateUrl: "./movie-admin-panel.component.html",
@ -11,16 +12,19 @@ import { MovieAdvancedOptionsComponent } from "../movie-advanced-options/movie-a
export class MovieAdminPanelComponent implements OnInit { export class MovieAdminPanelComponent implements OnInit {
@Input() public movie: IMovieRequests; @Input() public movie: IMovieRequests;
@Output() public advancedOptionsChanged = new EventEmitter<IAdvancedData>();
public radarrEnabled: boolean;
public radarrProfiles: IRadarrProfile[]; public radarrProfiles: IRadarrProfile[];
public selectedRadarrProfile: IRadarrProfile; public selectedRadarrProfile: IRadarrProfile;
public radarrRootFolders: IRadarrRootFolder[]; public radarrRootFolders: IRadarrRootFolder[];
public selectRadarrRootFolders: IRadarrRootFolder; public selectRadarrRootFolders: IRadarrRootFolder;
constructor(private radarrService: RadarrService, private dialog: MatDialog) { } constructor(private radarrService: RadarrService, private requestService: RequestServiceV2, private dialog: MatDialog) { }
public async ngOnInit() { public async ngOnInit() {
if (await this.radarrService.isRadarrEnabled()) { this.radarrEnabled = await this.radarrService.isRadarrEnabled();
if (this.radarrEnabled) {
this.radarrService.getQualityProfilesFromSettings().subscribe(c => { this.radarrService.getQualityProfilesFromSettings().subscribe(c => {
this.radarrProfiles = c; this.radarrProfiles = c;
this.setQualityOverrides(); this.setQualityOverrides();
@ -32,10 +36,16 @@ export class MovieAdminPanelComponent implements OnInit {
} }
} }
public openAdvancedOptions() { public async openAdvancedOptions() {
const dialog = this.dialog.open(MovieAdvancedOptionsComponent, { width: "700px", data: <IAdvancedData>{ profiles: this.radarrProfiles, rootFolders: this.radarrRootFolders }, panelClass: 'modal-panel' }) const dialog = this.dialog.open(MovieAdvancedOptionsComponent, { width: "700px", data: <IAdvancedData>{ profiles: this.radarrProfiles, rootFolders: this.radarrRootFolders }, panelClass: 'modal-panel' })
dialog.afterClosed().subscribe(result => { await dialog.afterClosed().subscribe(async result => {
console.log(result); if(result) {
// get the name and ids
result.rootFolder = result.rootFolders.filter(f => f.id === +result.rootFolderId)[0];
result.profile = result.profiles.filter(f => f.id === +result.profileId)[0];
await this.requestService.updateMovieAdvancedOptions({qualityOverride: result.profileId, rootPathOverride: result.rootFolderId, requestId: this.movie.id}).toPromise();
this.advancedOptionsChanged.emit(result);
}
}); });
} }

View file

@ -4,18 +4,19 @@
<div mat-dialog-content> <div mat-dialog-content>
<mat-form-field> <mat-form-field>
<mat-label>Radarr Quality Profile</mat-label> <mat-label>Radarr Quality Profile</mat-label>
<mat-select [(value)]="options.profile"> <mat-select [(value)]="data.profileId">
<mat-option *ngFor="let profile of data.profiles" value="{{profile.id}}">{{profile.name}}</mat-option> <mat-option *ngFor="let profile of data.profiles" value="{{profile.id}}">{{profile.name}}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
<mat-form-field> <mat-form-field>
<mat-label>Radarr Root Folders</mat-label> <mat-label>Radarr Root Folders</mat-label>
<mat-select [(value)]="options.rootFolder"> <mat-select [(value)]="data.rootFolderId">
<mat-option *ngFor="let profile of data.rootFolders" value="{{profile.id}}">{{profile.path}}</mat-option> <mat-option *ngFor="let profile of data.rootFolders" value="{{profile.id}}">{{profile.path}}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>
</div> </div>
<div mat-dialog-actions> <div mat-dialog-actions>
<button mat-button [mat-dialog-close]="options" cdkFocusInitial>Ok</button> <button mat-button [mat-dialog-close]="" cdkFocusInitial>Close</button>
<button mat-button [mat-dialog-close]="data" cdkFocusInitial>Save</button>
</div> </div>

View file

@ -1,6 +1,6 @@
import { Component, Inject } from "@angular/core"; import { Component, Inject } from "@angular/core";
import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material"; import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material";
import { IAdvancedModel, IAdvancedData } from "../../../../../interfaces"; import { IAdvancedData } from "../../../../../interfaces";
@Component({ @Component({
templateUrl: "./movie-advanced-options.component.html", templateUrl: "./movie-advanced-options.component.html",
@ -8,7 +8,7 @@ import { IAdvancedModel, IAdvancedData } from "../../../../../interfaces";
}) })
export class MovieAdvancedOptionsComponent { export class MovieAdvancedOptionsComponent {
public options: IAdvancedModel; constructor(public dialogRef: MatDialogRef<MovieAdvancedOptionsComponent>, @Inject(MAT_DIALOG_DATA) public data: IAdvancedData,
) {
constructor(public dialogRef: MatDialogRef<MovieAdvancedOptionsComponent>, @Inject(MAT_DIALOG_DATA) public data: IAdvancedData) { } }
} }

View file

@ -19,6 +19,14 @@
</div> </div>
</div> </div>
<div *ngIf="advancedOptions">
<strong>Root Folder Override</strong>
<div>{{advancedOptions.rootFolder.path}}</div>
</div>
<div *ngIf="advancedOptions">
<strong>Quality Override</strong>
<div>{{advancedOptions.profile.name}}</div>
</div>
<br /> <br />
<div *ngIf="movie.genres"> <div *ngIf="movie.genres">
<strong>Genres:</strong> <strong>Genres:</strong>

View file

@ -1,5 +1,6 @@
import { Component, ViewEncapsulation, Input } from "@angular/core"; import { Component, ViewEncapsulation, Input } from "@angular/core";
import { ISearchMovieResultV2 } from "../../../../interfaces/ISearchMovieResultV2"; import { ISearchMovieResultV2 } from "../../../../interfaces/ISearchMovieResultV2";
import { IAdvancedData } from "../../../../interfaces";
@Component({ @Component({
templateUrl: "./movie-information-panel.component.html", templateUrl: "./movie-information-panel.component.html",
@ -9,4 +10,5 @@ import { ISearchMovieResultV2 } from "../../../../interfaces/ISearchMovieResultV
}) })
export class MovieInformationPanelComponent { export class MovieInformationPanelComponent {
@Input() public movie: ISearchMovieResultV2; @Input() public movie: ISearchMovieResultV2;
@Input() public advancedOptions: IAdvancedData;
} }

View file

@ -12,6 +12,7 @@ import { PipeModule } from "../pipes/pipe.module";
import * as fromComponents from './components'; import * as fromComponents from './components';
import { AuthGuard } from "../auth/auth.guard"; import { AuthGuard } from "../auth/auth.guard";
import { RequestServiceV2 } from "../services/requestV2.service";
const routes: Routes = [ const routes: Routes = [
@ -36,9 +37,7 @@ const routes: Routes = [
...fromComponents.entryComponents ...fromComponents.entryComponents
], ],
providers: [ providers: [
SearchService, ...fromComponents.providers
RequestService,
RadarrService,
], ],
}) })

View file

@ -1,10 +1,10 @@
import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; import { APP_BASE_HREF } from "@angular/common";
import { Injectable, Inject } from "@angular/core"; import { Injectable, Inject } from "@angular/core";
import { HttpClient } from "@angular/common/http"; import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs"; import { Observable } from "rxjs";
import { ServiceHelpers } from "./service.helpers"; import { ServiceHelpers } from "./service.helpers";
import { IRequestsViewModel, IMovieRequests, ITvRequests, IChildRequests } from "../interfaces"; import { IRequestsViewModel, IMovieRequests, IChildRequests, IMovieAdvancedOptions, IRequestEngineResult } from "../interfaces";
@Injectable() @Injectable()
@ -21,4 +21,7 @@ export class RequestServiceV2 extends ServiceHelpers {
return this.http.get<IRequestsViewModel<IChildRequests>>(`${this.url}tv/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers}); return this.http.get<IRequestsViewModel<IChildRequests>>(`${this.url}tv/${count}/${position}/${sortProperty}/${order}`, {headers: this.headers});
} }
public updateMovieAdvancedOptions(options: IMovieAdvancedOptions): Observable<IRequestEngineResult> {
return this.http.post<IRequestEngineResult>(`${this.url}movie/advancedoptions`, options, {headers: this.headers});
}
} }

View file

@ -26,7 +26,6 @@ export class SignalRNotificationService {
this.hubConnection.on("Notification", (data: any) => { this.hubConnection.on("Notification", (data: any) => {
debugger;
this.Notification.emit(data); this.Notification.emit(data);
}); });

View file

@ -4,7 +4,9 @@ using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks; using System.Threading.Tasks;
using Ombi.Core; using Ombi.Core;
using Ombi.Core.Engine;
using Ombi.Core.Engine.Interfaces; using Ombi.Core.Engine.Interfaces;
using Ombi.Core.Models.Requests;
using Ombi.Core.Models.UI; using Ombi.Core.Models.UI;
using Ombi.Store.Entities.Requests; using Ombi.Store.Entities.Requests;
@ -49,5 +51,11 @@ namespace Ombi.Controllers.V2
{ {
return await _tvRequestEngine.GetRequests(count, position, sort, sortOrder); return await _tvRequestEngine.GetRequests(count, position, sort, sortOrder);
} }
[HttpPost("movie/advancedoptions")]
public async Task<RequestEngineResult> UpdateAdvancedOptions([FromBody] MovieAdvancedOptions options)
{
return await _movieRequestEngine.UpdateAdvancedOptions(options);
}
} }
} }