mirror of
https://github.com/simon987/task_tracker.git
synced 2025-04-19 18:16:45 +00:00
Apply CodeRefactor manual fixes
This commit is contained in:
parent
be9bcc087a
commit
f50df4226d
@ -1,12 +1,12 @@
|
|||||||
# Build
|
# Build
|
||||||
FROM golang:latest as go_build
|
FROM golang:1.11.5 as go_build
|
||||||
WORKDIR /go/src/github.com/simon987/task_tracker/
|
WORKDIR /go/src/github.com/simon987/task_tracker/
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
RUN go get ./main/ && GOOS=linux CGO_ENABLED=0 go build -a -installsuffix cgo -o tt_api ./main/
|
RUN go get ./main/ && GOOS=linux CGO_ENABLED=0 go build -a -installsuffix cgo -o tt_api ./main/
|
||||||
|
|
||||||
# Execute in alpine
|
# Execute in alpine
|
||||||
FROM alpine:latest
|
FROM alpine:3.9.2
|
||||||
WORKDIR /root
|
WORKDIR /root
|
||||||
|
|
||||||
COPY --from=go_build ["/go/src/github.com/simon987/task_tracker/tt_api",\
|
COPY --from=go_build ["/go/src/github.com/simon987/task_tracker/tt_api",\
|
||||||
|
@ -138,7 +138,7 @@ func (api *WebAPI) GetTaskFromProject(r *Request) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api WebAPI) validateSignature(r *Request) (*storage.Worker, error) {
|
func (api *WebAPI) validateSignature(r *Request) (*storage.Worker, error) {
|
||||||
|
|
||||||
widStr := string(r.Ctx.Request.Header.Peek("X-Worker-Id"))
|
widStr := string(r.Ctx.Request.Header.Peek("X-Worker-Id"))
|
||||||
timeStampStr := string(r.Ctx.Request.Header.Peek("Timestamp"))
|
timeStampStr := string(r.Ctx.Request.Header.Peek("Timestamp"))
|
||||||
|
1
jenkins/Jenkinsfile
vendored
1
jenkins/Jenkinsfile
vendored
@ -36,6 +36,7 @@ pipeline {
|
|||||||
agent {
|
agent {
|
||||||
docker {
|
docker {
|
||||||
image 'golang:latest'
|
image 'golang:latest'
|
||||||
|
args '--network "host"'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
steps {
|
steps {
|
||||||
|
@ -6,8 +6,7 @@ import {Credentials} from './models/credentials';
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class ApiService {
|
export class ApiService {
|
||||||
|
|
||||||
// public url: string = window.location.protocol + "//" + window.location.hostname + "/api";
|
public url: string = window.location.protocol + '//' + window.location.hostname + '/api';
|
||||||
public url = 'https://tt.simon987.net/api';
|
|
||||||
private options: {
|
private options: {
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
responseType: 'json'
|
responseType: 'json'
|
||||||
|
@ -52,7 +52,7 @@ export class AppRoutingModule {
|
|||||||
|
|
||||||
private updateTitle(tr: TranslateService, title: Title, url: string) {
|
private updateTitle(tr: TranslateService, title: Title, url: string) {
|
||||||
url = url.substr(1);
|
url = url.substr(1);
|
||||||
tr.get('title.' + url.substring(0, url.indexOf('/') == -1 ? url.length : url.indexOf('/')))
|
tr.get('title.' + url.substring(0, url.indexOf('/') === -1 ? url.length : url.indexOf('/')))
|
||||||
.subscribe((t) => title.setTitle(t));
|
.subscribe((t) => title.setTitle(t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,6 @@
|
|||||||
padding: 0 14px;
|
padding: 0 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nav-link {
|
|
||||||
}
|
|
||||||
|
|
||||||
.large-nav {
|
.large-nav {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
<mat-toolbar color="primary">
|
<mat-toolbar color="primary">
|
||||||
<div class="large-nav">
|
<div class="large-nav">
|
||||||
<button mat-button [class.mat-accent]="router.url == '/'" class="nav-title"
|
<button mat-button [class.mat-accent]="router.url === '/'" class="nav-title"
|
||||||
[routerLink]="''">{{"nav.title" | translate}}</button>
|
[routerLink]="''">{{"nav.title" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/log'" class="nav-link"
|
<button mat-button [class.mat-accent]="router.url === '/log'" class="nav-link"
|
||||||
[routerLink]="'log'">{{"nav.logs" | translate}}</button>
|
[routerLink]="'log'">{{"nav.logs" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/projects'" class="nav-link"
|
<button mat-button [class.mat-accent]="router.url === '/projects'" class="nav-link"
|
||||||
[routerLink]="'projects'">{{"nav.project_list" | translate}}</button>
|
[routerLink]="'projects'">{{"nav.project_list" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/workers'" class="nav-link"
|
<button mat-button [class.mat-accent]="router.url === '/workers'" class="nav-link"
|
||||||
[routerLink]="'workers'">{{"nav.worker_dashboard" | translate}}</button>
|
[routerLink]="'workers'">{{"nav.worker_dashboard" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/new_project'" class="nav-link"
|
<button mat-button [class.mat-accent]="router.url === '/new_project'" class="nav-link"
|
||||||
[routerLink]="'new_project'"
|
[routerLink]="'new_project'"
|
||||||
*ngIf="authService.logged">{{"nav.new_project" | translate}}</button>
|
*ngIf="authService.logged">{{"nav.new_project" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/manager_list'" class="nav-link"
|
<button mat-button [class.mat-accent]="router.url === '/manager_list'" class="nav-link"
|
||||||
[routerLink]="'manager_list'"
|
[routerLink]="'manager_list'"
|
||||||
*ngIf="authService.logged && authService.account.tracker_admin"
|
*ngIf="authService.logged && authService.account.tracker_admin"
|
||||||
>{{"nav.manager_list" | translate}}</button>
|
>{{"nav.manager_list" | translate}}</button>
|
||||||
@ -21,28 +21,28 @@
|
|||||||
<mat-icon>more_vert</mat-icon>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #smallNav>
|
<mat-menu #smallNav>
|
||||||
<button mat-menu-item [class.mat-accent]="router.url == '/'" class="nav-title"
|
<button mat-menu-item [class.mat-accent]="router.url === '/'" class="nav-title"
|
||||||
[routerLink]="''">{{"nav.title" | translate}}</button>
|
[routerLink]="''">{{"nav.title" | translate}}</button>
|
||||||
<button mat-menu-item [class.mat-accent]="router.url == '/log'" class="nav-link"
|
<button mat-menu-item [class.mat-accent]="router.url === '/log'" class="nav-link"
|
||||||
[routerLink]="'log'">{{"nav.logs" | translate}}</button>
|
[routerLink]="'log'">{{"nav.logs" | translate}}</button>
|
||||||
<button mat-menu-item [class.mat-accent]="router.url == '/projects'" class="nav-link"
|
<button mat-menu-item [class.mat-accent]="router.url === '/projects'" class="nav-link"
|
||||||
[routerLink]="'projects'">{{"nav.project_list" | translate}}</button>
|
[routerLink]="'projects'">{{"nav.project_list" | translate}}</button>
|
||||||
<button mat-menu-item [class.mat-accent]="router.url == '/workers'" class="nav-link"
|
<button mat-menu-item [class.mat-accent]="router.url === '/workers'" class="nav-link"
|
||||||
[routerLink]="'workers'">{{"nav.worker_dashboard" | translate}}</button>
|
[routerLink]="'workers'">{{"nav.worker_dashboard" | translate}}</button>
|
||||||
<button mat-menu-item [class.mat-accent]="router.url == '/new_project'" class="nav-link"
|
<button mat-menu-item [class.mat-accent]="router.url === '/new_project'" class="nav-link"
|
||||||
[routerLink]="'new_project'"
|
[routerLink]="'new_project'"
|
||||||
*ngIf="authService.logged">{{"nav.new_project" | translate}}</button>
|
*ngIf="authService.logged">{{"nav.new_project" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/manager_list'" class="nav-link"
|
<button mat-button [class.mat-accent]="router.url === '/manager_list'" class="nav-link"
|
||||||
[routerLink]="'manager_list'"
|
[routerLink]="'manager_list'"
|
||||||
*ngIf="authService.logged && authService.account.tracker_admin"
|
*ngIf="authService.logged && authService.account.tracker_admin"
|
||||||
>{{"nav.manager_list" | translate}}</button>
|
>{{"nav.manager_list" | translate}}</button>
|
||||||
</mat-menu>
|
</mat-menu>
|
||||||
</div>
|
</div>
|
||||||
<span class="spacer"></span>
|
<span class="spacer"></span>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/login'"
|
<button mat-button [class.mat-accent]="router.url === '/login'"
|
||||||
class="nav-link" *ngIf="!authService.account"
|
class="nav-link" *ngIf="!authService.account"
|
||||||
[routerLink]="'login'">{{"nav.login" | translate}}</button>
|
[routerLink]="'login'">{{"nav.login" | translate}}</button>
|
||||||
<button mat-button [class.mat-accent]="router.url == '/account'"
|
<button mat-button [class.mat-accent]="router.url === '/account'"
|
||||||
class="nav-link" *ngIf="authService.account"
|
class="nav-link" *ngIf="authService.account"
|
||||||
[routerLink]="'account'">{{"nav.account" | translate}}</button>
|
[routerLink]="'account'">{{"nav.account" | translate}}</button>
|
||||||
|
|
||||||
|
@ -33,6 +33,6 @@ export class LoginComponent implements OnInit {
|
|||||||
|
|
||||||
canCreate(): boolean {
|
canCreate(): boolean {
|
||||||
return this.credentials.username && this.credentials.username != '' &&
|
return this.credentials.username && this.credentials.username != '' &&
|
||||||
this.credentials.password == this.credentials.repeatPassword;
|
this.credentials.password === this.credentials.repeatPassword;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
.table-container {
|
|
||||||
/*height: 600px;*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.mat-table {
|
.mat-table {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
|
@ -42,7 +42,7 @@ export class ManagerListComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canDemote(manager: Manager) {
|
canDemote(manager: Manager) {
|
||||||
return manager.tracker_admin && manager.username != this.authService.account.username;
|
return manager.tracker_admin && manager.username !== this.authService.account.username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public promote(manager: Manager) {
|
public promote(manager: Manager) {
|
||||||
@ -61,7 +61,7 @@ export class ManagerListComponent implements OnInit {
|
|||||||
this.data.data = data['content']['managers'];
|
this.data.data = data['content']['managers'];
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
if (error && (error.status == 401 || error.status == 403)) {
|
if (error && (error.status === 401 || error.status === 403)) {
|
||||||
console.log(error.error.message);
|
console.log(error.error.message);
|
||||||
this.translate.get('manager_list.unauthorized')
|
this.translate.get('manager_list.unauthorized')
|
||||||
.subscribe(t => this.messengerService.show(t));
|
.subscribe(t => this.messengerService.show(t));
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[placeholder]="'perms.manager_select' | translate"
|
[placeholder]="'perms.manager_select' | translate"
|
||||||
(opened)="loadManagerList()">
|
(opened)="loadManagerList()">
|
||||||
<mat-select-trigger></mat-select-trigger>
|
<mat-select-trigger></mat-select-trigger>
|
||||||
<mat-option disabled *ngIf="managerList == undefined">
|
<mat-option disabled *ngIf="managerList === undefined">
|
||||||
{{"project_select.loading" | translate}}
|
{{"project_select.loading" | translate}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
<mat-option *ngFor="let m of managerList" [value]="m">
|
<mat-option *ngFor="let m of managerList" [value]="m">
|
||||||
|
@ -17,7 +17,7 @@ export class ManagerRoleOnProject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get readRole(): boolean {
|
get readRole(): boolean {
|
||||||
return (this.role & 1) != 0;
|
return (this.role & 1) !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
set readRole(role: boolean) {
|
set readRole(role: boolean) {
|
||||||
@ -29,7 +29,7 @@ export class ManagerRoleOnProject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get editRole(): boolean {
|
get editRole(): boolean {
|
||||||
return (this.role & 2) != 0;
|
return (this.role & 2) !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
set editRole(role: boolean) {
|
set editRole(role: boolean) {
|
||||||
@ -41,7 +41,7 @@ export class ManagerRoleOnProject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get manageRole(): boolean {
|
get manageRole(): boolean {
|
||||||
return (this.role & 4) != 0;
|
return (this.role & 4) !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
set manageRole(role: boolean) {
|
set manageRole(role: boolean) {
|
||||||
@ -53,7 +53,7 @@ export class ManagerRoleOnProject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get secretRole(): boolean {
|
get secretRole(): boolean {
|
||||||
return (this.role & 8) != 0;
|
return (this.role & 8) !== 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
set secretRole(role: boolean) {
|
set secretRole(role: boolean) {
|
||||||
|
@ -66,7 +66,7 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public isSafeUrl(url: string) {
|
public isSafeUrl(url: string) {
|
||||||
if (url.substr(0, 'http'.length) == 'http') {
|
if (url.substr(0, 'http'.length) === 'http') {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,10 +82,10 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
return b.time_stamp - a.time_stamp;
|
return b.time_stamp - a.time_stamp;
|
||||||
})[0] : null;
|
})[0] : null;
|
||||||
|
|
||||||
if (this.lastSnapshot == null || (this.lastSnapshot.awaiting_verification_count == 0 &&
|
if (this.lastSnapshot === null || (this.lastSnapshot.awaiting_verification_count === 0 &&
|
||||||
this.lastSnapshot.closed_task_count == 0 &&
|
this.lastSnapshot.closed_task_count === 0 &&
|
||||||
this.lastSnapshot.new_task_count == 0 &&
|
this.lastSnapshot.new_task_count === 0 &&
|
||||||
this.lastSnapshot.failed_task_count == 0)) {
|
this.lastSnapshot.failed_task_count === 0)) {
|
||||||
this.noTasks = true;
|
this.noTasks = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -114,8 +114,8 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
this.statusPie.update();
|
this.statusPie.update();
|
||||||
|
|
||||||
this.apiService.getAssigneeStats(this.projectId)
|
this.apiService.getAssigneeStats(this.projectId)
|
||||||
.subscribe((data: any) => {
|
.subscribe((statsData: any) => {
|
||||||
this.assignees = data.content.assignees;
|
this.assignees = statsData.content.assignees;
|
||||||
const colors = this.assignees.map(() => {
|
const colors = this.assignees.map(() => {
|
||||||
return this.colors.random[Math.floor(Math.random() * this.colors.random.length)];
|
return this.colors.random[Math.floor(Math.random() * this.colors.random.length)];
|
||||||
});
|
});
|
||||||
@ -218,10 +218,10 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
|
|
||||||
private setupStatusPie() {
|
private setupStatusPie() {
|
||||||
|
|
||||||
if (this.lastSnapshot == undefined || (this.lastSnapshot.awaiting_verification_count == 0 &&
|
if (this.lastSnapshot === undefined || (this.lastSnapshot.awaiting_verification_count === 0 &&
|
||||||
this.lastSnapshot.closed_task_count == 0 &&
|
this.lastSnapshot.closed_task_count === 0 &&
|
||||||
this.lastSnapshot.new_task_count == 0 &&
|
this.lastSnapshot.new_task_count === 0 &&
|
||||||
this.lastSnapshot.failed_task_count == 0)) {
|
this.lastSnapshot.failed_task_count === 0)) {
|
||||||
this.noTasks = true;
|
this.noTasks = true;
|
||||||
|
|
||||||
this.lastSnapshot = {
|
this.lastSnapshot = {
|
||||||
@ -324,8 +324,8 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
this.project = data.content.project;
|
this.project = data.content.project;
|
||||||
|
|
||||||
this.apiService.getMonitoringSnapshots(60, this.projectId)
|
this.apiService.getMonitoringSnapshots(60, this.projectId)
|
||||||
.subscribe((data: any) => {
|
.subscribe((monitoringData: any) => {
|
||||||
this.snapshots = data.content.snapshots;
|
this.snapshots = monitoringData.content.snapshots;
|
||||||
this.lastSnapshot = this.snapshots ? this.snapshots.sort((a, b) => {
|
this.lastSnapshot = this.snapshots ? this.snapshots.sort((a, b) => {
|
||||||
return b.time_stamp - a.time_stamp;
|
return b.time_stamp - a.time_stamp;
|
||||||
})[0] : null;
|
})[0] : null;
|
||||||
@ -338,8 +338,8 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.apiService.getAssigneeStats(this.projectId)
|
this.apiService.getAssigneeStats(this.projectId)
|
||||||
.subscribe((data: any) => {
|
.subscribe((assigneeData: any) => {
|
||||||
this.assignees = data.content.assignees;
|
this.assignees = assigneeData.content.assignees;
|
||||||
this.setupAssigneesPie();
|
this.setupAssigneesPie();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
return NaN;
|
return NaN;
|
||||||
} else {
|
} else {
|
||||||
return xs.reduce(
|
return xs.reduce(
|
||||||
([acc, last], x) => [acc + (x - last), x],
|
([acc, last], y) => [acc + (y - last), y],
|
||||||
[0, x]
|
[0, x]
|
||||||
) [0] / xs.length;
|
) [0] / xs.length;
|
||||||
}
|
}
|
||||||
@ -395,7 +395,7 @@ export class ProjectDashboardComponent implements OnInit {
|
|||||||
|
|
||||||
const interval = this.snapshots.length > 1 ? this.snapshots[0].time_stamp - this.snapshots[1].time_stamp : 0;
|
const interval = this.snapshots.length > 1 ? this.snapshots[0].time_stamp - this.snapshots[1].time_stamp : 0;
|
||||||
|
|
||||||
if (interval != 0) {
|
if (interval !== 0) {
|
||||||
this.avgTask = averageDelta(this.snapshots.reverse().map(s => s.closed_task_count) as any) / interval;
|
this.avgTask = averageDelta(this.snapshots.reverse().map(s => s.closed_task_count) as any) / interval;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -37,11 +37,11 @@
|
|||||||
{{"project.secret" | translate}}</button>
|
{{"project.secret" | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</mat-expansion-panel>
|
</mat-expansion-panel>
|
||||||
<span *ngIf="projects && projects.length == 0">
|
<span *ngIf="projects && projects.length === 0">
|
||||||
{{"projects.empty" | translate}}
|
{{"projects.empty" | translate}}
|
||||||
</span>
|
</span>
|
||||||
<mat-progress-bar mode="indeterminate"
|
<mat-progress-bar mode="indeterminate"
|
||||||
*ngIf="projects == null"></mat-progress-bar>
|
*ngIf="projects === null"></mat-progress-bar>
|
||||||
</mat-accordion>
|
</mat-accordion>
|
||||||
</mat-card-content>
|
</mat-card-content>
|
||||||
</mat-card>
|
</mat-card>
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</mat-list-item>
|
</mat-list-item>
|
||||||
</mat-list>
|
</mat-list>
|
||||||
<p *ngIf="!accesses || accesses.length == 0">{{"perms.no_workers"|translate}}</p>
|
<p *ngIf="!accesses || accesses.length === 0">{{"perms.no_workers"|translate}}</p>
|
||||||
|
|
||||||
<h3>{{"perms.managers" | translate}}</h3>
|
<h3>{{"perms.managers" | translate}}</h3>
|
||||||
<manager-select (managerChange)="onSelectManager($event)"></manager-select>
|
<manager-select (managerChange)="onSelectManager($event)"></manager-select>
|
||||||
|
@ -68,7 +68,7 @@ export class ProjectPermsComponent implements OnInit {
|
|||||||
this.accesses = data['content']['accesses'];
|
this.accesses = data['content']['accesses'];
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
if (error && (error.status == 401 || error.status == 403)) {
|
if (error && (error.status === 401 || error.status === 403)) {
|
||||||
this.unauthorized = true;
|
this.unauthorized = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -88,7 +88,7 @@ export class ProjectPermsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public onSelectManager(manager: Manager) {
|
public onSelectManager(manager: Manager) {
|
||||||
if (manager.id != this.auth.account.id) {
|
if (manager.id !== this.auth.account.id) {
|
||||||
this.apiService.setManagerRoleOnProject(this.projectId, 1, manager.id)
|
this.apiService.setManagerRoleOnProject(this.projectId, 1, manager.id)
|
||||||
.subscribe(() => this.refresh());
|
.subscribe(() => this.refresh());
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
[placeholder]="'project.chain' | translate"
|
[placeholder]="'project.chain' | translate"
|
||||||
(opened)="loadProjectList()">
|
(opened)="loadProjectList()">
|
||||||
<mat-select-trigger>{{project?.name}}</mat-select-trigger>
|
<mat-select-trigger>{{project?.name}}</mat-select-trigger>
|
||||||
<mat-option disabled *ngIf="projectList == undefined">
|
<mat-option disabled *ngIf="projectList === undefined">
|
||||||
{{"project_select.loading" | translate}}
|
{{"project_select.loading" | translate}}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
<mat-option [value]="null" *ngIf="projectList">
|
<mat-option [value]="null" *ngIf="projectList">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user