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 d9366e7d1..d95460b40 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 @@ -98,7 +98,9 @@ - - + + + + \ No newline at end of file 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 8b4ae170a..ca36a5d62 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 @@ -62,11 +62,11 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { this.manageOwnRequests = this.auth.hasRole("ManageOwnRequests") if (this.isAdmin) { this.displayedColumns.unshift('select'); - } - + } + this.is4kEnabled = this.featureFacade.is4kEnabled(); if ((this.isAdmin || this.auth.hasRole("Request4KMovie")) - && this.is4kEnabled) { + && this.is4kEnabled) { this.displayedColumns.splice(4, 0, 'has4kRequest'); } @@ -155,13 +155,13 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { private checkDate(date: Date|string): boolean { if (typeof date === 'string') { - return new Date(date).getFullYear() > 1; + return new Date(date).getFullYear() > 1; } if (date instanceof Date) { - return date.getFullYear() > 1; + return date.getFullYear() > 1; } return false; - } + } public switchFilter(type: RequestFilterType) { this.currentFilter = type; @@ -172,15 +172,15 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { const numSelected = this.selection.selected.length; const numRows = this.dataSource.data.length; return numSelected === numRows; - } + } - public masterToggle() { + public masterToggle() { this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach(row => this.selection.select(row)); - } + } - public async bulkDelete() { + public async bulkDelete() { if (this.selection.isEmpty()) { return; } @@ -194,13 +194,13 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { this.selection.clear(); 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()) { return; } @@ -222,12 +222,45 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { this.selection.clear(); this.ngAfterViewInit(); }) - } + } - public getRequestDate(request: IMovieRequests) : Date { + public bulkDeny = () => this.bulkDenyInternal(false); + + public bulkDeny4K = () => this.bulkDenyInternal(true); + + private bulkDenyInternal(is4k: boolean) { + if (this.selection.isEmpty()) { + return; + } + let tasks = new Array>(); + 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 { if (new Date(request.requestedDate).getFullYear() === 1) { return request.requestedDate4k; } return request.requestedDate; - } + } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html index dc1c04467..b32c872ac 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html @@ -1,14 +1,20 @@ - - {{'Requests.RequestPanel.Delete' | translate}} - {{'Requests.RequestPanel.Approve' | translate}} + + {{'Requests.RequestPanel.Deny' | translate}} + {{'Requests.RequestPanel.Approve4K' | translate}} + + {{'Requests.RequestPanel.Deny4K' | translate}} + {{'Requests.RequestPanel.ChangeAvailability' | translate}} + + {{'Requests.RequestPanel.Delete' | translate}} + \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts index b3de64235..909c34544 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts @@ -5,6 +5,8 @@ import { IRequestEngineResult, RequestType } from '../../../interfaces'; import { UpdateType } from '../../models/UpdateType'; import { TranslateService } from '@ngx-translate/core'; import { firstValueFrom, Observable } from 'rxjs'; +import { DenyDialogComponent } from '../../../media-details/components/shared/deny-dialog/deny-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; @Component({ selector: 'request-options', @@ -17,6 +19,7 @@ export class RequestOptionsComponent { constructor(@Inject(MAT_BOTTOM_SHEET_DATA) public data: any, private requestService: RequestService, private messageService: MessageService, + public dialog: MatDialog, private bottomSheetRef: MatBottomSheetRef, private translate: TranslateService) { } @@ -33,11 +36,11 @@ export class RequestOptionsComponent { } request.subscribe(result => { if (result.result) { - this.messageService.send(this.translate.instant("Requests.SuccessfullyDeleted")); - this.bottomSheetRef.dismiss({type: UpdateType.Delete}); - return; + this.messageService.send(this.translate.instant("Requests.SuccessfullyDeleted")); + this.bottomSheetRef.dismiss({type: UpdateType.Delete}); + return; } else { - this.messageService.sendRequestEngineResultError(result); + this.messageService.sendRequestEngineResultError(result); } }); } @@ -57,6 +60,24 @@ export class RequestOptionsComponent { 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() { if (this.data.type != RequestType.movie) { return; diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts index 8117e0c22..4ea6e4886 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts @@ -35,6 +35,11 @@ export class RequestsListComponent { event.onChange(); return; } + if (result.type == UpdateType.Deny) { + event.request.requestStatus = 'Common.Denied'; + event.onChange(); + return; + } }); } } diff --git a/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts b/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts index 3a0f690db..9e54b1114 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts @@ -1,5 +1,6 @@ export enum UpdateType { Delete, Approve, - Availability + Availability, + Deny } \ No newline at end of file diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index ad4aeaae2..a9c40c197 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -207,10 +207,13 @@ "RequestPanel": { "Delete":"Delete Request", "Approve":"Approve Request", + "Deny":"Deny Request", "Approve4K":"Approve 4K Request", + "Deny4K":"Deny 4K Request", "ChangeAvailability":"Mark Available", "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Approved": "Successfully approved selected items", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", "SuccessfullyDeleted": "Request successfully deleted",