wip on the system logs page

pull/3895/head
Jamie Rees 5 years ago
parent ac1266bf6e
commit b6c53a69fa

@ -17,6 +17,7 @@ export class MoviesGridComponent implements AfterViewInit {
public isLoadingResults = true; public isLoadingResults = true;
public displayedColumns: string[] = ['requestedUser.requestedBy', 'title', 'requestedDate', 'status', 'requestStatus', 'actions']; public displayedColumns: string[] = ['requestedUser.requestedBy', 'title', 'requestedDate', 'status', 'requestStatus', 'actions'];
public gridCount: string = "15"; public gridCount: string = "15";
public showUnavailableRequests: boolean;
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator; @ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
@ViewChild(MatSort, {static: false}) sort: MatSort; @ViewChild(MatSort, {static: false}) sort: MatSort;
@ -41,7 +42,7 @@ export class MoviesGridComponent implements AfterViewInit {
this.isLoadingResults = true; this.isLoadingResults = true;
// eturn this.exampleDatabase!.getRepoIssues( // eturn this.exampleDatabase!.getRepoIssues(
// this.sort.active, this.sort.direction, this.paginator.pageIndex); // this.sort.active, this.sort.direction, this.paginator.pageIndex);
return this.requestService.getMovieRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); return this.loadData();
}), }),
map((data: IRequestsViewModel<IMovieRequests>) => { map((data: IRequestsViewModel<IMovieRequests>) => {
// Flip flag to show that loading has finished. // Flip flag to show that loading has finished.
@ -56,4 +57,12 @@ export class MoviesGridComponent implements AfterViewInit {
}) })
).subscribe(data => this.dataSource = data); ).subscribe(data => this.dataSource = data);
} }
public loadData(): Observable<IRequestsViewModel<IMovieRequests>> {
if (this.showUnavailableRequests) {
return this.requestService.getMovieUnavailableRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction);
} else {
return this.requestService.getMovieRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction);
}
}
} }

@ -1,7 +1,7 @@
import { Component, AfterViewInit, ViewChild } from "@angular/core"; import { Component, AfterViewInit, ViewChild } from "@angular/core";
import { IRequestsViewModel, ITvRequests, IChildRequests } from "../../../interfaces"; import { IRequestsViewModel, IChildRequests } from "../../../interfaces";
import { MatPaginator, MatSort } from "@angular/material"; import { MatPaginator, MatSort } from "@angular/material";
import { merge, Observable, of as observableOf } from 'rxjs'; import { merge, of as observableOf, Observable } from 'rxjs';
import { catchError, map, startWith, switchMap } from 'rxjs/operators'; import { catchError, map, startWith, switchMap } from 'rxjs/operators';
import { RequestServiceV2 } from "../../../services/requestV2.service"; import { RequestServiceV2 } from "../../../services/requestV2.service";
@ -17,6 +17,7 @@ export class TvGridComponent implements AfterViewInit {
public isLoadingResults = true; public isLoadingResults = true;
public displayedColumns: string[] = ['series', 'requestedBy', 'status', 'requestStatus', 'requestedDate','actions']; public displayedColumns: string[] = ['series', 'requestedBy', 'status', 'requestStatus', 'requestedDate','actions'];
public gridCount: string = "15"; public gridCount: string = "15";
public showUnavailableRequests: boolean;
@ViewChild(MatPaginator, {static: false}) paginator: MatPaginator; @ViewChild(MatPaginator, {static: false}) paginator: MatPaginator;
@ViewChild(MatSort, {static: false}) sort: MatSort; @ViewChild(MatSort, {static: false}) sort: MatSort;
@ -35,7 +36,7 @@ export class TvGridComponent implements AfterViewInit {
startWith({}), startWith({}),
switchMap(() => { switchMap(() => {
this.isLoadingResults = true; this.isLoadingResults = true;
return this.requestService.getTvRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction); return this.loadData();
}), }),
map((data: IRequestsViewModel<IChildRequests>) => { map((data: IRequestsViewModel<IChildRequests>) => {
// Flip flag to show that loading has finished. // Flip flag to show that loading has finished.
@ -50,4 +51,12 @@ export class TvGridComponent implements AfterViewInit {
}) })
).subscribe(data => this.dataSource = data); ).subscribe(data => this.dataSource = data);
} }
private loadData(): Observable<IRequestsViewModel<IChildRequests>> {
if(this.showUnavailableRequests) {
return this.requestService.getTvUnavailableRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction);
} else {
return this.requestService.getTvRequests(+this.gridCount, this.paginator.pageIndex * +this.gridCount, this.sort.active, this.sort.direction);
}
}
} }

@ -0,0 +1,35 @@
import { APP_BASE_HREF } from "@angular/common";
import { Injectable, Inject } from "@angular/core";
import { HttpClient } from "@angular/common/http";
import { ServiceHelpers } from "./service.helpers";
@Injectable()
export class FileDownloadService extends ServiceHelpers {
constructor(http: HttpClient, @Inject(APP_BASE_HREF) href:string) {
super(http, "/api/v2/system/", href);
}
downloadFile(url: string, contentType: string): void {
this.http.get(url).subscribe((response: any) => {
// It is necessary to create a new blob object with mime-type explicitly set
// otherwise only Chrome works like it should
const newBlob = new Blob([(response)], { type: contentType });
// IE doesn't allow using a blob object directly as link href
// instead it is necessary to use msSaveOrOpenBlob
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(newBlob);
return;
}
// For other browsers:
// Create a link pointing to the ObjectURL containing the blob.
const downloadURL = URL.createObjectURL(response);
window.open(downloadURL);
});
}
}

@ -20,3 +20,5 @@ export * from "./searchV2.service";
export * from "./custompage.service"; export * from "./custompage.service";
export * from "./message.service"; export * from "./message.service";
export * from "./hub.service"; export * from "./hub.service";
export * from "./system.service";
export * from "./filedownload.service";

@ -0,0 +1,21 @@
import { APP_BASE_HREF } from "@angular/common";
import { Injectable, Inject } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { Observable } from "rxjs";
import { ServiceHelpers } from "./service.helpers";
@Injectable()
export class SystemService extends ServiceHelpers {
constructor(http: HttpClient, @Inject(APP_BASE_HREF) href:string) {
super(http, "/api/v2/system/", href);
}
public getAvailableLogs(): Observable<string[]> {
return this.http.get<string[]>(`${this.url}logs/`, {headers: this.headers});
}
public getLog(logName: string): Observable<string> {
return this.http.get(`${this.url}logs/${logName}`, {responseType: 'text'});
}
}

@ -0,0 +1,19 @@
<settings-menu></settings-menu>
<div *ngIf="logs" class="small-middle-container">
<legend>Logs</legend>
<mat-tab-group (selectedTabChange)="logDetail = null">
<mat-tab *ngFor="let log of logs" label="{{log}}">
<ng-template matTabContent>
<button mat-raised-button color="primary" (click)="loadLog(log);">Load</button>
<pre class="code-block">
<code>
{{logDetail}}
</code>
</pre>
</ng-template>
</mat-tab>
</mat-tab-group>
</div>

@ -0,0 +1,8 @@
.small-middle-container{
margin: auto;
width: 80%;
}
.code-block {
font-size: 10px;
}

@ -0,0 +1,23 @@

import { Component, OnInit } from "@angular/core";
import { SystemService } from "../../services";
@Component({
templateUrl: "./logs.component.html",
styleUrls:["./logs.component.scss"]
})
export class LogsComponent implements OnInit {
public logs: string[];
public logDetail: string;
constructor(private readonly systemService: SystemService) { }
public async ngOnInit() {
this.logs = await this.systemService.getAvailableLogs().toPromise();
}
public async loadLog(logName: string) {
this.logDetail = await this.systemService.getLog(logName).toPromise();
}
}

@ -9,7 +9,7 @@ import { AuthGuard } from "../auth/auth.guard";
import { AuthService } from "../auth/auth.service"; import { AuthService } from "../auth/auth.service";
import { import {
CouchPotatoService, EmbyService, IssuesService, JobService, LidarrService, MobileService, NotificationMessageService, PlexService, RadarrService, CouchPotatoService, EmbyService, IssuesService, JobService, LidarrService, MobileService, NotificationMessageService, PlexService, RadarrService,
RequestRetryService, SonarrService, TesterService, ValidationService, RequestRetryService, SonarrService, TesterService, ValidationService, SystemService, FileDownloadService,
} from "../services"; } from "../services";
import { PipeModule } from "../pipes/pipe.module"; import { PipeModule } from "../pipes/pipe.module";
@ -52,6 +52,7 @@ import { AutoCompleteModule, CalendarModule, DialogModule, InputSwitchModule, In
import { MatMenuModule} from "@angular/material"; import { MatMenuModule} from "@angular/material";
import { SharedModule } from "../shared/shared.module"; import { SharedModule } from "../shared/shared.module";
import { HubService } from "../services/hub.service"; import { HubService } from "../services/hub.service";
import { LogsComponent } from "./logs/logs.component";
const routes: Routes = [ const routes: Routes = [
{ path: "Ombi", component: OmbiComponent, canActivate: [AuthGuard] }, { path: "Ombi", component: OmbiComponent, canActivate: [AuthGuard] },
@ -84,6 +85,7 @@ const routes: Routes = [
{ path: "Lidarr", component: LidarrComponent, canActivate: [AuthGuard] }, { path: "Lidarr", component: LidarrComponent, canActivate: [AuthGuard] },
{ path: "Vote", component: VoteComponent, canActivate: [AuthGuard] }, { path: "Vote", component: VoteComponent, canActivate: [AuthGuard] },
{ path: "FailedRequests", component: FailedRequestsComponent, canActivate: [AuthGuard] }, { path: "FailedRequests", component: FailedRequestsComponent, canActivate: [AuthGuard] },
{ path: "Logs", component: LogsComponent, canActivate: [AuthGuard] },
]; ];
@NgModule({ @NgModule({
@ -141,6 +143,7 @@ const routes: Routes = [
LidarrComponent, LidarrComponent,
VoteComponent, VoteComponent,
FailedRequestsComponent, FailedRequestsComponent,
LogsComponent,
], ],
exports: [ exports: [
RouterModule, RouterModule,
@ -162,6 +165,8 @@ const routes: Routes = [
LidarrService, LidarrService,
RequestRetryService, RequestRetryService,
HubService, HubService,
SystemService,
FileDownloadService
], ],
}) })

@ -56,7 +56,7 @@
<button mat-menu-item [routerLink]="['/Settings/FailedRequests']">Failed Requests</button> <button mat-menu-item [routerLink]="['/Settings/FailedRequests']">Failed Requests</button>
<button mat-menu-item [routerLink]="['/Settings/Update']">Update</button> <button mat-menu-item [routerLink]="['/Settings/Update']">Update</button>
<button mat-menu-item [routerLink]="['/Settings/Jobs']">Scheduled Tasks</button> <button mat-menu-item [routerLink]="['/Settings/Jobs']">Scheduled Tasks</button>
<button mat-menu-item [routerLink]="['/Settings/Jobs']">Logs</button> <button mat-menu-item [routerLink]="['/Settings/Logs']">Logs</button>
</mat-menu> </mat-menu>
<hr/> <hr/>
Loading…
Cancel
Save