Added the ability to deny a request with a reason

This commit is contained in:
TidusJar 2018-12-17 15:56:24 +00:00
parent bd3a243af9
commit e6d48e5364
7 changed files with 73 additions and 40 deletions

View file

@ -49,7 +49,7 @@ namespace Ombi.Notifications
}
Overview = req?.Overview;
Year = req?.ReleaseDate.Year.ToString();
DenyReason = req?.DeniedReason;
if (req?.RequestType == RequestType.Movie)
{
PosterImage = string.Format((req?.PosterPath ?? string.Empty).StartsWith("/", StringComparison.InvariantCultureIgnoreCase)
@ -88,6 +88,7 @@ namespace Ombi.Notifications
UserName = req?.RequestedUser?.UserName;
}
DenyReason = req?.DeniedReason;
Alias = (req?.RequestedUser?.Alias.HasValue() ?? false) ? req?.RequestedUser?.Alias : req?.RequestedUser?.UserName;
Title = title;
RequestedDate = req?.RequestedDate.ToString("D");
@ -126,6 +127,7 @@ namespace Ombi.Notifications
{
title = req?.ParentRequest.Title;
}
DenyReason = req?.DeniedReason;
ApplicationUrl = (s?.ApplicationUrl.HasValue() ?? false) ? s.ApplicationUrl : string.Empty;
ApplicationName = string.IsNullOrEmpty(s?.ApplicationName) ? "Ombi" : s?.ApplicationName;
RequestedUser = req?.RequestedUser?.UserName;
@ -217,7 +219,6 @@ namespace Ombi.Notifications
public string UserName { get; set; }
public string IssueUser => UserName;
public string Alias { get; set; }
public string Title { get; set; }
public string RequestedDate { get; set; }
public string Type { get; set; }
@ -235,6 +236,7 @@ namespace Ombi.Notifications
public string IssueSubject { get; set; }
public string NewIssueComment { get; set; }
public string UserPreference { get; set; }
public string DenyReason { get; set; }
// System Defined
private string LongDate => DateTime.Now.ToString("D");
@ -269,6 +271,7 @@ namespace Ombi.Notifications
{nameof(UserName),UserName},
{nameof(Alias),Alias},
{nameof(UserPreference),UserPreference},
{nameof(DenyReason),DenyReason},
};
}
}

View file

@ -55,6 +55,10 @@ export interface IAlbumUpdateModel {
id: number;
}
export interface IDenyAlbumModel extends IAlbumUpdateModel {
reason: string;
}
export interface IFullBaseRequest extends IBaseRequest {
imdbId: string;
overview: string;
@ -117,6 +121,10 @@ export interface ITvUpdateModel {
id: number;
}
export interface ITvDenyModel extends ITvUpdateModel {
reason: string;
}
export enum OrderType {
RequestedDateAsc = 1,
RequestedDateDesc = 2,

View file

@ -92,7 +92,7 @@
</div>
<div *ngIf="request.denied" id="requestDenied">
{{ 'Requests.Denied' | translate }}
<i style="color:red;" class="fa fa-check"></i>
<i style="color:red;" class="fa fa-check" pTooltip="{{request.deniedReason}}"></i>
</div>
@ -265,4 +265,15 @@
<button class="btn btn-sm btn-primary-outline" (click)="clearFilter($event)">
<i class="fa fa-filter"></i> {{ 'Filter.ClearFilter' | translate }}</button>
</p-sidebar>
</p-sidebar>
<p-dialog *ngIf="requestToDeny" header="Deny Request '{{requestToDeny.title}}''" [(visible)]="denyDisplay" [draggable]="false">
<span>Please enter a rejection reason, the user will be notified of this:</span>
<textarea [(ngModel)]="rejectionReason" class="form-control-custom form-control"></textarea>
<p-footer>
<button type="button" (click)="denyRequest();" label="Reject" class="btn btn-success">Deny</button>
<button type="button"(click)="denyDisplay=false" label="Close" class="btn btn-danger">Close</button>
</p-footer>
</p-dialog>

View file

@ -34,6 +34,9 @@ export class MusicRequestsComponent implements OnInit {
public orderType: OrderType = OrderType.RequestedDateDesc;
public OrderType = OrderType;
public denyDisplay: boolean;
public requestToDeny: IAlbumRequest;
public rejectionReason: string;
public totalAlbums: number = 100;
private currentlyLoaded: number;
@ -126,23 +129,22 @@ export class MusicRequestsComponent implements OnInit {
}
public deny(request: IAlbumRequest) {
request.denied = true;
this.denyRequest(request);
this.requestToDeny = request;
this.denyDisplay = true;
}
// public selectRootFolder(searchResult: IAlbumRequest, rootFolderSelected: IRadarrRootFolder, event: any) {
// event.preventDefault();
// // searchResult.rootPathOverride = rootFolderSelected.id;
// this.setOverride(searchResult);
// this.updateRequest(searchResult);
// }
// public selectQualityProfile(searchResult: IMovieRequests, profileSelected: IRadarrProfile, event: any) {
// event.preventDefault();
// searchResult.qualityOverride = profileSelected.id;
// this.setOverride(searchResult);
// this.updateRequest(searchResult);
// }
public denyRequest() {
this.requestService.denyAlbum({ id: this.requestToDeny.id, reason: this.rejectionReason })
.subscribe(x => {
if (x.result) {
this.notificationService.success(
`Request for ${this.requestToDeny.title} has been denied successfully`);
} else {
this.notificationService.warning("Request Denied", x.message ? x.message : x.errorMessage);
this.requestToDeny.denied = false;
}
});
}
public reportIssue(catId: IIssueCategory, req: IAlbumRequest) {
this.issueRequest = req;
@ -266,19 +268,6 @@ export class MusicRequestsComponent implements OnInit {
});
}
private denyRequest(request: IAlbumRequest) {
this.requestService.denyAlbum({ id: request.id })
.subscribe(x => {
if (x.result) {
this.notificationService.success(
`Request for ${request.title} has been denied successfully`);
} else {
this.notificationService.warning("Request Denied", x.message ? x.message : x.errorMessage);
request.denied = false;
}
});
}
private loadInit() {
this.requestService.getAlbumRequests(this.amountToLoad, 0, this.orderType, this.filter)
.subscribe(x => {

View file

@ -21,7 +21,8 @@
<button id="unavailableBtn" *ngIf="child.available" (click)="changeAvailability(child, false)" style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i> {{ 'Requests.MarkUnavailable' | translate }}</button>
<button id="availableBtn" *ngIf="!child.available" (click)="changeAvailability(child, true)" style="text-align: right" value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}</button>
<button id="denyBtn" *ngIf="!child.denied" type="button" (click)="deny(child)" class="btn btn-sm btn-danger-outline deny"><i class="fa fa-times"></i> {{ 'Requests.Deny' | translate }}</button>
<button id="denyBtn" *ngIf="!child.denied" type="button" (click)="deny(child)" class="btn btn-sm btn-danger-outline deny">
<i class="fa fa-times"></i> {{ 'Requests.Deny' | translate }}</button>
</div>
<div *ngIf="isAdmin || isRequestUser(child)">
@ -76,7 +77,9 @@
{{ep.airDate | amLocal | amDateFormat: 'L' }}
</td>
<td>
<span *ngIf="child.denied" class="label label-danger" id="deniedLabel" [translate]="'Common.Denied'"></span>
<span *ngIf="child.denied" class="label label-danger" id="deniedLabel" [translate]="'Common.Denied'">
<i style="color:red;" class="fa fa-check" pTooltip="{{child.deniedReason}}"></i>
</span>
<span *ngIf="!child.denied && ep.available" class="label label-success" id="availableLabel" [translate]="'Common.Available'"></span>
<span *ngIf="!child.denied &&ep.approved && !ep.available" class="label label-info" id="processingRequestLabel" [translate]="'Common.ProcessingRequest'"></span>
<div *ngIf="!child.denied && !ep.approved">
@ -98,3 +101,12 @@
</div>
</div>
<p-dialog *ngIf="requestToDeny" header="Deny Request '{{requestToDeny.title}}''" [(visible)]="denyDisplay" [draggable]="false">
<span>Please enter a rejection reason, the user will be notified of this:</span>
<textarea [(ngModel)]="rejectionReason" class="form-control-custom form-control"></textarea>
<p-footer>
<button type="button" (click)="denyRequest();" label="Reject" class="btn btn-success">Deny</button>
<button type="button"(click)="denyDisplay=false" label="Close" class="btn btn-danger">Close</button>
</p-footer>
</p-dialog>

View file

@ -11,6 +11,10 @@ export class TvRequestChildrenComponent {
@Input() public childRequests: IChildRequests[];
@Input() public isAdmin: boolean;
@Input() public currentUser: string;
public denyDisplay: boolean;
public requestToDeny: IChildRequests;
public rejectionReason: string;
@Output() public requestDeleted = new EventEmitter<number>();
@ -57,20 +61,26 @@ export class TvRequestChildrenComponent {
public deny(request: IChildRequests) {
request.denied = true;
this.requestToDeny = request;
this.denyDisplay = true;
request.seasonRequests.forEach((season) => {
season.episodes.forEach((ep) => {
ep.approved = false;
});
});
this.requestService.denyChild({ id: request.id })
}
public denyRequest() {
this.requestService.denyChild({ id: this.requestToDeny.id, reason: this.rejectionReason })
.subscribe(x => {
this.denyDisplay = false;
if (x.result) {
this.notificationService.success(
`Request has been denied successfully`);
} else {
this.notificationService.warning("Request Denied", x.message ? x.message : x.errorMessage);
request.approved = false;
this.requestToDeny.approved = false;
}
});
}

View file

@ -5,8 +5,8 @@ import { HttpClient } from "@angular/common/http";
import { Observable } from "rxjs";
import { TreeNode } from "primeng/primeng";
import { FilterType, IAlbumRequest, IAlbumRequestModel, IAlbumUpdateModel, IChildRequests, IDenyMovieModel, IFilter, IMovieRequestModel,
IMovieRequests, IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel, ITvRequests, ITvUpdateModel, OrderType } from "../interfaces";
import { FilterType, IAlbumRequest, IAlbumRequestModel, IAlbumUpdateModel, IChildRequests, IDenyAlbumModel, IDenyMovieModel, IFilter,
IMovieRequestModel, IMovieRequests, IMovieUpdateModel, IRequestEngineResult, IRequestsViewModel, ITvDenyModel, ITvRequests, ITvUpdateModel, OrderType } from "../interfaces";
import { ITvRequestViewModel } from "../interfaces";
import { ServiceHelpers } from "./service.helpers";
@ -118,7 +118,7 @@ export class RequestService extends ServiceHelpers {
return this.http.put<IChildRequests>(`${this.url}tv/child`, JSON.stringify(child), {headers: this.headers});
}
public denyChild(child: ITvUpdateModel): Observable<IRequestEngineResult> {
public denyChild(child: ITvDenyModel): Observable<IRequestEngineResult> {
return this.http.put<IRequestEngineResult>(`${this.url}tv/deny`, JSON.stringify(child), {headers: this.headers});
}
@ -161,7 +161,7 @@ export class RequestService extends ServiceHelpers {
return this.http.post<IRequestEngineResult>(`${this.url}music/Approve`, JSON.stringify(Album), {headers: this.headers});
}
public denyAlbum(Album: IAlbumUpdateModel): Observable<IRequestEngineResult> {
public denyAlbum(Album: IDenyAlbumModel): Observable<IRequestEngineResult> {
return this.http.put<IRequestEngineResult>(`${this.url}music/Deny`, JSON.stringify(Album), {headers: this.headers});
}