Moved to webpack and started on new style

This commit is contained in:
Jamie.Rees 2017-06-09 21:19:26 +01:00
parent 03a8319f5c
commit dbade585e2
118 changed files with 167651 additions and 612 deletions

3
src/Ombi/ClientApp/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
**/*.js
**/*.js.map
**/*.css

View file

@ -7,14 +7,10 @@ import { ILocalUser } from './auth/IUserLogin';
import { ICustomizationSettings } from './interfaces/ISettings'; import { ICustomizationSettings } from './interfaces/ISettings';
import style from './app.component.css';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './app.component.html', templateUrl: './app.component.html',
styles: [style] styleUrls: ['./app.component.scss']
}) })
export class AppComponent implements OnInit { export class AppComponent implements OnInit {

View file

@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule } from '@angular/forms'; import { FormsModule } from '@angular/forms';
import { MdButtonModule, MdCardModule } from '@angular/material'; import { MdButtonModule, MdCardModule, MdInputModule, MdTabsModule } from '@angular/material';
import { RouterModule, Routes } from '@angular/router'; import { RouterModule, Routes } from '@angular/router';
import { HttpModule } from '@angular/http'; import { HttpModule } from '@angular/http';
@ -81,7 +81,9 @@ const routes: Routes = [
MdButtonModule, MdButtonModule,
NgbModule.forRoot(), NgbModule.forRoot(),
DragulaModule, DragulaModule,
MdCardModule MdCardModule,
MdInputModule,
MdTabsModule
], ],
declarations: [ declarations: [
AppComponent, AppComponent,

View file

@ -5,7 +5,7 @@ import { AuthHttp, AuthConfig } from 'angular2-jwt';
export function authHttpServiceFactory(http: Http, options: RequestOptions) { export function authHttpServiceFactory(http: Http, options: RequestOptions) {
return new AuthHttp(new AuthConfig({ return new AuthHttp(new AuthConfig({
tokenName: 'id_token', tokenName: 'id_token',
tokenGetter: (() => localStorage.getItem('id_token')), tokenGetter: (() => localStorage.getItem('id_token')!),
globalHeaders: [{ 'Content-Type': 'application/json' }], globalHeaders: [{ 'Content-Type': 'application/json' }],
}), http, options); }), http, options);
} }

View file

@ -31,7 +31,9 @@ export class AuthService extends ServiceHelpers {
claims(): ILocalUser { claims(): ILocalUser {
if (this.loggedIn()) { if (this.loggedIn()) {
var token = localStorage.getItem('id_token'); var token = localStorage.getItem('id_token');
if (!token) {
throw "Invalid token";
}
var json = this.jwtHelper.decodeToken(token); var json = this.jwtHelper.decodeToken(token);
var roles = json["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"] var roles = json["http://schemas.microsoft.com/ws/2008/06/identity/claims/role"]
var name = json["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"]; var name = json["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"];

View file

@ -1,7 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
@Component({ @Component({
moduleId: module.id,
template: '<h2>Page not found</h2>' template: '<h2>Page not found</h2>'
}) })
export class PageNotFoundComponent { } export class PageNotFoundComponent { }

View file

@ -6,9 +6,8 @@ import { IRequestCountModel } from '../interfaces/IRequestModel';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './landingpage.component.html', templateUrl: './landingpage.component.html',
styleUrls: ['./landingpage.component.css'] styleUrls: ['./landingpage.component.scss']
}) })
export class LandingPageComponent implements OnInit { export class LandingPageComponent implements OnInit {

View file

@ -9,7 +9,6 @@ import { NotificationService } from '../services/notification.service';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './login.component.html', templateUrl: './login.component.html',
}) })
export class LoginComponent { export class LoginComponent {

View file

@ -17,7 +17,6 @@ import { IMovieRequestModel } from '../interfaces/IRequestModel';
@Component({ @Component({
selector: 'movie-requests', selector: 'movie-requests',
moduleId: module.id,
templateUrl: './movierequests.component.html' templateUrl: './movierequests.component.html'
}) })
export class MovieRequestsComponent implements OnInit, OnDestroy { export class MovieRequestsComponent implements OnInit, OnDestroy {

View file

@ -4,7 +4,6 @@ import { IMediaBase } from '../interfaces/IRequestModel';
@Component({ @Component({
selector: 'request-card', selector: 'request-card',
moduleId: module.id,
templateUrl: './request-card.component.html' templateUrl: './request-card.component.html'
}) })
export class RequestCardComponent { export class RequestCardComponent {

View file

@ -4,7 +4,6 @@ import { RequestService } from '../services/request.service';
import { ITvRequestModel, IMovieRequestModel, IRequestGrid } from '../interfaces/IRequestModel'; import { ITvRequestModel, IMovieRequestModel, IRequestGrid } from '../interfaces/IRequestModel';
@Component({ @Component({
moduleId: module.id,
templateUrl: './request-grid.component.html' templateUrl: './request-grid.component.html'
}) })
export class RequestGridComponent implements OnInit { export class RequestGridComponent implements OnInit {

View file

@ -2,7 +2,6 @@
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './request.component.html' templateUrl: './request.component.html'
}) })
export class RequestComponent { export class RequestComponent {

View file

@ -17,7 +17,6 @@ import { ITvRequestModel } from '../interfaces/IRequestModel';
@Component({ @Component({
selector: 'tv-requests', selector: 'tv-requests',
moduleId: module.id,
templateUrl: './tvrequests.component.html' templateUrl: './tvrequests.component.html'
}) })
export class TvRequestsComponent implements OnInit, OnDestroy { export class TvRequestsComponent implements OnInit, OnDestroy {

View file

@ -49,13 +49,13 @@
<span *ngIf="result.available" class="label label-success">Available</span> <span *ngIf="result.available" class="label label-success">Available</span>
<span *ngIf="result.approved && !result.available" class="label label-info">Processing Request</span> <span *ngIf="result.approved && !result.available" class="label label-info">Processing Request</span>
<div *ngIf="result.requested && !result.available; then requested else notRequested"></div> <div *ngIf="result.requested && !result.available; then requested else notRequested"></div>
<template #requested> <ng-template #requested>
<span *ngIf="!result.available" class="label label-warning">Pending Approval</span> <span *ngIf="!result.available" class="label label-warning">Pending Approval</span>
</template> </ng-template>
<template #notRequested> <ng-template #notRequested>
<span *ngIf="!result.available" class="label label-danger">Not Yet Requested</span> <span *ngIf="!result.available" class="label label-danger">Not Yet Requested</span>
</template> </ng-template>
<span id="{{id}}netflixTab"></span> <span id="{{id}}netflixTab"></span>
@ -87,12 +87,12 @@
</div> </div>
<div *ngIf="!result.available"> <div *ngIf="!result.available">
<div *ngIf="result.requested; then requestedBtn else notRequestedBtn"></div> <div *ngIf="result.requested; then requestedBtn else notRequestedBtn"></div>
<template #requestedBtn> <ng-template #requestedBtn>
<button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button> <button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]><i class="fa fa-check"></i> Requested</button>
</template> </ng-template>
<template #notRequestedBtn> <ng-template #notRequestedBtn>
<button id="{{result.id}}" style="text-align: right" class="btn btn-primary-outline" (click)="request(result)"><i class="fa fa-plus"></i> Request</button> <button id="{{result.id}}" style="text-align: right" class="btn btn-primary-outline" (click)="request(result)"><i class="fa fa-plus"></i> Request</button>
</template> </ng-template>
</div> </div>
<!--{{#if_eq type "tv"}} <!--{{#if_eq type "tv"}}
{{#if_eq tvFullyAvailable true}} {{#if_eq tvFullyAvailable true}}

View file

@ -14,7 +14,6 @@ import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
@Component({ @Component({
selector: 'movie-search', selector: 'movie-search',
moduleId: module.id,
templateUrl: './moviesearch.component.html', templateUrl: './moviesearch.component.html',
}) })
export class MovieSearchComponent implements OnInit, OnDestroy { export class MovieSearchComponent implements OnInit, OnDestroy {

View file

@ -31,6 +31,12 @@
<div [hidden]="!showMovie"> <div [hidden]="!showMovie">
<movie-search></movie-search> <movie-search></movie-search>
<md-tab-group>
<md-tab label="Tab 1">
<input mdInput placeholder="Movie Search" value="d">
</md-tab>
<md-tab label="Tab 2">Content 2</md-tab>
</md-tab-group>
</div> </div>
<!-- <!--

View file

@ -1,7 +1,5 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
@Component({ @Component({
selector: 'ombi',
moduleId: module.id,
templateUrl: './search.component.html', templateUrl: './search.component.html',
}) })
export class SearchComponent implements OnInit { export class SearchComponent implements OnInit {

View file

@ -47,13 +47,13 @@
<span *ngIf="ep.available" class="label label-success">Available</span> <span *ngIf="ep.available" class="label label-success">Available</span>
<span *ngIf="ep.approved && !ep.available" class="label label-info">Processing Request</span> <span *ngIf="ep.approved && !ep.available" class="label label-info">Processing Request</span>
<div *ngIf="ep.requested && !ep.available; then requested else notRequested"></div> <div *ngIf="ep.requested && !ep.available; then requested else notRequested"></div>
<template #requested> <ng-template #requested>
<span *ngIf="!ep.available" class="label label-warning">Pending Approval</span> <span *ngIf="!ep.available" class="label label-warning">Pending Approval</span>
</template> </ng-template>
<template #notRequested> <ng-template #notRequested>
<span *ngIf="!ep.available" class="label label-danger">Not Yet Requested</span> <span *ngIf="!ep.available" class="label label-danger">Not Yet Requested</span>
</template> </ng-template>
</td> </td>
<td> <td>

View file

@ -14,9 +14,8 @@ import { IEpisodesRequested } from "../interfaces/IRequestModel";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './seriesinformation.component.html', templateUrl: './seriesinformation.component.html',
styleUrls: ['./seriesinformation.component.css'] styleUrls: ['./seriesinformation.component.scss']
}) })
export class SeriesInformationComponent implements OnInit, OnDestroy { export class SeriesInformationComponent implements OnInit, OnDestroy {

View file

@ -59,13 +59,13 @@
<span *ngIf="result.available" class="label label-success">Available</span> <span *ngIf="result.available" class="label label-success">Available</span>
<span *ngIf="result.approved && !result.available" class="label label-info">Processing Request</span> <span *ngIf="result.approved && !result.available" class="label label-info">Processing Request</span>
<div *ngIf="result.requested && !result.available; then requested else notRequested"></div> <div *ngIf="result.requested && !result.available; then requested else notRequested"></div>
<template #requested> <ng-template #requested>
<span *ngIf="!result.available" class="label label-warning">Pending Approval</span> <span *ngIf="!result.available" class="label label-warning">Pending Approval</span>
</template> </ng-template>
<template #notRequested> <ng-template #notRequested>
<span *ngIf="!result.available" class="label label-danger">Not Yet Requested</span> <span *ngIf="!result.available" class="label label-danger">Not Yet Requested</span>
</template> </ng-template>
<span id="{{id}}netflixTab"></span> <span id="{{id}}netflixTab"></span>

View file

@ -13,12 +13,9 @@ import { NotificationService } from '../services/notification.service';
import { ISearchTvResult } from '../interfaces/ISearchTvResult'; import { ISearchTvResult } from '../interfaces/ISearchTvResult';
import { IRequestEngineResult } from '../interfaces/IRequestEngineResult'; import { IRequestEngineResult } from '../interfaces/IRequestEngineResult';
import template from './tvsearch.component.html';
@Component({ @Component({
selector: 'tv-search', selector: 'tv-search',
moduleId: module.id, templateUrl: './tvsearch.component.html',
template: template,
}) })
export class TvSearchComponent implements OnInit, OnDestroy { export class TvSearchComponent implements OnInit, OnDestroy {

View file

@ -37,7 +37,7 @@ export class IdentityService extends ServiceAuthHelpers {
} }
hasRole(role: string): boolean { hasRole(role: string): boolean {
var roles = localStorage.getItem("roles") as string[]; var roles = localStorage.getItem("roles") as string[] | null;
if (roles) { if (roles) {
if (roles.indexOf(role) > -1) { if (roles.indexOf(role) > -1) {
return true; return true;

View file

@ -6,7 +6,6 @@ import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './customization.component.html', templateUrl: './customization.component.html',
}) })
export class CustomizationComponent implements OnInit { export class CustomizationComponent implements OnInit {

View file

@ -6,7 +6,6 @@ import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './emby.component.html', templateUrl: './emby.component.html',
}) })
export class EmbyComponent implements OnInit { export class EmbyComponent implements OnInit {

View file

@ -6,7 +6,6 @@ import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './landingpage.component.html', templateUrl: './landingpage.component.html',
}) })
export class LandingPageComponent implements OnInit { export class LandingPageComponent implements OnInit {

View file

@ -6,7 +6,6 @@ import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './ombi.component.html', templateUrl: './ombi.component.html',
}) })
export class OmbiComponent implements OnInit { export class OmbiComponent implements OnInit {

View file

@ -11,7 +11,6 @@ import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './plex.component.html', templateUrl: './plex.component.html',
}) })
export class PlexComponent implements OnInit, OnDestroy { export class PlexComponent implements OnInit, OnDestroy {

View file

@ -10,7 +10,6 @@ import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './radarr.component.html', templateUrl: './radarr.component.html',
}) })
export class RadarrComponent implements OnInit { export class RadarrComponent implements OnInit {

View file

@ -1,7 +1,6 @@
import { Component } from '@angular/core'; import { Component } from '@angular/core';
@Component({ @Component({
selector: 'settings-menu', selector: 'settings-menu',
moduleId: module.id,
templateUrl: './settingsmenu.component.html' templateUrl: './settingsmenu.component.html'
}) })
export class SettingsMenuComponent { export class SettingsMenuComponent {

View file

@ -10,7 +10,6 @@ import { NotificationService } from "../../services/notification.service";
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './sonarr.component.html', templateUrl: './sonarr.component.html',
}) })
export class SonarrComponent implements OnInit, OnDestroy { export class SonarrComponent implements OnInit, OnDestroy {

View file

@ -5,7 +5,6 @@ import { IdentityService } from '../services/identity.service';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './usermanagement.component.html' templateUrl: './usermanagement.component.html'
}) })
export class UserManagementComponent implements OnInit { export class UserManagementComponent implements OnInit {

View file

@ -8,7 +8,6 @@ import { NotificationService } from '../../services/notification.service';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './createadmin.component.html', templateUrl: './createadmin.component.html',
}) })
export class CreateAdminComponent { export class CreateAdminComponent {

View file

@ -8,7 +8,6 @@ import { IEmbySettings } from '../../interfaces/ISettings';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './emby.component.html', templateUrl: './emby.component.html',
}) })
export class EmbyComponent { export class EmbyComponent {

View file

@ -4,7 +4,6 @@ import { Router } from '@angular/router';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './mediaserver.component.html', templateUrl: './mediaserver.component.html',
}) })
export class MediaServerComponent { export class MediaServerComponent {

View file

@ -8,7 +8,6 @@ import { IPlexAuthentication } from '../../interfaces/IPlex';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './plex.component.html', templateUrl: './plex.component.html',
}) })
export class PlexComponent { export class PlexComponent {

View file

@ -4,7 +4,6 @@ import { Router } from '@angular/router';
@Component({ @Component({
selector: 'ombi', selector: 'ombi',
moduleId: module.id,
templateUrl: './welcome.component.html', templateUrl: './welcome.component.html',
}) })
export class WelcomeComponent { export class WelcomeComponent {

View file

@ -0,0 +1,24 @@
import './polyfills';
import 'bootstrap/dist/js/bootstrap';
import 'pace-progress';
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
if (module['hot']) {
module['hot'].accept();
module['hot'].dispose(() => {
// Before restarting the app, we create a new root element and dispose the old one
const oldRootElem = document.querySelector('app');
const newRootElem = document.createElement('app');
if (oldRootElem && oldRootElem.parentNode) {
oldRootElem.parentNode.insertBefore(newRootElem, oldRootElem);
}
modulePromise.then(appModule => appModule.destroy());
});
} else {
enableProdMode();
}
const modulePromise = platformBrowserDynamic().bootstrapModule(AppModule);

View file

@ -1,4 +1,3 @@
// TypeScript transpiles our app to ES5 but some dependencies are written in ES6 so must polyfill
import 'core-js/es6/string'; import 'core-js/es6/string';
import 'core-js/es6/array'; import 'core-js/es6/array';
import 'core-js/es6/object'; import 'core-js/es6/object';
@ -6,9 +5,7 @@ import 'core-js/es6/object';
import 'core-js/es7/reflect'; import 'core-js/es7/reflect';
import 'zone.js/dist/zone'; import 'zone.js/dist/zone';
import { config } from './config'; if (module['hot']) {
if (config.env === config.envs.local) {
Error['stackTraceLimit'] = Infinity; Error['stackTraceLimit'] = Infinity;
require('zone.js/dist/long-stack-trace-zone'); require('zone.js/dist/long-stack-trace-zone');
} }

View file

@ -13,15 +13,26 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Content Include="wwwroot\**" /> <!-- Files not to show in IDE -->
<Content Remove="package-lock.json" />
<Compile Remove="wwwroot\dist\**" />
<!-- Files not to publish (note that the 'dist' subfolders are re-added below) -->
<Content Remove="ClientApp\**" />
<Content Remove="wwwroot\dist\**" />
<EmbeddedResource Remove="wwwroot\dist\**" />
<None Remove="wwwroot\dist\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <Target Name="RunWebpack" AfterTargets="ComputeFilesToPublish">
<Content Remove="wwwroot/systemjs.config.js.map" /> <ItemGroup>
<Content Remove="wwwroot\systemjs.config.js" /> <DistFiles Include="wwwroot\dist\**" />
</ItemGroup> <ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
<ItemGroup> <ItemGroup>
<PackageReference Include="AutoMapper" Version="6.0.2" /> <PackageReference Include="AutoMapper" Version="6.0.2" />
@ -60,62 +71,4 @@
<ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj" /> <ProjectReference Include="..\Ombi.TheMovieDbApi\Ombi.Api.TheMovieDb.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Content Update="wwwroot\app\interfaces\ISonarr - Copy.js">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\interfaces\ISonarr - Copy.js.map">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\interfaces\ISonarr - Copy.ts">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\requests\request - Copy.component.js">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\requests\request - Copy.component.js.map">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\requests\request - Copy.component.ts">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\requests\request-grid - Copy.component.html">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\requests\request-card.component.js">
<DependentUpon>request-card.component.ts</DependentUpon>
</Content>
<Content Update="wwwroot\app\requests\request-grid - Copy.component.js">
<DependentUpon>request-grid - Copy.component.ts</DependentUpon>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\requests\request-card.component.js.map">
<DependentUpon>request-card.component.js</DependentUpon>
</Content>
<Content Update="wwwroot\app\requests\request-grid - Copy.component.js.map">
<DependentUpon>request-grid - Copy.component.js</DependentUpon>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\requests\request-grid - Copy.component.ts">
<DependentUpon>request-grid - Copy.component.html</DependentUpon>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\services\applications\sonarr - Copy.service.js">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\services\applications\sonarr - Copy.service.ts">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\settings\radarr\sonarr.component.js">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\settings\radarr\sonarr.component.js.map">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
<Content Update="wwwroot\app\settings\radarr\sonarr.component.ts">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</Content>
</ItemGroup>
</Project> </Project>

View file

@ -9,6 +9,7 @@ using Hangfire.SQLite;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.SpaServices.Webpack;
using Microsoft.AspNetCore.StaticFiles; using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -128,6 +129,10 @@ namespace Ombi
if (env.IsDevelopment()) if (env.IsDevelopment())
{ {
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions
{
HotModuleReplacement = true
});
} }
app.UseHangfireServer(); app.UseHangfireServer();

View file

@ -0,0 +1,2 @@
body {
}

View file

@ -1,4 +1,5 @@
$primary-colour: #df691a; @import '../base.scss';
$primary-colour: #df691a;
$primary-colour-outline: #ff761b; $primary-colour-outline: #ff761b;
$bg-colour: #333333; $bg-colour: #333333;
$bg-colour-disabled: #252424; $bg-colour-disabled: #252424;

View file

@ -1,8 +1,6 @@
@import "./bootstrap.css"; //@import "~primeng/resources/themes/omega/theme.scss";
//@import "./lib/tether.css";
@import "../node_modules/primeng/resources/themes/omega/theme.scss";
@import "../node_modules/@angular/material/prebuilt-themes/deeppurple-amber";
@import "./lib/primeng.css";
$fa-font-path: "../fonts/lib"; /*@import './Themes/plex.scss';*/
@import "../bower_components/font-awesome/scss/font-awesome.scss";
/*$fa-font-path: "../fonts/lib";
@import "../bower_components/font-awesome/scss/font-awesome.scss";*/

View file

@ -1 +1 @@
 <ombi>Loading..</ombi>

View file

@ -0,0 +1,2 @@
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

View file

@ -1,26 +1,17 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Ombi</title> <title>Ombi</title>
<base href="@Url.Content("~/")" /> <base href="/" />
<script src="@Url.Content("~/lib/pace.js")?v=@ViewBag.AssemblyVersion"></script> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link href="@Url.Content("~/css/lib/pace-theme-flash.css")" rel="stylesheet" /> <link rel="stylesheet" href="~/dist/main.css" asp-append-version="true" />
<link href="@Url.Content("~/css/base.css")" rel="stylesheet" type="text/css"/> <link rel="stylesheet" href="~/dist/vendor.css" asp-append-version="true" />
<link href="@Url.Content("~/css/Themes/plex.css")" rel="stylesheet" type="text/css" /> <script src="~/dist/vendor.js" asp-append-version="true" defer></script>
@*<link href="@Url.Content("~/css/lib/primeng.css")" rel="stylesheet" />*@ <script src="~/dist/main.js" asp-append-version="true" defer></script>
</head>
<script src="@Url.Content("~/lib/system.js")?v="></script> <body>
<script src="@Url.Content("~/lib/jquery.js")?v="></script> @RenderBody()
<script src="@Url.Content("~/lib/tether.js")?v="></script> </body>
<script src="@Url.Content("~/lib/bootstrap.js")?v="></script>
<script src="@Url.Content("~/systemjs.config.js")?v="></script>
</head>
<body>
@RenderBody()
<ombi></ombi>
</body>
</html> </html>

View file

@ -1,2 +1,3 @@
@using Ombi @using Ombi
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers @addTagHelper "*, Microsoft.AspNetCore.Mvc.TagHelpers"
@addTagHelper "*, Microsoft.AspNetCore.SpaServices"

View file

@ -1,3 +1,3 @@
@{ @{
Layout = "_Layout"; Layout = "_Layout";
} }

View file

@ -1,337 +1,59 @@
/// <binding BeforeBuild='build' ProjectOpened='watch' /> /// <binding BeforeBuild='build' />
'use strict'; 'use strict';
var gulp = require('gulp');
var sass = require('gulp-sass');
var changed = require('gulp-changed');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var path = require('path');
var del = require('del');
var merge = require('merge-stream');
var gulpif = require('gulp-if');
var runSequence = require('run-sequence');
var cleancss = require('gulp-clean-css');
var filter = require('gulp-filter');
var systemJSBuilder = require('systemjs-builder');
var run = require('gulp-run');
var fs = require('fs');
var wwwroot = './wwwroot'; const gulp = require('gulp');
const run = require('gulp-run');
const runSequence = require('run-sequence');
const del = require('del');
const path = require('path');
var paths = { const outputDir = './wwwroot/dist';
wwwroot: wwwroot,
npm: { // These will be resolved automatically and copied to output directory as its name, only works for pre-bundled modules e.g. angular
src: [
'@angular/animations',
'@angular/animations/browser',
'@angular/core',
'@angular/common',
'@angular/compiler',
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/http',
'@angular/router',
'@angular/forms',
'@angular/platform-browser/animations',
'@angular/material',
'@ng-bootstrap/ng-bootstrap',
'ngx-infinite-scroll'
],
dest: './lib'
},
lib: { // These are simple single-file dependencies with optional rename, for more files or folders use modules
src: [
{
file: './node_modules/systemjs/dist/system.src.js',
rename: 'system'
},
{
file: './node_modules/systemjs/dist/system-polyfills.src.js',
rename: 'system-polyfills'
},
{
file: './node_modules/jquery/dist/jquery.min.js',
rename: 'jquery'
},
'./bower_components/PACE/pace.js',
'./node_modules/bootstrap/dist/js/bootstrap.js',
'./node_modules/tether/dist/js/tether.js',
'./node_modules/angular2-jwt/angular2-jwt.js',
'./node_modules/dragula/dist/dragula.js'
function getEnvOptions() {
], var options = [];
dest: './lib/' if (global.prod) {
}, options.push('--env.prod');
libcss: [ // Normal css files to be copied }
{ if (global.analyse) {
src: [ options.push('--env.analyse');
'./bower_components/font-awesome/css/font-awesome.css', }
'./bower_components/PACE/themes/orange/pace-theme-barber-shop.css', if (options.length > 0) {
'./bower_components/PACE/themes/orange/pace-theme-big-counter.css', return " " + options.join(" ");
'./bower_components/PACE/themes/orange/pace-theme-fill-left.css', } else {
'./bower_components/PACE/themes/orange/pace-theme-flash.css', return "";
'./bower_components/PACE/themes/orange/pace-theme-flat-top.css',
'./bower_components/PACE/themes/orange/pace-theme-loading-bar.css',
'./node_modules/primeng/resources/primeng.css',
'./node_modules/tether/dist/css/tether.css',
'./node_modules/@angular/material/prebuilt-themes/deeppurple-amber.css',
'./node_modules/dragula/dist/dragula.js'
],
dest: './css/lib/'
},
{
src: './Styles/**/*.css',
dest: './css',
filter: '**/*.css'
}
],
libfonts: [ // Library fonts
{
src: [
'./bower_components/font-awesome/fonts/*'
],
dest: './fonts/lib/'
},
{
src: [
'./node_modules/primeng/resources/themes/omega/fonts/*'
],
dest: './css/fonts/'
}
],
libimages: [ // Library images
{
src: [
'./node_modules/primeng/resources/themes/omega/images/*'
],
dest: './images/'
}
],
modules: [ // This is for modules with multiple files that require each other, used when npm can't be used
{
name: 'zone.js',
src: ['./node_modules/zone.js/**/*.js'],
dest: './lib/zone.js/'
},
{
name: 'rxjs',
src: ['./node_modules/rxjs/**/*.js', '!./node_modules/rxjs/src/**/*.js'],
dest: './lib/rxjs/'
},
{
name: 'core-js',
src: ['./node_modules/core-js/**/*.js'],
dest: './lib/core-js/'
},
{
name: 'primeng',
src: './node_modules/primeng/**/*.js',
dest: './lib/primeng/'
},
{
name: 'ng2-dragula',
src: './node_modules/ng2-dragula/**/*.js',
dest: './lib/ng2-dragula/'
}
],
sass: // Simple sass->css compilation
{
src: ['./Styles/**/*.scss', '!./Styles/primeng/**'],
dest: './css/',
filter: '**/*.css'
},
bundle: { // This is the config for the bundler, you shouldn't need to change this
root: './',
dest: './lib/bundle.js',
bundle: 'app/main.js',
app: 'app/**/*',
config: {
baseURL: wwwroot,
packages: {
'.': {
defaultExtension: 'js'
}
},
map: {
text: 'app/text-loader'
},
meta: {
'*.css': {
loader: 'text'
},
'*.html': {
loader: 'text'
}
},
paths: {
'*': 'lib/*',
'app/*': 'app/*'
}
}
} }
} }
gulp.task('npm', function () { gulp.task('vendor', function () {
var streams = [] return run('webpack --config webpack.config.vendor.js' + getEnvOptions()).exec();
for (let module of paths.npm.src) {
let file = require.resolve(module);
streams.push(
gulp.src(file)
.pipe(gulpif(global.full, sourcemaps.init()))
.pipe(gulpif(global.full, uglify({ source_map: true })))
.pipe(rename((path => { path.basename = module })))
.pipe(gulpif(global.full, sourcemaps.write('../maps')))
.pipe(gulp.dest(path.join(paths.wwwroot, paths.npm.dest)))
);
}
return merge(streams);
})
gulp.task('lib', function () {
var streams = []
for (let module of paths.lib.src) {
streams.push(
gulp.src(typeof module === "string" ? module : module.file)
.pipe(gulpif(global.full, sourcemaps.init()))
.pipe(gulpif(global.full, uglify({ source_map: true })))
.pipe(rename(function (path) {
if (typeof module !== "string" && module.rename) {
path.basename = module.rename;
}
}))
.pipe(gulpif(global.full, sourcemaps.write('maps')))
.pipe(gulp.dest(path.join(paths.wwwroot, paths.lib.dest)))
);
}
return merge(streams);
})
gulp.task('libcss', function () {
var streams = []
for (let module of paths.libcss) {
var f = filter("**/*.css", { restore: true });
streams.push(
gulp.src(module.src)
.pipe(f)
.pipe(gulpif(global.full, sourcemaps.init()))
.pipe(gulpif(global.full, cleancss()))
.pipe(gulpif(global.full, sourcemaps.write(`${module.name ? '.' : ''}./maps/${module.name ? module.name : ''}`)))
.pipe(f.restore)
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
);
}
return merge(streams);
})
gulp.task('libfonts', function () {
var streams = []
for (let module of paths.libfonts) {
streams.push(
gulp.src(module.src)
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
);
}
return merge(streams);
})
gulp.task('libimages', function () {
var streams = []
for (let module of paths.libimages) {
streams.push(
gulp.src(module.src)
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
);
}
return merge(streams);
})
gulp.task('modules', function () {
var streams = []
for (let module of paths.modules) {
streams.push(
gulp.src(module.src)
.pipe(gulpif(global.full, sourcemaps.init()))
.pipe(gulpif(global.full, uglify({ source_map: true })))
.pipe(gulpif(global.full, sourcemaps.write(`${module.name ? '.' : ''}./maps/${module.name ? module.name : ''}`)))
.pipe(gulp.dest(path.join(paths.wwwroot, module.dest)))
);
}
return merge(streams);
})
gulp.task('sass', function () {
return gulp.src(paths.sass.src)
.pipe(changed(paths.sass.dest))
.pipe(gulpif(global.full, sourcemaps.init()))
.pipe(sass({ outputStyle: global.full ? 'compressed' : 'nested' }).on('error', sass.logError))
.pipe(gulpif(global.full, sourcemaps.write('maps')))
.pipe(gulp.dest(path.join(paths.wwwroot, paths.sass.dest)))
}); });
gulp.task('main', function () {
gulp.task('bundle', ['typescript_firstrun'], function () { return run('webpack --config webpack.config.js' + getEnvOptions()).exec();
var builder = new systemJSBuilder(paths.bundle.root);
builder.config(paths.bundle.config);
del.sync(path.join(paths.wwwroot, paths.bundle.dest), { force: true });
return builder.bundle(paths.bundle.bundle + (global.full ? '' : ' - [' + paths.bundle.app + ']'), path.join(paths.wwwroot, paths.bundle.dest), {
sourceMaps: global.full
})
})
gulp.task('clean', function () {
return del([
paths.sass.dest + paths.sass.filter,
paths.lib.dest,
paths.bundle.dest,
...paths.modules.map(m => m.dest),
...paths.libcss.map(m => m.dest + (m.filter ? m.filter : '')),
...paths.libfonts.map(m => m.dest)
].map(x => path.join(paths.wwwroot, x)), { force: true });
})
// Runs the TypeScript compiler
function runTSC() {
return run('tsc').exec();
}
// Allows app to bundle libs on first run by compiling the app first, only compiles if entry point doesn't exist
gulp.task('typescript_firstrun', function () {
var bundle = path.join(paths.wwwroot, paths.bundle.bundle);
var exists = fs.existsSync(bundle);
if (!exists) {
console.log(`'${bundle}' doesn't exist - compiling TypeScript`);
return runTSC();
}
})
gulp.task('typescript', function () {
return runTSC();
}); });
uglify().on('error', gulp.task('test_compile', function () {
function(err) { return run('webpack boot-tests=./ClientApp/test/boot-tests.ts' + getEnvOptions()).exec();
gutil.log(gutil.colors.red('[Error]'), err.toString());
this.emit('end');
});
gulp.task('fullvar', () => { global.full = true });
gulp.task('copy', ['lib', 'libcss', 'libfonts', 'libimages', 'npm', 'modules']);
gulp.task('compile', callback => runSequence('copy', 'sass', callback));
gulp.task('build', callback => runSequence('compile', 'bundle', callback));
gulp.task('full', callback => runSequence('clean', 'compile', callback));
// Use this in a build server environment to compile and bundle everything
gulp.task('publish', callback => runSequence('fullvar', 'full', 'typescript', 'bundle', callback));
// Auto compiles sass files on change, note that this doesn't seem to pick up new files at the moment
gulp.task('watch', function () {
gulp.watch(paths.sass.src, ['sass']);
gulp.watch('./Styles/**/*.css', ['libcss']); // legacy css
}); });
gulp.task('test_run', function () {
return run('karma start ClientApp/test/karma.conf.js').exec();
});
gulp.task('prod_var', function () {
global.prod = true;
})
gulp.task('analyse_var', function () {
global.analyse = true;
})
gulp.task('clean', function() {
del.sync(outputDir, { force: true });
});
gulp.task('test', callback => runSequence('test_compile', 'test_run'));
gulp.task('build', callback => runSequence('vendor', 'main', callback));
gulp.task('analyse', callback => runSequence('analyse_var', 'build'));
gulp.task('full', callback => runSequence('clean', 'build'));
gulp.task('publish', callback => runSequence('prod_var', 'build'));

File diff suppressed because it is too large Load diff

View file

@ -1,51 +1,74 @@
{ {
"name": "ombi", "name": "Ombi",
"version": "1.0.0",
"private": true, "private": true,
"version": "1.0.0",
"scripts": {
"test": "gulp test"
},
"dependencies": { "dependencies": {
"@angular/animations": "^4.1.0", "@angular/animations": "4.1.3",
"@angular/common": "^4.1.0", "@angular/common": "^4.1.3",
"@angular/compiler": "^4.1.0", "@angular/compiler": "4.1.3",
"@angular/compiler-cli": "^4.1.0", "@angular/core": "4.1.3",
"@angular/core": "^4.1.0", "@angular/forms": "4.1.3",
"@angular/forms": "^4.1.0", "@angular/http": "4.1.3",
"@angular/http": "^4.1.0", "@angular/material": "2.0.0-beta.5",
"@angular/material": "^2.0.0-beta.3", "@angular/platform-browser": "4.1.3",
"@angular/platform-browser": "^4.1.0", "@angular/platform-browser-dynamic": "4.1.3",
"@angular/platform-browser-dynamic": "^4.1.0", "@angular/platform-server": "4.1.3",
"@angular/platform-server": "^4.1.0", "@angular/router": "4.1.3",
"@angular/router": "^4.1.0", "@covalent/core": "^1.0.0-beta.4",
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.25", "@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.26",
"@types/jquery": "^2.0.33", "@types/core-js": "^0.9.41",
"@types/systemjs": "^0.20.2", "@types/node": "7.0.23",
"angular2-jwt": "^0.2.0", "angular2-jwt": "^0.2.3",
"angular2-moment": "^1.3.3", "angular2-moment": "^1.3.3",
"bootstrap": "3.3.6", "angular2-template-loader": "0.6.2",
"aspnet-webpack": "^1.0.29",
"awesome-typescript-loader": "3.1.3",
"bootstrap": "^3.3.7",
"bootswatch": "^3.3.7",
"core-js": "^2.4.1", "core-js": "^2.4.1",
"css": "2.2.1",
"css-loader": "0.28.4",
"del": "^2.2.2", "del": "^2.2.2",
"gulp": "~3.9.1", "event-source-polyfill": "0.0.9",
"gulp-changed": "^1.3.0", "expose-loader": "0.7.3",
"gulp-clean-css": "^3.0.4", "extract-text-webpack-plugin": "^2.1.0",
"gulp-filter": "^5.0.0", "file-loader": "0.11.1",
"gulp-if": "^2.0.2", "font-awesome": "^4.7.0",
"gulp-rename": "^1.2.2", "gulp": "^3.9.1",
"gulp-run": "^1.7.1", "gulp-run": "^1.7.1",
"gulp-sass": "^2.3.2", "hammerjs": "^2.0.8",
"gulp-sourcemaps": "^1.9.0", "html-loader": "0.4.5",
"gulp-systemjs-builder": "^0.15.0", "jquery": "3.2.1",
"gulp-uglify": "^1.5.4", "ng2-dragula": "^1.5.0",
"jquery": "2.2.1", "ngx-infinite-scroll": "^0.5.1",
"merge-stream": "^1.0.1", "node-sass": "^4.5.3",
"nanoscroller": "^0.8.7", "pace-progress": "^1.0.2",
"ng2-dragula": "^1.3.1", "primeng": "^4.0.3",
"ngx-infinite-scroll": "^0.4.1", "reflect-metadata": "0.1.10",
"primeng": "^2.0.5",
"run-sequence": "^1.2.2", "run-sequence": "^1.2.2",
"rxjs": "^5.0.3", "rxjs": "5.4.0",
"systemjs": "^0.19.41", "sass-loader": "^6.0.5",
"systemjs-builder": "^0.15.34", "to-string-loader": "1.1.5",
"tether": "^1.4.0", "typescript": "2.3.4",
"typescript": "^2.3.0", "url-loader": "0.5.8",
"zone.js": "^0.8.5" "webpack": "^2.6.1",
"webpack-bundle-analyzer": "^2.8.2",
"webpack-hot-middleware": "2.18.0",
"zone.js": "0.8.11"
},
"devDependencies": {
"@types/chai": "4.0.0",
"@types/jasmine": "2.5.48",
"chai": "4.0.1",
"jasmine-core": "2.6.2",
"karma": "1.7.0",
"karma-chai": "0.1.0",
"karma-chrome-launcher": "2.1.1",
"karma-cli": "1.0.1",
"karma-jasmine": "1.1.0",
"karma-webpack": "2.0.3"
} }
} }

View file

@ -1,8 +1,7 @@
{ {
"compilerOptions": { "compilerOptions": {
"target": "es5", "target": "es5",
"lib": [ "es5", "es2015" ], "lib": [ "es6", "dom" ],
"module": "commonjs",
"moduleResolution": "node", "moduleResolution": "node",
"sourceMap": true, "sourceMap": true,
"strictNullChecks": true, "strictNullChecks": true,
@ -16,5 +15,5 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"skipLibCheck": true "skipLibCheck": true
}, },
"compileOnSave": true "exclude": [ "bin", "node_modules" ]
} }

Some files were not shown because too many files have changed in this diff Show more