Client: add requests stats page

pull/10/head
Chocobozzz 2016-09-23 17:09:38 +02:00
parent ccc64aa679
commit eb4f957eca
16 changed files with 168 additions and 1 deletions

3
.gitignore vendored
View File

@ -15,3 +15,6 @@ thumbnails
config/production.yaml
ffmpeg
.tags
*.sublime-project
*.sublime-workspace
torrent/

View File

@ -2,6 +2,7 @@ import { Routes } from '@angular/router';
import { AdminComponent } from './admin.component';
import { FriendsRoutes } from './friends';
import { RequestsRoutes } from './requests';
import { UsersRoutes } from './users';
export const AdminRoutes: Routes = [
@ -15,6 +16,7 @@ export const AdminRoutes: Routes = [
pathMatch: 'full'
},
...FriendsRoutes,
...RequestsRoutes,
...UsersRoutes
]
}

View File

@ -1,4 +1,5 @@
export * from './friends';
export * from './requests';
export * from './users';
export * from './admin.component';
export * from './admin.routes';

View File

@ -10,6 +10,11 @@
<span class="hidden-xs glyphicon glyphicon-cloud"></span>
<a [routerLink]="['/admin/friends/list']">List friends</a>
</div>
<div id="panel-request-stats" class="panel-button">
<span class="hidden-xs glyphicon glyphicon-stats"></span>
<a [routerLink]="['/admin/requests/stats']">Request stats</a>
</div>
</div>
<div class="panel-block">

View File

@ -0,0 +1,4 @@
export * from './request-stats';
export * from './shared';
export * from './requests.component';
export * from './requests.routes';

View File

@ -0,0 +1 @@
export * from './request-stats.component';

View File

@ -0,0 +1,18 @@
<h3>Requests stats</h3>
<div *ngIf="stats !== null">
<div>
<span class="label-description">Interval seconds between requests:</span>
{{ secondsInterval }}
</div>
<div>
<span class="label-description">Remaining time before the scheduled request:</span>
{{ remainingSeconds }}
</div>
<div>
<span class="label-description">Total requests:</span>
{{ stats.requests.length }}
</div>
</div>

View File

@ -0,0 +1,6 @@
.label-description {
display: inline-block;
width: 350px;
font-weight: bold;
color: black;
}

View File

@ -0,0 +1,59 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { RequestService, RequestStats } from '../shared';
@Component({
selector: 'my-request-stats',
templateUrl: './request-stats.component.html',
styleUrls: [ './request-stats.component.scss' ]
})
export class RequestStatsComponent implements OnInit, OnDestroy {
stats: RequestStats = null;
private interval: NodeJS.Timer = null;
constructor(private requestService: RequestService) { }
ngOnInit() {
this.getStats();
}
ngOnDestroy() {
if (this.secondsInterval !== null) {
clearInterval(this.interval);
}
}
get remainingSeconds() {
return Math.floor(this.stats.remainingMilliSeconds / 1000);
}
get secondsInterval() {
return Math.floor(this.stats.milliSecondsInterval / 1000);
}
getStats() {
this.requestService.getStats().subscribe(
stats => {
console.log(stats);
this.stats = stats;
this.runInterval();
},
err => alert(err)
);
}
private runInterval() {
this.interval = setInterval(() => {
this.stats.remainingMilliSeconds -= 1000;
if (this.stats.remainingMilliSeconds <= 0) {
setTimeout(() => this.getStats(), this.stats.remainingMilliSeconds + 100);
clearInterval(this.interval);
}
}, 1000);
}
}

View File

@ -0,0 +1,8 @@
import { Component } from '@angular/core';
@Component({
template: '<router-outlet></router-outlet>'
})
export class RequestsComponent {
}

View File

@ -0,0 +1,22 @@
import { Routes } from '@angular/router';
import { RequestsComponent } from './requests.component';
import { RequestStatsComponent } from './request-stats';
export const RequestsRoutes: Routes = [
{
path: 'requests',
component: RequestsComponent,
children: [
{
path: '',
redirectTo: 'stats',
pathMatch: 'full'
},
{
path: 'stats',
component: RequestStatsComponent
}
]
}
];

View File

@ -0,0 +1,2 @@
export * from './request-stats.model';
export * from './request.service';

View File

@ -0,0 +1,8 @@
export interface RequestStats {
milliSecondsInterval: number;
remainingMilliSeconds: number;
requests: {
request: any,
to: any
}[];
}

View File

@ -0,0 +1,21 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { RequestStats } from './request-stats.model';
import { AuthHttp, RestExtractor } from '../../../shared';
@Injectable()
export class RequestService {
private static BASE_REQUEST_URL: string = '/api/v1/requests/';
constructor (
private authHttp: AuthHttp,
private restExtractor: RestExtractor
) {}
getStats(): Observable<RequestStats> {
return this.authHttp.get(RequestService.BASE_REQUEST_URL + 'stats')
.map(this.restExtractor.extractDataGet)
.catch((res) => this.restExtractor.handleError(res));
}
}

View File

@ -26,6 +26,9 @@ import {
FriendListComponent,
FriendService,
MenuAdminComponent,
RequestsComponent,
RequestStatsComponent,
RequestService,
UsersComponent,
UserAddComponent,
UserListComponent,
@ -66,6 +69,7 @@ const APP_PROVIDERS = [
VideoService,
SearchService,
FriendService,
RequestService,
UserService,
AccountService,
WebTorrentService
@ -88,6 +92,8 @@ const APP_PROVIDERS = [
LoginComponent,
MenuAdminComponent,
MenuComponent,
RequestsComponent,
RequestStatsComponent,
SearchComponent,
UserAddComponent,
UserListComponent,

View File

@ -32,7 +32,8 @@ function getStatsRequests (req, res, next) {
return res.json({
requests: requests,
remainingMilliSeconds: remainingMilliSeconds
remainingMilliSeconds: remainingMilliSeconds,
milliSecondsInterval: constants.REQUESTS_INTERVAL
})
})
}