remove is_admin field in user management list and add field validation on create a new user

This commit is contained in:
Lebeau Elise 2021-12-10 13:51:19 +00:00 committed by Sylvain MATHIEU
parent 0c0d77e220
commit 11029db956
9 changed files with 100 additions and 26 deletions

View File

@ -2,19 +2,33 @@
<form [formGroup]="addUserForm" class="input-field">
<mat-form-field class="input-field">
<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 class="input-field">
<input matInput type="text" formControlName="full_name" placeholder="Full name" />
</mat-form-field>
<mat-form-field class="input-field">
<input matInput type="text" formControlName="email" placeholder="Email" />
</mat-form-field>
<mat-form-field class="input-field">
<input matInput type="text" formControlName="password" placeholder="Password" />
<mat-error *ngIf="form.email?.touched && form.email?.errors && form.email?.errors.required"
>Email is required</mat-error>
<mat-error *ngIf="form.email?.errors && form.email?.errors.email"
>Email is invalid</mat-error>
</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">
<button mat-button (click)="onCancelClick()" color="accent">Cancel</button>

View File

@ -2,10 +2,6 @@
width: 100%;
}
.checkbox-field {
display: block;
margin-bottom: 5px;
}
.button-div {
float: right;

View File

@ -17,6 +17,8 @@ import {UserService} from "@services/user.service";
import {Server} from "@models/server";
import {User} from "@models/users/user";
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({
selector: 'app-add-user-dialog',
@ -36,16 +38,22 @@ export class AddUserDialogComponent implements OnInit {
username: new FormControl(null, [
Validators.required,
Validators.minLength(3),
Validators.pattern("[a-zA-Z0-9_-]+$")]),
Validators.pattern("[a-zA-Z0-9_-]+$")],
[userNameAsyncValidator(this.server, this.userService)]),
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,
[Validators.required, Validators.minLength(6), Validators.maxLength(100)]),
is_active: new FormControl(true),
is_superadmin: new FormControl(false)
is_active: new FormControl(true)
});
}
get form() {
return this.addUserForm.controls;
}
onCancelClick() {
this.dialogRef.close();
}

View File

@ -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);
})
);
};
};

View File

@ -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);
})
);
};
};

View File

@ -35,32 +35,40 @@
</mat-cell>
</ng-container>
<ng-container matColumnDef="name">
<mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
<ng-container matColumnDef="username">
<mat-header-cell *matHeaderCellDef mat-sort-header> Username </mat-header-cell>
<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>
</ng-container>
<ng-container matColumnDef="email">
<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 matColumnDef="is_active">
<mat-header-cell *matHeaderCellDef mat-sort-header> Active </mat-header-cell>
<mat-cell *matCellDef="let row">{{row.is_active}}</mat-cell>
<mat-header-cell *matHeaderCellDef mat-sort-header class="active-col"> Active </mat-header-cell>
<mat-cell *matCellDef="let row" class="active-col">{{row.is_active}}</mat-cell>
</ng-container>
<ng-container matColumnDef="is_superadmin">
<mat-header-cell *matHeaderCellDef mat-sort-header> Admin </mat-header-cell>
<mat-cell *matCellDef="let row">{{row.is_superadmin}}</mat-cell>
<ng-container matColumnDef="last_login">
<mat-header-cell *matHeaderCellDef mat-sort-header> Last Login </mat-header-cell>
<mat-cell *matCellDef="let row" class="overflow-col">{{row.last_login}}</mat-cell>
</ng-container>
<ng-container matColumnDef="updated_at">
<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 matColumnDef="delete">
<mat-header-cell *matHeaderCellDef> </mat-header-cell>
<mat-cell *matCellDef="let row"><button mat-button (click)="onDelete(row)"><mat-icon>delete</mat-icon></button></mat-cell>
<mat-header-cell *matHeaderCellDef class="small-col"> </mat-header-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>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>

View File

@ -11,5 +11,20 @@
}
.small-col {
flex-grow: 0.3;
}
.active-col {
flex-grow: 0.5;
}
.overflow-col {
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
padding-right: 5px;
}
.custom-tooltip {
font-size:100px;
}

View File

@ -34,7 +34,7 @@ export class UserManagementComponent implements OnInit {
server: Server;
dataSource: UserDataSource;
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, []);
searchText: string = '';

View File

@ -24,6 +24,7 @@ export class UserFilterPipe implements PipeTransform {
searchText = searchText.toLowerCase();
return items.userDatabase.data.filter((item) => {
return (item.username && item.username.toLowerCase().includes(searchText))
|| (item.full_name && item.full_name.toLowerCase().includes(searchText))
|| (item.email && item.email.toLowerCase().includes(searchText));
});
}