Started on the approval panel for tv shows

pull/3895/head
tidusjar 6 years ago
parent 833544694a
commit b68e9fc080

@ -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>
<div class="row">
<div class="col-12 col-md-2">
<!--Just some space yo-->
<div class="row card-spacer media-row">
</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>
Requests
</mat-panel-title>
</mat-expansion-panel-header>
<tv-requests-panel [tvRequest]="tvRequest"></tv-requests-panel>
</mat-expansion-panel>
</mat-accordion>
</div>
</div>
<div class="row card-spacer media-row">
<div class="col-12 col-md-3"></div>
<!-- <div class="col-12 col-md-9">
<mat-accordion>
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
Recommendations
</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>
</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>
@ -150,4 +99,4 @@
</div>
</section>
</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);
}
const tvBanner = await this.imageService.getTvBanner(this.tvdbId).toPromise();
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,

@ -1,54 +1,64 @@
@media (max-width: 978px) {
.top-spacing {
padding-top: 10%;
}
.top-spacing {
padding-top: 10%;
}
.modal-panel {
max-height: 100vh !important;
max-width: 100vw !important;
height: 100%;
}
}
@media (min-width: 979px) {
.top-spacing {
padding-top: 4%;
}
.top-spacing {
padding-top: 4%;
}
}
html, body{
min-height: 100vh;
overflow: auto;
html,
body {
min-height: 100vh;
overflow: auto;
}
.spinner-container {
position: relative;
margin-left: 50%;
position: relative;
margin-left: 50%;
}
.bottom-page-gap {
height: 50px;
height: 50px;
}
/* Scrollbar */
::-webkit-scrollbar {
width: 7px;
background: rgba(0, 0, 0, 0);
width: 7px;
background: rgba(0, 0, 0, 0);
}
::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0);
background: rgba(0, 0, 0, 0);
}
::-webkit-scrollbar-thumb {
border-radius: 3px;
background: #41927b;
border-radius: 3px;
background: #41927b;
}
.sidenav ::-webkit-scrollbar-track {
display: none;
display: none;
}
.grow {
transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
}
.grow:hover {
transform: scale(1.1);
color: black;
transform: scale(1.1);
color: black;
}
table {
width: 100%;
}
Loading…
Cancel
Save