mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-02-02 01:08:21 +00:00
user management, add paginator
This commit is contained in:
parent
11029db956
commit
596a11210f
@ -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 {Server} from "../../../models/server";
|
||||
import {UserService} from "../../../services/user.service";
|
||||
import {FormControl} from "@angular/forms";
|
||||
|
@ -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 {Server} from "../../../models/server";
|
||||
import {FormControl} from "@angular/forms";
|
||||
import {timer} from "rxjs";
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
<form>
|
||||
<mat-form-field class="full-width">
|
||||
<input matInput placeholder="Search by name" [(ngModel)]="searchText" [ngModelOptions]="{ standalone: true }" />
|
||||
<input matInput placeholder="Search by username, full name or email" [(ngModel)]="searchText" [ngModelOptions]="{ standalone: true }" />
|
||||
</mat-form-field>
|
||||
</form>
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
<ng-container matColumnDef="full_name">
|
||||
<mat-header-cell *matHeaderCellDef mat-sort-header> Full Name </mat-header-cell>
|
||||
<mat-cell *matCellDef="let row">
|
||||
<div [matTooltip]="row.full_name" class="overflow-col">{{ row.full_name }}</div>
|
||||
<div [matTooltip]="row.full_name" matTooltipClass="custom-tooltip" class="overflow-col">{{ row.full_name }}</div>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="email">
|
||||
@ -74,6 +74,11 @@
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns"></mat-row>
|
||||
</mat-table>
|
||||
|
||||
<mat-paginator [pageSizeOptions]="[5, 10, 20]"
|
||||
showFirstLastButtons
|
||||
aria-label="Select page">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,7 +13,7 @@
|
||||
import {Component, OnInit, ViewChild} from '@angular/core';
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {Server} from "@models/server";
|
||||
import {MatSort, MatSortable} from "@angular/material/sort";
|
||||
import {MatSort, MatSortable, Sort} from "@angular/material/sort";
|
||||
import {UserService} from "@services/user.service";
|
||||
import {ProgressService} from "../../common/progress/progress.service";
|
||||
import {User} from "@models/users/user";
|
||||
@ -24,6 +24,8 @@ import {AddUserDialogComponent} from "@components/user-management/add-user-dialo
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {DeleteUserDialogComponent} from "@components/user-management/delete-user-dialog/delete-user-dialog.component";
|
||||
import {ToasterService} from "@services/toaster.service";
|
||||
import {MatPaginator} from "@angular/material/paginator";
|
||||
import {MatTableDataSource} from "@angular/material/table";
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-management',
|
||||
@ -32,12 +34,12 @@ import {ToasterService} from "@services/toaster.service";
|
||||
})
|
||||
export class UserManagementComponent implements OnInit {
|
||||
server: Server;
|
||||
dataSource: UserDataSource;
|
||||
userDatabase = new UserDatabase();
|
||||
dataSource = new MatTableDataSource<User>();
|
||||
displayedColumns = ['select', 'username', 'full_name', 'email', 'is_active', 'last_login', 'updated_at', 'delete'];
|
||||
selection = new SelectionModel<User>(true, []);
|
||||
searchText: string = '';
|
||||
|
||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||
@ViewChild(MatSort, { static: true }) sort: MatSort;
|
||||
|
||||
constructor(
|
||||
@ -53,17 +55,27 @@ export class UserManagementComponent implements OnInit {
|
||||
if (!this.server) this.router.navigate(['/servers']);
|
||||
|
||||
this.refresh();
|
||||
this.sort.sort(<MatSortable>{
|
||||
id: 'name',
|
||||
start: 'asc',
|
||||
});
|
||||
this.dataSource = new UserDataSource(this.userDatabase, this.sort);
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.dataSource.paginator = this.paginator;
|
||||
this.dataSource.sort = this.sort;
|
||||
this.dataSource.sortingDataAccessor = (item, property) => {
|
||||
switch (property) {
|
||||
case 'username':
|
||||
case 'full_name':
|
||||
case 'email':
|
||||
return item[property] ? item[property].toLowerCase() : '';
|
||||
default:
|
||||
return item[property];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.userService.list(this.server).subscribe(
|
||||
(users: User[]) => {
|
||||
this.userDatabase.addUsers(users);
|
||||
this.dataSource.data = users;
|
||||
},
|
||||
(error) => {
|
||||
this.progressService.setError(error);
|
||||
@ -98,16 +110,18 @@ export class UserManagementComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
isAllSelected() {
|
||||
const numSelected = this.selection.selected.length;
|
||||
const numRows = this.userDatabase.data.length;
|
||||
const numRows = this.dataSource.data.length;
|
||||
return numSelected === numRows;
|
||||
}
|
||||
|
||||
masterToggle() {
|
||||
this.isAllSelected() ?
|
||||
this.selection.clear() :
|
||||
this.userDatabase.data.forEach(row => this.selection.select(row));
|
||||
this.dataSource.data.forEach(row => this.selection.select(row));
|
||||
}
|
||||
|
||||
deleteMultiple() {
|
||||
@ -130,53 +144,3 @@ export class UserManagementComponent implements OnInit {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
export class UserDatabase {
|
||||
dataChange: BehaviorSubject<User[]> = new BehaviorSubject<User[]>([]);
|
||||
|
||||
get data(): User[] {
|
||||
return this.dataChange.value;
|
||||
}
|
||||
|
||||
public addUsers(users: User[]) {
|
||||
this.dataChange.next(users);
|
||||
}
|
||||
|
||||
public remove(user: User) {
|
||||
const index = this.data.indexOf(user);
|
||||
if (index >= 0) {
|
||||
this.data.splice(index, 1);
|
||||
this.dataChange.next(this.data.slice());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class UserDataSource extends DataSource<any> {
|
||||
constructor(public userDatabase: UserDatabase, private sort: MatSort) {
|
||||
super();
|
||||
}
|
||||
|
||||
connect(): Observable<User[]> {
|
||||
const displayDataChanges = [this.userDatabase.dataChange, this.sort.sortChange];
|
||||
|
||||
return merge(...displayDataChanges).pipe(
|
||||
map(() => {
|
||||
if (!this.sort.active || this.sort.direction === '') {
|
||||
return this.userDatabase.data;
|
||||
}
|
||||
|
||||
return this.userDatabase.data.sort((a, b) => {
|
||||
const propertyA = a[this.sort.active];
|
||||
const propertyB = b[this.sort.active];
|
||||
|
||||
const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
|
||||
const valueB = isNaN(+propertyB) ? propertyB : +propertyB;
|
||||
|
||||
return (valueA < valueB ? -1 : 1) * (this.sort.direction === 'asc' ? 1 : -1);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
disconnect() {}
|
||||
}
|
||||
|
@ -11,18 +11,19 @@
|
||||
* Author: Sylvain MATHIEU, Elise LEBEAU
|
||||
*/
|
||||
import { Pipe, PipeTransform } from '@angular/core';
|
||||
import {UserDataSource} from "@components/user-management/user-management.component";
|
||||
import {User} from "@models/users/user";
|
||||
import {MatTableDataSource} from "@angular/material/table";
|
||||
|
||||
@Pipe({
|
||||
name: 'userFilter'
|
||||
})
|
||||
export class UserFilterPipe implements PipeTransform {
|
||||
|
||||
transform(items: UserDataSource, searchText: string) {
|
||||
transform(items: MatTableDataSource<User>, searchText: string) {
|
||||
if (!items) return [];
|
||||
if (!searchText) return items;
|
||||
searchText = searchText.toLowerCase();
|
||||
return items.userDatabase.data.filter((item) => {
|
||||
return items.data.filter((item: User) => {
|
||||
return (item.username && item.username.toLowerCase().includes(searchText))
|
||||
|| (item.full_name && item.full_name.toLowerCase().includes(searchText))
|
||||
|| (item.email && item.email.toLowerCase().includes(searchText));
|
||||
|
Loading…
x
Reference in New Issue
Block a user