mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-01-20 11:38:59 +00:00
New group, add user to group functionality
This commit is contained in:
parent
707f5b6c7f
commit
7bff9b40de
@ -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,
|
||||||
|
@ -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>
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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}`);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
|
@ -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";
|
||||||
|
Loading…
Reference in New Issue
Block a user