Add Deny option to requests list

pull/4584/head
sephrat 3 years ago
parent 2aaeb2bd38
commit 448f196165

@ -98,7 +98,9 @@
<button id="bulkFab" *ngIf="selection.hasValue() && isAdmin" mat-fab color="accent" class="floating-fab" [matMenuTriggerFor]="aboveMenu"> <button id="bulkFab" *ngIf="selection.hasValue() && isAdmin" mat-fab color="accent" class="floating-fab" [matMenuTriggerFor]="aboveMenu">
<i class="fas fa-bars"></i></button> <i class="fas fa-bars"></i></button>
<mat-menu #aboveMenu="matMenu" yPosition="above"> <mat-menu #aboveMenu="matMenu" yPosition="above">
<button id="deleteFabButton" mat-menu-item (click)="bulkDelete()">{{'Requests.RequestPanel.Delete' | translate}}</button>
<button id="approveFabButton" mat-menu-item (click)="bulkApprove()">{{'Requests.RequestPanel.Approve' | translate}}</button> <button id="approveFabButton" mat-menu-item (click)="bulkApprove()">{{'Requests.RequestPanel.Approve' | translate}}</button>
<button id="approve4kFabButton" mat-menu-item (click)="bulkApprove4K()">{{'Requests.RequestPanel.Approve4K' | translate}}</button> <button *ngIf="is4kEnabled" id="approve4kFabButton" mat-menu-item (click)="bulkApprove4K()">{{'Requests.RequestPanel.Approve4K' | translate}}</button>
<button id="denyFabButton" mat-menu-item (click)="bulkDeny()">{{'Requests.RequestPanel.Deny' | translate}}</button>
<button *ngIf="is4kEnabled" id="deny4kFabButton" mat-menu-item (click)="bulkDeny4K()">{{'Requests.RequestPanel.Deny4K' | translate}}</button>
<button id="deleteFabButton" mat-menu-item (click)="bulkDelete()">{{'Requests.RequestPanel.Delete' | translate}}</button>
</mat-menu> </mat-menu>

@ -62,11 +62,11 @@ export class MoviesGridComponent implements OnInit, AfterViewInit {
this.manageOwnRequests = this.auth.hasRole("ManageOwnRequests") this.manageOwnRequests = this.auth.hasRole("ManageOwnRequests")
if (this.isAdmin) { if (this.isAdmin) {
this.displayedColumns.unshift('select'); this.displayedColumns.unshift('select');
} }
this.is4kEnabled = this.featureFacade.is4kEnabled(); this.is4kEnabled = this.featureFacade.is4kEnabled();
if ((this.isAdmin || this.auth.hasRole("Request4KMovie")) if ((this.isAdmin || this.auth.hasRole("Request4KMovie"))
&& this.is4kEnabled) { && this.is4kEnabled) {
this.displayedColumns.splice(4, 0, 'has4kRequest'); this.displayedColumns.splice(4, 0, 'has4kRequest');
} }
@ -155,13 +155,13 @@ export class MoviesGridComponent implements OnInit, AfterViewInit {
private checkDate(date: Date|string): boolean { private checkDate(date: Date|string): boolean {
if (typeof date === 'string') { if (typeof date === 'string') {
return new Date(date).getFullYear() > 1; return new Date(date).getFullYear() > 1;
} }
if (date instanceof Date) { if (date instanceof Date) {
return date.getFullYear() > 1; return date.getFullYear() > 1;
} }
return false; return false;
} }
public switchFilter(type: RequestFilterType) { public switchFilter(type: RequestFilterType) {
this.currentFilter = type; this.currentFilter = type;
@ -172,15 +172,15 @@ export class MoviesGridComponent implements OnInit, AfterViewInit {
const numSelected = this.selection.selected.length; const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length; const numRows = this.dataSource.data.length;
return numSelected === numRows; return numSelected === numRows;
} }
public masterToggle() { public masterToggle() {
this.isAllSelected() ? this.isAllSelected() ?
this.selection.clear() : this.selection.clear() :
this.dataSource.data.forEach(row => this.selection.select(row)); this.dataSource.data.forEach(row => this.selection.select(row));
} }
public async bulkDelete() { public async bulkDelete() {
if (this.selection.isEmpty()) { if (this.selection.isEmpty()) {
return; return;
} }
@ -194,13 +194,13 @@ export class MoviesGridComponent implements OnInit, AfterViewInit {
this.selection.clear(); this.selection.clear();
this.ngAfterViewInit(); this.ngAfterViewInit();
}); });
} }
public bulkApprove = () => this.bulkApproveInternal(false); public bulkApprove = () => this.bulkApproveInternal(false);
public bulkApprove4K = () => this.bulkApproveInternal(true); public bulkApprove4K = () => this.bulkApproveInternal(true);
private bulkApproveInternal(is4k: boolean) { private bulkApproveInternal(is4k: boolean) {
if (this.selection.isEmpty()) { if (this.selection.isEmpty()) {
return; return;
} }
@ -222,12 +222,45 @@ export class MoviesGridComponent implements OnInit, AfterViewInit {
this.selection.clear(); this.selection.clear();
this.ngAfterViewInit(); this.ngAfterViewInit();
}) })
} }
public bulkDeny = () => this.bulkDenyInternal(false);
public bulkDeny4K = () => this.bulkDenyInternal(true);
private bulkDenyInternal(is4k: boolean) {
if (this.selection.isEmpty()) {
return;
}
let tasks = new Array<Observable<IRequestEngineResult>>();
this.selection.selected.forEach((selected) => {
tasks.push(this.requestServiceV1.denyMovie({
id: selected.id,
is4K: is4k,
reason: `` // TOOD: reuse DenyDialog to allow for a reason to be entered
}));
});
this.isLoadingResults = true;
forkJoin(tasks).subscribe((result: IRequestEngineResult[]) => {
this.isLoadingResults = false;
const failed = result.filter(x => !x.result);
if (failed.length > 0) {
this.notification.error("Some requests failed to deny: " + failed[0].errorMessage);
this.selection.clear();
return;
}
this.notification.success(this.translateService.instant('Requests.RequestPanel.Denied'));
this.selection.clear();
this.ngAfterViewInit();
})
}
public getRequestDate(request: IMovieRequests) : Date { public getRequestDate(request: IMovieRequests): Date {
if (new Date(request.requestedDate).getFullYear() === 1) { if (new Date(request.requestedDate).getFullYear() === 1) {
return request.requestedDate4k; return request.requestedDate4k;
} }
return request.requestedDate; return request.requestedDate;
} }
} }

@ -1,14 +1,20 @@
<mat-nav-list> <mat-nav-list>
<a id="requestDelete" *ngIf="data.isAdmin || data.manageOwnRequests" (click)="delete()" mat-list-item>
<span mat-line>{{'Requests.RequestPanel.Delete' | translate}}</span>
</a>
<a id="requestApprove" *ngIf="data.canApprove && data.isAdmin && data.hasRegularRequest" (click)="approve()" mat-list-item> <a id="requestApprove" *ngIf="data.canApprove && data.isAdmin && data.hasRegularRequest" (click)="approve()" mat-list-item>
<span mat-line>{{'Requests.RequestPanel.Approve' | translate}}</span> <span mat-line>{{'Requests.RequestPanel.Approve' | translate}}</span>
</a> </a>
<a id="requestDeny" *ngIf="data.canApprove && data.isAdmin && data.hasRegularRequest" (click)="deny()" mat-list-item>
<span mat-line>{{'Requests.RequestPanel.Deny' | translate}}</span>
</a>
<a id="requestApprove4k" *ngIf="data.canApprove && data.isAdmin && data.has4kRequest ?? false" (click)="approve4K()" mat-list-item> <a id="requestApprove4k" *ngIf="data.canApprove && data.isAdmin && data.has4kRequest ?? false" (click)="approve4K()" mat-list-item>
<span mat-line>{{'Requests.RequestPanel.Approve4K' | translate}}</span> <span mat-line>{{'Requests.RequestPanel.Approve4K' | translate}}</span>
</a> </a>
<a id="requestDeny4k" *ngIf="data.canApprove && data.isAdmin && data.has4kRequest ?? false" (click)="deny4K()" mat-list-item>
<span mat-line>{{'Requests.RequestPanel.Deny4K' | translate}}</span>
</a>
<a id="requestChangeAvailability" *ngIf="data.type !== RequestType.tvShow && data.isAdmin" (click)="changeAvailability()" mat-list-item> <a id="requestChangeAvailability" *ngIf="data.type !== RequestType.tvShow && data.isAdmin" (click)="changeAvailability()" mat-list-item>
<span mat-line>{{'Requests.RequestPanel.ChangeAvailability' | translate}}</span> <span mat-line>{{'Requests.RequestPanel.ChangeAvailability' | translate}}</span>
</a> </a>
<a id="requestDelete" *ngIf="data.isAdmin || data.manageOwnRequests" (click)="delete()" mat-list-item>
<span mat-line>{{'Requests.RequestPanel.Delete' | translate}}</span>
</a>
</mat-nav-list> </mat-nav-list>

@ -5,6 +5,8 @@ import { IRequestEngineResult, RequestType } from '../../../interfaces';
import { UpdateType } from '../../models/UpdateType'; import { UpdateType } from '../../models/UpdateType';
import { TranslateService } from '@ngx-translate/core'; import { TranslateService } from '@ngx-translate/core';
import { firstValueFrom, Observable } from 'rxjs'; import { firstValueFrom, Observable } from 'rxjs';
import { DenyDialogComponent } from '../../../media-details/components/shared/deny-dialog/deny-dialog.component';
import { MatDialog } from '@angular/material/dialog';
@Component({ @Component({
selector: 'request-options', selector: 'request-options',
@ -17,6 +19,7 @@ export class RequestOptionsComponent {
constructor(@Inject(MAT_BOTTOM_SHEET_DATA) public data: any, constructor(@Inject(MAT_BOTTOM_SHEET_DATA) public data: any,
private requestService: RequestService, private requestService: RequestService,
private messageService: MessageService, private messageService: MessageService,
public dialog: MatDialog,
private bottomSheetRef: MatBottomSheetRef<RequestOptionsComponent>, private bottomSheetRef: MatBottomSheetRef<RequestOptionsComponent>,
private translate: TranslateService) { } private translate: TranslateService) { }
@ -33,11 +36,11 @@ export class RequestOptionsComponent {
} }
request.subscribe(result => { request.subscribe(result => {
if (result.result) { if (result.result) {
this.messageService.send(this.translate.instant("Requests.SuccessfullyDeleted")); this.messageService.send(this.translate.instant("Requests.SuccessfullyDeleted"));
this.bottomSheetRef.dismiss({type: UpdateType.Delete}); this.bottomSheetRef.dismiss({type: UpdateType.Delete});
return; return;
} else { } else {
this.messageService.sendRequestEngineResultError(result); this.messageService.sendRequestEngineResultError(result);
} }
}); });
} }
@ -57,6 +60,24 @@ export class RequestOptionsComponent {
return; return;
} }
public deny = () => this.denyInternal(false);
public deny4K = () => this.denyInternal(true);
private async denyInternal(is4K: boolean) {
const dialogRef = this.dialog.open(DenyDialogComponent, {
width: '250px',
data: { requestId: this.data.id, is4K: is4K, requestType: this.data.type }
});
dialogRef.afterClosed().subscribe(result => {
if (result.denied) {
this.bottomSheetRef.dismiss({ type: UpdateType.Deny });
}
});
}
public async approve4K() { public async approve4K() {
if (this.data.type != RequestType.movie) { if (this.data.type != RequestType.movie) {
return; return;

@ -35,6 +35,11 @@ export class RequestsListComponent {
event.onChange(); event.onChange();
return; return;
} }
if (result.type == UpdateType.Deny) {
event.request.requestStatus = 'Common.Denied';
event.onChange();
return;
}
}); });
} }
} }

@ -1,5 +1,6 @@
export enum UpdateType { export enum UpdateType {
Delete, Delete,
Approve, Approve,
Availability Availability,
Deny
} }

@ -207,10 +207,13 @@
"RequestPanel": { "RequestPanel": {
"Delete":"Delete Request", "Delete":"Delete Request",
"Approve":"Approve Request", "Approve":"Approve Request",
"Deny":"Deny Request",
"Approve4K":"Approve 4K Request", "Approve4K":"Approve 4K Request",
"Deny4K":"Deny 4K Request",
"ChangeAvailability":"Mark Available", "ChangeAvailability":"Mark Available",
"Deleted": "Successfully deleted selected items", "Deleted": "Successfully deleted selected items",
"Approved": "Successfully approved selected items" "Approved": "Successfully approved selected items",
"Denied": "Successfully denied selected items"
}, },
"SuccessfullyApproved": "Successfully Approved", "SuccessfullyApproved": "Successfully Approved",
"SuccessfullyDeleted": "Request successfully deleted", "SuccessfullyDeleted": "Request successfully deleted",

Loading…
Cancel
Save