mirror of
https://github.com/simon987/task_tracker.git
synced 2025-12-10 13:44:30 +00:00
Various little improvements. More work on permissions
This commit is contained in:
@@ -13,6 +13,10 @@
|
||||
{{"account.username" | translate}}:
|
||||
<pre>{{authService.account.username}}</pre>
|
||||
</mat-list-item>
|
||||
<mat-list-item>
|
||||
{{"account.register_time" | translate}}:
|
||||
<pre>{{moment.unix(authService.account.register_time).utc().format("YYYY-MM-DD HH:mm:ss UTC")}}</pre>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
<mat-expansion-panel>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {AuthService} from "../auth.service";
|
||||
|
||||
import * as moment from "moment"
|
||||
|
||||
@Component({
|
||||
selector: 'app-account-details',
|
||||
templateUrl: './account-details.component.html',
|
||||
@@ -8,6 +10,8 @@ import {AuthService} from "../auth.service";
|
||||
})
|
||||
export class AccountDetailsComponent implements OnInit {
|
||||
|
||||
public moment = moment;
|
||||
|
||||
constructor(public authService: AuthService) {
|
||||
}
|
||||
|
||||
|
||||
@@ -69,4 +69,16 @@ export class ApiService {
|
||||
return this.http.get(this.url + `/project/requests/${project}`)
|
||||
}
|
||||
|
||||
getAllManagers() {
|
||||
return this.http.get(this.url + "/manager/list")
|
||||
}
|
||||
|
||||
promote(managerId: number) {
|
||||
return this.http.get(this.url + `/manager/promote/${managerId}`)
|
||||
}
|
||||
|
||||
demote(managerId: number) {
|
||||
return this.http.get(this.url + `/manager/demote/${managerId}`)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import {LoginComponent} from "./login/login.component";
|
||||
import {AccountDetailsComponent} from "./account-details/account-details.component";
|
||||
import {WorkerDashboardComponent} from "./worker-dashboard/worker-dashboard.component";
|
||||
import {ProjectPermsComponent} from "./project-perms/project-perms.component";
|
||||
import {ManagerListComponent} from "./manager-list/manager-list.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{path: "log", component: LogsComponent},
|
||||
@@ -22,7 +23,8 @@ const routes: Routes = [
|
||||
{path: "project/:id/update", component: UpdateProjectComponent},
|
||||
{path: "project/:id/perms", component: ProjectPermsComponent},
|
||||
{path: "new_project", component: CreateProjectComponent},
|
||||
{path: "workers", component: WorkerDashboardComponent}
|
||||
{path: "workers", component: WorkerDashboardComponent},
|
||||
{path: "manager_list", component: ManagerListComponent}
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
||||
@@ -11,6 +11,10 @@
|
||||
<button mat-button [class.mat-accent]="router.url == '/new_project'" class="nav-link"
|
||||
[routerLink]="'new_project'"
|
||||
*ngIf="authService.logged">{{"nav.new_project" | translate}}</button>
|
||||
<button mat-button [class.mat-accent]="router.url == '/manager_list'" class="nav-link"
|
||||
[routerLink]="'manager_list'"
|
||||
*ngIf="authService.logged && authService.account.tracker_admin"
|
||||
>{{"nav.manager_list" | translate}}</button>
|
||||
</div>
|
||||
<div class="small-nav">
|
||||
<button mat-button [matMenuTriggerFor]="smallNav">
|
||||
@@ -28,6 +32,10 @@
|
||||
<button mat-menu-item [class.mat-accent]="router.url == '/new_project'" class="nav-link"
|
||||
[routerLink]="'new_project'"
|
||||
*ngIf="authService.logged">{{"nav.new_project" | translate}}</button>
|
||||
<button mat-button [class.mat-accent]="router.url == '/manager_list'" class="nav-link"
|
||||
[routerLink]="'manager_list'"
|
||||
*ngIf="authService.logged && authService.account.tracker_admin"
|
||||
>{{"nav.manager_list" | translate}}</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
<span class="nav-spacer"></span>
|
||||
|
||||
@@ -48,6 +48,7 @@ import {LoginComponent} from './login/login.component';
|
||||
import {AccountDetailsComponent} from './account-details/account-details.component';
|
||||
import {WorkerDashboardComponent} from './worker-dashboard/worker-dashboard.component';
|
||||
import {ProjectPermsComponent} from './project-perms/project-perms.component';
|
||||
import {ManagerListComponent} from './manager-list/manager-list.component';
|
||||
|
||||
|
||||
export function createTranslateLoader(http: HttpClient) {
|
||||
@@ -68,6 +69,7 @@ export function createTranslateLoader(http: HttpClient) {
|
||||
AccountDetailsComponent,
|
||||
WorkerDashboardComponent,
|
||||
ProjectPermsComponent,
|
||||
ManagerListComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
||||
@@ -60,6 +60,7 @@ export class AuthService {
|
||||
.subscribe(() =>
|
||||
this.apiService.getAccountDetails()
|
||||
.subscribe((data: any) => {
|
||||
this.logged = true;
|
||||
this.account = data.manager;
|
||||
this.router.navigateByUrl("/account");
|
||||
}),
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<mat-form-field appearance="outline">
|
||||
<mat-label>{{ "project.clone_url" | translate}}</mat-label>
|
||||
<input type="text" matInput [(ngModel)]="project.clone_url"
|
||||
<input type="text" matInput [(ngModel)]="project.clone_url" (change)="cloneUrlChange()"
|
||||
[placeholder]="'project.clone_url_placeholder' | translate">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="outline">
|
||||
@@ -23,7 +23,9 @@
|
||||
</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-checkbox matInput [(ngModel)]="project.public" style="padding-top: 1em">
|
||||
<mat-checkbox [(ngModel)]="project.public"
|
||||
[disabled]="!authService.logged || !authService.account.tracker_admin"
|
||||
style="padding-top: 1em">
|
||||
{{"project.public" | translate}}</mat-checkbox>
|
||||
|
||||
</mat-card-content>
|
||||
|
||||
@@ -3,6 +3,7 @@ import {Project} from "../models/project";
|
||||
import {ApiService} from "../api.service";
|
||||
import {MessengerService} from "../messenger.service";
|
||||
import {Router} from "@angular/router";
|
||||
import {AuthService} from "../auth.service";
|
||||
|
||||
|
||||
@Component({
|
||||
@@ -16,14 +17,21 @@ export class CreateProjectComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService,
|
||||
private messengerService: MessengerService,
|
||||
public authService: AuthService,
|
||||
private router: Router) {
|
||||
this.project.name = "test";
|
||||
this.project.public = true;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
cloneUrlChange() {
|
||||
let tokens = this.project.clone_url.split("/");
|
||||
|
||||
if (tokens.length > 2) {
|
||||
this.project.git_repo = tokens[tokens.length - 2] + "/" + tokens[tokens.length - 1]
|
||||
}
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.apiService.createProject(this.project).subscribe(
|
||||
data => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.table-container {
|
||||
height: 600px;
|
||||
/*height: 600px;*/
|
||||
}
|
||||
|
||||
.mat-table {
|
||||
|
||||
@@ -1,56 +1,63 @@
|
||||
<div class="container">
|
||||
<div class="table-container">
|
||||
<mat-form-field style="margin-right: 10px">
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" [placeholder]="'logs.filter' | translate">
|
||||
</mat-form-field>
|
||||
<mat-button-toggle-group name="level" aria-label="Font Style" (change)="filterLevelChange($event)">
|
||||
<mat-button-toggle value="1">{{"logs.fatal" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="2">{{"logs.panic" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="3">{{"logs.error" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="4">{{"logs.warn" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="5">{{"logs.info" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="6">{{"logs.debug" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="7">{{"logs.trace" | translate}}</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
<mat-card class="table-container">
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{"logs.title" | translate}}</mat-card-title>
|
||||
<mat-card-subtitle>{{"logs.subtitle" | translate}}</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<mat-form-field style="margin-right: 10px">
|
||||
<input matInput (keyup)="applyFilter($event.target.value)" [placeholder]="'logs.filter' | translate">
|
||||
</mat-form-field>
|
||||
<mat-button-toggle-group name="level" aria-label="Font Style" (change)="filterLevelChange($event)">
|
||||
<mat-button-toggle value="1">{{"logs.fatal" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="2">{{"logs.panic" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="3">{{"logs.error" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="4">{{"logs.warn" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="5">{{"logs.info" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="6">{{"logs.debug" | translate}}</mat-button-toggle>
|
||||
<mat-button-toggle value="7">{{"logs.trace" | translate}}</mat-button-toggle>
|
||||
</mat-button-toggle-group>
|
||||
|
||||
<button mat-raised-button style="float: right"
|
||||
[title]="'dashboard.refresh' | translate"
|
||||
(click)="refresh()">
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
<div class="mat-elevation-z8">
|
||||
<button mat-raised-button style="float: right"
|
||||
[title]="'dashboard.refresh' | translate"
|
||||
(click)="refresh()">
|
||||
<mat-icon>refresh</mat-icon>
|
||||
</button>
|
||||
<div class="mat-elevation-z8">
|
||||
|
||||
<mat-table [dataSource]="data" matSort matSortActive="timestamp"
|
||||
matSortDirection="desc">
|
||||
<mat-table [dataSource]="data" matSort matSortActive="timestamp"
|
||||
matSortDirection="desc">
|
||||
|
||||
<ng-container matColumnDef="level">
|
||||
<mat-header-cell style="flex: 0 0 9em" mat-sort-header
|
||||
*matHeaderCellDef>{{"logs.level" | translate}}</mat-header-cell>
|
||||
<mat-cell style="flex: 0 0 8em"
|
||||
*matCellDef="let entry"> {{("logs." + entry.level) | translate}} </mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="timestamp">
|
||||
<mat-header-cell style="flex: 0 0 15em" mat-sort-header
|
||||
*matHeaderCellDef>{{"logs.time" | translate}}</mat-header-cell>
|
||||
<mat-cell style="flex: 0 0 12em" *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>
|
||||
<ng-container matColumnDef="level">
|
||||
<mat-header-cell style="flex: 0 0 9em" mat-sort-header
|
||||
*matHeaderCellDef>{{"logs.level" | translate}}</mat-header-cell>
|
||||
<mat-cell style="flex: 0 0 8em"
|
||||
*matCellDef="let entry"> {{("logs." + entry.level) | translate}} </mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="timestamp">
|
||||
<mat-header-cell style="flex: 0 0 15em" mat-sort-header
|
||||
*matHeaderCellDef>{{"logs.time" | translate}}</mat-header-cell>
|
||||
<mat-cell style="flex: 0 0 12em" *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-header-row *matHeaderRowDef="logsCols"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: logsCols;"></mat-row>
|
||||
</mat-table>
|
||||
<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>
|
||||
<mat-paginator [length]="logs.length" [pageSizeOptions]="[5,10,25,100]" [pageSize]="5"></mat-paginator>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ export class LogsComponent implements OnInit {
|
||||
this.getLogs(Number(event.value))
|
||||
}
|
||||
|
||||
private refresh() {
|
||||
public refresh() {
|
||||
this.getLogs(this.filterLevel)
|
||||
}
|
||||
|
||||
|
||||
53
web/angular/src/app/manager-list/manager-list.component.html
Normal file
53
web/angular/src/app/manager-list/manager-list.component.html
Normal file
@@ -0,0 +1,53 @@
|
||||
<div class="container">
|
||||
<mat-card class="mat-elevation-z8">
|
||||
<mat-card-header>
|
||||
<mat-card-title>{{"manager_list.title" | translate}}</mat-card-title>
|
||||
<mat-card-subtitle>{{"manager_list.subtitle" | translate}}</mat-card-subtitle>
|
||||
</mat-card-header>
|
||||
|
||||
<mat-card-content>
|
||||
|
||||
<mat-table [dataSource]="data" matSort matSortActive="username" matSortDirection="asc">
|
||||
|
||||
<ng-container matColumnDef="username">
|
||||
<mat-header-cell mat-sort-header
|
||||
*matHeaderCellDef>{{"manager_list.username" | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let manager"> {{manager.username}} </mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="tracker_admin">
|
||||
<mat-header-cell *matHeaderCellDef
|
||||
mat-sort-header>{{"manager_list.role" | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let manager">
|
||||
<mat-icon *ngIf="manager.tracker_admin" [title]="'manager_list.tracker_admin' | translate">
|
||||
supervisor_account
|
||||
</mat-icon>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="register_time">
|
||||
<mat-header-cell *matHeaderCellDef>{{"manager_list.register_time" | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let manager">
|
||||
{{moment.unix(manager.register_time).utc().format("UTC YYYY-MM-DD HH:mm:ss")}}
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="actions">
|
||||
<mat-header-cell *matHeaderCellDef>{{"manager_list.actions" | translate}}</mat-header-cell>
|
||||
<mat-cell *matCellDef="let manager">
|
||||
<button mat-raised-button color="primary"
|
||||
*ngIf="canPromote(manager)"
|
||||
(click)="promote(manager)">{{"manager_list.promote" | translate}}</button>
|
||||
<button mat-raised-button color="warn"
|
||||
*ngIf="canDemote(manager)"
|
||||
(click)="demote(manager)">{{"manager_list.demote" | translate}}</button>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<mat-header-row *matHeaderRowDef="cols"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: cols;"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<mat-paginator [class.hidden]="managers.length<25" [length]="managers.length"
|
||||
[pageSizeOptions]="[25,50,100]" [pageSize]="25"></mat-paginator>
|
||||
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
70
web/angular/src/app/manager-list/manager-list.component.ts
Normal file
70
web/angular/src/app/manager-list/manager-list.component.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {ApiService} from "../api.service";
|
||||
import {MessengerService} from "../messenger.service";
|
||||
import {TranslateService} from "@ngx-translate/core";
|
||||
import {MatPaginator, MatSort, MatTableDataSource} from "@angular/material";
|
||||
|
||||
import * as moment from "moment"
|
||||
import {AuthService} from "../auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-manager-list',
|
||||
templateUrl: './manager-list.component.html',
|
||||
styleUrls: ['./manager-list.component.css']
|
||||
})
|
||||
export class ManagerListComponent implements OnInit {
|
||||
|
||||
managers = [];
|
||||
data;
|
||||
moment = moment;
|
||||
cols = ['username', 'tracker_admin', 'register_time', 'actions'];
|
||||
|
||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||
@ViewChild(MatSort) sort: MatSort;
|
||||
|
||||
constructor(private apiService: ApiService,
|
||||
private messengerService: MessengerService,
|
||||
private translate: TranslateService,
|
||||
private authService: AuthService
|
||||
) {
|
||||
this.data = new MatTableDataSource<Manager>()
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.getManagers();
|
||||
this.data.paginator = this.paginator;
|
||||
this.data.sort = this.sort;
|
||||
}
|
||||
|
||||
canPromote(manager: Manager) {
|
||||
return !manager.tracker_admin
|
||||
}
|
||||
|
||||
canDemote(manager: Manager) {
|
||||
return manager.tracker_admin && manager.username != this.authService.account.username
|
||||
}
|
||||
|
||||
public promote(manager: Manager) {
|
||||
this.apiService.promote(manager.id)
|
||||
.subscribe(() => this.getManagers())
|
||||
}
|
||||
|
||||
public demote(manager: Manager) {
|
||||
this.apiService.demote(manager.id)
|
||||
.subscribe(() => this.getManagers())
|
||||
}
|
||||
|
||||
private getManagers() {
|
||||
this.apiService.getAllManagers()
|
||||
.subscribe(data => {
|
||||
this.data.data = data["managers"]
|
||||
},
|
||||
error => {
|
||||
if (error && (error.status == 401 || error.status == 403)) {
|
||||
console.log(error.error.message);
|
||||
this.translate.get("manager_list.unauthorized")
|
||||
.subscribe(t => this.messengerService.show(t));
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
interface Manager {
|
||||
id: number;
|
||||
username: string
|
||||
website_admin: boolean;
|
||||
tracker_admin: boolean
|
||||
register_time: number
|
||||
}
|
||||
|
||||
@@ -18,9 +18,11 @@
|
||||
<div>
|
||||
<button mat-raised-button color="primary" [routerLink]="'/project/' + project.id">
|
||||
<mat-icon>timeline</mat-icon>{{"projects.dashboard" | translate}}</button>
|
||||
<button mat-raised-button color="primary" [routerLink]="'/project/' + project.id + '/update'">
|
||||
<button mat-raised-button color="primary" [routerLink]="'/project/' + project.id + '/update'"
|
||||
*ngIf="authService.logged">
|
||||
<mat-icon>build</mat-icon>{{"project.update" | translate}}</button>
|
||||
<button mat-raised-button color="primary" [routerLink]="'/project/' + project.id + '/perms'">
|
||||
<button mat-raised-button color="primary" [routerLink]="'/project/' + project.id + '/perms'"
|
||||
*ngIf="authService.logged">
|
||||
<mat-icon>perm_identity</mat-icon>
|
||||
{{"project.perms" | translate}}</button>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {Component, OnInit} from '@angular/core';
|
||||
import {ApiService} from "../api.service";
|
||||
import {Project} from "../models/project";
|
||||
import {AuthService} from "../auth.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-project-list',
|
||||
@@ -9,7 +10,8 @@ import {Project} from "../models/project";
|
||||
})
|
||||
export class ProjectListComponent implements OnInit {
|
||||
|
||||
constructor(private apiService: ApiService) {
|
||||
constructor(private apiService: ApiService,
|
||||
public authService: AuthService) {
|
||||
}
|
||||
|
||||
projects: Project[];
|
||||
|
||||
@@ -1,10 +1,3 @@
|
||||
.unauthorized {
|
||||
text-align: center;
|
||||
color: #616161;
|
||||
min-height: 3em;
|
||||
margin-top: 2em !important;
|
||||
}
|
||||
|
||||
.text-mono {
|
||||
font-family: Hack, Courier, "Courier New", monospace;
|
||||
color: #ff4081;
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
<h4 mat-line>{{w.alias}}</h4>
|
||||
<div mat-line>
|
||||
Id=<span class="text-mono">{{w.id}}</span>, {{"perms.created" | translate}}
|
||||
<span class="text-mono">{{moment.unix(w.created).format("YYYY-MM-DD HH:mm:ss UTC")}}</span>
|
||||
<span
|
||||
class="text-mono">{{moment.unix(w.created).utc().format("UTC YYYY-MM-DD HH:mm:ss")}}</span>
|
||||
</div>
|
||||
<span style="flex: 1 1 auto;"></span>
|
||||
<button mat-raised-button color="primary" [title]="'perms.grant' | translate">
|
||||
|
||||
@@ -54,7 +54,7 @@ export class ProjectPermsComponent implements OnInit {
|
||||
})
|
||||
}
|
||||
|
||||
private refresh() {
|
||||
public refresh() {
|
||||
this.getProjectRequests()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ export class WorkerDashboardComponent implements OnInit {
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
private refresh() {
|
||||
public refresh() {
|
||||
this.apiService.getWorkerStats()
|
||||
.subscribe((data: any) => {
|
||||
this.updateChart(data.stats)
|
||||
|
||||
@@ -7,9 +7,12 @@
|
||||
"new_project": "New Project",
|
||||
"login": "Login",
|
||||
"worker_dashboard": "Workers",
|
||||
"account": "Account"
|
||||
"account": "Account",
|
||||
"manager_list": "Managers"
|
||||
},
|
||||
"logs": {
|
||||
"title": "Logs",
|
||||
"subtitle": "",
|
||||
"filter": "Filter",
|
||||
"time": "Time (UTC)",
|
||||
"level": "Level",
|
||||
@@ -43,7 +46,8 @@
|
||||
"login": "Login",
|
||||
"new_account": "Create account",
|
||||
"account": "Account details",
|
||||
"workers": "Workers"
|
||||
"workers": "Workers",
|
||||
"manager_list": "Managers"
|
||||
},
|
||||
"project": {
|
||||
"name": "Project name",
|
||||
@@ -82,7 +86,8 @@
|
||||
"title": "Account details",
|
||||
"subtitle": "toto: subtitle",
|
||||
"username": "Username",
|
||||
"logout": "Logout"
|
||||
"logout": "Logout",
|
||||
"register_time": "Register date"
|
||||
},
|
||||
"workers": {
|
||||
"title": "Completed tasks per worker",
|
||||
@@ -100,5 +105,17 @@
|
||||
"messenger": {
|
||||
"close": "Close",
|
||||
"unauthorized": "Unauthorized"
|
||||
},
|
||||
"manager_list": {
|
||||
"title": "Manager list",
|
||||
"subtitle": "",
|
||||
"username": "Username",
|
||||
"role": "Role",
|
||||
"tracker_admin": "Tracker administrator",
|
||||
"actions": "Actions",
|
||||
"unauthorized": "You are not authorized to access this page",
|
||||
"promote": "Promote",
|
||||
"demote": "Demote",
|
||||
"register_time": "Register date"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
"nav": {
|
||||
"title": "task_tracker (fr)",
|
||||
"lang_select": "Langue",
|
||||
"logs": "Journal",
|
||||
"logs": "Journaux",
|
||||
"project_list": "Projets",
|
||||
"new_project": "Nouveau projet",
|
||||
"login": "Ouvrir un session",
|
||||
"worker_dashboard": "Workers",
|
||||
"account": "Compte"
|
||||
"account": "Compte",
|
||||
"manager_list": "Managers"
|
||||
},
|
||||
"logs": {
|
||||
"title": "Journaux",
|
||||
"subtitle": "",
|
||||
"filter": "Filtrer",
|
||||
"time": "Date (UTC)",
|
||||
"level": "Niveau",
|
||||
@@ -44,7 +47,8 @@
|
||||
"login": "Ouverture de session",
|
||||
"new_account": "Création de compte",
|
||||
"account": "Compte",
|
||||
"workers": "Workers"
|
||||
"workers": "Workers",
|
||||
"manager_list": "Managers"
|
||||
},
|
||||
"project": {
|
||||
"name": "Nom du projet",
|
||||
@@ -84,7 +88,8 @@
|
||||
"title": "Détails du compte",
|
||||
"subtitle": "toto: sous-titre",
|
||||
"username": "Nom d'utilisateur",
|
||||
"logout": "Fermer la session"
|
||||
"logout": "Fermer la session",
|
||||
"register_time": "Date de création"
|
||||
},
|
||||
"workers": {
|
||||
"title": "Tâches complétés par worker",
|
||||
@@ -102,6 +107,18 @@
|
||||
"messenger": {
|
||||
"close": "Fermer",
|
||||
"unauthorized": "Non autorisé"
|
||||
},
|
||||
"manager_list": {
|
||||
"title": "Liste ",
|
||||
"subtitle": "",
|
||||
"username": "Nom d'utilisateur",
|
||||
"role": "Rôle",
|
||||
"tracker_admin": "Administrateur",
|
||||
"actions": "Actions",
|
||||
"unauthorized": "Vou n'êtes pas authorisé à accéder à cette page",
|
||||
"promote": "Promouvoir",
|
||||
"demote": "Rétrograder",
|
||||
"register_time": "Date d'inscription"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ body {
|
||||
padding-left: 15px;
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
margin-top: 15px;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
@media (min-width: 576px) {
|
||||
@@ -86,3 +86,11 @@ pre {
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.unauthorized {
|
||||
text-align: center;
|
||||
color: #616161;
|
||||
min-height: 3em;
|
||||
margin-top: 2em !important;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user