mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-06-22 08:30:09 +00:00
user management, add multiple user selection
This commit is contained in:
committed by
Sylvain MATHIEU
parent
4e207d270e
commit
0c0d77e220
@ -1,4 +1,7 @@
|
|||||||
<h1 mat-dialog-title>Are you sure to delete user named: '{{data.user.username}}' ?</h1>
|
<h1 mat-dialog-title>Are you sure you want to delete the following users ?</h1>
|
||||||
|
<ul>
|
||||||
|
<li *ngFor="let user of data.users">{{ user.username }} {{ user.full_name ? '- ' + user.full_name : '' }}</li>
|
||||||
|
</ul>
|
||||||
<div mat-dialog-actions class="button-div">
|
<div mat-dialog-actions class="button-div">
|
||||||
<button mat-button (click)="onCancel()" color="accent">No, cancel</button>
|
<button mat-button (click)="onCancel()" color="accent">No, cancel</button>
|
||||||
<button mat-button (click)="onDelete()" tabindex="2" class="add-project-button" mat-raised-button color="primary">
|
<button mat-button (click)="onDelete()" tabindex="2" class="add-project-button" mat-raised-button color="primary">
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
.button-div {
|
.button-div {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
@ -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 {Component, Inject, OnInit} from '@angular/core';
|
import {Component, Inject, OnInit} from '@angular/core';
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
||||||
import {User} from "@models/users/user";
|
import {User} from "@models/users/user";
|
||||||
@ -11,7 +23,7 @@ import {UserService} from "@services/user.service";
|
|||||||
export class DeleteUserDialogComponent implements OnInit {
|
export class DeleteUserDialogComponent implements OnInit {
|
||||||
|
|
||||||
constructor(private dialogRef: MatDialogRef<DeleteUserDialogComponent>,
|
constructor(private dialogRef: MatDialogRef<DeleteUserDialogComponent>,
|
||||||
@Inject(MAT_DIALOG_DATA) public data: { user: User }) { }
|
@Inject(MAT_DIALOG_DATA) public data: { users: User[] }) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
<div class="default-header">
|
<div class="default-header">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1 class="col">User Management</h1>
|
<h1 class="col">User Management</h1>
|
||||||
|
<button class="col" mat-raised-button color="primary" (click)="deleteMultiple()" class="add-button" [disabled]="selection.selected.length == 0">
|
||||||
|
Delete Users
|
||||||
|
</button>
|
||||||
<button class="col" mat-raised-button color="primary" (click)="addUser()" class="add-button">
|
<button class="col" mat-raised-button color="primary" (click)="addUser()" class="add-button">
|
||||||
Add User
|
Add User
|
||||||
</button>
|
</button>
|
||||||
@ -17,6 +20,21 @@
|
|||||||
<div class="default-content">
|
<div class="default-content">
|
||||||
<div class="mat-elevation-z8">
|
<div class="mat-elevation-z8">
|
||||||
<mat-table #table [dataSource]="dataSource | userFilter: searchText" matSort>
|
<mat-table #table [dataSource]="dataSource | userFilter: searchText" matSort>
|
||||||
|
<ng-container matColumnDef="select" >
|
||||||
|
<mat-header-cell *matHeaderCellDef class="small-col">
|
||||||
|
<mat-checkbox (change)="$event ? masterToggle() : null"
|
||||||
|
[checked]="selection.hasValue() && isAllSelected()"
|
||||||
|
[indeterminate]="selection.hasValue() && !isAllSelected()">
|
||||||
|
</mat-checkbox>
|
||||||
|
</mat-header-cell>
|
||||||
|
<mat-cell *matCellDef="let row" class="small-col">
|
||||||
|
<mat-checkbox (click)="$event.stopPropagation()"
|
||||||
|
(change)="$event ? selection.toggle(row) : null"
|
||||||
|
[checked]="selection.isSelected(row)">
|
||||||
|
</mat-checkbox>
|
||||||
|
</mat-cell>
|
||||||
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="name">
|
<ng-container matColumnDef="name">
|
||||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
|
<mat-header-cell *matHeaderCellDef mat-sort-header> Name </mat-header-cell>
|
||||||
<mat-cell *matCellDef="let row">
|
<mat-cell *matCellDef="let row">
|
||||||
|
@ -9,3 +9,7 @@
|
|||||||
margin-left: -470px;
|
margin-left: -470px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.small-col {
|
||||||
|
flex-grow: 0.5;
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@ import {UserService} from "@services/user.service";
|
|||||||
import {ProgressService} from "../../common/progress/progress.service";
|
import {ProgressService} from "../../common/progress/progress.service";
|
||||||
import {User} from "@models/users/user";
|
import {User} from "@models/users/user";
|
||||||
import {BehaviorSubject, merge, Observable} from "rxjs";
|
import {BehaviorSubject, merge, Observable} from "rxjs";
|
||||||
import {DataSource} from "@angular/cdk/collections";
|
import {DataSource, SelectionModel} from "@angular/cdk/collections";
|
||||||
import {map} from "rxjs/operators";
|
import {map} from "rxjs/operators";
|
||||||
import {AddUserDialogComponent} from "@components/user-management/add-user-dialog/add-user-dialog.component";
|
import {AddUserDialogComponent} from "@components/user-management/add-user-dialog/add-user-dialog.component";
|
||||||
import {MatDialog} from "@angular/material/dialog";
|
import {MatDialog} from "@angular/material/dialog";
|
||||||
@ -34,8 +34,8 @@ export class UserManagementComponent implements OnInit {
|
|||||||
server: Server;
|
server: Server;
|
||||||
dataSource: UserDataSource;
|
dataSource: UserDataSource;
|
||||||
userDatabase = new UserDatabase();
|
userDatabase = new UserDatabase();
|
||||||
displayedColumns = ['name', 'email', 'is_active', 'is_superadmin', 'updated_at', 'delete'];
|
displayedColumns = ['select', 'name', 'email', 'is_active', 'is_superadmin', 'updated_at', 'delete'];
|
||||||
|
selection = new SelectionModel<User>(true, []);
|
||||||
searchText: string = '';
|
searchText: string = '';
|
||||||
|
|
||||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||||
@ -84,7 +84,7 @@ export class UserManagementComponent implements OnInit {
|
|||||||
|
|
||||||
onDelete(user: User) {
|
onDelete(user: User) {
|
||||||
this.dialog
|
this.dialog
|
||||||
.open(DeleteUserDialogComponent, {width: '500px', data: {user: user}})
|
.open(DeleteUserDialogComponent, {width: '500px', data: {users: [user]}})
|
||||||
.afterClosed()
|
.afterClosed()
|
||||||
.subscribe((isDeletedConfirm) => {
|
.subscribe((isDeletedConfirm) => {
|
||||||
if (isDeletedConfirm) {
|
if (isDeletedConfirm) {
|
||||||
@ -97,6 +97,38 @@ export class UserManagementComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAllSelected() {
|
||||||
|
const numSelected = this.selection.selected.length;
|
||||||
|
const numRows = this.userDatabase.data.length;
|
||||||
|
return numSelected === numRows;
|
||||||
|
}
|
||||||
|
|
||||||
|
masterToggle() {
|
||||||
|
this.isAllSelected() ?
|
||||||
|
this.selection.clear() :
|
||||||
|
this.userDatabase.data.forEach(row => this.selection.select(row));
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteMultiple() {
|
||||||
|
this.dialog
|
||||||
|
.open(DeleteUserDialogComponent, {width: '500px', data: {users: this.selection.selected}})
|
||||||
|
.afterClosed()
|
||||||
|
.subscribe((isDeletedConfirm) => {
|
||||||
|
if (isDeletedConfirm) {
|
||||||
|
this.selection.selected.forEach((user: User) => {
|
||||||
|
this.userService.delete(this.server, user.user_id)
|
||||||
|
.subscribe(() => {
|
||||||
|
this.refresh()
|
||||||
|
}, (error) => {
|
||||||
|
this.toasterService.error(`An error occur while trying to delete user ${user.username}`);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
this.selection.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserDatabase {
|
export class UserDatabase {
|
||||||
|
@ -2,6 +2,7 @@ export interface User {
|
|||||||
created_at: string;
|
created_at: string;
|
||||||
email: string;
|
email: string;
|
||||||
full_name: string;
|
full_name: string;
|
||||||
|
last_login: string;
|
||||||
is_active: boolean;
|
is_active: boolean;
|
||||||
is_superadmin: boolean;
|
is_superadmin: boolean;
|
||||||
updated_at: string;
|
updated_at: string;
|
||||||
|
@ -20,7 +20,6 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
add(server: Server, user: any): Observable<User> {
|
add(server: Server, user: any): Observable<User> {
|
||||||
console.log(user)
|
|
||||||
return this.httpServer.post<User>(server, `/users`, {
|
return this.httpServer.post<User>(server, `/users`, {
|
||||||
username: user.username,
|
username: user.username,
|
||||||
is_active: user.is_active,
|
is_active: user.is_active,
|
||||||
|
Reference in New Issue
Block a user