mirror of
https://github.com/simon987/task_tracker.git
synced 2025-04-24 12:35:52 +00:00
translated logs page
This commit is contained in:
parent
87f4d08984
commit
a02a5c83ed
28
web/angular/src/app/TranslatedPaginatorConfiguration.ts
Normal file
28
web/angular/src/app/TranslatedPaginatorConfiguration.ts
Normal 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}`
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
@ -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() {
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
.nav-spacer {
|
.nav-spacer {
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
padding: 0 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-link {
|
||||||
|
}
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user