New group, add user to group functionality

This commit is contained in:
Lebeau Elise 2022-02-03 08:48:44 +00:00 committed by Sylvain MATHIEU
parent 707f5b6c7f
commit 7bff9b40de
8 changed files with 172 additions and 14 deletions

View File

@ -312,6 +312,7 @@ import {MatFormFieldModule} from "@angular/material/form-field";
import { PermissionsFilterPipe } from './components/permissions-management/permissions-filter.pipe'; import { PermissionsFilterPipe } from './components/permissions-management/permissions-filter.pipe';
import { PermissionsTypeFilterPipe } from './components/permissions-management/permissions-type-filter.pipe'; import { PermissionsTypeFilterPipe } from './components/permissions-management/permissions-type-filter.pipe';
import { DisplayPathPipe } from './components/permissions-management/display-path.pipe'; import { DisplayPathPipe } from './components/permissions-management/display-path.pipe';
import {RolePermissionsComponent} from "@components/role-management/role-detail/role-permissions/role-permissions.component";
@NgModule({ @NgModule({
declarations: [ declarations: [
@ -536,7 +537,8 @@ import { DisplayPathPipe } from './components/permissions-management/display-pat
PermissionsFilterPipe, PermissionsFilterPipe,
PermissionsTypeFilterPipe, PermissionsTypeFilterPipe,
FilterCompletePipe, FilterCompletePipe,
DisplayPathPipe DisplayPathPipe,
RolePermissionsComponent
], ],
imports: [ imports: [
BrowserModule, BrowserModule,

View File

@ -19,10 +19,51 @@
>Group with this name exists</mat-error >Group with this name exists</mat-error
> >
</mat-form-field> </mat-form-field>
<div mat-dialog-actions> </form>
<h5>Add users to group: </h5>
<div class="filter">
<mat-form-field class="input-field">
<mat-label>Search user </mat-label>
<input matInput type="text" [(ngModel)]="searchText" >
</mat-form-field>
</div>
<div class="users">
<div class="col">
Users available :
<div *ngFor="let user of users">
<div class="userList" *ngIf="toDisplay(user)">
<div>{{user.username}}</div>
<div>{{user.email}}</div>
<mat-icon (click)="addUser(user)">add</mat-icon>
</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 mat-dialog-actions class="button-div">
<button mat-button (click)="onNoClick()" color="accent">Cancel</button> <button mat-button (click)="onNoClick()" color="accent">Cancel</button>
<button mat-button (click)="onAddClick()" tabindex="2" class="add-project-button" mat-raised-button color="primary"> <button mat-button (click)="onAddClick()" tabindex="2" class="add-project-button" mat-raised-button color="primary">
Add group Add group
</button> </button>
</div> </div>
</form>

View File

@ -5,3 +5,20 @@
.project-snackbar { .project-snackbar {
background: #2196f3; background: #2196f3;
} }
.userList {
display: flex;
margin: 10px;
justify-content: space-between;
flex: 1 1 auto
}
.users {
display: flex;
height: 350px;
overflow: auto;
}
.button-div {
float: right;
}

View File

@ -17,6 +17,11 @@ import {groupNameAsyncValidator} from "@components/group-management/add-group-di
import {GroupNameValidator} from "@components/group-management/add-group-dialog/GroupNameValidator"; import {GroupNameValidator} from "@components/group-management/add-group-dialog/GroupNameValidator";
import {GroupService} from "../../../services/group.service"; import {GroupService} from "../../../services/group.service";
import {Server} from "../../../models/server"; import {Server} from "../../../models/server";
import {BehaviorSubject, forkJoin, timer} from "rxjs";
import {User} from "@models/users/user";
import {UserService} from "@services/user.service";
import {ToasterService} from "@services/toaster.service";
import {PageEvent} from "@angular/material/paginator";
@Component({ @Component({
selector: 'app-add-group-dialog', selector: 'app-add-group-dialog',
@ -27,15 +32,26 @@ import {Server} from "../../../models/server";
export class AddGroupDialogComponent implements OnInit { export class AddGroupDialogComponent implements OnInit {
groupNameForm: FormGroup; groupNameForm: FormGroup;
server: Server;
users: Set<User>;
usersToAdd: Set<User> = new Set([]);
searchText: string;
loading = false;
constructor(private dialogRef: MatDialogRef<AddGroupDialogComponent>, constructor(private dialogRef: MatDialogRef<AddGroupDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: { server: Server }, @Inject(MAT_DIALOG_DATA) public data: { server: Server },
private formBuilder: FormBuilder, private formBuilder: FormBuilder,
private groupNameValidator: GroupNameValidator, private groupNameValidator: GroupNameValidator,
private groupService: GroupService) { private groupService: GroupService,
private userService: UserService,
private toasterService: ToasterService) {
} }
ngOnInit(): void { ngOnInit(): void {
this.server = this.data.server;
this.groupNameForm = this.formBuilder.group({ this.groupNameForm = this.formBuilder.group({
groupName: new FormControl( groupName: new FormControl(
null, null,
@ -43,6 +59,7 @@ export class AddGroupDialogComponent implements OnInit {
[groupNameAsyncValidator(this.data.server, this.groupService)] [groupNameAsyncValidator(this.data.server, this.groupService)]
), ),
}); });
this.getUsers();
} }
onKeyDown(event) { onKeyDown(event) {
@ -60,10 +77,58 @@ export class AddGroupDialogComponent implements OnInit {
return; return;
} }
const groupName = this.groupNameForm.controls['groupName'].value; const groupName = this.groupNameForm.controls['groupName'].value;
this.dialogRef.close(groupName); const toAdd = Array.from(this.usersToAdd.values());
this.groupService.addGroup(this.server, groupName)
.subscribe((group) => {
toAdd.forEach((user: User) => {
this.groupService.addMemberToGroup(this.server, group, user)
.subscribe(() => {
this.toasterService.success(`user ${user.username} was added`);
},
(error) => {
this.toasterService.error(`An error occur while trying to add user ${user.username} to group ${groupName}`);
})
})
this.dialogRef.close(true);
}, (error) => {
this.toasterService.error(`An error occur while trying to create new group ${groupName}`);
this.dialogRef.close(false);
});
} }
onNoClick() { onNoClick() {
this.dialogRef.close(); this.dialogRef.close();
} }
get toDisplay() {
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.users.delete(user);
}
delUser(user: User) {
this.usersToAdd.delete(user);
this.users.add(user);
}
} }

View File

@ -26,6 +26,8 @@ import {forkJoin} from "rxjs";
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 {User} from "@models/users/user";
@Component({ @Component({
selector: 'app-group-management', selector: 'app-group-management',
templateUrl: './group-management.component.html', templateUrl: './group-management.component.html',
@ -91,16 +93,11 @@ export class GroupManagementComponent implements OnInit {
addGroup() { addGroup() {
this.dialog this.dialog
.open(AddGroupDialogComponent, {width: '250px', height: '250px', data: {server: this.server}}) .open(AddGroupDialogComponent, {width: '1000px', height: '700px', data: {server: this.server}})
.afterClosed() .afterClosed()
.subscribe((name: string) => { .subscribe((added: boolean) => {
if (name) { if (added) {
this.groupService.addGroup(this.server, name) this.refresh();
.subscribe(() => {
this.refresh();
}, (error) => {
this.toasterService.error(`An error occur while trying to create new group ${name}`);
});
} }
}); });
} }

View File

@ -1,3 +1,15 @@
/*
* 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 {SubPath} from "./SubPath"; import {SubPath} from "./SubPath";
export class PermissionPath { export class PermissionPath {

View File

@ -1,3 +1,15 @@
/*
* 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
*/
export class SubPath { export class SubPath {
constructor(public value: string, constructor(public value: string,
public displayValue: string, public displayValue: string,

View File

@ -1,3 +1,15 @@
/*
* 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 {Pipe, PipeTransform} from '@angular/core'; import {Pipe, PipeTransform} from '@angular/core';
import {map, switchMap} from "rxjs/operators"; import {map, switchMap} from "rxjs/operators";
import {forkJoin, Observable, of} from "rxjs"; import {forkJoin, Observable, of} from "rxjs";