translated logs page

This commit is contained in:
simon987 2019-02-05 21:16:06 -05:00
parent 87f4d08984
commit a02a5c83ed
10 changed files with 153 additions and 63 deletions

View File

@ -0,0 +1,28 @@
import {MatPaginatorIntl} from "@angular/material";
import {TranslateService} from "@ngx-translate/core";
export function TranslatedPaginator(translate: TranslateService) {
const paginatorIntl = new MatPaginatorIntl();
getTranslations(translate, paginatorIntl);
translate.onLangChange.subscribe(() => {
getTranslations(translate, paginatorIntl)
});
return paginatorIntl;
}
function getTranslations(tr: TranslateService, p: MatPaginatorIntl) {
tr.get("logs.first_page_label").subscribe((t) => p.firstPageLabel = t);
tr.get("logs.last_page_label").subscribe((t) => p.lastPageLabel = t);
tr.get("logs.items_per_page").subscribe((t) => p.itemsPerPageLabel = t);
tr.get("logs.next_page").subscribe((t) => p.nextPageLabel = t);
tr.get("logs.prev_page").subscribe((t) => p.previousPageLabel = t);
tr.get("logs.of").subscribe((of) =>
p.getRangeLabel = (page, pageSize, length) => `${page * pageSize + 1}-${Math.min(pageSize * (page + 1), length)} ${of} ${length}`
);
}

View File

@ -13,7 +13,7 @@ export class ApiService {
} }
getLogs() { getLogs() {
return this.http.post(this.url + "/logs", "{\"level\":\"info\", \"since\":10000}"); return this.http.post(this.url + "/logs", "{\"level\":6, \"since\":1}");
} }
getProjects() { getProjects() {

View File

@ -1,3 +1,10 @@
.nav-spacer { .nav-spacer {
flex: 1 1 auto; flex: 1 1 auto;
} }
.icon {
padding: 0 14px;
}
.nav-link {
}

View File

@ -1,8 +1,9 @@
<mat-toolbar color="primary"> <mat-toolbar color="primary">
<span>{{ "nav.title" | translate }}</span> <button mat-button class="nav-title" [routerLink]="''">{{"nav.title" | translate}}</button>
<button mat-button class="nav-link" [routerLink]="'log'">{{"nav.logs" | translate}}</button>
<button mat-button class="nav-link" [routerLink]="'projects'">{{"nav.project_list" | translate}}</button>
<button mat-button class="nav-link" [routerLink]="'new_project'">{{"nav.new_project" | translate}}</button>
<span class="nav-spacer"></span> <span class="nav-spacer"></span>
<mat-icon class="example-icon">favorite</mat-icon>
<mat-icon class="example-icon">delete</mat-icon>
<mat-form-field [floatLabel]="'never'"> <mat-form-field [floatLabel]="'never'">
<mat-select [placeholder]="'nav.langSelect' | translate" (selectionChange)="langChange($event)"> <mat-select [placeholder]="'nav.langSelect' | translate" (selectionChange)="langChange($event)">
<mat-option *ngFor="let lang of langList" [value]="lang.lang"> <mat-option *ngFor="let lang of langList" [value]="lang.lang">
@ -12,12 +13,6 @@
</mat-form-field> </mat-form-field>
</mat-toolbar> </mat-toolbar>
<ul>
<li><a [routerLink]="''">Index</a></li>
<li><a [routerLink]="'log'">Logs</a></li>
<li><a [routerLink]="'projects'">list</a></li>
<li><a [routerLink]="'new_project'">new project</a></li>
</ul>
<messenger-snack-bar></messenger-snack-bar> <messenger-snack-bar></messenger-snack-bar>

View File

@ -17,6 +17,7 @@ import {
MatIconModule, MatIconModule,
MatInputModule, MatInputModule,
MatMenuModule, MatMenuModule,
MatPaginatorIntl,
MatPaginatorModule, MatPaginatorModule,
MatSelectModule, MatSelectModule,
MatSliderModule, MatSliderModule,
@ -36,8 +37,9 @@ import {CreateProjectComponent} from './create-project/create-project.component'
import {FormsModule, ReactiveFormsModule} from "@angular/forms"; import {FormsModule, ReactiveFormsModule} from "@angular/forms";
import {UpdateProjectComponent} from './update-project/update-project.component'; import {UpdateProjectComponent} from './update-project/update-project.component';
import {SnackBarComponent} from "./messenger/snack-bar.component"; import {SnackBarComponent} from "./messenger/snack-bar.component";
import {TranslateLoader, TranslateModule} from "@ngx-translate/core"; import {TranslateLoader, TranslateModule, TranslateService} from "@ngx-translate/core";
import {TranslateHttpLoader} from "@ngx-translate/http-loader"; import {TranslateHttpLoader} from "@ngx-translate/http-loader";
import {TranslatedPaginator} from "./TranslatedPaginatorConfiguration";
export function createTranslateLoader(http: HttpClient) { export function createTranslateLoader(http: HttpClient) {
@ -95,6 +97,7 @@ export function createTranslateLoader(http: HttpClient) {
providers: [ providers: [
ApiService, ApiService,
MessengerService, MessengerService,
{provide: MatPaginatorIntl, useFactory: TranslatedPaginator, deps: [TranslateService]}
], ],
entryComponents: [ entryComponents: [
SnackBarComponent, SnackBarComponent,

View File

@ -1,32 +1,40 @@
<div class="table-container"> <div class="container">
<mat-form-field> <div class="table-container">
<input matInput (keyup)="applyFilter($event.target.value)" placeholder="Filter"> <mat-form-field>
</mat-form-field> <input matInput (keyup)="applyFilter($event.target.value)" [placeholder]="'logs.filter' | translate">
<mat-table [dataSource]="data" class="mat-elevation-z8" matSort matSortActive="timestamp" matSortDirection="desc"> </mat-form-field>
<div class="mat-elevation-z8">
<ng-container matColumnDef="level"> <mat-table [dataSource]="data" matSort matSortActive="timestamp"
<mat-header-cell style="flex: 0 0 6em" mat-sort-header *matHeaderCellDef>Level</mat-header-cell> matSortDirection="desc">
<mat-cell style="flex: 0 0 6em" *matCellDef="let entry"> {{entry.level}} </mat-cell>
</ng-container>
<ng-container matColumnDef="timestamp">
<mat-header-cell style="flex: 0 0 21em" mat-sort-header *matHeaderCellDef>Time</mat-header-cell>
<mat-cell style="flex: 0 0 17em" *matCellDef="let entry"> {{entry.timestamp}} </mat-cell>
</ng-container>
<ng-container matColumnDef="message">
<mat-header-cell mat-sort-header *matHeaderCellDef>Message</mat-header-cell>
<mat-cell style="flex: 0 0 30em" *matCellDef="let entry"> {{entry.message}} </mat-cell>
</ng-container>
<ng-container matColumnDef="data">
<mat-header-cell mat-sort-header *matHeaderCellDef>Data</mat-header-cell>
<mat-cell *matCellDef="let entry">
<pre>{{entry.data}}</pre>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="logsCols"></mat-header-row> <ng-container matColumnDef="level">
<mat-row *matRowDef="let row; columns: logsCols;"></mat-row> <mat-header-cell style="flex: 0 0 6em" mat-sort-header
</mat-table> *matHeaderCellDef>{{"logs.level" | translate}}</mat-header-cell>
<mat-cell style="flex: 0 0 6em" *matCellDef="let entry"> {{entry.level}} </mat-cell>
</ng-container>
<ng-container matColumnDef="timestamp">
<mat-header-cell style="flex: 0 0 21em" mat-sort-header
*matHeaderCellDef>{{"logs.time" | translate}}</mat-header-cell>
<mat-cell style="flex: 0 0 17em" *matCellDef="let entry"> {{entry.timestamp}} </mat-cell>
</ng-container>
<ng-container matColumnDef="message">
<mat-header-cell mat-sort-header *matHeaderCellDef>{{"logs.message" | translate}}</mat-header-cell>
<mat-cell style="flex: 0 0 30em" *matCellDef="let entry"> {{entry.message}} </mat-cell>
</ng-container>
<ng-container matColumnDef="data">
<mat-header-cell mat-sort-header *matHeaderCellDef>{{"logs.data" | translate}}</mat-header-cell>
<mat-cell *matCellDef="let entry">
<pre>{{entry.data}}</pre>
</mat-cell>
</ng-container>
<mat-paginator [length]="logs.length" [pageSizeOptions]="[5,10,25,100]" [pageSize]="5"></mat-paginator> <mat-header-row *matHeaderRowDef="logsCols"></mat-header-row>
<mat-row *matRowDef="let row; columns: logsCols;"></mat-row>
</mat-table>
<mat-paginator [length]="logs.length" [pageSizeOptions]="[5,10,25,100]" [pageSize]="5"></mat-paginator>
</div>
</div>
</div> </div>

View File

@ -45,7 +45,7 @@ export class LogsComponent implements OnInit {
message: entry.message, message: entry.message,
timestamp: moment.unix(entry.timestamp).toISOString(), timestamp: moment.unix(entry.timestamp).toISOString(),
data: JSON.stringify(JSON.parse(entry.data), null, 2), data: JSON.stringify(JSON.parse(entry.data), null, 2),
level: entry.level.toUpperCase() level: entry.level
} }
}); });
} }

View File

@ -1,6 +1,23 @@
{ {
"nav": { "nav": {
"title": "task_tracker", "title": "task_tracker",
"langSelect": "Language" "langSelect": "Language",
"logs": "Logs",
"project_list": "Projects",
"new_project": "New Project"
},
"logs": {
"filter": "Filter",
"time": "Time",
"level": "Level",
"message": "Message",
"data": "Details",
"first_page_label": "First page",
"last_page_label": "Last page",
"of": "of",
"items_per_page": "Items per page",
"next_page": "Next page",
"prev_page": "Previous page"
} }
} }

View File

@ -1,6 +1,23 @@
{ {
"nav": { "nav": {
"title": "task_tracker (fr)", "title": "task_tracker (fr)",
"langSelect": "Langue" "langSelect": "Langue",
"logs": "Journal",
"project_list": "Projets",
"new_project": "Nouveau projet"
},
"logs": {
"filter": "Filtrer",
"time": "Date",
"level": "Niveau",
"message": "Message",
"data": "Details",
"first_page_label": "Première page",
"last_page_label": "Dernière page",
"of": "de",
"items_per_page": "Items par page",
"next_page": "Page suivante",
"prev_page": "Page précédante"
} }
} }

View File

@ -1,36 +1,51 @@
/* You can add global styles to this file, and also import other style files */ /* You can add global styles to this file, and also import other style files */
@import "~@angular/material/prebuilt-themes/indigo-pink.css"; @import "~@angular/material/prebuilt-themes/indigo-pink.css";
.line-new { body {
fill: none; margin: 0;
stroke: #31a6a2;
stroke-width: 3;
} }
.line-failed { .nav-title {
fill: none; font-weight: bold;
stroke: #8c2627; font-size: 18px;
stroke-width: 3;
} }
.line-closed {
fill: none; .container {
stroke: #62f24b; width: 100%;
stroke-width: 3; padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
margin-top: 15px;
} }
.overlay { @media (min-width: 576px) {
fill: none; .container {
pointer-events: all; max-width: 540px;
}
} }
/* Style the dots by assigning a fill and stroke */ @media (min-width: 768px) {
.dot { .container {
fill: #ffab00; max-width: 720px;
stroke: #fff; }
} }
.focus circle { @media (min-width: 992px) {
fill: none; .container {
stroke: steelblue; max-width: 960px;
}
}
@media (min-width: 1200px) {
.container {
max-width: 1140px;
}
}
@media (min-width: 1600px) {
.container {
max-width: 1440px;
}
} }