mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-14 02:26:55 -07:00
Merge branch 'develop' of https://github.com/ombi-app/Ombi into develop
This commit is contained in:
commit
e514aa4678
39 changed files with 485 additions and 337 deletions
|
@ -98,3 +98,21 @@ stages:
|
|||
isPreRelease: true
|
||||
changeLogCompareToRelease: 'lastNonDraftRelease'
|
||||
changeLogType: 'commitBased'
|
||||
|
||||
- task: PowerShell@2
|
||||
displayName: "Trigger APT build"
|
||||
inputs:
|
||||
targetType: 'inline'
|
||||
script: |
|
||||
$body = @{
|
||||
"ref"="main"
|
||||
"inputs"= @{"version"= "$(gitTag)"}
|
||||
} | ConvertTo-Json
|
||||
|
||||
$header = @{
|
||||
"Accept"="application/vnd.github.v3+json"
|
||||
"Authorization"="Bearer $(APTPAT)"
|
||||
"User-Agent"="Ombi"
|
||||
}
|
||||
|
||||
Invoke-RestMethod -Uri "https://api.github.com/repos/Ombi-app/Ombi.Apt/actions/workflows/build-deb.yml/dispatches" -Method 'Post' -Body $body -Headers $header
|
|
@ -256,6 +256,7 @@ a.poster-overlay:hover{
|
|||
::ng-deep .ombi-card .button-request-container .button-request{
|
||||
padding-right:0px;
|
||||
padding-left:0px;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.c:hover .button-request-container {
|
||||
|
|
|
@ -4,6 +4,8 @@ import { IssuesService } from "../services";
|
|||
|
||||
import { IIssueCount, IIssues, IPagenator, IssueStatus } from "../interfaces";
|
||||
|
||||
import { PageEvent } from '@angular/material/paginator';
|
||||
|
||||
@Component({
|
||||
templateUrl: "issues.component.html",
|
||||
styleUrls: ['issues.component.scss']
|
||||
|
@ -16,7 +18,7 @@ export class IssuesComponent implements OnInit {
|
|||
|
||||
public count: IIssueCount;
|
||||
|
||||
private takeAmount = 10;
|
||||
private takeAmount = 50;
|
||||
private pendingSkip = 0;
|
||||
private inProgressSkip = 0;
|
||||
private resolvedSkip = 0;
|
||||
|
@ -30,18 +32,18 @@ export class IssuesComponent implements OnInit {
|
|||
this.issueService.getIssuesCount().subscribe(x => this.count = x);
|
||||
}
|
||||
|
||||
public changePagePending(event: IPagenator) {
|
||||
this.pendingSkip = event.first;
|
||||
public changePagePending(event: PageEvent) {
|
||||
this.pendingSkip = event.pageSize * event.pageIndex++;
|
||||
this.getPending();
|
||||
}
|
||||
|
||||
public changePageInProg(event: IPagenator) {
|
||||
this.inProgressSkip = event.first;
|
||||
public changePageInProg(event: PageEvent) {
|
||||
this.inProgressSkip = event.pageSize * event.pageIndex++;
|
||||
this.getInProg();
|
||||
}
|
||||
|
||||
public changePageResolved(event: IPagenator) {
|
||||
this.resolvedSkip = event.first;
|
||||
public changePageResolved(event: PageEvent) {
|
||||
this.resolvedSkip = event.pageSize * event.pageIndex++;
|
||||
this.getResolved();
|
||||
}
|
||||
|
||||
|
|
|
@ -26,94 +26,17 @@
|
|||
<td mat-cell *matCellDef="let element"> {{element.userReported.userAlias}} </td>
|
||||
</ng-container>
|
||||
|
||||
<!-- <ng-container matColumnDef="requestedUser.requestedBy">
|
||||
<th mat-header-cell *matHeaderCellDef> {{'Requests.RequestedBy' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.requestedUser?.userAlias}} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="requestedDate">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.RequestDate' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.requestedDate | amLocal | amDateFormat: 'LL'}} </td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="status">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.Status' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.status}} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<ng-container matColumnDef="requestStatus">
|
||||
<th mat-header-cell *matHeaderCellDef mat-sort-header disableClear> {{ 'Requests.RequestStatus' | translate}} </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.requestStatus | translate}} </td>
|
||||
</ng-container>-->
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef> </th>
|
||||
<td mat-cell *matCellDef="let element">
|
||||
<button *ngIf="element.requestType === 1" mat-raised-button color="accent" [routerLink]="'/details/movie/' + element.providerId">{{ 'Issues.Details' | translate}}</button>
|
||||
<button *ngIf="element.requestType === 0" mat-raised-button color="accent" [routerLink]="'/details/tv/' + element.providerId">{{ 'Issues.Details' | translate}}</button>
|
||||
<button *ngIf="element.requestType === 2" mat-raised-button color="accent" [routerLink]="'/details/artist/request/' + element.providerId">{{ 'Issues.Details' | translate}}</button>
|
||||
<!-- <button mat-raised-button color="warn" (click)="openOptions(element)" *ngIf="isAdmin"> {{ 'Requests.Options' | translate}}</button> -->
|
||||
</td>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
|
||||
<!-- <table class="table table-striped table-hover table-responsive table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th (click)="setOrder('title', $event)">
|
||||
<a [translate]="'Issues.ColumnTitle'"></a>
|
||||
<span *ngIf="order === 'title'">
|
||||
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
||||
</span>
|
||||
</th>
|
||||
<th (click)="setOrder('issueCategory.value', $event)">
|
||||
<a [translate]="'Issues.Category'"></a>
|
||||
<span *ngIf="order === 'issueCategory.value'">
|
||||
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
||||
</span>
|
||||
</th>
|
||||
<th (click)="setOrder('status', $event)">
|
||||
<a [translate]="'Issues.Status'"></a>
|
||||
<span *ngIf="order === 'status'">
|
||||
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
||||
</span>
|
||||
</th>
|
||||
<th (click)="setOrder('reportedUser', $event)">
|
||||
<a [translate]="'Issues.ReportedBy'"></a>
|
||||
<span *ngIf="order === 'reportedUser'">
|
||||
<span [hidden]="reverse"><i class="fa fa-arrow-down" aria-hidden="true"></i></span><span [hidden]="!reverse"><i class="fa fa-arrow-up" aria-hidden="true"></i></span>
|
||||
</span>
|
||||
</th>
|
||||
<th>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let issue of issues | orderBy: order : reverse : 'case-insensitive'">
|
||||
<td>
|
||||
{{issue.title}}
|
||||
</td>
|
||||
<td>
|
||||
{{issue.issueCategory.value}}
|
||||
</td>
|
||||
<td>
|
||||
{{IssueStatus[issue.status] | humanize}}
|
||||
</td>
|
||||
<td *ngIf="issue.userReported?.alias">
|
||||
{{issue.userReported.alias}}
|
||||
</td>
|
||||
<td *ngIf="!issue.userReported?.alias">
|
||||
{{issue.userReported.userName}}
|
||||
</td>
|
||||
<td>
|
||||
<a [routerLink]="['/issues/' + issue.id]" class="btn btn-sm btn-info-outline" [translate]="'Issues.Details'"></a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p-paginator [rows]="rowCount" [totalRecords]="totalRecords" (onPageChange)="paginate($event)"></p-paginator> -->
|
||||
<mat-paginator (page)="paginate($event)" [length]="totalRecords"></mat-paginator>
|
|
@ -14,7 +14,9 @@ export class IssuesTableComponent {
|
|||
@Output() public changePage = new EventEmitter<IPagenator>();
|
||||
|
||||
public displayedColumns = ["title", "category", "subject", "status", "reportedBy", "actions"]
|
||||
public IssueStatus = IssueStatus;
|
||||
public IssueStatus = IssueStatus;
|
||||
public resultsLength: number;
|
||||
public gridCount: string = "15";
|
||||
|
||||
public order: string = "id";
|
||||
public reverse = false;
|
||||
|
@ -44,11 +46,6 @@ export class IssuesTableComponent {
|
|||
}
|
||||
|
||||
public paginate(event: IPagenator) {
|
||||
//event.first = Index of the first record (current index)
|
||||
//event.rows = Number of rows to display in new page
|
||||
//event.page = Index of the new page
|
||||
//event.pageCount = Total number of pages
|
||||
|
||||
this.changePage.emit(event);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
{{'Login.UsernamePlaceholder' | translate}} is <strong>required</strong></mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="full-width" appearance="outline">
|
||||
<mat-form-field *ngIf="!authenticationSettings.allowNoPassword" class="full-width" appearance="outline">
|
||||
<mat-label>{{'Login.PasswordPlaceholder' | translate}}</mat-label>
|
||||
<input id="password-field" color="black" type="password" matInput formControlName="password" />
|
||||
</mat-form-field>
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
[isAdmin]="isAdmin"
|
||||
[canRequestOnBehalf]="!hasRequest && !movie.available"
|
||||
[canShowAdvanced]="showAdvanced && movieRequest"
|
||||
[type]="requestType"
|
||||
(openTrailer)="openDialog()"
|
||||
(onRequestBehalf)="openRequestOnBehalf()"
|
||||
(onAdvancedOptions)="openAdvancedOptions()"
|
||||
|
@ -103,7 +104,7 @@
|
|||
<div class="row">
|
||||
<div class="col-12 col-md-2">
|
||||
<mat-card class="mat-elevation-z8">
|
||||
<mat-card-content class="medium-font">
|
||||
<mat-card-content>
|
||||
<movie-information-panel [movie]="movie" [request]="movieRequest" [advancedOptions]="showAdvanced"></movie-information-panel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
|
|
@ -27,6 +27,9 @@ export class MovieDetailsComponent {
|
|||
public advancedOptions: IAdvancedData;
|
||||
public showAdvanced: boolean; // Set on the UI
|
||||
|
||||
public requestType = RequestType.movie;
|
||||
|
||||
|
||||
private theMovidDbId: number;
|
||||
private imdbId: string;
|
||||
|
||||
|
|
|
@ -1,21 +1,23 @@
|
|||
<div *ngIf="movie">
|
||||
<span *ngIf="movie.voteAverage"
|
||||
matTooltip="{{'MediaDetails.Votes' | translate }} {{movie.voteCount | thousandShort: 1}}">
|
||||
<img class="rating-small" src="{{baseUrl}}/images/tmdb-logo.svg"> {{movie.voteAverage | number:'1.0-1'}}/10
|
||||
</span>
|
||||
<span *ngIf="ratings?.critics_rating && ratings?.critics_score">
|
||||
<img class="rating-small"
|
||||
src="{{baseUrl}}/images/{{ratings.critics_rating === 'Rotten' ? 'rotten-rotten.svg' : 'rotten-fresh.svg'}}">
|
||||
{{ratings.critics_score}}%
|
||||
</span>
|
||||
<span *ngIf="ratings?.audience_rating && ratings?.audience_score">
|
||||
<img class="rating-small"
|
||||
src="{{baseUrl}}/images/{{ratings.audience_rating === 'Upright' ? 'rotten-audience-fresh.svg' : 'rotten-audience-rotten.svg'}}">
|
||||
{{ratings.audience_score}}%
|
||||
</span>
|
||||
<div *ngIf="streams?.length > 0">
|
||||
<div *ngIf="movie" class="left-panel-details">
|
||||
<div class="rating medium-font">
|
||||
<span *ngIf="movie.voteAverage"
|
||||
matTooltip="{{'MediaDetails.Votes' | translate }} {{movie.voteCount | thousandShort: 1}}">
|
||||
<img class="rating-small" src="{{baseUrl}}/images/tmdb-logo.svg"> {{movie.voteAverage | number:'1.0-1'}}/10
|
||||
</span>
|
||||
<span *ngIf="ratings?.critics_rating && ratings?.critics_score">
|
||||
<img class="rating-small"
|
||||
src="{{baseUrl}}/images/{{ratings.critics_rating === 'Rotten' ? 'rotten-rotten.svg' : 'rotten-fresh.svg'}}">
|
||||
{{ratings.critics_score}}%
|
||||
</span>
|
||||
<span *ngIf="ratings?.audience_rating && ratings?.audience_score">
|
||||
<img class="rating-small"
|
||||
src="{{baseUrl}}/images/{{ratings.audience_rating === 'Upright' ? 'rotten-audience-fresh.svg' : 'rotten-audience-rotten.svg'}}">
|
||||
{{ratings.audience_score}}%
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="streams?.length > 0" class="streaming-on">
|
||||
<hr>
|
||||
<strong>{{'MediaDetails.StreamingOn' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.StreamingOn' | translate }}:</span>
|
||||
<div>
|
||||
<span *ngFor="let stream of streams">
|
||||
<img class="stream-small" [matTooltip]="stream.streamingProvider" src="https://image.tmdb.org/t/p/original{{stream.logo}}">
|
||||
|
@ -24,18 +26,16 @@
|
|||
</div>
|
||||
<hr>
|
||||
<div>
|
||||
<strong>{{'MediaDetails.Status' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Status' | translate }}:</span>
|
||||
{{movie.status}}
|
||||
</div>
|
||||
<div>
|
||||
<strong>{{'MediaDetails.Availability' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Availability' | translate }}:</span>
|
||||
<span *ngIf="movie.available"> {{'Common.Available' | translate}}</span>
|
||||
<span *ngIf="!movie.available"> {{'Common.NotAvailable' | translate}}</span>
|
||||
|
||||
</div>
|
||||
|
||||
<div *ngIf="!movie.available">
|
||||
<strong>{{'MediaDetails.RequestStatus' | translate }}</strong>
|
||||
<span class="label">{{'MediaDetails.RequestStatus' | translate }}</span>
|
||||
<div *ngIf="movie.approved && !movie.available">{{'Common.ProcessingRequest' | translate}}</div>
|
||||
<div *ngIf="movie.requested && !movie.approved && !movie.available">{{'Common.PendingApproval' | translate}}
|
||||
</div>
|
||||
|
@ -44,27 +44,27 @@
|
|||
</div>
|
||||
|
||||
<div *ngIf="request">
|
||||
<strong>{{'Requests.RequestedBy' | translate }}:</strong>
|
||||
<span class="label">{{'Requests.RequestedBy' | translate }}:</span>
|
||||
{{request.requestedUser.userAlias}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="request">
|
||||
<strong>{{'Requests.RequestDate' | translate }}:</strong>
|
||||
<span class="label">{{'Requests.RequestDate' | translate }}:</span>
|
||||
{{request.requestedDate | date}}
|
||||
</div>
|
||||
|
||||
|
||||
<div *ngIf="movie.quality">
|
||||
<strong>{{'MediaDetails.Quality' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Quality' | translate }}:</span>
|
||||
<div>{{movie.quality | quality}}</div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="advancedOptions && request && request.rootPathOverrideTitle">
|
||||
<strong>{{'MediaDetails.RootFolderOverride' | translate }}</strong>
|
||||
<span class="label">{{'MediaDetails.RootFolderOverride' | translate }}</span>
|
||||
<div>{{request.rootPathOverrideTitle}}</div>
|
||||
</div>
|
||||
<div *ngIf="advancedOptions && request && request.qualityOverrideTitle">
|
||||
<strong>{{'MediaDetails.QualityOverride' | translate }}</strong>
|
||||
<span class="label">{{'MediaDetails.QualityOverride' | translate }}</span>
|
||||
<div>{{request.qualityOverrideTitle}}</div>
|
||||
</div>
|
||||
|
||||
|
@ -72,34 +72,34 @@
|
|||
|
||||
<hr>
|
||||
|
||||
<strong>{{'MediaDetails.TheatricalRelease' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.TheatricalRelease' | translate }}:</span>
|
||||
{{movie.releaseDate | date: 'mediumDate'}}
|
||||
|
||||
<div *ngIf="movie.digitalReleaseDate">
|
||||
<strong>{{'MediaDetails.DigitalRelease' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.DigitalRelease' | translate }}:</span>
|
||||
{{movie.digitalReleaseDate | date: 'mediumDate'}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="movie.voteCount">
|
||||
<strong>{{'MediaDetails.Votes' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Votes' | translate }}:</span>
|
||||
{{movie.voteCount | thousandShort: 1}}
|
||||
</div>
|
||||
<div>
|
||||
<strong>{{'MediaDetails.Runtime' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Runtime' | translate }}:</span>
|
||||
{{'MediaDetails.Minutes' | translate:{runtime: movie.runtime} }}
|
||||
</div>
|
||||
<div *ngIf="movie.revenue">
|
||||
<strong>{{'MediaDetails.Revenue' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Revenue' | translate }}:</span>
|
||||
{{movie.revenue | currency: 'USD'}}
|
||||
</div>
|
||||
<div *ngIf="movie.budget">
|
||||
<strong>{{'MediaDetails.Budget' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Budget' | translate }}:</span>
|
||||
{{movie.budget | currency: 'USD'}}
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<div class="genre-button-container" *ngIf="movie.genres">
|
||||
<strong>{{'MediaDetails.Genres' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Genres' | translate }}:</span>
|
||||
<div>
|
||||
<mat-chip-list>
|
||||
<mat-chip selected *ngFor="let genre of movie.genres">
|
||||
|
@ -111,7 +111,7 @@
|
|||
|
||||
<hr />
|
||||
<div class="keyword-button-container" *ngIf="movie?.keywords?.keywordsValue?.length > 0">
|
||||
<strong>{{'MediaDetails.Keywords' | translate }}:</strong>
|
||||
<span class="label">{{'MediaDetails.Keywords' | translate }}:</span>
|
||||
<mat-chip-list>
|
||||
<mat-chip selected *ngFor="let keyword of movie.keywords.keywordsValue">
|
||||
{{keyword.name}}
|
||||
|
|
|
@ -35,7 +35,8 @@
|
|||
</button>
|
||||
<button mat-menu-item [disabled]="!canShowAdvanced" (click)="openAdvancedOptions()">
|
||||
<mat-icon>movie_filter</mat-icon>
|
||||
<span>{{'MediaDetails.RadarrConfiguration' | translate}}</span>
|
||||
<span *ngIf="type === RequestType.movie">{{'MediaDetails.RadarrConfiguration' | translate}}</span>
|
||||
<span *ngIf="type === RequestType.tvShow">{{'MediaDetails.SonarrConfiguration' | translate}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Component, Input, Output, EventEmitter } from "@angular/core";
|
||||
import { RequestType } from "../../../../interfaces";
|
||||
@Component({
|
||||
selector: "social-icons",
|
||||
templateUrl: "./social-icons.component.html",
|
||||
|
@ -18,6 +19,7 @@ export class SocialIconsComponent {
|
|||
@Input() embyUrl: string;
|
||||
@Input() jellyfinUrl: string;
|
||||
@Input() doNotAppend: boolean;
|
||||
@Input() type: RequestType;
|
||||
|
||||
@Input() isAdmin: boolean;
|
||||
@Input() canRequestOnBehalf: boolean;
|
||||
|
@ -27,6 +29,8 @@ export class SocialIconsComponent {
|
|||
@Output() onRequestBehalf: EventEmitter<any> = new EventEmitter();
|
||||
@Output() onAdvancedOptions: EventEmitter<any> = new EventEmitter();
|
||||
|
||||
public RequestType = RequestType;
|
||||
|
||||
|
||||
public openDialog() {
|
||||
this.openTrailer.emit();
|
||||
|
|
|
@ -1,63 +1,68 @@
|
|||
<div>
|
||||
<span *ngIf="tv.rating">
|
||||
<img style="width: 4em;" src="{{baseUrl}}/images/tvm-logo.png"> {{tv.rating}}/10
|
||||
</span>
|
||||
<span *ngIf="ratings?.score && ratings?.class">
|
||||
<img class="rating-small" src="{{baseUrl}}/images/{{ratings.class === 'rotten' ? 'rotten-rotten.svg' : 'rotten-fresh.svg'}}"> {{ratings.score}}%
|
||||
</span>
|
||||
|
||||
<div *ngIf="streams?.length > 0">
|
||||
<div class="left-panel-details">
|
||||
<div>
|
||||
<div class="rating medium-font">
|
||||
<span *ngIf="tv.rating">
|
||||
<img class="rating-small" src="{{baseUrl}}/images/tvm-logo.png"> {{tv.rating}}/10
|
||||
</span>
|
||||
<span *ngIf="ratings?.score && ratings?.class">
|
||||
<img class="rating-small" src="{{baseUrl}}/images/{{ratings.class === 'rotten' ? 'rotten-rotten.svg' : 'rotten-fresh.svg'}}"> {{ratings.score}}%
|
||||
</span>
|
||||
</div>
|
||||
<div *ngIf="streams?.length > 0" class="streaming-on-container">
|
||||
<hr>
|
||||
<div class="streaming-on-content">
|
||||
<span class="label">{{'MediaDetails.StreamingOn' | translate }}:</span>
|
||||
<div>
|
||||
<span *ngFor="let stream of streams">
|
||||
<img class="stream-small" [matTooltip]="stream.streamingProvider" src="https://image.tmdb.org/t/p/original{{stream.logo}}">
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<strong>{{'MediaDetails.StreamingOn' | translate }}:</strong>
|
||||
<div *ngIf="tv.status">
|
||||
<span class="label">{{'MediaDetails.Status' | translate }}:</span>
|
||||
{{tv.status}}
|
||||
</div>
|
||||
<span class="label">First Aired:</span>
|
||||
{{tv.firstAired | date: 'mediumDate'}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="seasonCount">
|
||||
<span class="label">Seasons:</span>
|
||||
{{seasonCount}}
|
||||
</div>
|
||||
<div *ngIf="totalEpisodes">
|
||||
<span class="label">Episodes:</span>
|
||||
{{totalEpisodes}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="advancedOptions && request?.rootPathOverrideTitle">
|
||||
<span class="label">{{'MediaDetails.RootFolderOverride' | translate }}:</span>
|
||||
<div>{{request.rootPathOverrideTitle}}</div>
|
||||
</div>
|
||||
<div *ngIf="advancedOptions && request?.qualityOverrideTitle">
|
||||
<span class="label">{{'MediaDetails.QualityOverride' | translate }}:</span>
|
||||
<div>{{request.qualityOverrideTitle}}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="label">{{'MediaDetails.Runtime' | translate }}:</span>
|
||||
{{'MediaDetails.Minutes' | translate:{ runtime: tv.runtime} }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="tv.network">
|
||||
<span class="label">Network:</span>
|
||||
{{tv.network.name}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="tv.genre">
|
||||
<span class="label">{{'MediaDetails.Genres' | translate }}:</span>
|
||||
<div>
|
||||
<span *ngFor="let stream of streams">
|
||||
<img class="stream-small" [matTooltip]="stream.streamingProvider" src="https://image.tmdb.org/t/p/original{{stream.logo}}">
|
||||
</span>
|
||||
<span *ngFor="let genre of tv.genre">
|
||||
{{genre}} |
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div *ngIf="tv.status">
|
||||
<strong>{{'MediaDetails.Status' | translate }}:</strong>
|
||||
{{tv.status}}
|
||||
</div>
|
||||
<strong>First Aired:</strong>
|
||||
{{tv.firstAired | date: 'mediumDate'}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="seasonCount">
|
||||
<strong>Seasons:</strong>
|
||||
{{seasonCount}}
|
||||
</div>
|
||||
<div *ngIf="totalEpisodes">
|
||||
<strong>Episodes:</strong>
|
||||
{{totalEpisodes}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="advancedOptions && request?.rootPathOverrideTitle">
|
||||
<strong>{{'MediaDetails.RootFolderOverride' | translate }}:</strong>
|
||||
<div>{{request.rootPathOverrideTitle}}</div>
|
||||
</div>
|
||||
<div *ngIf="advancedOptions && request?.qualityOverrideTitle">
|
||||
<strong>{{'MediaDetails.QualityOverride' | translate }}:</strong>
|
||||
<div>{{request.qualityOverrideTitle}}</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<strong>{{'MediaDetails.Runtime' | translate }}:</strong>
|
||||
{{'MediaDetails.Minutes' | translate:{ runtime: tv.runtime} }}
|
||||
</div>
|
||||
|
||||
<div *ngIf="tv.network">
|
||||
<strong>Network:</strong>
|
||||
{{tv.network.name}}
|
||||
</div>
|
||||
|
||||
<div *ngIf="tv.genre">
|
||||
<strong>{{'MediaDetails.Genres' | translate }}:</strong>
|
||||
<div>
|
||||
<span *ngFor="let genre of tv.genre">
|
||||
{{genre}} |
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -16,73 +16,64 @@
|
|||
|
||||
<top-banner [background]="tv.background" [available]="tv.available" [title]="tv.title"
|
||||
[releaseDate]="tv.firstAired" [tagline]="tv.certification"></top-banner>
|
||||
<div class="social-icons-container">
|
||||
<social-icons
|
||||
[homepage]="tv.homepage"
|
||||
[tvdbId]="tv.id"
|
||||
[hasTrailer]="tv.trailer"
|
||||
(openTrailer)="openDialog()"
|
||||
[imdbId]="tv.imdbId"
|
||||
[available]="tv.available || tv.partlyAvailable"
|
||||
[plexUrl]="tv.plexUrl"
|
||||
[embyUrl]="tv.embyUrl"
|
||||
[jellyfinUrl]="tv.jellyfinUrl"
|
||||
[isAdmin]="isAdmin"
|
||||
[canRequestOnBehalf]="!showRequest"
|
||||
[canShowAdvanced]="showAdvanced && showRequest"
|
||||
[type]="requestType"
|
||||
(onRequestBehalf)="openRequestOnBehalf()"
|
||||
(onAdvancedOptions)="openAdvancedOptions()"
|
||||
>
|
||||
</social-icons>
|
||||
</div>
|
||||
|
||||
<section id="info-wrapper">
|
||||
<div class="small-middle-container">
|
||||
<div class="row justify-content-center justify-content-sm-start">
|
||||
|
||||
<media-poster [posterPath]="tv.images?.medium"></media-poster>
|
||||
|
||||
|
||||
<div class="row justify-content-center justify-content-sm-start header-container">
|
||||
<div class="details-poster-container">
|
||||
<media-poster [posterPath]="tv.images?.medium"></media-poster>
|
||||
</div>
|
||||
<!--Next to poster-->
|
||||
<div class="col-12 col-lg-2 col-xl-3 media-row">
|
||||
<div class="details-button-container">
|
||||
<div class="col-12 media-row">
|
||||
<button *ngIf="!tv.fullyAvailable" mat-raised-button class="btn-spacing" color="primary"
|
||||
(click)="request()"><i class="fas fa-plus"></i>
|
||||
{{ 'Common.Request' | translate }}</button>
|
||||
|
||||
<social-icons [homepage]="tv.homepage" [tvdbId]="tv.id" [hasTrailer]="tv.trailer"
|
||||
(openTrailer)="openDialog()" [imdbId]="tv.imdbId" [available]="tv.available || tv.partlyAvailable"
|
||||
[plexUrl]="tv.plexUrl" [embyUrl]="tv.embyUrl" [jellyfinUrl]="tv.jellyfinUrl">
|
||||
</social-icons>
|
||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
||||
[disabled]>
|
||||
<i class="fas fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button
|
||||
class="btn-spacing" color="accent" [disabled]>
|
||||
<i class="fas fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
|
||||
</div>
|
||||
<button mat-raised-button class="btn-spacing" color="danger" (click)="issue()">
|
||||
<i class="fas fa-exclamation"></i> {{
|
||||
'Requests.ReportIssue' | translate }}</button>
|
||||
|
||||
<div class="col-12 col-lg-5 col-xl-5 media-row">
|
||||
|
||||
<!-- <button *ngIf="!tv.fullyAvailable" mat-raised-button class="btn-spacing" color="primary"
|
||||
(click)="request()"><i class="fas fa-plus"></i>
|
||||
{{ 'Common.Request' | translate }}</button> -->
|
||||
|
||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
||||
[disabled]>
|
||||
<i class="fas fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button
|
||||
class="btn-spacing" color="accent" [disabled]>
|
||||
<i class="fas fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
|
||||
<button mat-raised-button class="btn-spacing" color="danger" (click)="issue()">
|
||||
<i class="fas fa-exclamation"></i> {{
|
||||
'Requests.ReportIssue' | translate }}</button>
|
||||
|
||||
</div>
|
||||
<!-- Setting/Configuration admin area -->
|
||||
<div class="col-12 col-lg-1 col-xl-1 media-row content-end">
|
||||
<button *ngIf="isAdmin" mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item (click)="openRequestOnBehalf()" [disabled]="fullyAvailable">
|
||||
<mat-icon>supervised_user_circle</mat-icon>
|
||||
<span>{{'MediaDetails.RequestOnBehalf' | translate}}</span>
|
||||
</button>
|
||||
<button mat-menu-item [disabled]="!showAdvanced || !showRequest"
|
||||
(click)="openAdvancedOptions()">
|
||||
<mat-icon>movie_filter</mat-icon>
|
||||
<span>{{'MediaDetails.SonarrConfiguration' | translate}}</span>
|
||||
</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-2">
|
||||
<mat-card class="mat-elevation-z8">
|
||||
<mat-card-content class="medium-font">
|
||||
<mat-card class="mat-elevation-z8 spacing-below">
|
||||
<mat-card-content>
|
||||
<tv-information-panel [tv]="tv" [request]="showRequest"
|
||||
[advancedOptions]="showAdvanced"></tv-information-panel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-12 col-md-10">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
|
@ -95,7 +86,6 @@
|
|||
<div class="col-12">
|
||||
<cast-carousel [cast]="tv.cast"></cast-carousel>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { NewIssueComponent } from "../shared/new-issue/new-issue.component";
|
|||
import { TvAdvancedOptionsComponent } from "./panels/tv-advanced-options/tv-advanced-options.component";
|
||||
import { RequestServiceV2 } from "../../../services/requestV2.service";
|
||||
import { RequestBehalfComponent } from "../shared/request-behalf/request-behalf.component";
|
||||
import { forkJoin } from "rxjs";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./tv-details.component.html",
|
||||
|
@ -27,6 +28,7 @@ export class TvDetailsComponent implements OnInit {
|
|||
public isAdmin: boolean;
|
||||
public advancedOptions: IAdvancedData;
|
||||
public showAdvanced: boolean; // Set on the UI
|
||||
public requestType = RequestType.tvShow;
|
||||
|
||||
private tvdbId: number;
|
||||
|
||||
|
@ -63,6 +65,7 @@ export class TvDetailsComponent implements OnInit {
|
|||
if (this.tv.requestId) {
|
||||
this.tvRequest = await this.requestService.getChildRequests(this.tv.requestId).toPromise();
|
||||
this.showRequest = this.tvRequest.length > 0 ? this.tvRequest[0].parentRequest : undefined;
|
||||
this.loadAdvancedInfo();
|
||||
}
|
||||
|
||||
const tvBanner = await this.imageService.getTvBanner(this.tvdbId).toPromise();
|
||||
|
@ -97,7 +100,7 @@ export class TvDetailsComponent implements OnInit {
|
|||
// get the name and ids
|
||||
result.rootFolder = result.rootFolders.filter(f => f.id === +result.rootFolderId)[0];
|
||||
result.profile = result.profiles.filter(f => f.id === +result.profileId)[0];
|
||||
await this.requestService2.updateTvAdvancedOptions({ qualityOverride: result.profileId, rootPathOverride: result.rootFolderId, requestId: this.tv.id }).toPromise();
|
||||
await this.requestService2.updateTvAdvancedOptions({ qualityOverride: result.profileId, rootPathOverride: result.rootFolderId, requestId: this.showRequest.id }).toPromise();
|
||||
this.setAdvancedOptions(result);
|
||||
}
|
||||
});
|
||||
|
@ -116,10 +119,35 @@ export class TvDetailsComponent implements OnInit {
|
|||
this.advancedOptions = data;
|
||||
console.log(this.advancedOptions);
|
||||
if (data.rootFolderId) {
|
||||
this.showRequest.qualityOverrideTitle = data.rootFolders.filter(x => x.id == data.rootFolderId)[0].path;
|
||||
this.showRequest.qualityOverrideTitle = data.profiles.filter(x => x.id == data.profileId)[0].name;
|
||||
}
|
||||
if (data.profileId) {
|
||||
this.showRequest.rootPathOverrideTitle = data.profiles.filter(x => x.id == data.profileId)[0].name;
|
||||
this.showRequest.rootPathOverrideTitle = data.rootFolders.filter(x => x.id == data.rootFolderId)[0].path;
|
||||
}
|
||||
}
|
||||
|
||||
private loadAdvancedInfo() {
|
||||
const profile = this.sonarrService.getQualityProfilesWithoutSettings();
|
||||
const folders = this.sonarrService.getRootFoldersWithoutSettings();
|
||||
|
||||
forkJoin([profile, folders]).subscribe(x => {
|
||||
const sonarrProfiles = x[0];
|
||||
const sonarrRootFolders = x[1];
|
||||
|
||||
const profile = sonarrProfiles.filter((p) => {
|
||||
return p.id === this.showRequest.qualityOverride;
|
||||
});
|
||||
if (profile.length > 0) {
|
||||
this.showRequest.qualityOverrideTitle = profile[0].name;
|
||||
}
|
||||
|
||||
const path = sonarrRootFolders.filter((folder) => {
|
||||
return folder.id === this.showRequest.rootFolder;
|
||||
});
|
||||
if (path.length > 0) {
|
||||
this.showRequest.rootPathOverrideTitle = path[0].path;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,11 +143,11 @@
|
|||
}
|
||||
|
||||
.btn-spacing {
|
||||
margin-right: 10px !important;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.spacing-below {
|
||||
margin-bottom: 15px !important;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.left-seperator {
|
||||
|
@ -170,8 +170,9 @@
|
|||
}
|
||||
|
||||
.media-row {
|
||||
padding-top: 56px;
|
||||
padding-left: 26px;
|
||||
position:absolute;
|
||||
bottom:0;
|
||||
margin-bottom:20px;
|
||||
}
|
||||
|
||||
.cast-profile-img {
|
||||
|
@ -239,16 +240,16 @@
|
|||
}
|
||||
|
||||
.viewon-btn.plex {
|
||||
border: 1px solid #E5A00D;
|
||||
color: #E5A00D;
|
||||
box-shadow: inset 0px 0px 0px 1px #e5a00d;
|
||||
}
|
||||
.viewon-btn.emby {
|
||||
border: 1px solid #52b54a;
|
||||
color: #52b54a;
|
||||
box-shadow: inset 0px 0px 0px 1px #52b54a;
|
||||
}
|
||||
.viewon-btn.jellyfin {
|
||||
border: 1px solid #00a4dc;
|
||||
color: #00a4dc;
|
||||
box-shadow: inset 0px 0px 0px 1px #00a4dc;
|
||||
}
|
||||
|
||||
::ng-deep .p-carousel-indicators {
|
||||
|
@ -269,8 +270,87 @@
|
|||
|
||||
.details-button-container{
|
||||
width:100%;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
.info-wrapper .row{
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.rating{
|
||||
display:flex;
|
||||
justify-content: space-evenly;
|
||||
width:100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.left-panel-details .label{
|
||||
font-weight:500;
|
||||
}
|
||||
|
||||
.left-panel-details .streaming-on-content{
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-flow:row wrap;
|
||||
}
|
||||
|
||||
.left-panel-details .streaming-on-content .label{
|
||||
white-space:nowrap;
|
||||
padding-right:10px;
|
||||
}
|
||||
|
||||
.left-panel-details{
|
||||
font-weight:100;
|
||||
}
|
||||
|
||||
.genre-button-container .mat-chip-list .mat-chip-list-wrapper{
|
||||
margin-top:3px;
|
||||
margin:0;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
.keyword-button-container .mat-chip-list .mat-chip-list-wrapper{
|
||||
margin-top:3px;
|
||||
margin:0;
|
||||
margin-left: -6px;
|
||||
}
|
||||
|
||||
.mat-card-header{
|
||||
font-size: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.media-row .mat-raised-button{
|
||||
padding:2px 1.5em;;
|
||||
width:170px;
|
||||
margin-top:10px;
|
||||
margin-left:10px;
|
||||
}
|
||||
|
||||
@media (max-width:500px){
|
||||
.row.justify-content-center.justify-content-sm-start.header-container{
|
||||
flex-wrap:wrap;
|
||||
}
|
||||
|
||||
.media-row{
|
||||
position:relative;
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.media-row .mat-raised-button{
|
||||
width:100%;
|
||||
margin-left:0px;
|
||||
}
|
||||
|
||||
.media-row .btn-spacing{
|
||||
margin-right:0;
|
||||
}
|
||||
|
||||
.media-row span{
|
||||
width:100%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
</div>
|
||||
|
||||
<button *ngIf="selection.hasValue() && isAdmin" mat-fab color="accent" class="floating-fab" [matMenuTriggerFor]="aboveMenu">
|
||||
<mat-icon>add</mat-icon></button>
|
||||
<i class="fas fa-bars"></i></button>
|
||||
<mat-menu #aboveMenu="matMenu" yPosition="above">
|
||||
<button mat-menu-item (click)="bulkDelete()">{{'Requests.RequestPanel.Delete' | translate}}</button>
|
||||
<button mat-menu-item (click)="bulkApprove()">{{'Requests.RequestPanel.Approve' | translate}}</button>
|
||||
|
|
|
@ -43,6 +43,10 @@ export class JobService extends ServiceHelpers {
|
|||
return this.http.post<boolean>(`${this.url}plexrecentlyadded/`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public clearMediaserverData(): Observable<boolean> {
|
||||
return this.http.post<boolean>(`${this.url}clearmediaserverdata/`, {headers: this.headers});
|
||||
}
|
||||
|
||||
public runEmbyCacher(): Observable<boolean> {
|
||||
return this.http.post<boolean>(`${this.url}embycontentcacher/`, {headers: this.headers});
|
||||
}
|
||||
|
|
|
@ -105,6 +105,12 @@
|
|||
<button mat-raised-button (click)="runCacher()" type="button" id="save" class="mat-focus-indicator mat-stroked-button mat-button-base">Manually Run Cacher</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button mat-raised-button (click)="clearDataAndResync()" type="button" id="clearData"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">
|
||||
Clear Data And Resync
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
|
|
@ -92,4 +92,12 @@ export class EmbyComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public clearDataAndResync(): void {
|
||||
this.jobService.clearMediaserverData().subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Triggered the Clear MediaServer Resync");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,6 +105,12 @@
|
|||
<button mat-raised-button (click)="runCacher()" type="button" id="save" class="mat-focus-indicator mat-stroked-button mat-button-base">Manually Run Cacher</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button mat-raised-button (click)="clearDataAndResync()" type="button" id="clearData"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">
|
||||
Clear Data And Resync
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
|
|
@ -93,4 +93,12 @@ export class JellyfinComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
public clearDataAndResync(): void {
|
||||
this.jobService.clearMediaserverData().subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Triggered the Clear MediaServer Resync");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<settings-menu></settings-menu>
|
||||
<wiki [path]="'/settings/scheduled-tasks/'"></wiki>
|
||||
<wiki [path]="'settings/jobs/'"></wiki>
|
||||
<div *ngIf="form" class="small-middle-container">
|
||||
<fieldset>
|
||||
<legend>Job Settings</legend>
|
||||
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
|
||||
<small>Changes require a restart.</small><p>
|
||||
<small>You can generate valid CRON Expressions here: <a href="https://www.cronmaker.com/" target="_blank">https://www.cronmaker.com/</a></small>
|
||||
<small>You can generate valid CRON Expressions here: <a href="http://www.cronmaker.com/" target="_blank">https://www.cronmaker.com/</a></small>
|
||||
<div style="margin-top:1em;">
|
||||
<div class="form-group cronBox">
|
||||
<mat-form-field appearance="outline" floatLabel=always>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<settings-menu>
|
||||
</settings-menu>
|
||||
<div *ngIf="form" class="container">
|
||||
<div *ngIf="form" class="small-middle-container">
|
||||
<fieldset>
|
||||
<legend>Mobile Notifications</legend>
|
||||
|
||||
|
@ -47,7 +47,7 @@
|
|||
|
||||
<div class="md-form-field ">
|
||||
<div>
|
||||
<button mat-raised-button type="submit " color="primary" [disabled]="form.invalid ">Submit</button>
|
||||
<button mat-raised-button type="submit " color="accent" [disabled]="form.invalid ">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -11,6 +11,7 @@ import { MatTableDataSource } from "@angular/material/table";
|
|||
|
||||
@Component({
|
||||
templateUrl: "./cloudmobile.component.html",
|
||||
styleUrls: ["./notificationtemplate.component.scss"]
|
||||
})
|
||||
export class CloudMobileComponent implements OnInit {
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
Test
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
|
@ -53,7 +53,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
Test
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
|
@ -58,7 +58,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -3,71 +3,73 @@
|
|||
<div *ngIf="form" class="small-middle-container">
|
||||
<fieldset>
|
||||
<legend>Legacy Mobile Notifications</legend>
|
||||
<div class="col-md-6">
|
||||
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
|
||||
<div class="row">
|
||||
<div *ngIf="userList" class="col-md-8">
|
||||
<table class="table table-striped table-hover table-responsive table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<a>Username/Alias</a>
|
||||
</th>
|
||||
<th>
|
||||
<a>Mobile Devices Registered</a>
|
||||
</th>
|
||||
<div class="lmobile-container">
|
||||
<div class="col-md-6">
|
||||
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
|
||||
<div class="row">
|
||||
<div *ngIf="userList" class="col-md-8">
|
||||
<table class="table table-striped table-hover table-responsive table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<a>Username/Alias</a>
|
||||
</th>
|
||||
<th>
|
||||
<a>Mobile Devices Registered</a>
|
||||
</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let user of userList">
|
||||
<td>
|
||||
{{user.username}}
|
||||
</td>
|
||||
<td>
|
||||
{{user.devices}}
|
||||
</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let user of userList">
|
||||
<td>
|
||||
{{user.username}}
|
||||
</td>
|
||||
<td>
|
||||
{{user.devices}}
|
||||
</td>
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="form-group">
|
||||
<label for="select" class="control-label">Users</label>
|
||||
<div>
|
||||
<select class="form-control form-control-custom" id="select" [(ngModel)]="testUserId" [ngModelOptions]="{standalone: true}">
|
||||
<option value="">Please select</option>
|
||||
<option *ngFor="let x of userList" [value]="x.userId">{{x.username}}</option>
|
||||
</select>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-danger-outline">Send Test Notification</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="remove(form)" class="btn btn-danger-outline">Remove User</button>
|
||||
<div class="row lmobile-actions">
|
||||
<div class="form-group">
|
||||
<label for="select" class="control-label">Users</label>
|
||||
<div>
|
||||
<select class="form-control form-control-custom" id="select" [(ngModel)]="testUserId" [ngModelOptions]="{standalone: true}">
|
||||
<option value="">Please select</option>
|
||||
<option *ngFor="let x of userList" [value]="x.userId">{{x.username}}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-danger-outline">Send Test Notification</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="remove(form)" class="btn btn-danger-outline">Remove User</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="col-md-6">
|
||||
<notification-templates [templates]="templates" [showSubject]="false"></notification-templates>
|
||||
<div class="col-md-6 issue-content">
|
||||
<notification-templates [templates]="templates" [showSubject]="false"></notification-templates>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
|
@ -1,15 +1,30 @@
|
|||
@import "~styles/shared.scss";
|
||||
::ng-deep ngb-accordion > div.card {
|
||||
color:white;
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
::ng-deep ngb-accordion > div.card > div.card-header {
|
||||
padding:0px;
|
||||
}
|
||||
|
||||
.small-middle-container{
|
||||
margin: auto;
|
||||
width: 95%;
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.lmobile-actions{
|
||||
display:flex;
|
||||
justify-content: left;
|
||||
align-items:flex-end;
|
||||
}
|
||||
|
||||
.lmobile-actions .form-group{
|
||||
margin-right:10px;
|
||||
}
|
||||
|
||||
.lmobile-container{
|
||||
display:flex;
|
||||
margin-top:10px;
|
||||
}
|
||||
|
||||
.issue-content{
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mat-raised-button{
|
||||
margin-right:10px;
|
||||
}
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
Test
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
|
@ -43,7 +43,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
Test
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
|
@ -85,7 +85,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
Test
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
|
@ -68,7 +68,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
Test
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
|
@ -52,7 +52,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
<button [disabled]="form.invalid" mat-raised-button type="button" (click)="test(form)" class="btn btn-primary-outline">
|
||||
Test
|
||||
<div id="spinner"></div>
|
||||
</button>
|
||||
|
@ -40,7 +40,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<button [disabled]="form.invalid" type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
<button [disabled]="form.invalid" mat-raised-button type="submit" id="save" class="btn btn-primary-outline">Submit</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
|
|
@ -158,15 +158,21 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button mat-raised-button (click)="runCacher()" type="button" id="save"
|
||||
<button mat-raised-button (click)="runCacher()" type="button" id="fullSync"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">Manually Run Full
|
||||
Sync</button><br />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button mat-raised-button (click)="runRecentlyAddedCacher()" type="button" id="save"
|
||||
<button mat-raised-button (click)="runRecentlyAddedCacher()" type="button" id="recentlyAddedSync"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">Manually Run Recently
|
||||
Added Sync</button>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button mat-raised-button (click)="clearDataAndResync()" type="button" id="clearData"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">
|
||||
Clear Data And Resync
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
|
|
@ -73,10 +73,9 @@ export class PlexComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
public addTab(event: MatTabChangeEvent) {
|
||||
|
||||
const tabName = event.tab.textLabel;
|
||||
if (tabName == "Add Server"){
|
||||
|
||||
|
||||
if (this.settings.servers == null) {
|
||||
this.settings.servers = [];
|
||||
}
|
||||
|
@ -146,6 +145,14 @@ export class PlexComponent implements OnInit, OnDestroy {
|
|||
});
|
||||
}
|
||||
|
||||
public clearDataAndResync(): void {
|
||||
this.jobService.clearMediaserverData().subscribe(x => {
|
||||
if (x) {
|
||||
this.notificationService.success("Triggered the Clear MediaServer Resync");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.subscriptions.next();
|
||||
this.subscriptions.complete();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div *ngIf="!text" class="col-md-4 ml-auto ">
|
||||
<a href="{{domain}}{{url}}" target="_blank">
|
||||
<button mat-raised-button color="accent">
|
||||
<span>Wiki</span>
|
||||
<span>Docs</span>
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
@ -141,3 +141,19 @@
|
|||
.mat-flat-button, .mat-raised-button, .mat-fab, .mat-mini-fab{
|
||||
background-color: $ombi-active;
|
||||
}
|
||||
|
||||
hr{
|
||||
border-top: 1px solid $ombi-background-primary;
|
||||
}
|
||||
|
||||
.form-control{
|
||||
background-color: $ombi-background-accent;
|
||||
color:#FFF;
|
||||
border: 1px solid $ombi-background-accent;
|
||||
}
|
||||
|
||||
.form-control:focus{
|
||||
background-color: $ombi-background-accent;
|
||||
color:#FFF;
|
||||
border: 1px solid $ombi-active;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ using Ombi.Schedule.Jobs.Emby;
|
|||
using Ombi.Schedule.Jobs.Jellyfin;
|
||||
using Ombi.Schedule.Jobs.Ombi;
|
||||
using Ombi.Schedule.Jobs.Plex;
|
||||
using Ombi.Schedule.Jobs.Plex.Interfaces;
|
||||
using Ombi.Schedule.Jobs.Radarr;
|
||||
using Quartz;
|
||||
|
||||
|
@ -125,6 +126,17 @@ namespace Ombi.Controllers.V1
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear out the media server and resync
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("clearmediaserverdata")]
|
||||
public bool ClearMediaServerData()
|
||||
{
|
||||
OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IMediaDatabaseRefresh), "System"));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Runs a smaller version of the content cacher
|
||||
/// </summary>
|
||||
|
|
4
src/Ombi/yarn.lock
Normal file
4
src/Ombi/yarn.lock
Normal file
|
@ -0,0 +1,4 @@
|
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue