mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-22 14:22:21 +00:00
user management, create edit user detail dialog
This commit is contained in:
parent
eb5437d005
commit
cbeca9d0ca
@ -474,7 +474,7 @@ import { DeleteUserDialogComponent } from './components/user-management/delete-u
|
|||||||
AddUserDialogComponent,
|
AddUserDialogComponent,
|
||||||
UserFilterPipe,
|
UserFilterPipe,
|
||||||
DeleteGroupDialogComponent,
|
DeleteGroupDialogComponent,
|
||||||
DeleteUserDialogComponent
|
DeleteUserDialogComponent,
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<mat-form-field class="input-field">
|
<mat-form-field class="input-field">
|
||||||
<input matInput type="text" formControlName="password" placeholder="Password" />
|
<input matInput type="password" formControlName="password" placeholder="Password" />
|
||||||
<mat-error *ngIf="form.password?.touched && form.password?.errors"
|
<mat-error *ngIf="form.password?.touched && form.password?.errors"
|
||||||
>A password between 6 and 100 characters is required.</mat-error>
|
>A password between 6 and 100 characters is required.</mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
@ -65,7 +65,6 @@ export class AddUserDialogComponent implements OnInit {
|
|||||||
const newUser = this.addUserForm.value;
|
const newUser = this.addUserForm.value;
|
||||||
this.userService.add(this.server, newUser)
|
this.userService.add(this.server, newUser)
|
||||||
.subscribe((user: User) => {
|
.subscribe((user: User) => {
|
||||||
console.log("Done ", user)
|
|
||||||
this.toasterService.success(`User ${user.username} added`);
|
this.toasterService.success(`User ${user.username} added`);
|
||||||
this.dialogRef.close();
|
this.dialogRef.close();
|
||||||
},
|
},
|
||||||
|
@ -16,12 +16,12 @@ import {FormControl} from "@angular/forms";
|
|||||||
import {timer} from "rxjs";
|
import {timer} from "rxjs";
|
||||||
import {map, switchMap} from "rxjs/operators";
|
import {map, switchMap} from "rxjs/operators";
|
||||||
|
|
||||||
export const userEmailAsyncValidator = (server: Server, userService: UserService) => {
|
export const userEmailAsyncValidator = (server: Server, userService: UserService, except: string = '') => {
|
||||||
return (control: FormControl) => {
|
return (control: FormControl) => {
|
||||||
return timer(500).pipe(
|
return timer(500).pipe(
|
||||||
switchMap(() => userService.list(server)),
|
switchMap(() => userService.list(server)),
|
||||||
map((response) => {
|
map((response) => {
|
||||||
return (response.find((n) => n.email === control.value) ? { emailExists: true } : null);
|
return (response.find((n) => n.email === control.value && control.value !== except) ? { emailExists: true } : null);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -16,12 +16,12 @@ import {timer} from "rxjs";
|
|||||||
import {map, switchMap} from "rxjs/operators";
|
import {map, switchMap} from "rxjs/operators";
|
||||||
import {UserService} from "../../../services/user.service";
|
import {UserService} from "../../../services/user.service";
|
||||||
|
|
||||||
export const userNameAsyncValidator = (server: Server, userService: UserService) => {
|
export const userNameAsyncValidator = (server: Server, userService: UserService, except: string = '') => {
|
||||||
return (control: FormControl) => {
|
return (control: FormControl) => {
|
||||||
return timer(500).pipe(
|
return timer(500).pipe(
|
||||||
switchMap(() => userService.list(server)),
|
switchMap(() => userService.list(server)),
|
||||||
map((response) => {
|
map((response) => {
|
||||||
return (response.find((n) => n.username === control.value) ? { userExists: true } : null);
|
return (response.find((n) => n.username === control.value && control.value !== except) ? { userExists: true } : null);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
<h1 mat-dialog-title>Update user</h1>
|
||||||
|
<form [formGroup]="editUserForm" 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-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-error *ngIf="form.email?.errors && form.email?.errors.emailExists"
|
||||||
|
>User with this email exists</mat-error>
|
||||||
|
</mat-form-field>
|
||||||
|
|
||||||
|
|
||||||
|
<mat-form-field class="input-field">
|
||||||
|
<input matInput type="password" formControlName="password" placeholder="Password" />
|
||||||
|
<mat-error *ngIf="form.password?.touched && form.password?.errors"
|
||||||
|
>Password must be between 6 and 100 characters</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>
|
||||||
|
<button mat-button (click)="onEditClick()" tabindex="2" mat-raised-button color="primary"
|
||||||
|
[disabled]="!editUserForm.valid">
|
||||||
|
Edit user
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
@ -0,0 +1,8 @@
|
|||||||
|
.input-field {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.button-div {
|
||||||
|
float: right;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { EditUserDialogComponent } from './edit-user-dialog.component';
|
||||||
|
|
||||||
|
describe('EditUserDialogComponent', () => {
|
||||||
|
let component: EditUserDialogComponent;
|
||||||
|
let fixture: ComponentFixture<EditUserDialogComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [ EditUserDialogComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(EditUserDialogComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Software Name : GNS3 Web UI
|
||||||
|
* Version: 3
|
||||||
|
* SPDX-FileCopyrightText: Copyright (c) 2022 Orange Business Services
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* This software is distributed under the GPL-3.0 or any later version,
|
||||||
|
* the text of which is available at https://www.gnu.org/licenses/gpl-3.0.txt
|
||||||
|
* or see the "LICENSE" file for more details.
|
||||||
|
*
|
||||||
|
* Author: Sylvain MATHIEU, Elise LEBEAU
|
||||||
|
*/
|
||||||
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
|
import {FormControl, FormGroup, Validators} from "@angular/forms";
|
||||||
|
import {Server} from "@models/server";
|
||||||
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
|
import {UserService} from "@services/user.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";
|
||||||
|
import {User} from "@models/users/user";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-edit-user-dialog',
|
||||||
|
templateUrl: './edit-user-dialog.component.html',
|
||||||
|
styleUrls: ['./edit-user-dialog.component.scss']
|
||||||
|
})
|
||||||
|
export class EditUserDialogComponent implements OnInit {
|
||||||
|
|
||||||
|
editUserForm: FormGroup;
|
||||||
|
|
||||||
|
constructor(public dialogRef: MatDialogRef<EditUserDialogComponent>,
|
||||||
|
public userService: UserService,
|
||||||
|
private toasterService: ToasterService,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: { user: User, server: Server }) {}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.editUserForm = new FormGroup({
|
||||||
|
username: new FormControl(this.data.user.username, [
|
||||||
|
Validators.required,
|
||||||
|
Validators.minLength(3),
|
||||||
|
Validators.pattern("[a-zA-Z0-9_-]+$")],
|
||||||
|
[userNameAsyncValidator(this.data.server, this.userService, this.data.user.username)]),
|
||||||
|
full_name: new FormControl(this.data.user.full_name),
|
||||||
|
email: new FormControl(this.data.user.email,
|
||||||
|
[Validators.email, Validators.required],
|
||||||
|
[userEmailAsyncValidator(this.data.server, this.userService, this.data.user.email)]),
|
||||||
|
password: new FormControl(null,
|
||||||
|
[Validators.minLength(6), Validators.maxLength(100)]),
|
||||||
|
is_active: new FormControl(this.data.user.is_active)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get form() {
|
||||||
|
return this.editUserForm.controls;
|
||||||
|
}
|
||||||
|
|
||||||
|
onCancelClick() {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
onEditClick() {
|
||||||
|
if (!this.editUserForm.valid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const updatedUser = this.editUserForm.value;
|
||||||
|
|
||||||
|
updatedUser.user_id = this.data.user.user_id;
|
||||||
|
console.log(updatedUser)
|
||||||
|
this.userService.update(this.data.server, updatedUser)
|
||||||
|
.subscribe((user: User) => {
|
||||||
|
console.log("Done ", user)
|
||||||
|
this.toasterService.success(`User ${user.username} updated`);
|
||||||
|
this.dialogRef.close();
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
this.toasterService.error('Cannot update user : ' + error);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -38,7 +38,7 @@
|
|||||||
<ng-container matColumnDef="username">
|
<ng-container matColumnDef="username">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Username </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" [matTooltip]="row.username" >{{ row.username }}</a>
|
<a class="table-link" [matTooltip]="row.username" (click)="onEdit(row)">{{ row.username }}</a>
|
||||||
</mat-cell>
|
</mat-cell>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container matColumnDef="full_name">
|
<ng-container matColumnDef="full_name">
|
||||||
|
@ -26,6 +26,7 @@ import {DeleteUserDialogComponent} from "@components/user-management/delete-user
|
|||||||
import {ToasterService} from "@services/toaster.service";
|
import {ToasterService} from "@services/toaster.service";
|
||||||
import {MatPaginator} from "@angular/material/paginator";
|
import {MatPaginator} from "@angular/material/paginator";
|
||||||
import {MatTableDataSource} from "@angular/material/table";
|
import {MatTableDataSource} from "@angular/material/table";
|
||||||
|
import {EditUserDialogComponent} from "@components/user-management/edit-user-dialog/edit-user-dialog.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-user-management',
|
selector: 'app-user-management',
|
||||||
@ -143,4 +144,13 @@ export class UserManagementComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onEdit(user: User) {
|
||||||
|
this.dialog
|
||||||
|
.open(EditUserDialogComponent, {width: '500px', data: {user: user, server: this.server}})
|
||||||
|
.afterClosed()
|
||||||
|
.subscribe(() => {
|
||||||
|
this.refresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,16 +20,14 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add(server: Server, user: any): Observable<User> {
|
add(server: Server, user: any): Observable<User> {
|
||||||
return this.httpServer.post<User>(server, `/users`, {
|
return this.httpServer.post<User>(server, `/users`, user);
|
||||||
username: user.username,
|
|
||||||
is_active: user.is_active,
|
|
||||||
email: user.email,
|
|
||||||
full_name: user.full_name,
|
|
||||||
password: user.password
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(server: Server, user_id: string) {
|
delete(server: Server, user_id: string) {
|
||||||
return this.httpServer.delete(server, `/users/${user_id}`);
|
return this.httpServer.delete(server, `/users/${user_id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update(server: Server, user: User): Observable<User> {
|
||||||
|
return this.httpServer.put<User>(server, `/users/${user.user_id}`, user);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user