mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-30 03:28:28 -07:00
wip on the system logs page
This commit is contained in:
parent
ac1266bf6e
commit
b6c53a69fa
10 changed files with 137 additions and 6 deletions
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
35
src/Ombi/ClientApp/src/app/services/filedownload.service.ts
Normal file
35
src/Ombi/ClientApp/src/app/services/filedownload.service.ts
Normal file
|
@ -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";
|
||||||
|
|
21
src/Ombi/ClientApp/src/app/services/system.service.ts
Normal file
21
src/Ombi/ClientApp/src/app/services/system.service.ts
Normal file
|
@ -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'});
|
||||||
|
}
|
||||||
|
}
|
19
src/Ombi/ClientApp/src/app/settings/logs/logs.component.html
Normal file
19
src/Ombi/ClientApp/src/app/settings/logs/logs.component.html
Normal file
|
@ -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;
|
||||||
|
}
|
23
src/Ombi/ClientApp/src/app/settings/logs/logs.component.ts
Normal file
23
src/Ombi/ClientApp/src/app/settings/logs/logs.component.ts
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue