add user to groups when creating user + refactor add users when creating group

This commit is contained in:
Lebeau Elise 2022-02-07 14:48:44 +00:00 committed by Sylvain MATHIEU
parent c400ad551e
commit 02285265e3
7 changed files with 142 additions and 59 deletions

View File

@ -22,39 +22,27 @@
</form> </form>
<h5>Add users to group: </h5> <h5>Add users to group: </h5>
<div class="filter"> <mat-form-field class="input-field">
<mat-form-field class="input-field"> <mat-label>Users</mat-label>
<mat-label>Search user </mat-label> <input type="text"
<input matInput type="text" [(ngModel)]="searchText" > matInput
</mat-form-field> [matAutocomplete]="auto"
</div> [formControl]="autocompleteControl">
<mat-autocomplete #auto="matAutocomplete"[displayWith]="displayFn" (optionSelected)='selectedUser($event.option.value)'>
<mat-option *ngFor="let user of filteredUsers | async" [value]="user" >
{{user.username}} - {{user.email}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="users"> <div class="users">
<div class="col"> <div *ngFor="let user of usersToAdd">
Users available : <div class="userList">
<div *ngFor="let user of users"> <div>{{user.username}}</div>
<div class="userList" *ngIf="toDisplay(user)"> <div>{{user.email}}</div>
<div>{{user.username}}</div> <mat-icon (click)="delUser(user)">delete</mat-icon>
<div>{{user.email}}</div>
<mat-icon (click)="addUser(user)">add</mat-icon>
</div>
</div> </div>
</div> </div>
<mat-divider [vertical]="true"></mat-divider>
<div class="col">
Users to add :
<div *ngFor="let user of usersToAdd">
<div class="userList" *ngIf="toDisplay(user)">
<div>{{user.username}}</div>
<div>{{user.email}}</div>
<mat-icon (click)="delUser(user)">delete</mat-icon>
</div>
</div>
</div>
</div> </div>

View File

@ -10,13 +10,14 @@
display: flex; display: flex;
margin: 10px; margin: 10px;
justify-content: space-between; justify-content: space-between;
flex: 1 1 auto flex: 1 1 auto;
} }
.users { .users {
display: flex; display: flex;
height: 350px; height: 180px;
overflow: auto; overflow: auto;
flex-direction: column;
} }
.button-div { .button-div {

View File

@ -22,6 +22,9 @@ import {User} from "@models/users/user";
import {UserService} from "@services/user.service"; import {UserService} from "@services/user.service";
import {ToasterService} from "@services/toaster.service"; import {ToasterService} from "@services/toaster.service";
import {PageEvent} from "@angular/material/paginator"; import {PageEvent} from "@angular/material/paginator";
import {Observable} from "rxjs/Rx";
import {Group} from "@models/groups/group";
import {map, startWith} from "rxjs/operators";
@Component({ @Component({
selector: 'app-add-group-dialog', selector: 'app-add-group-dialog',
@ -34,11 +37,12 @@ export class AddGroupDialogComponent implements OnInit {
groupNameForm: FormGroup; groupNameForm: FormGroup;
server: Server; server: Server;
users: Set<User>; users: User[];
usersToAdd: Set<User> = new Set([]); usersToAdd: Set<User> = new Set([]);
filteredUsers: Observable<User[]>
searchText: string;
loading = false; loading = false;
autocompleteControl = new FormControl();
constructor(private dialogRef: MatDialogRef<AddGroupDialogComponent>, constructor(private dialogRef: MatDialogRef<AddGroupDialogComponent>,
@ -59,7 +63,14 @@ export class AddGroupDialogComponent implements OnInit {
[groupNameAsyncValidator(this.data.server, this.groupService)] [groupNameAsyncValidator(this.data.server, this.groupService)]
), ),
}); });
this.getUsers(); this.userService.list(this.server)
.subscribe((users: User[]) => {
this.users = users;
this.filteredUsers = this.autocompleteControl.valueChanges.pipe(
startWith(''),
map(value => this._filter(value)),
);
})
} }
onKeyDown(event) { onKeyDown(event) {
@ -102,33 +113,25 @@ export class AddGroupDialogComponent implements OnInit {
this.dialogRef.close(); this.dialogRef.close();
} }
get toDisplay() { selectedUser(user: User) {
return (user: User) => !this.searchText || user.username.includes(this.searchText) || user.email?.includes(this.searchText);
}
getUsers() {
this.userService.list(this.data.server)
.subscribe((users) => {
if (this.usersToAdd) {
users = users.filter((user: User) => {
return !this.usersToAdd.has(user);
});
}
this.users = new Set(users);
});
}
addUser(user: User) {
this.usersToAdd.add(user); this.usersToAdd.add(user);
this.users.delete(user);
} }
delUser(user: User) { delUser(user: User) {
this.usersToAdd.delete(user); this.usersToAdd.delete(user);
this.users.add(user); }
private _filter(value: string): User[] {
if (typeof value === 'string') {
const filterValue = value.toLowerCase();
return this.users.filter(option => option.username.toLowerCase().includes(filterValue)
|| (option.email?.toLowerCase().includes(filterValue)));
}
}
displayFn(value): string {
return value && value.username ? value.username : '';
} }
} }

View File

@ -93,7 +93,7 @@ export class GroupManagementComponent implements OnInit {
addGroup() { addGroup() {
this.dialog this.dialog
.open(AddGroupDialogComponent, {width: '1000px', height: '700px', data: {server: this.server}}) .open(AddGroupDialogComponent, {width: '600px', height: '500px', data: {server: this.server}})
.afterClosed() .afterClosed()
.subscribe((added: boolean) => { .subscribe((added: boolean) => {
if (added) { if (added) {

View File

@ -29,6 +29,31 @@
<mat-checkbox formControlName="is_active">Is active</mat-checkbox> <mat-checkbox formControlName="is_active">Is active</mat-checkbox>
<mat-divider class="my-2"></mat-divider>
<h6> Add user to groups : </h6>
<mat-form-field class="input-field">
<mat-label>Groups</mat-label>
<input type="text"
matInput
[matAutocomplete]="auto"
[formControl]="autocompleteControl">
<mat-autocomplete #auto="matAutocomplete"[displayWith]="displayFn" (optionSelected)='selectedGroup($event.option.value)'>
<mat-option *ngFor="let group of filteredGroups | async" [value]="group" >
{{group.name}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
<div class="groups">
<div *ngFor="let group of groupsToAdd">
<div class="groupList">
<div>{{group.name}}</div>
<mat-icon (click)="deleteGroup(group)" >delete</mat-icon>
</div>
</div>
</div>
<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>

View File

@ -6,3 +6,17 @@
.button-div { .button-div {
float: right; float: right;
} }
.groupList {
display: flex;
margin: 10px;
justify-content: space-between;
flex: 1 1 auto
}
.groups {
display: flex;
height: 180px;
overflow: auto;
flex-direction: column;
}

View File

@ -19,6 +19,12 @@ 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 {userNameAsyncValidator} from "@components/user-management/add-user-dialog/userNameAsyncValidator";
import {userEmailAsyncValidator} from "@components/user-management/add-user-dialog/userEmailAsyncValidator"; import {userEmailAsyncValidator} from "@components/user-management/add-user-dialog/userEmailAsyncValidator";
import {BehaviorSubject} from "rxjs";
import {Group} from "@models/groups/group";
import {GroupService} from "@services/group.service";
import {Observable} from "rxjs/Rx";
import {startWith} from "rxjs/operators";
import {map} from "rxjs//operators";
@Component({ @Component({
selector: 'app-add-user-dialog', selector: 'app-add-user-dialog',
@ -29,9 +35,15 @@ export class AddUserDialogComponent implements OnInit {
addUserForm: FormGroup; addUserForm: FormGroup;
server: Server; server: Server;
groups: Group[];
groupsToAdd: Set<Group> = new Set([]);
autocompleteControl = new FormControl();
filteredGroups: Observable<Group[]>;
constructor(public dialogRef: MatDialogRef<AddUserDialogComponent>, constructor(public dialogRef: MatDialogRef<AddUserDialogComponent>,
public userService: UserService, public userService: UserService,
private toasterService: ToasterService) { } private toasterService: ToasterService,
private groupService: GroupService) { }
ngOnInit(): void { ngOnInit(): void {
this.addUserForm = new FormGroup({ this.addUserForm = new FormGroup({
@ -48,6 +60,24 @@ export class AddUserDialogComponent implements OnInit {
[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)
}); });
this.groupService.getGroups(this.server)
.subscribe((groups: Group[]) => {
this.groups = groups;
this.filteredGroups = this.autocompleteControl.valueChanges.pipe(
startWith(''),
map(value => this._filter(value)),
);
})
}
private _filter(value: string): Group[] {
if (typeof value === 'string') {
const filterValue = value.toLowerCase();
return this.groups.filter(option => option.name.toLowerCase().includes(filterValue));
}
} }
get form() { get form() {
@ -63,13 +93,35 @@ export class AddUserDialogComponent implements OnInit {
return; return;
} }
const newUser = this.addUserForm.value; const newUser = this.addUserForm.value;
const toAdd = Array.from(this.groupsToAdd.values());
this.userService.add(this.server, newUser) this.userService.add(this.server, newUser)
.subscribe((user: User) => { .subscribe((user: User) => {
this.toasterService.success(`User ${user.username} added`); this.toasterService.success(`User ${user.username} added`);
toAdd.forEach((group: Group) => {
this.groupService.addMemberToGroup(this.server, group, user)
.subscribe(() => {
this.toasterService.success(`user ${user.username} was added to group ${group.name}`);
},
(error) => {
this.toasterService.error(`An error occur while trying to add user ${user.username} to group ${group.name}`);
})
})
this.dialogRef.close(); this.dialogRef.close();
}, },
(error) => { (error) => {
this.toasterService.error('Cannot create user : ' + error); this.toasterService.error('Cannot create user : ' + error);
}) })
} }
deleteGroup(group: Group) {
this.groupsToAdd.delete(group);
}
selectedGroup(value: any) {
this.groupsToAdd.add(value);
}
displayFn(value): string {
return value && value.name ? value.name : '';
}
} }