mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-21 07:58:25 +00:00
remove is_admin field in user management list and add field validation on create a new user
This commit is contained in:
committed by
Sylvain MATHIEU
parent
0c0d77e220
commit
11029db956
@ -2,19 +2,33 @@
|
|||||||
<form [formGroup]="addUserForm" class="input-field">
|
<form [formGroup]="addUserForm" class="input-field">
|
||||||
<mat-form-field class="input-field">
|
<mat-form-field class="input-field">
|
||||||
<input matInput type="text" formControlName="username" placeholder="Username" />
|
<input matInput type="text" formControlName="username" placeholder="Username" />
|
||||||
|
<mat-error *ngIf="form.username?.touched && form.username?.errors && form.username?.errors.required"
|
||||||
|
>Username is required</mat-error>
|
||||||
|
<mat-error *ngIf="form.username?.errors && form.username?.errors.pattern"
|
||||||
|
>Username is incorrect</mat-error>
|
||||||
|
<mat-error *ngIf="form.username?.errors && form.username?.errors.userExists"
|
||||||
|
>User with this username exists</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="input-field">
|
<mat-form-field class="input-field">
|
||||||
<input matInput type="text" formControlName="full_name" placeholder="Full name" />
|
<input matInput type="text" formControlName="full_name" placeholder="Full name" />
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="input-field">
|
<mat-form-field class="input-field">
|
||||||
<input matInput type="text" formControlName="email" placeholder="Email" />
|
<input matInput type="text" formControlName="email" placeholder="Email" />
|
||||||
</mat-form-field>
|
<mat-error *ngIf="form.email?.touched && form.email?.errors && form.email?.errors.required"
|
||||||
<mat-form-field class="input-field">
|
>Email is required</mat-error>
|
||||||
<input matInput type="text" formControlName="password" placeholder="Password" />
|
<mat-error *ngIf="form.email?.errors && form.email?.errors.email"
|
||||||
|
>Email is invalid</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-checkbox formControlName="is_active" class="checkbox-field">Is active</mat-checkbox>
|
|
||||||
<mat-checkbox formControlName="is_superadmin" class="checkbox-field">Is admin</mat-checkbox>
|
<mat-form-field class="input-field">
|
||||||
|
<input matInput type="text" formControlName="password" placeholder="Password" />
|
||||||
|
<mat-error *ngIf="form.password?.touched && form.password?.errors"
|
||||||
|
>A password between 6 and 100 characters is required.</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
|
||||||
|
<mat-checkbox formControlName="is_active">Is active</mat-checkbox>
|
||||||
|
|
||||||
<div mat-dialog-actions class="button-div">
|
<div mat-dialog-actions class="button-div">
|
||||||
<button mat-button (click)="onCancelClick()" color="accent">Cancel</button>
|
<button mat-button (click)="onCancelClick()" color="accent">Cancel</button>
|
||||||
|
@ -2,10 +2,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox-field {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-div {
|
.button-div {
|
||||||
float: right;
|
float: right;
|
||||||
|
@ -17,6 +17,8 @@ import {UserService} from "@services/user.service";
|
|||||||
import {Server} from "@models/server";
|
import {Server} from "@models/server";
|
||||||
import {User} from "@models/users/user";
|
import {User} from "@models/users/user";
|
||||||
import {ToasterService} from "@services/toaster.service";
|
import {ToasterService} from "@services/toaster.service";
|
||||||
|
import {userNameAsyncValidator} from "@components/user-management/add-user-dialog/userNameAsyncValidator";
|
||||||
|
import {userEmailAsyncValidator} from "@components/user-management/add-user-dialog/userEmailAsyncValidator";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-add-user-dialog',
|
selector: 'app-add-user-dialog',
|
||||||
@ -36,16 +38,22 @@ export class AddUserDialogComponent implements OnInit {
|
|||||||
username: new FormControl(null, [
|
username: new FormControl(null, [
|
||||||
Validators.required,
|
Validators.required,
|
||||||
Validators.minLength(3),
|
Validators.minLength(3),
|
||||||
Validators.pattern("[a-zA-Z0-9_-]+$")]),
|
Validators.pattern("[a-zA-Z0-9_-]+$")],
|
||||||
|
[userNameAsyncValidator(this.server, this.userService)]),
|
||||||
full_name: new FormControl(),
|
full_name: new FormControl(),
|
||||||
email: new FormControl(null, [Validators.email, Validators.required]),
|
email: new FormControl(null,
|
||||||
|
[Validators.email, Validators.required],
|
||||||
|
[userEmailAsyncValidator(this.server, this.userService)]),
|
||||||
password: new FormControl(null,
|
password: new FormControl(null,
|
||||||
[Validators.required, Validators.minLength(6), Validators.maxLength(100)]),
|
[Validators.required, Validators.minLength(6), Validators.maxLength(100)]),
|
||||||
is_active: new FormControl(true),
|
is_active: new FormControl(true)
|
||||||
is_superadmin: new FormControl(false)
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get form() {
|
||||||
|
return this.addUserForm.controls;
|
||||||
|
}
|
||||||
|
|
||||||
onCancelClick() {
|
onCancelClick() {
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
import {Server} from "../../../models/server";
|
||||||
|
import {UserService} from "../../../services/user.service";
|
||||||
|
import {FormControl} from "@angular/forms";
|
||||||
|
import {timer} from "rxjs";
|
||||||
|
import {map, switchMap} from "rxjs/operators";
|
||||||
|
|
||||||
|
export const userEmailAsyncValidator = (server: Server, userService: UserService) => {
|
||||||
|
return (control: FormControl) => {
|
||||||
|
return timer(500).pipe(
|
||||||
|
switchMap(() => userService.list(server)),
|
||||||
|
map((response) => {
|
||||||
|
return (response.find((n) => n.email === control.value) ? { emailExists: true } : null);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
@ -0,0 +1,16 @@
|
|||||||
|
import {Server} from "../../../models/server";
|
||||||
|
import {FormControl} from "@angular/forms";
|
||||||
|
import {timer} from "rxjs";
|
||||||
|
import {map, switchMap} from "rxjs/operators";
|
||||||
|
import {UserService} from "../../../services/user.service";
|
||||||
|
|
||||||
|
export const userNameAsyncValidator = (server: Server, userService: UserService) => {
|
||||||
|
return (control: FormControl) => {
|
||||||
|
return timer(500).pipe(
|
||||||
|
switchMap(() => userService.list(server)),
|
||||||
|
map((response) => {
|
||||||
|
return (response.find((n) => n.username === control.value) ? { userExists: true } : null);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
@ -35,32 +35,40 @@
|
|||||||
</mat-cell>
|
</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="username">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header> Username </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row">
|
<mat-cell *matCellDef="let row">
|
||||||
<a class="table-link">{{ row.username }}</a>
|
<a class="table-link" [matTooltip]="row.username" >{{ row.username }}</a>
|
||||||
|
</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
<ng-container matColumnDef="full_name">
|
||||||
|
<mat-header-cell *matHeaderCellDef mat-sort-header> Full Name </mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row">
|
||||||
|
<div [matTooltip]="row.full_name" class="overflow-col">{{ row.full_name }}</div>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container matColumnDef="email">
|
<ng-container matColumnDef="email">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Mail </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header> Mail </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row">{{ row.email }}</mat-cell>
|
<mat-cell *matCellDef="let row">
|
||||||
|
<div [matTooltip]="row.email" matTooltipClass="custom-tooltip" class="overflow-col">{{ row.email }}</div>
|
||||||
|
</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container matColumnDef="is_active">
|
<ng-container matColumnDef="is_active">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Active </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header class="active-col"> Active </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row">{{row.is_active}}</mat-cell>
|
<mat-cell *matCellDef="let row" class="active-col">{{row.is_active}}</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container matColumnDef="is_superadmin">
|
<ng-container matColumnDef="last_login">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Admin </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header> Last Login </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row">{{row.is_superadmin}}</mat-cell>
|
<mat-cell *matCellDef="let row" class="overflow-col">{{row.last_login}}</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container matColumnDef="updated_at">
|
<ng-container matColumnDef="updated_at">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Last Update </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header> Last Update </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row">{{row.updated_at ? row.updated_at : row.created_at}}</mat-cell>
|
<mat-cell *matCellDef="let row" class="overflow-col">{{row.updated_at ? row.updated_at : row.created_at}}</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="delete">
|
<ng-container matColumnDef="delete">
|
||||||
<mat-header-cell *matHeaderCellDef> </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef class="small-col"> </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row"><button mat-button (click)="onDelete(row)"><mat-icon>delete</mat-icon></button></mat-cell>
|
<mat-cell *matCellDef="let row" class="small-col"><button mat-button (click)="onDelete(row)"><mat-icon>delete</mat-icon></button></mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||||
|
@ -11,5 +11,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.small-col {
|
.small-col {
|
||||||
|
flex-grow: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-col {
|
||||||
flex-grow: 0.5;
|
flex-grow: 0.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.overflow-col {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-tooltip {
|
||||||
|
font-size:100px;
|
||||||
|
}
|
||||||
|
@ -34,7 +34,7 @@ export class UserManagementComponent implements OnInit {
|
|||||||
server: Server;
|
server: Server;
|
||||||
dataSource: UserDataSource;
|
dataSource: UserDataSource;
|
||||||
userDatabase = new UserDatabase();
|
userDatabase = new UserDatabase();
|
||||||
displayedColumns = ['select', 'name', 'email', 'is_active', 'is_superadmin', 'updated_at', 'delete'];
|
displayedColumns = ['select', 'username', 'full_name', 'email', 'is_active', 'last_login', 'updated_at', 'delete'];
|
||||||
selection = new SelectionModel<User>(true, []);
|
selection = new SelectionModel<User>(true, []);
|
||||||
searchText: string = '';
|
searchText: string = '';
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@ export class UserFilterPipe implements PipeTransform {
|
|||||||
searchText = searchText.toLowerCase();
|
searchText = searchText.toLowerCase();
|
||||||
return items.userDatabase.data.filter((item) => {
|
return items.userDatabase.data.filter((item) => {
|
||||||
return (item.username && item.username.toLowerCase().includes(searchText))
|
return (item.username && item.username.toLowerCase().includes(searchText))
|
||||||
|
|| (item.full_name && item.full_name.toLowerCase().includes(searchText))
|
||||||
|| (item.email && item.email.toLowerCase().includes(searchText));
|
|| (item.email && item.email.toLowerCase().includes(searchText));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user