Merge branch 'feature/v4' into jellyfin-redux

This commit is contained in:
Joshua M. Boniface 2020-12-19 14:56:10 -05:00 committed by GitHub
commit 5233d0caab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 222 additions and 176 deletions

View file

@ -155,7 +155,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (!hasImdb) if (!hasImdb)
{ {
var id = await GetImdbId(hasTheMovieDb, hasTvDbId, show.Title, show.TheMovieDbId, show.TvDbId); var id = await GetImdbId(hasTheMovieDb, hasTvDbId, show.Title, show.TheMovieDbId, show.TvDbId, RequestType.TvShow);
show.ImdbId = id; show.ImdbId = id;
_plexRepo.UpdateWithoutSave(show); _plexRepo.UpdateWithoutSave(show);
} }
@ -189,7 +189,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (!hasImdb) if (!hasImdb)
{ {
var id = await GetImdbId(hasTheMovieDb, hasTvDbId, show.Title, show.TheMovieDbId, show.TvDbId); var id = await GetImdbId(hasTheMovieDb, hasTvDbId, show.Title, show.TheMovieDbId, show.TvDbId, RequestType.TvShow);
show.ImdbId = id; show.ImdbId = id;
_embyRepo.UpdateWithoutSave(show); _embyRepo.UpdateWithoutSave(show);
} }
@ -255,7 +255,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (!hasImdb) if (!hasImdb)
{ {
var imdbId = await GetImdbId(hasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty); var imdbId = await GetImdbId(hasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty, RequestType.Movie);
movie.ImdbId = imdbId; movie.ImdbId = imdbId;
_plexRepo.UpdateWithoutSave(movie); _plexRepo.UpdateWithoutSave(movie);
} }
@ -309,7 +309,7 @@ namespace Ombi.Schedule.Jobs.Ombi
if (!movie.HasImdb) if (!movie.HasImdb)
{ {
var imdbId = await GetImdbId(movie.HasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty); var imdbId = await GetImdbId(movie.HasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty, RequestType.Movie);
movie.ImdbId = imdbId; movie.ImdbId = imdbId;
_embyRepo.UpdateWithoutSave(movie); _embyRepo.UpdateWithoutSave(movie);
} }
@ -422,7 +422,7 @@ namespace Ombi.Schedule.Jobs.Ombi
return string.Empty; return string.Empty;
} }
private async Task<string> GetImdbId(bool hasTheMovieDb, bool hasTvDbId, string title, string theMovieDbId, string tvDbId) private async Task<string> GetImdbId(bool hasTheMovieDb, bool hasTvDbId, string title, string theMovieDbId, string tvDbId, RequestType type)
{ {
_log.LogInformation("The media item {0} does not have a ImdbId, searching for ImdbId", title); _log.LogInformation("The media item {0} does not have a ImdbId, searching for ImdbId", title);
// Looks like TV Maze does not provide the moviedb id, neither does the TV endpoint on TheMovieDb // Looks like TV Maze does not provide the moviedb id, neither does the TV endpoint on TheMovieDb
@ -431,13 +431,22 @@ namespace Ombi.Schedule.Jobs.Ombi
_log.LogInformation("The show {0} has TheMovieDbId but not ImdbId, searching for ImdbId", title); _log.LogInformation("The show {0} has TheMovieDbId but not ImdbId, searching for ImdbId", title);
if (int.TryParse(theMovieDbId, out var id)) if (int.TryParse(theMovieDbId, out var id))
{ {
var result = await _movieApi.GetTvExternals(id); switch (type)
{
return result.imdb_id; case RequestType.TvShow:
var result = await _movieApi.GetTvExternals(id);
return result.imdb_id;
case RequestType.Movie:
var r = await _movieApi.GetMovieInformationWithExtraInfo(id);
return r.ImdbId;
default:
break;
}
} }
} }
if (hasTvDbId) if (hasTvDbId && type == RequestType.TvShow)
{ {
_log.LogInformation("The show {0} has tvdbid but not ImdbId, searching for ImdbId", title); _log.LogInformation("The show {0} has tvdbid but not ImdbId, searching for ImdbId", title);
if (int.TryParse(tvDbId, out var id)) if (int.TryParse(tvDbId, out var id))

View file

@ -3,7 +3,7 @@
<div class="small-middle-container"> <div class="small-middle-container">
<div *ngIf="form && customizationSettings && authenticationSettings"> <div *ngIf="form && customizationSettings && authenticationSettings">
<mat-card class="mat-elevation-z8 top-margin"> <mat-card class="mat-elevation-z8 top-margin login-card">
<img mat-card-image *ngIf="!customizationSettings.logo" src="{{baseUrl}}/images/logo.png"> <img mat-card-image *ngIf="!customizationSettings.logo" src="{{baseUrl}}/images/logo.png">
<img mat-card-image *ngIf="customizationSettings.logo" [src]="customizationSettings.logo"> <img mat-card-image *ngIf="customizationSettings.logo" [src]="customizationSettings.logo">
<mat-card-content id="login-box" *ngIf="!authenticationSettings.enableOAuth || loginWithOmbi"> <mat-card-content id="login-box" *ngIf="!authenticationSettings.enableOAuth || loginWithOmbi">

View file

@ -228,4 +228,7 @@ div.bg {
.login-buttons { .login-buttons {
text-align: center; text-align: center;
}
.login-card {
background: #424242;
} }

View file

@ -1,130 +1,145 @@
<settings-menu> <settings-menu></settings-menu>
</settings-menu>
<wiki [url]="'https://github.com/tidusjar/Ombi/wiki/Job-Settings'"></wiki> <wiki [url]="'https://github.com/tidusjar/Ombi/wiki/Job-Settings'"></wiki>
<div *ngIf="form"> <div *ngIf="form" class="small-middle-container">
<fieldset> <fieldset>
<legend>Job Settings</legend> <legend>Job Settings</legend>
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)" style="padding-top:5%;"> <form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
<div class="col-md-6"> <small>Changes require a restart.</small><p>
<small>Changes to any of the below requires you to restart Ombi. </small> <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="https://www.cronmaker.com/" target="_blank">https://www.cronmaker.com/</a></small> <div style="margin-top:1em;">
<div class="form-group"> <div class="form-group cronBox">
<label for="sonarrSync" class="control-label">Sonarr Sync</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('sonarrSync').hasError('required')}" id="sonarrSync" name="sonarrSync" formControlName="sonarrSync"> <mat-label for="sonarrSync" class="control-mat-label">Sonarr Sync</mat-label>
<small *ngIf="form.get('sonarrSync').hasError('required')" class="error-text">The Sonarr Sync is required</small> <input matInput type="text" [ngClass]="{'form-error': form.get('sonarrSync').hasError('required')}" id="sonarrSync" name="sonarrSync" formControlName="sonarrSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('sonarrSync')?.value)">Test</button> <small *ngIf="form.get('sonarrSync').hasError('required')" class="error-text">The Sonarr Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('sonarrSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="sickRageSync" class="control-label">SickRage Sync</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('sonarrSync').hasError('required')}" id="sickRageSync" name="sickRageSync" formControlName="sickRageSync"> <mat-label for="sickRageSync" class="control-mat-label">SickRage Sync</mat-label>
<small *ngIf="form.get('sickRageSync').hasError('required')" class="error-text">The SickRage Sync is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('sonarrSync').hasError('required')}" id="sickRageSync" name="sickRageSync" formControlName="sickRageSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('sickRageSync')?.value)">Test</button> <small *ngIf="form.get('sickRageSync').hasError('required')" class="error-text">The SickRage Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('sickRageSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="radarrSync" class="control-label">Radarr Sync</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('radarrSync').hasError('required')}" id="radarrSync" name="radarrSync" formControlName="radarrSync"> <mat-label for="radarrSync" class="control-mat-label">Radarr Sync</mat-label>
<small *ngIf="form.get('radarrSync').hasError('required')" class="error-text">The Radarr Sync is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('radarrSync').hasError('required')}" id="radarrSync" name="radarrSync" formControlName="radarrSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('radarrSync')?.value)">Test</button> <small *ngIf="form.get('radarrSync').hasError('required')" class="error-text">The Radarr Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('radarrSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="lidarrArtistSync" class="control-label">Lidarr Sync</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('lidarrArtistSync').hasError('required')}" id="lidarrArtistSync" name="lidarrArtistSync" formControlName="lidarrArtistSync"> <mat-label for="lidarrArtistSync" class="control-mat-label">Lidarr Sync</mat-label>
<small *ngIf="form.get('lidarrArtistSync').hasError('required')" class="error-text">The Lidarr Sync is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('lidarrArtistSync').hasError('required')}" id="lidarrArtistSync" name="lidarrArtistSync" formControlName="lidarrArtistSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('lidarrArtistSync')?.value)">Test</button> <small *ngIf="form.get('lidarrArtistSync').hasError('required')" class="error-text">The Lidarr Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('lidarrArtistSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="couchPotatoSync" class="control-label">CouchPotato Sync</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('radarrSync').hasError('required')}" id="couchPotatoSync" name="couchPotatoSync" formControlName="couchPotatoSync"> <mat-label for="couchPotatoSync" class="control-mat-label">CouchPotato Sync</mat-label>
<small *ngIf="form.get('couchPotatoSync').hasError('required')" class="error-text">The CouchPotato Sync is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('radarrSync').hasError('required')}" id="couchPotatoSync" name="couchPotatoSync" formControlName="couchPotatoSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('couchPotatoSync')?.value)">Test</button> <small *ngIf="form.get('couchPotatoSync').hasError('required')" class="error-text">The CouchPotato Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('couchPotatoSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="automaticUpdater" class="control-label">Automatic Update</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('automaticUpdater').hasError('required')}" id="automaticUpdater" name="automaticUpdater" formControlName="automaticUpdater"> <mat-label for="automaticUpdater" class="control-mat-label">Automatic Update</mat-label>
<small *ngIf="form.get('automaticUpdater').hasError('required')" class="error-text">The Automatic Update is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('automaticUpdater').hasError('required')}" id="automaticUpdater" name="automaticUpdater" formControlName="automaticUpdater">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('automaticUpdater')?.value)">Test</button> <small *ngIf="form.get('automaticUpdater').hasError('required')" class="error-text">The Automatic Update is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('automaticUpdater')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="retryRequests" class="control-label">Retry Failed Requests</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('retryRequests').hasError('required')}" id="retryRequests" name="retryRequests" formControlName="retryRequests"> <mat-label for="retryRequests" class="control-mat-label">Retry Failed Requests</mat-label>
<small *ngIf="form.get('retryRequests').hasError('required')" class="error-text">The Retry Requests is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('retryRequests').hasError('required')}" id="retryRequests" name="retryRequests" formControlName="retryRequests">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('retryRequests')?.value)">Test</button> <small *ngIf="form.get('retryRequests').hasError('required')" class="error-text">The Retry Requests is required</small></mat-form-field>
</div> <button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('retryRequests')?.value)">Test</button>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="plexContentSync" class="control-label">Plex Sync</label>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('plexContentSync').hasError('required')}" id="plexContentSync" name="plexContentSync" formControlName="plexContentSync">
<small *ngIf="form.get('plexContentSync').hasError('required')" class="error-text">The Plex Sync is required</small>
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('plexContentSync')?.value)">Test</button>
</div>
<div class="form-group">
<label for="plexRecentlyAddedSync" class="control-label">Plex Recently Added Sync</label>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('plexRecentlyAddedSync').hasError('required')}" id="plexRecentlyAddedSync" name="plexRecentlyAddedSync" formControlName="plexRecentlyAddedSync">
<small *ngIf="form.get('plexRecentlyAddedSync').hasError('required')" class="error-text">The Plex Sync is required</small>
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('plexRecentlyAddedSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="embyContentSync" class="control-label">Emby Sync</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('embyContentSync').hasError('required')}" id="embyContentSync" name="embyContentSync" formControlName="embyContentSync"> <mat-label for="plexContentSync" class="control-mat-label">Plex Sync</mat-label>
<small *ngIf="form.get('embyContentSync').hasError('required')" class="error-text">The Emby Sync is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('plexContentSync').hasError('required')}" id="plexContentSync" name="plexContentSync" formControlName="plexContentSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('embyContentSync')?.value)">Test</button> <small *ngIf="form.get('plexContentSync').hasError('required')" class="error-text">The Plex Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('plexContentSync')?.value)">Test</button>
</div>
<div class="form-group cronBox">
<mat-form-field appearance="outline" floatLabel=always>
<mat-label for="plexRecentlyAddedSync" class="control-mat-label">Plex Recently Added Sync</mat-label>
<input type="text" matInput [ngClass]="{'form-error': form.get('plexRecentlyAddedSync').hasError('required')}" id="plexRecentlyAddedSync" name="plexRecentlyAddedSync" formControlName="plexRecentlyAddedSync">
<small *ngIf="form.get('plexRecentlyAddedSync').hasError('required')" class="error-text">The Plex Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('plexRecentlyAddedSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="jellyfinContentSync" class="control-label">Jellyfin Sync</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('jellyfinContentSync').hasError('required')}" id="jellyfinContentSync" name="jellyfinContentSync" formControlName="jellyfinContentSync"> <mat-label for="embyContentSync" class="control-mat-label">Emby Sync</mat-label>
<small *ngIf="form.get('jellyfinContentSync').hasError('required')" class="error-text">The Jellyfin Sync is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('embyContentSync').hasError('required')}" id="embyContentSync" name="embyContentSync" formControlName="embyContentSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('jellyfinContentSync')?.value)">Test</button> <small *ngIf="form.get('embyContentSync').hasError('required')" class="error-text">The Emby Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('embyContentSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="userImporter" class="control-label">User Importer</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('userImporter').hasError('required')}" id="userImporter" name="userImporter" formControlName="userImporter"> <mat-label for="jellyfinContentSync" class="control-label">Jellyfin Sync</mat-label>
<small *ngIf="form.get('userImporter').hasError('required')" class="error-text">The User Importer is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('jellyfinContentSync').hasError('required')}" id="jellyfinContentSync" name="jellyfinContentSync" formControlName="jellyfinContentSync">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('userImporter')?.value)">Test</button> <small *ngIf="form.get('jellyfinContentSync').hasError('required')" class="error-text">The Jellyfin Sync is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('jellyfinContentSync')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="userImporter" class="control-label">Newsletter</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('newsletter').hasError('required')}" id="newsletter" name="newsletter" formControlName="newsletter"> <mat-label for="userImporter" class="control-mat-label">User Importer</mat-label>
<small *ngIf="form.get('newsletter').hasError('required')" class="error-text">The Newsletter is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('userImporter').hasError('required')}" id="userImporter" name="userImporter" formControlName="userImporter">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('newsletter')?.value)">Test</button> <small *ngIf="form.get('userImporter').hasError('required')" class="error-text">The User Importer is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('userImporter')?.value)">Test</button>
</div>
<div class="form-group cronBox">
<mat-form-field appearance="outline" floatLabel=always>
<mat-label for="userImporter" class="control-mat-label">Newsletter</mat-label>
<input type="text" matInput [ngClass]="{'form-error': form.get('newsletter').hasError('required')}" id="newsletter" name="newsletter" formControlName="newsletter">
<small *ngIf="form.get('newsletter').hasError('required')" class="error-text">The Newsletter is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('newsletter')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="userImporter" class="control-label">Issue Purge/Delete</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('issuesPurge').hasError('required')}" id="issuesPurge" name="issuesPurge" formControlName="issuesPurge"> <mat-label for="userImporter" class="control-mat-label">Issue Purge/Delete</mat-label>
<small *ngIf="form.get('issuesPurge').hasError('required')" class="error-text">The Issues Purge is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('issuesPurge').hasError('required')}" id="issuesPurge" name="issuesPurge" formControlName="issuesPurge">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('issuesPurge')?.value)">Test</button> <small *ngIf="form.get('issuesPurge').hasError('required')" class="error-text">The Issues Purge is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('issuesPurge')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="userImporter" class="control-label">Media Data Refresh</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('mediaDatabaseRefresh').hasError('required')}" id="mediaDatabaseRefresh" name="mediaDatabaseRefresh" formControlName="mediaDatabaseRefresh"> <mat-label for="userImporter" class="control-mat-label">Media Data Refresh</mat-label>
<small *ngIf="form.get('mediaDatabaseRefresh').hasError('required')" class="error-text">The Media Database Refresh is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('mediaDatabaseRefresh').hasError('required')}" id="mediaDatabaseRefresh" name="mediaDatabaseRefresh" formControlName="mediaDatabaseRefresh">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('mediaDatabaseRefresh')?.value)">Test</button> <small *ngIf="form.get('mediaDatabaseRefresh').hasError('required')" class="error-text">The Media Database Refresh is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('mediaDatabaseRefresh')?.value)">Test</button>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<label for="userImporter" class="control-label">Auto Available Request Deletion</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom" [ngClass]="{'form-error': form.get('autoDeleteRequests').hasError('required')}" id="autoDeleteRequests" name="autoDeleteRequests" formControlName="autoDeleteRequests"> <mat-label for="userImporter" class="control-mat-label">Auto Available Request Deletion</mat-label>
<small *ngIf="form.get('autoDeleteRequests').hasError('required')" class="error-text">Auto Available Request Deletion is required</small> <input type="text" matInput [ngClass]="{'form-error': form.get('autoDeleteRequests').hasError('required')}" id="autoDeleteRequests" name="autoDeleteRequests" formControlName="autoDeleteRequests">
<button type="button" class="btn btn-sm btn-primary-outline" (click)="testCron(form.get('autoDeleteRequests')?.value)">Test</button> <small *ngIf="form.get('autoDeleteRequests').hasError('required')" class="error-text">Auto Available Request Deletion is required</small></mat-form-field>
<button mat-raised-button type="button" class="btn btn-sm btn-primary-outline cronbtn" (click)="testCron(form.get('autoDeleteRequests')?.value)">Test</button>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group cronBox">
<div> <div>
<button type="submit" [disabled]="form.invalid" class="btn btn-primary-outline">Submit</button> <button mat-raised-button type="submit" [disabled]="form.invalid" class="mat-focus-indicator mat-raised-button mat-button-base mat-accent">Submit</button>
</div> </div>
</div> </div>
</form> </form>
</fieldset> </fieldset>
</div> </div>

View file

@ -1,5 +1,16 @@
.small-middle-container{ .small-middle-container{
margin: auto; margin: auto;
width: 85%; width: 95%;
margin-top:10px; margin-top:10px;
}
.cronBox {
width: 300px;
display: inline-flex;
padding-left: 0px;
margin-right: 1em;
}
.cronbtn {
max-height: 36px;
margin-top: 1em;
margin-left: .5em;
} }

View file

@ -140,7 +140,7 @@ export class SonarrComponent implements OnInit {
this.languageProfiles.unshift({ name: "Please Select", id: -1 }); this.languageProfiles.unshift({ name: "Please Select", id: -1 });
this.langRunning = false; this.langRunning = false;
this.notificationService.success("Successfully retrieved the Languge Profiles"); this.notificationService.success("Successfully retrieved the Language Profiles");
}); });
} }
@ -191,4 +191,4 @@ function validateProfile(qualityProfile): { [key: string]:boolean } | null {
return { 'profileValidation': true }; return { 'profileValidation': true };
} }
return null; return null;
} }

View file

@ -4,85 +4,87 @@
<div *ngIf="form" class="small-middle-container"> <div *ngIf="form" class="small-middle-container">
<fieldset> <fieldset>
<legend>Update Settings</legend> <legend>Update Settings</legend>
<div class="form-group" style="float: right"> <div class="md-form-field" style="margin-top:1em">
<div *ngIf="updateAvailable"> <div *ngIf="updateAvailable"><button mat-raised-button (click)="update()" [disabled]="!enableUpdateButton" class="btn btn-success-outline">Update</button></div>
<button (click)="update()" [disabled]="!enableUpdateButton" class="btn btn-success-outline">Update</button> <div *ngIf="!updateAvailable"><button mat-raised-button (click)="checkForUpdate()" class="btn btn-primary-outline">Check For Update</button></div>
</div>
<div *ngIf="!updateAvailable">
<button (click)="checkForUpdate()" class="btn btn-primary-outline">Check For Update</button>
</div>
</div> </div>
<form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)" style="padding-top:5%;"> <div class="md-form-field" style="margin-top:1em"></div>
<div class="col-md-6"> <form novalidate [formGroup]="form" (ngSubmit)="onSubmit(form)">
<div class="form-group"> <div class="md-form-field">
<div class="checkbox"> <mat-slide-toggle id="autoUpdateEnabled" formControlName="autoUpdateEnabled">
<input type="checkbox" id="autoUpdateEnabled" formControlName="autoUpdateEnabled"> <mat-mat-label for="autoUpdateEnabled">Enable Automatic Update</mat-mat-label>
<label for="autoUpdateEnabled">Enable Automatic Update</label> </mat-slide-toggle>
</div>
</div> </div>
<!-- <div class="form-group"> <!-- <div class="md-form-field">
<div class="checkbox"> <mat-slide-toggle id="testMode" formControlName="testMode">
<input type="checkbox" id="testMode" formControlName="testMode"> <mat-label for="testMode">Test Mode</mat-label>
<label for="testMode">Test Mode</label>
</div> </div>
</div> --> </div> -->
<div class="form-group" *ngIf="isWindows"> <div class="md-form-field" *ngIf="isWindows">
<div class="checkbox"> <mat-slide-toggle id="windowsService" formControlName="windowsService">
<input type="checkbox" id="windowsService" formControlName="windowsService"> <mat-label for="windowsService">Running as a Windows Service</mat-label>
<label for="windowsService">Running as a Windows Service</label> </mat-slide-toggle>
</div>
</div> </div>
<div class="form-group" *ngIf="!form.value.windowsService"> <div class="md-form-field" *ngIf="!form.value.windowsService">
<div class="checkbox"> <mat-slide-toggle id="useScript" formControlName="useScript">
<input type="checkbox" id="useScript" formControlName="useScript"> <mat-label for="useScript">Use your own updater script</mat-label>
<label for="useScript">Use your own updater script</label> </mat-slide-toggle>
</div>
</div> </div>
<div class="md-form-field" style="margin-top:1em"></div>
<div *ngIf="form.value.windowsService"> <div *ngIf="form.value.windowsService">
<div class="form-group"> <div class="md-form-field textEntry">
<label for="windowsServiceName" class="control-label">Windows Service Name</label> <mat-form-field appearance="outline" floatLabel=always><mat-label for="windowsServiceName" class="control-mat-label">Windows Service Name</mat-label>
<input type="text" class="form-control form-control-custom " id="windowsServiceName" name="windowsServiceName" formControlName="windowsServiceName"> <input matInput id="windowsServiceName" name="windowsServiceName" formControlName="windowsServiceName">
</mat-form-field>
</div> </div>
</div> </div>
<div [hidden]="!useScript || form.value.windowsService"> <div [hidden]="!useScript || form.value.windowsService">
<small>For information how to use this, please press the wiki button at the top of the page</small> <small>For information how to use this, please press the wiki button at the top of the page</small>
<div class="form-group"> <div class="md-form-field textEntry">
<label for="scriptLocation" class="control-label">Script Path</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom " id="scriptLocation" name="scriptLocation" formControlName="scriptLocation"> <mat-label for="scriptLocation" class="control-mat-label">Script Path</mat-label>
<input matInput id="scriptLocation" name="scriptLocation" formControlName="scriptLocation">
</mat-form-field>
</div> </div>
</div> </div>
<div [hidden]="useScript || form.value.windowsService"> <div [hidden]="useScript || form.value.windowsService">
<small >By default the process name is Ombi, but this could be different for your system. We need to know the process name so we can kill that process to update the files.</small> <small >By default the process name is Ombi, but this could be different for your system. We need to know the process name so we can kill that process to update the files.</small>
<div class="form-group"> <div class="md-form-field textEntry">
<label for="processName">Ombi Process Name</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" id="processName" class="form-control form-control-custom" placeholder="Ombi" formControlName="processName"> <mat-label for="processName">Ombi Process Name</mat-label>
<input matInput id="processName" placeholder="Ombi" formControlName="processName">
</mat-form-field>
</div> </div>
</div> </div>
<div class="form-group">
<div>
<button type="submit" class="btn btn-primary-outline ">Submit</button> <div class="md-form-field" [hidden]="useScript" *ngIf="isWindows">
</div>
</div>
</div>
<div class="col-md-6" [hidden]="useScript" *ngIf="isWindows">
<small>If you are getting any permissions issues, you can specify a user for the update process to run under.</small> <small>If you are getting any permissions issues, you can specify a user for the update process to run under.</small>
<div class="form-group"> <div class="md-form-field textEntry">
<label for="username" class="control-label">Username</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="text" class="form-control form-control-custom " id="username" name="username" formControlName="username"> <mat-label for="username" class="control-mat-label">Username</mat-label>
<input matInput id="username" name="username" formControlName="username">
</mat-form-field>
</div> </div>
<div class="form-group"> <div class="md-form-field textEntry">
<label for="password">Password</label> <mat-form-field appearance="outline" floatLabel=always>
<input type="password" id="password" class="form-control form-control-custom" formControlName="password"> <mat-label for="password">Password</mat-label>
<input matInput type="password" id="password" formControlName="password">
</mat-form-field>
</div>
</div>
<div class="md-form-field" style="margin-top:1em;">
<div>
<button mat-raised-button type="submit" color="primary" [disabled]="form.invalid" class="mat-focus-indicator mat-stroked-button accent mat-accent mat-raised-button mat-button-base" ng-reflect-disabled="false"><span class="mat-button-wrapper">Submit</span><div matripple="" class="mat-ripple mat-button-ripple" ng-reflect-disabled="false" ng-reflect-centered="false" ng-reflect-trigger="[object HTMLButtonElement]"></div><div class="mat-button-focus-overlay"></div></button>
</div> </div>
</div> </div>
</form> </form>

View file

@ -1,5 +1,8 @@
.small-middle-container{ .small-middle-container {
margin: auto; margin: auto;
width: 85%; width: 95%;
margin-top:10px; margin-top: 10px;
} }
.textEntry {
width: 300px;
}

View file

@ -49,12 +49,11 @@
{{ep.airDateDisplay }} {{ep.airDateDisplay }}
</div> </div>
<div class="col-3"> <div class="col-3">
<ng-template [ngIf]="ep.available"><span class="label label-success" id="availableLabel">Available</span></ng-template> <ng-template [ngIf]="ep.available"><span class="label label-success" id="availableLabel">{{'Common.Available' | translate}}</span></ng-template>
<ng-template [ngIf]="ep.approved && !ep.available "><span class="label label-info" id="processingRequestLabel">Processing <ng-template [ngIf]="ep.requested && ep.approved && !ep.available "><span class="label label-info" id="processingRequestLabel">{{'Common.ProcessingRequest' | translate}}</span></ng-template>
Request</span></ng-template>
<ng-template [ngIf]="ep.selected"><span class="label label-info" id="selectedLabel">Selected</span></ng-template> <ng-template [ngIf]="ep.selected"><span class="label label-info" id="selectedLabel">Selected</span></ng-template>
<ng-template [ngIf]="ep.requested && !ep.approved && !ep.available && !ep.selected"><span class="label label-warning" <ng-template [ngIf]="ep.requested && !ep.approved && !ep.available && !ep.selected"><span class="label label-warning"
id="pendingApprovalLabel">Pending Approval</span> id="pendingApprovalLabel">{{'Common.PendingApproval' | translate}}</span>
</ng-template> </ng-template>
<ng-template [ngIf]="!ep.requested && !ep.available && !ep.approved && !ep.selected"><span class="label label-danger" <ng-template [ngIf]="!ep.requested && !ep.available && !ep.approved && !ep.selected"><span class="label label-danger"
id="notRequetsedLabel">Not Requested</span></ng-template> id="notRequetsedLabel">Not Requested</span></ng-template>

View file

@ -7,7 +7,7 @@
<button type="button" style="float:right;" mat-raised-button color="primary" (click)="showBulkEdit = !showBulkEdit" [disabled]="this.selection.selected.length <= 0">Bulk Edit</button> <button type="button" style="float:right;" mat-raised-button color="primary" (click)="showBulkEdit = !showBulkEdit" [disabled]="this.selection.selected.length <= 0">Bulk Edit</button>
</div> </div>
<div class="content"> <div class="content" >
<table mat-table *ngIf="dataSource" [dataSource]="dataSource" matSort class="mat-elevation-z8"> <table mat-table *ngIf="dataSource" [dataSource]="dataSource" matSort class="mat-elevation-z8">
<ng-container matColumnDef="select"> <ng-container matColumnDef="select">

View file

@ -10,7 +10,7 @@ import { SelectionModel } from "@angular/cdk/collections";
templateUrl: "./usermanagement.component.html", templateUrl: "./usermanagement.component.html",
styleUrls: ["./usermanagement.component.scss"], styleUrls: ["./usermanagement.component.scss"],
}) })
export class UserManagementComponent implements OnInit, AfterViewInit { export class UserManagementComponent implements OnInit {
public displayedColumns: string[] = ['select', 'username', 'alias', 'email', 'roles', 'remainingRequests', public displayedColumns: string[] = ['select', 'username', 'alias', 'email', 'roles', 'remainingRequests',
'nextRequestDue', 'lastLoggedIn', 'userType', 'actions', 'welcome']; 'nextRequestDue', 'lastLoggedIn', 'userType', 'actions', 'welcome'];
@ -32,13 +32,15 @@ export class UserManagementComponent implements OnInit, AfterViewInit {
constructor(private identityService: IdentityService, constructor(private identityService: IdentityService,
private settingsService: SettingsService, private settingsService: SettingsService,
private notificationService: NotificationService, private notificationService: NotificationService,
private plexSettings: SettingsService) { } private plexSettings: SettingsService) {
this.dataSource = new MatTableDataSource();
}
public async ngOnInit() { public async ngOnInit() {
this.users = await this.identityService.getUsers().toPromise(); this.users = await this.identityService.getUsers().toPromise();
this.dataSource = new MatTableDataSource(this.users); this.dataSource = new MatTableDataSource(this.users);
this.dataSource.sort = this.sort;
this.plexSettings.getPlex().subscribe(x => this.plexEnabled = x.enable); this.plexSettings.getPlex().subscribe(x => this.plexEnabled = x.enable);
@ -47,10 +49,6 @@ export class UserManagementComponent implements OnInit, AfterViewInit {
this.settingsService.getEmailNotificationSettings().subscribe(x => this.emailSettings = x); this.settingsService.getEmailNotificationSettings().subscribe(x => this.emailSettings = x);
} }
public ngAfterViewInit(): void {
this.dataSource.sort = this.sort;
}
public welcomeEmail(user: IUser) { public welcomeEmail(user: IUser) {
if (!user.emailAddress) { if (!user.emailAddress) {
this.notificationService.error("The user needs an email address."); this.notificationService.error("The user needs an email address.");
@ -103,6 +101,9 @@ export class UserManagementComponent implements OnInit, AfterViewInit {
} }
public isAllSelected() { public isAllSelected() {
if (!this.dataSource) {
return;
}
const numSelected = this.selection.selected.length; const numSelected = this.selection.selected.length;
const numRows = this.dataSource.data.length; const numRows = this.dataSource.data.length;
return numSelected === numRows; return numSelected === numRows;
@ -110,6 +111,9 @@ export class UserManagementComponent implements OnInit, AfterViewInit {
public masterToggle() { public masterToggle() {
if (!this.dataSource) {
return;
}
this.isAllSelected() ? this.isAllSelected() ?
this.selection.clear() : this.selection.clear() :
this.dataSource.data.forEach(row => this.selection.select(row)); this.dataSource.data.forEach(row => this.selection.select(row));

View file

@ -82,7 +82,7 @@
<meta property="og:image" content="~/images/logo.png" /> <meta property="og:image" content="~/images/logo.png" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet"> <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">
<meta property="og:site_name" content=“@appName” /> <meta property="og:site_name" content="@appName" />
<base href="/@baseUrl" /> <base href="/@baseUrl" />
<!--<link rel="apple-touch-icon" sizes="180x180" href="~/images/favicon/apple-touch-icon.png"> <!--<link rel="apple-touch-icon" sizes="180x180" href="~/images/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="~/images/favicon/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="32x32" href="~/images/favicon/favicon-32x32.png">