More on the issues, we can now work through the issues flow

pull/3554/head
Jamie Rees 5 years ago
parent c787e58f3b
commit cdfe91e3a4

@ -16,13 +16,7 @@
<!--Next to poster-->
<div class="col-12 col-lg-3 col-xl-3 media-row">
<social-icons
[homepage]="artist.links.homePage"
[doNotAppend]="true"
[imdbId]="artist.links.imdb"
[twitter]="artist.links.twitter"
[facebook]="artist.links.facebook"
[instagram]="artist.links.instagram"></social-icons>
<social-icons [homepage]="artist.links.homePage" [doNotAppend]="true" [imdbId]="artist.links.imdb" [twitter]="artist.links.twitter" [facebook]="artist.links.facebook" [instagram]="artist.links.instagram"></social-icons>
</div>
@ -36,6 +30,8 @@
<button mat-raised-button *ngIf="selectedAlbums.length > 0" class="btn-spacing" color="accent" (click)="clearSelection()">
<i class="fa fa-minus"></i> {{ 'MediaDetails.ClearSelection' | translate }}</button>
<!-- <button mat-raised-button class="btn-green btn-spacing" *ngIf="movie.available"> {{
'Common.Available' | translate }}</button> -->
<!-- <span *ngIf="!movie.available">
@ -110,8 +106,17 @@
<div class="row">
<div class="col-12">
<artist-release-panel (onAlbumSelect)="albumSelected($event)"
(albumLoad)="albumLoad($event)" *ngIf="artist.releaseGroups.length > 0" [releases]="artist.releaseGroups"></artist-release-panel>
<artist-release-panel (onAlbumSelect)="albumSelected($event)" (albumLoad)="albumLoad($event)" *ngIf="artist.releaseGroups.length > 0" [releases]="artist.releaseGroups"></artist-release-panel>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="issuesPanel" *ngIf="artist.requestId">
<issues-panel [requestId]="artist.requestId" [isAdmin]="isAdmin"></issues-panel>
</div>
</div>
</div>

@ -11,12 +11,13 @@ import { DenyDialogComponent } from "./shared/deny-dialog/deny-dialog.component"
import { TvRequestsPanelComponent } from "./tv/panels/tv-requests/tv-requests-panel.component";
import { MovieAdminPanelComponent } from "./movie/panels/movie-admin-panel/movie-admin-panel.component";
import { MovieAdvancedOptionsComponent } from "./movie/panels/movie-advanced-options/movie-advanced-options.component";
import { SearchService, RequestService, RadarrService } from "../../services";
import { SearchService, RequestService, RadarrService, IssuesService } from "../../services";
import { RequestServiceV2 } from "../../services/requestV2.service";
import { NewIssueComponent } from "./shared/new-issue/new-issue.component";
import { ArtistDetailsComponent } from "./artist/artist-details.component";
import { ArtistInformationPanel } from "./artist/panels/artist-information-panel/artist-information-panel.component";
import { ArtistReleasePanel } from "./artist/panels/artist-release-panel/artist-release-panel.component";
import { IssuesPanelComponent } from "./shared/issues-panel/issues-panel.component";
export const components: any[] = [
MovieDetailsComponent,
@ -36,6 +37,7 @@ export const components: any[] = [
ArtistDetailsComponent,
ArtistInformationPanel,
ArtistReleasePanel,
IssuesPanelComponent,
];
export const entryComponents: any[] = [
@ -50,4 +52,5 @@ export const providers: any[] = [
RequestService,
RadarrService,
RequestServiceV2,
IssuesService,
];

@ -16,8 +16,8 @@
<!--Next to poster-->
<div class="col-12 col-lg-3 col-xl-3 media-row">
<social-icons [homepage]="movie.homepage" [theMoviedbId]="movie.id" [hasTrailer]="movie.videos?.results?.length > 0" (openTrailer)="openDialog()" [imdbId]="movie.imdbId" [twitter]="movie.externalIds.twitterId" [facebook]="movie.externalIds.facebookId" [instagram]="movie.externalIds.instagramId"
[available]="movie.available" [plexUrl]="movie.plexUrl" [embyUrl]="movie.embyUrl"></social-icons>
<social-icons [homepage]="movie.homepage" [theMoviedbId]="movie.id" [hasTrailer]="movie.videos?.results?.length > 0" (openTrailer)="openDialog()" [imdbId]="movie.imdbId" [twitter]="movie.externalIds.twitterId" [facebook]="movie.externalIds.facebookId"
[instagram]="movie.externalIds.instagramId" [available]="movie.available" [plexUrl]="movie.plexUrl" [embyUrl]="movie.embyUrl"></social-icons>
</div>
@ -109,7 +109,11 @@
<div class="row">
<div class="col-12">
<mat-accordion class="mat-elevation-z8 spacing-below">
<div class="issuesPanel" *ngIf="movie.requestId">
<issues-panel [requestId]="movie.requestId" [isAdmin]="isAdmin"></issues-panel>
</div>
<mat-accordion class=" mat-elevation-z8 spacing-below ">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>
@ -117,7 +121,7 @@
</mat-panel-title>
</mat-expansion-panel-header>
<div class="row card-spacer" *ngIf="movie.recommendations?.results?.length > 0">
<div class="row card-spacer " *ngIf="movie.recommendations?.results?.length> 0">
<div class="col-md-2" *ngFor="let r of movie.recommendations?.results">
<div class="sidebar affixable affix-top preview-poster">

@ -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;
});
}
}

@ -16,14 +16,12 @@
</mat-form-field>
<mat-form-field class="col-12">
<textarea matInput placeholder="{{ 'Issues.IssueDialog.DescriptionPlaceholder' | translate}}"
[(ngModel)]="issue.description"></textarea>
<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 [disabled]="issue.subject.length <= 0 || !issue.issueCategoryId || issue.description.length <= 0" (click)="createIssue()" [mat-dialog-close]="data" cdkFocusInitial>{{ 'Common.Submit' | translate}}</button>
</div>

@ -41,7 +41,6 @@ export class NewIssueComponent implements OnInit {
this.issueCategories = await this.issueService.getCategories().toPromise();
}
public async createIssue() {
const result = await this.issueService.createIssue(this.issue).toPromise();
if(result) {

@ -3,8 +3,7 @@
</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">
@ -15,23 +14,25 @@
<!--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 [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 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>
<button *ngIf="(tvRequest)" mat-raised-button class="btn-spacing" color="danger" (click)="issue()">
<i class="fa fa-exclamation"></i> {{
'Requests.ReportIssue' | translate }}</button>
</div>
</div>
@ -70,10 +71,14 @@
<!--Just some space yo-->
</div>
<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>

@ -6,8 +6,9 @@ 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";
import { IChildRequests, RequestType } from "../../../interfaces";
import { AuthService } from "../../../auth/auth.service";
import { NewIssueComponent } from "../shared/new-issue/new-issue.component";
@Component({
templateUrl: "./tv-details.component.html",
@ -59,6 +60,13 @@ export class TvDetailsComponent implements OnInit {
this.dialog.open(EpisodeRequestComponent, { width: "800px", data: this.tv, panelClass: 'modal-panel' })
}
public async issue() {
const dialogRef = this.dialog.open(NewIssueComponent, {
width: '500px',
data: {requestId: this.tvRequest ? this.tv.requestId : null, requestType: RequestType.tvShow, imdbid: this.tv.theTvDbId, title: this.tv.title}
});
}
public openDialog() {
debugger;
let trailerLink = this.tv.trailer;

@ -1,12 +1,10 @@
@import "~@angular/material/theming";
@import "~styles/variables.scss";
//MINE
@media (max-width: 570px) {
h1 {
font-size: 1.5rem;
}
.mobile-poster {
display: block;
position: absolute;
@ -14,8 +12,6 @@
left: 12px;
bottom: 2px;
}
#info-wrapper .sidebar-poster {
margin-top: -126px !important;
}
@ -55,7 +51,6 @@
position: relative;
}
#summary-wrapper .full-screenshot.enabled,
.summary-wrapper .full-screenshot.enabled,
#watching-wrapper .full-screenshot.enabled,
@ -83,7 +78,7 @@
background-image: -o-linear-gradient(top, transparent 0%, rgba(0, 0, 0, 0.3) 100%);
background-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.3) 100%);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#4D000000', GradientType=0);
// filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#4D000000', GradientType=0);
}
.available-bottom-border {
@ -109,13 +104,10 @@
position: relative;
}
.grey-text {
color: #999;
}
#summary-wrapper .summary .container h1,
.summary-wrapper .summary .container h1 {
margin: 0;
@ -127,7 +119,6 @@
min-height: 600px;
}
#info-wrapper .sidebar.affixable.affix-top {
position: relative !important;
}
@ -219,3 +210,8 @@
.medium-font {
font-size: 16px;
}
.issuesPanel {
padding-top: 1%;
padding-bottom: 1%;
}

@ -29,6 +29,10 @@ export class IssuesService extends ServiceHelpers {
return this.http.get<IIssues[]>(this.url, {headers: this.headers});
}
public getIssuesByRequestId(requestId: number): Promise<IIssues[]> {
return this.http.get<IIssues[]>(`${this.url}request/${requestId}`, {headers: this.headers}).toPromise();
}
public getIssuesPage(take: number, skip: number, status: IssueStatus): Observable<IIssues[]> {
return this.http.get<IIssues[]>(`${this.url}${take}/${skip}/${status}`, {headers: this.headers});
}
@ -60,4 +64,8 @@ export class IssuesService extends ServiceHelpers {
public deleteComment(id: number): Observable<boolean> {
return this.http.delete<boolean>(`${this.url}comments/${id}`, { headers: this.headers });
}
public deleteIssue(id: number): Promise<boolean> {
return this.http.delete<boolean>(`${this.url}${id}`, { headers: this.headers }).toPromise();
}
}

@ -169,6 +169,14 @@ namespace Ombi.Controllers.V1
.FirstOrDefaultAsync();
}
[HttpGet("request/{id}")]
public async Task<IActionResult> GetIssueByRequestId([FromRoute] int id)
{
return new OkObjectResult(await _issues.GetAll().Where(x => x.RequestId == id)
.Include(x => x.IssueCategory)
.Include(x => x.UserReported).ToListAsync());
}
/// <summary>
/// Get's all the issue comments by id
/// </summary>

@ -188,7 +188,14 @@
"TitlePlaceholder": "Short title of your issue",
"SelectCategory": "Select Category",
"IssueCreated": "Issue has been created"
}
},
"Outstanding": "There are outstanding issues",
"ResolvedDate": "Resolved date",
"CreatedDate": "Raised on",
"MarkedAsResolved": "This issue has now been marked as resolved!",
"MarkedAsInProgress": "This issue has now been marked as in progress!",
"Delete": "Delete issue",
"DeletedIssue": "Issue has been deleted"
},
"Filter": {
"ClearFilter": "Clear Filter",

Loading…
Cancel
Save