mirror of https://github.com/Ombi-app/Ombi
parent
c787e58f3b
commit
cdfe91e3a4
@ -0,0 +1,63 @@
|
||||
<mat-accordion *ngIf="issuesCount > 0">
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
{{'Issues.Title' | translate}}
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
<span *ngIf="isOutstanding">{{issuesCount}} </span><span><mat-icon *ngIf="isOutstanding" matTooltip="{{'Issues.Outstanding' | translate}}">error_outline</mat-icon></span>
|
||||
<span *ngIf="!isOutstanding">{{issuesCount}}</span>
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<!-- content start -->
|
||||
|
||||
<mat-accordion class="mat-elevation-z8">
|
||||
<mat-expansion-panel *ngFor="let issue of issues">
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
{{ 'Issues.Subject' | translate}}: {{issue.subject}}
|
||||
</mat-panel-title>
|
||||
<mat-panel-description>
|
||||
{{ 'Issues.ReportedBy' | translate}}: {{issue.userReported.userAlias}}
|
||||
</mat-panel-description>
|
||||
<mat-panel-description>
|
||||
{{'Issues.Category' | translate}}: {{issue.issueCategory.value}}
|
||||
</mat-panel-description>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col">
|
||||
{{'Issues.Description' | translate}}: {{issue.description}}
|
||||
</div>
|
||||
<div class="col">
|
||||
{{'Issues.Status' | translate}}: {{IssueStatus[issue.status] | humanize}}
|
||||
</div>
|
||||
<div class="col" *ngIf="issue.resolvedDate">
|
||||
{{'Issues.ResolvedDate' | translate}}: {{issue.resolvedDate}}
|
||||
</div>
|
||||
<div class="col" *ngIf="issue.createdDate">
|
||||
{{'Issues.CreatedDate' | translate}}: {{issue.createdDate}}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
<div *ngIf="isAdmin" class="row action-buttons">
|
||||
<div class="button-padding">
|
||||
<button *ngIf="issue.status === IssueStatus.Pending && !settings.enableInProgress || issue.status == IssueStatus.InProgress" mat-raised-button color="accent" (click)="resolve(issue)"> {{ 'Issues.MarkResolved' | translate }}</button>
|
||||
</div>
|
||||
<div class="button-padding">
|
||||
<button *ngIf="issue.status === IssueStatus.Pending && settings.enableInProgress" mat-raised-button color="accent" (click)="inProgress(issue)"> {{ 'Issues.MarkInProgress' | translate }}</button>
|
||||
</div>
|
||||
<div class="button-padding">
|
||||
<button mat-raised-button color="warn" (click)="delete(issue)"> {{ 'Issues.Delete' | translate }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
<!-- content end -->
|
||||
</mat-expansion-panel>
|
||||
|
||||
</mat-accordion>
|
@ -0,0 +1,7 @@
|
||||
.action-buttons {
|
||||
padding-top: 1%;
|
||||
}
|
||||
|
||||
.button-padding {
|
||||
padding: 1%;
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
import { Component, Input, OnInit } from "@angular/core";
|
||||
import { IssuesService, NotificationService, SettingsService } from "../../../../services";
|
||||
import { RequestType, IIssues, IssueStatus, IIssueSettings } from "../../../../interfaces";
|
||||
import { TranslateService } from "@ngx-translate/core";
|
||||
|
||||
@Component({
|
||||
selector: "issues-panel",
|
||||
templateUrl: "./issues-panel.component.html",
|
||||
styleUrls: ["./issues-panel.component.scss"]
|
||||
})
|
||||
export class IssuesPanelComponent implements OnInit {
|
||||
|
||||
@Input() public requestId: number;
|
||||
@Input() public isAdmin: boolean;
|
||||
|
||||
public issuesCount: number;
|
||||
public issues: IIssues[];
|
||||
public IssueStatus = IssueStatus;
|
||||
public isOutstanding: boolean;
|
||||
public loadingFlag: boolean;
|
||||
public settings: IIssueSettings;
|
||||
|
||||
constructor(private issuesService: IssuesService, private notificationService: NotificationService,
|
||||
private translateService: TranslateService, private settingsService: SettingsService) {
|
||||
|
||||
}
|
||||
|
||||
public async ngOnInit() {
|
||||
this.issues = await this.issuesService.getIssuesByRequestId(this.requestId);
|
||||
this.issuesCount = this.issues.length;
|
||||
this.calculateOutstanding();
|
||||
this.settings = await this.settingsService.getIssueSettings().toPromise();
|
||||
}
|
||||
|
||||
public resolve(issue: IIssues) {
|
||||
this.issuesService.updateStatus({issueId: issue.id, status: IssueStatus.Resolved}).subscribe(x => {
|
||||
this.notificationService.success(this.translateService.instant("Issues.MarkedAsResolved"));
|
||||
issue.status = IssueStatus.Resolved;
|
||||
this.calculateOutstanding();
|
||||
});
|
||||
}
|
||||
|
||||
public inProgress(issue: IIssues) {
|
||||
this.issuesService.updateStatus({issueId: issue.id, status: IssueStatus.InProgress}).subscribe(x => {
|
||||
this.notificationService.success(this.translateService.instant("Issues.MarkedAsInProgress"));
|
||||
issue.status = IssueStatus.InProgress;
|
||||
});
|
||||
}
|
||||
|
||||
public async delete(issue: IIssues) {
|
||||
await this.issuesService.deleteIssue(issue.id);
|
||||
this.notificationService.success(this.translateService.instant("Issues.DeletedIssue"));
|
||||
this.issues = this.issues.filter((el) => { return el.id !== issue.id; });
|
||||
this.issuesCount = this.issues.length;
|
||||
this.calculateOutstanding();
|
||||
}
|
||||
|
||||
private calculateOutstanding() {
|
||||
this.isOutstanding = this.issues.some((i) => {
|
||||
return i.status !== IssueStatus.Resolved;
|
||||
});
|
||||
}
|
||||
}
|
@ -1,29 +1,27 @@
|
||||
<h1 mat-dialog-title>{{ 'Issues.IssueDialog.Title' | translate}}</h1>
|
||||
<div mat-dialog-content>
|
||||
|
||||
<div class="col-12">
|
||||
<mat-form-field class="col-12">
|
||||
<mat-label>{{'Issues.IssueDialog.SelectCategory' | translate}}</mat-label>
|
||||
<mat-select [(ngModel)]="issue.issueCategoryId">
|
||||
<mat-option *ngFor="let cat of issueCategories" [value]="cat.id">
|
||||
{{cat.value}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<div class="col-12">
|
||||
<mat-form-field class="col-12">
|
||||
<mat-label>{{'Issues.IssueDialog.SelectCategory' | translate}}</mat-label>
|
||||
<mat-select [(ngModel)]="issue.issueCategoryId">
|
||||
<mat-option *ngFor="let cat of issueCategories" [value]="cat.id">
|
||||
{{cat.value}}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="col-12">
|
||||
<input matInput placeholder="{{ 'Issues.IssueDialog.TitlePlaceholder' | translate}}" [(ngModel)]="issue.subject">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="col-12">
|
||||
<input matInput placeholder="{{ 'Issues.IssueDialog.TitlePlaceholder' | translate}}" [(ngModel)]="issue.subject">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="col-12">
|
||||
<textarea matInput placeholder="{{ 'Issues.IssueDialog.DescriptionPlaceholder' | translate}}"
|
||||
[(ngModel)]="issue.description"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<mat-form-field class="col-12">
|
||||
<textarea matInput placeholder="{{ 'Issues.IssueDialog.DescriptionPlaceholder' | translate}}" [(ngModel)]="issue.description"></textarea>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div mat-dialog-actions>
|
||||
<button mat-button (click)="onNoClick()">{{ 'Common.Cancel' | translate}}</button>
|
||||
<button mat-button (click)="createIssue()" [mat-dialog-close]="data"
|
||||
cdkFocusInitial>{{ 'Common.Submit' | translate}}</button>
|
||||
<button mat-button (click)="onNoClick()">{{ 'Common.Cancel' | translate}}</button>
|
||||
<button mat-button [disabled]="issue.subject.length <= 0 || !issue.issueCategoryId || issue.description.length <= 0" (click)="createIssue()" [mat-dialog-close]="data" cdkFocusInitial>{{ 'Common.Submit' | translate}}</button>
|
||||
</div>
|
@ -1,105 +1,110 @@
|
||||
<div *ngIf="!tv" class="justify-content-md-center top-spacing loading-spinner">
|
||||
<mat-spinner [color]="'accent'"></mat-spinner>
|
||||
<mat-spinner [color]="'accent'"></mat-spinner>
|
||||
</div>
|
||||
<div *ngIf="tv">
|
||||
|
||||
<top-banner [background]="tv.background" [available]="tv.available" [title]="tv.title" [releaseDate]="tv.firstAired"
|
||||
[tagline]="tv.certification"></top-banner>
|
||||
<top-banner [background]="tv.background" [available]="tv.available" [title]="tv.title" [releaseDate]="tv.firstAired" [tagline]="tv.certification"></top-banner>
|
||||
|
||||
<section id="info-wrapper">
|
||||
<div class="small-middle-container">
|
||||
<div class="row">
|
||||
<section id="info-wrapper">
|
||||
<div class="small-middle-container">
|
||||
<div class="row">
|
||||
|
||||
<media-poster [posterPath]="tv.images.medium"></media-poster>
|
||||
<media-poster [posterPath]="tv.images.medium"></media-poster>
|
||||
|
||||
<!--Next to poster-->
|
||||
<div class="col-12 col-lg-3 col-xl-3 media-row">
|
||||
<!--Next to poster-->
|
||||
<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>
|
||||
<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>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-6 col-xl-6 media-row">
|
||||
<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]>
|
||||
<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>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-2">
|
||||
<button *ngIf="(tvRequest)" mat-raised-button class="btn-spacing" color="danger" (click)="issue()">
|
||||
<i class="fa fa-exclamation"></i> {{
|
||||
'Requests.ReportIssue' | translate }}</button>
|
||||
|
||||
<mat-card class="mat-elevation-z8">
|
||||
<mat-card-content class="medium-font">
|
||||
<tv-information-panel [tv]="tv"></tv-information-panel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-12 col-md-10">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-card class="mat-elevation-z8 spacing-below">
|
||||
<mat-card-content>
|
||||
{{tv.overview}}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<cast-carousel [cast]="tv.cast"></cast-carousel>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-2">
|
||||
|
||||
<mat-card class="mat-elevation-z8">
|
||||
<mat-card-content class="medium-font">
|
||||
<tv-information-panel [tv]="tv"></tv-information-panel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-12 col-md-10">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<mat-card class="mat-elevation-z8 spacing-below">
|
||||
<mat-card-content>
|
||||
{{tv.overview}}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<cast-carousel [cast]="tv.cast"></cast-carousel>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-2">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-2">
|
||||
<!--Just some space yo-->
|
||||
|
||||
<!--Just some space yo-->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-12 col-md-10" *ngIf="tvRequest">
|
||||
<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" [isAdmin]="isAdmin"></tv-requests-panel>
|
||||
</mat-expansion-panel>
|
||||
<div class="col-12 col-md-10" *ngIf="tvRequest">
|
||||
<div class="issuesPanel">
|
||||
<issues-panel [requestId]="tv.requestId" [isAdmin]="isAdmin"></issues-panel>
|
||||
</div>
|
||||
<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" [isAdmin]="isAdmin"></tv-requests-panel>
|
||||
</mat-expansion-panel>
|
||||
|
||||
</mat-accordion>
|
||||
</mat-accordion>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="bottom-page-gap">
|
||||
</div>
|
||||
</section>
|
||||
<div class="bottom-page-gap">
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
Loading…
Reference in new issue