mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-12 16:22:55 -07:00
Started on the approval panel for tv shows
This commit is contained in:
parent
833544694a
commit
b68e9fc080
18 changed files with 183 additions and 134 deletions
|
@ -131,6 +131,7 @@ namespace Ombi.Core.Engine.V2
|
|||
item.Available = oldModel.Available;
|
||||
item.Approved = oldModel.Approved;
|
||||
item.SeasonRequests = oldModel.SeasonRequests;
|
||||
item.RequestId = oldModel.RequestId;
|
||||
|
||||
return await GetExtraInfo(showInfoTask, item);
|
||||
}
|
||||
|
|
|
@ -42,22 +42,11 @@ namespace Ombi.Core.Rule.Rules.Search
|
|||
}
|
||||
if (obj.Type == RequestType.TvShow)
|
||||
{
|
||||
//var tvRequests = Tv.GetRequest(obj.Id);
|
||||
//if (tvRequests != null) // Do we already have a request for this?
|
||||
//{
|
||||
|
||||
// obj.Requested = true;
|
||||
// obj.Approved = tvRequests.ChildRequests.Any(x => x.Approved);
|
||||
// obj.Available = tvRequests.ChildRequests.Any(x => x.Available);
|
||||
|
||||
// return Task.FromResult(Success());
|
||||
//}
|
||||
|
||||
var request = (SearchTvShowViewModel)obj;
|
||||
var tvRequests = Tv.GetRequest(obj.Id);
|
||||
if (tvRequests != null) // Do we already have a request for this?
|
||||
{
|
||||
|
||||
request.RequestId = tvRequests.Id;
|
||||
request.Requested = true;
|
||||
request.Approved = tvRequests.ChildRequests.Any(x => x.Approved);
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ export class DiscoverCardDetailsComponent implements OnInit {
|
|||
}
|
||||
} else if (this.data.type === RequestType.tvShow) {
|
||||
|
||||
this.dialog.open(EpisodeRequestComponent, { width: "700px", data: this.tv })
|
||||
this.dialog.open(EpisodeRequestComponent, { width: "700px", data: this.tv, panelClass: 'modal-panel' })
|
||||
}
|
||||
this.loading = false;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ export class DiscoverCardComponent implements OnInit {
|
|||
}
|
||||
|
||||
public openDetails(details: IDiscoverCardResult) {
|
||||
const ref = this.dialog.open(DiscoverCardDetailsComponent, { width:"700px", data: details })
|
||||
const ref = this.dialog.open(DiscoverCardDetailsComponent, { width:"700px", data: details, panelClass: 'modal-panel' })
|
||||
|
||||
ref.afterClosed().subscribe(result => {
|
||||
console.log('The dialog was closed');
|
||||
|
|
|
@ -41,6 +41,7 @@ export interface ISearchTvResultV2 {
|
|||
images: IImagesV2;
|
||||
cast: ICast[];
|
||||
crew: ICrew[];
|
||||
requestId: number;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2,12 +2,13 @@
|
|||
import { YoutubeTrailerComponent } from "./shared/youtube-trailer.component";
|
||||
import { TvDetailsComponent } from "./tv/tv-details.component";
|
||||
import { MovieInformationPanelComponent } from "./movie/panels/movie-information-panel.component";
|
||||
import { TvInformationPanelComponent } from "./tv/panels/tv-information-panel.component";
|
||||
import { TvInformationPanelComponent } from "./tv/panels/tv-information-panel/tv-information-panel.component";
|
||||
import { TopBannerComponent } from "./shared/top-banner/top-banner.component";
|
||||
import { SocialIconsComponent } from "./shared/social-icons/social-icons.component";
|
||||
import { MediaPosterComponent } from "./shared/media-poster/media-poster.component";
|
||||
import { CastCarouselComponent } from "./shared/cast-carousel/cast-carousel.component";
|
||||
import { DenyDialogComponent } from "./shared/deny-dialog/deny-dialog.component";
|
||||
import { TvRequestsPanelComponent } from "./tv/panels/tv-requests/tv-requests-panel.component";
|
||||
|
||||
export const components: any[] = [
|
||||
MovieDetailsComponent,
|
||||
|
@ -20,6 +21,7 @@ export const components: any[] = [
|
|||
MediaPosterComponent,
|
||||
CastCarouselComponent,
|
||||
DenyDialogComponent,
|
||||
TvRequestsPanelComponent
|
||||
];
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Component, ViewEncapsulation, Input, OnInit } from "@angular/core";
|
||||
import { ISearchTvResultV2 } from "../../../../interfaces/ISearchTvResultV2";
|
||||
import { ISearchTvResultV2 } from "../../../../../interfaces/ISearchTvResultV2";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./tv-information-panel.component.html",
|
||||
styleUrls: ["../../../media-details.component.scss"],
|
||||
styleUrls: ["../../../../media-details.component.scss"],
|
||||
selector: "tv-information-panel",
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
|
@ -0,0 +1,78 @@
|
|||
<mat-accordion class="mat-elevation-z8">
|
||||
|
||||
<mat-expansion-panel *ngFor="let request of tvRequest">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
<div *ngIf="request.approved && !request.available">{{'Common.ProcessingRequest' | translate}}</div>
|
||||
<div *ngIf="request.requested && !request.approved && !request.available">
|
||||
{{'Common.PendingApproval' | translate}}
|
||||
</div>
|
||||
<div *ngIf="!request.requested && !request.available && !request.approved">
|
||||
{{'Common.NotRequested' | translate}}
|
||||
</div>
|
||||
<div *ngIf="request.available">{{'Common.Available' | translate}}
|
||||
</div>
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
Requested By '{{request.requestedUser.userAlias}}' on
|
||||
{{request.requestedDate | amLocal | amDateFormat: 'LL' }}
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
|
||||
<mat-tab-group *ngFor="let season of request.seasonRequests">
|
||||
<mat-tab label="{{ 'Requests.Season' | translate }} {{season.seasonNumber}}">
|
||||
|
||||
<table mat-table [dataSource]="season.episodes" class="mat-elevation-z8">
|
||||
|
||||
|
||||
<ng-container matColumnDef="number">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'Requests.Number' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.episodeNumber}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="title">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'Requests.GridTitle' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.title}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="airDate">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'Requests.AirDate' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.airDate | amLocal | amDateFormat: 'L' }}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ 'Requests.GridStatus' | translate }} </th>
|
||||
<td mat-cell *matCellDef="let ep">
|
||||
|
||||
<span *ngIf="request.denied" class="label label-danger" id="deniedLabel"
|
||||
[translate]="'Common.Denied'">
|
||||
<i class="fa fa-check" matTooltip="{{request.deniedReason}}"></i>
|
||||
</span>
|
||||
<span *ngIf="!request.denied && ep.available" class="label label-success"
|
||||
id="availableLabel" [translate]="'Common.Available'"></span>
|
||||
<span *ngIf="!request.denied &&ep.approved && !ep.available" class="label label-info"
|
||||
id="processingRequestLabel" [translate]="'Common.ProcessingRequest'"></span>
|
||||
<div *ngIf="!request.denied && !ep.approved">
|
||||
<div *ngIf="!ep.available"><span class="label label-warning" id="pendingApprovalLabel"
|
||||
[translate]="'Common.PendingApproval'"></span></div>
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</mat-tab>
|
||||
|
||||
</mat-tab-group>
|
||||
|
||||
|
||||
<button mat-raised-button color="accent">Approve</button>
|
||||
|
||||
|
||||
|
||||
|
||||
</mat-expansion-panel>
|
||||
|
||||
</mat-accordion>
|
|
@ -0,0 +1,16 @@
|
|||
import { Component, ViewEncapsulation, Input, OnInit } from "@angular/core";
|
||||
import { IChildRequests } from "../../../../../interfaces";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./tv-requests-panel.component.html",
|
||||
styleUrls: ["./tv-requests-panel.component.scss"],
|
||||
selector: "tv-requests-panel"
|
||||
})
|
||||
export class TvRequestsPanelComponent implements OnInit {
|
||||
@Input() public tvRequest: IChildRequests[];
|
||||
|
||||
public displayedColumns: string[] = ['number', 'title', 'airDate', 'status'];
|
||||
public ngOnInit(): void {
|
||||
//
|
||||
}
|
||||
}
|
|
@ -13,19 +13,21 @@
|
|||
<div class="col-12 col-lg-3 col-xl-3 media-row">
|
||||
|
||||
<social-icons [homepage]="tv.homepage" [tvdbId]="tv.id" [hasTrailer]="tv.trailer" (openTrailer)="openDialog()"
|
||||
[imdbId]="tv.imdbId" [available]="tv.available" [plexUrl]="tv.plexUrl" [embyUrl]="tv.embyUrl"></social-icons>
|
||||
[imdbId]="tv.imdbId" [available]="tv.available" [plexUrl]="tv.plexUrl" [embyUrl]="tv.embyUrl">
|
||||
</social-icons>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6 col-xl-6 media-row">
|
||||
|
||||
<button *ngIf="!tv.fullyAvailable" mat-raised-button class="btn-spacing" color="primary" (click)="request()"><i
|
||||
class="fa fa-plus"></i>
|
||||
<button *ngIf="!tv.fullyAvailable" mat-raised-button class="btn-spacing" color="primary"
|
||||
(click)="request()"><i class="fa fa-plus"></i>
|
||||
{{ 'Common.Request' | translate }}</button>
|
||||
|
||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent" [disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent" [disabled]>
|
||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
||||
[disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -56,91 +58,38 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-2">
|
||||
|
||||
<!--Just some space yo-->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row card-spacer media-row">
|
||||
|
||||
|
||||
<div class="col-12 col-md-9">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="row card-spacer media-row">
|
||||
<div class="col-12 col-md-3"></div>
|
||||
|
||||
<!-- <div class="col-12 col-md-9">
|
||||
<div class="col-12 col-md-10">
|
||||
<mat-accordion>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Recommendations
|
||||
Requests
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<div class="row card-spacer" *ngIf="tv.recommendations.results.length > 0">
|
||||
|
||||
<div class="col-md-2" *ngFor="let r of tv.recommendations.results">
|
||||
<div class="sidebar affixable affix-top preview-poster">
|
||||
<div class="poster">
|
||||
<a [routerLink]="'/details/tv/'+r.id">
|
||||
<img class="real grow" matTooltip="{{r.title}}"
|
||||
src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}" alt="Poster"
|
||||
style="display: block;">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<tv-requests-panel [tvRequest]="tvRequest"></tv-requests-panel>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Similar
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<div class="row card-spacer" *ngIf="tv.similar.results.length > 0">
|
||||
|
||||
<div class="col-md-2" *ngFor="let r of tv.similar.results">
|
||||
<div class="sidebar affixable affix-top preview-poster">
|
||||
<div class="poster ">
|
||||
<a [routerLink]="'/details/tv/'+r.id">
|
||||
<img class="real grow" matTooltip="{{r.title}}"
|
||||
src="https://image.tmdb.org/t/p/w300/{{r.poster_path}}" alt="Poster"
|
||||
style="display: block;">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
Videos
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<div class="row card-spacer" *ngIf="tv.videos.results.length > 0">
|
||||
|
||||
<div class="col-md-6" *ngFor="let video of tv.videos.results">
|
||||
<iframe width="100%" height="315px"
|
||||
[src]="'https://www.youtube.com/embed/' + video.key | safe" frameborder="0"
|
||||
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</div> -->
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
import { Component, ViewEncapsulation } from "@angular/core";
|
||||
import { ImageService, SearchV2Service, MessageService } from "../../../services";
|
||||
import { ImageService, SearchV2Service, MessageService, RequestService } from "../../../services";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { ISearchTvResultV2 } from "../../../interfaces/ISearchTvResultV2";
|
||||
import { MatDialog } from "@angular/material";
|
||||
import { YoutubeTrailerComponent } from "../shared/youtube-trailer.component";
|
||||
import { EpisodeRequestComponent } from "../../../shared/episode-request/episode-request.component";
|
||||
import { IChildRequests } from "../../../interfaces";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./tv-details.component.html",
|
||||
|
@ -14,13 +15,14 @@ import { EpisodeRequestComponent } from "../../../shared/episode-request/episode
|
|||
})
|
||||
export class TvDetailsComponent {
|
||||
public tv: ISearchTvResultV2;
|
||||
public tvRequest: IChildRequests[];
|
||||
public fromSearch: boolean;
|
||||
|
||||
private tvdbId: number;
|
||||
|
||||
constructor(private searchService: SearchV2Service, private route: ActivatedRoute,
|
||||
private sanitizer: DomSanitizer, private imageService: ImageService,
|
||||
public dialog: MatDialog, public messageService: MessageService) {
|
||||
public dialog: MatDialog, public messageService: MessageService, private requestService: RequestService) {
|
||||
this.route.params.subscribe((params: any) => {
|
||||
this.tvdbId = params.tvdbId;
|
||||
this.fromSearch = params.search;
|
||||
|
@ -30,19 +32,23 @@ export class TvDetailsComponent {
|
|||
}
|
||||
|
||||
public async load() {
|
||||
if(this.fromSearch) {
|
||||
if (this.fromSearch) {
|
||||
this.tv = await this.searchService.getTvInfoWithMovieDbId(this.tvdbId);
|
||||
this.tvdbId = this.tv.id;
|
||||
} else {
|
||||
this.tv = await this.searchService.getTvInfo(this.tvdbId);
|
||||
}
|
||||
|
||||
if(this.tv.requestId) {
|
||||
this.tvRequest = await this.requestService.getChildRequests(this.tv.requestId).toPromise();
|
||||
}
|
||||
|
||||
const tvBanner = await this.imageService.getTvBanner(this.tvdbId).toPromise();
|
||||
this.tv.background = this.sanitizer.bypassSecurityTrustStyle("url(" + tvBanner + ")");
|
||||
}
|
||||
|
||||
public async request() {
|
||||
this.dialog.open(EpisodeRequestComponent, { width: "800px", data: this.tv })
|
||||
this.dialog.open(EpisodeRequestComponent, { width: "800px", data: this.tv, panelClass: 'modal-panel' })
|
||||
}
|
||||
|
||||
public openDialog() {
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button mat-raised-button color="primary" [routerLink]="'/details/movie/' + element.theMovieDbId">Details</button>
|
||||
<button mat-raised-button color="accent" [routerLink]="'/details/movie/' + element.theMovieDbId">Details</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -2,8 +2,3 @@
|
|||
margin: auto;
|
||||
width: 95%;
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
height:100%;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button mat-raised-button color="primary" [routerLink]="'/details/tv/' + element.parentRequest.tvDbId">Details</button>
|
||||
<button mat-raised-button color="accent" [routerLink]="'/details/tv/' + element.parentRequest.tvDbId">Details</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IssuesReportComponent } from "./issues-report.component";
|
|||
import { InputSwitchModule, SidebarModule } from "primeng/primeng";
|
||||
|
||||
import {
|
||||
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatTooltipModule, MatSelectModule, MatTableModule, MatPaginatorModule, MatSortModule} from '@angular/material';
|
||||
MatButtonModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, MatTooltipModule, MatSelectModule, MatTableModule, MatPaginatorModule, MatSortModule, MatTreeModule} from '@angular/material';
|
||||
import { MatCardModule, MatInputModule, MatTabsModule, MatAutocompleteModule, MatCheckboxModule, MatExpansionModule, MatDialogModule, MatProgressSpinnerModule,
|
||||
MatChipsModule } from "@angular/material";
|
||||
import { EpisodeRequestComponent } from "./episode-request/episode-request.component";
|
||||
|
@ -47,6 +47,7 @@ import { EpisodeRequestComponent } from "./episode-request/episode-request.compo
|
|||
MatSelectModule,
|
||||
MatPaginatorModule,
|
||||
MatSortModule,
|
||||
MatTreeModule,
|
||||
],
|
||||
entryComponents: [
|
||||
EpisodeRequestComponent
|
||||
|
@ -62,6 +63,7 @@ import { EpisodeRequestComponent } from "./episode-request/episode-request.compo
|
|||
EpisodeRequestComponent,
|
||||
TruncateModule,
|
||||
InputSwitchModule,
|
||||
MatTreeModule,
|
||||
MomentModule,MatCardModule,
|
||||
MatInputModule,
|
||||
MatTabsModule,
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
.top-spacing {
|
||||
padding-top: 10%;
|
||||
}
|
||||
.modal-panel {
|
||||
max-height: 100vh !important;
|
||||
max-width: 100vw !important;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 979px) {
|
||||
|
@ -10,7 +15,8 @@
|
|||
}
|
||||
}
|
||||
|
||||
html, body{
|
||||
html,
|
||||
body {
|
||||
min-height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
@ -24,8 +30,8 @@ html, body{
|
|||
height: 50px;
|
||||
}
|
||||
|
||||
|
||||
/* Scrollbar */
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
background: rgba(0, 0, 0, 0);
|
||||
|
@ -52,3 +58,7 @@ html, body{
|
|||
transform: scale(1.1);
|
||||
color: black;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue