mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2024-12-30 17:56:55 +00:00
add linked ACE to user and group detail page
This commit is contained in:
parent
ed4fd7c06a
commit
db66a09e3b
@ -73,6 +73,8 @@ import {AceManagementComponent} from "@components/ace-management/ace-management.
|
||||
import {ResourcePoolsManagementComponent} from "@components/resource-pools-management/resource-pools-management.component";
|
||||
import {ResourcePoolDetailsComponent} from "@components/resource-pool-details/resource-pool-details.component";
|
||||
import {ResourcePoolsResolver} from "@resolvers/resource-pools.resolver";
|
||||
import {GroupAcesResolver} from "@resolvers/group-ace.resolver.ts.resolver";
|
||||
import {UserAcesResolver} from "@resolvers/user-aces.resolver";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
@ -101,6 +103,7 @@ const routes: Routes = [
|
||||
resolve: {
|
||||
user: UserDetailResolver,
|
||||
groups: UserGroupsResolver,
|
||||
aces: UserAcesResolver,
|
||||
controller: ControllerResolve},
|
||||
},
|
||||
{
|
||||
@ -262,7 +265,7 @@ const routes: Routes = [
|
||||
members: GroupMembersResolver,
|
||||
controller: ControllerResolve,
|
||||
group: GroupResolver,
|
||||
roles: GroupRoleResolver
|
||||
aces: GroupAcesResolver
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -56,15 +56,34 @@
|
||||
[pageSizeOptions]="[5, 20, 50, 100]"></mat-paginator>
|
||||
</div>
|
||||
</mat-tab>
|
||||
<mat-tab label="Roles">
|
||||
<div><button mat-button (click)="openAddRoleDialog()" ><mat-icon>group_add</mat-icon></button></div>
|
||||
<div *ngFor="let role of roles" class="roles">
|
||||
<div>{{role.name}}</div>
|
||||
<div>
|
||||
<button mat-button (click)="openRemoveRoleDialog(role)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<mat-tab label="Aces">
|
||||
<div class="default-content">
|
||||
<table mat-table [dataSource]="aceDatasource" class="mat-elevation-z8">
|
||||
|
||||
<ng-container matColumnDef="endpoint">
|
||||
<th mat-header-cell *matHeaderCellDef> Endpoint </th>
|
||||
<td mat-cell *matCellDef="let element">{{element.endpoint_name}}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="role">
|
||||
<th mat-header-cell *matHeaderCellDef > Role </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.role_name}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="propagate">
|
||||
<th mat-header-cell *matHeaderCellDef > Propagate </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.propagate}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="allowed">
|
||||
<th mat-header-cell *matHeaderCellDef> Allowed </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.allowed}} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="aceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: aceDisplayedColumns;"></tr>
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
|
@ -1,3 +1,7 @@
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.main {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
@ -22,8 +22,14 @@ import {RemoveToGroupDialogComponent} from "@components/group-details/remove-to-
|
||||
import {GroupService} from "@services/group.service";
|
||||
import {ToasterService} from "@services/toaster.service";
|
||||
import {PageEvent} from "@angular/material/paginator";
|
||||
import {ACE, ACEDetailed, AceType} from "@models/api/ACE";
|
||||
import {UserService} from "@services/user.service";
|
||||
import {RoleService} from "@services/role.service";
|
||||
import {Role} from "@models/api/role";
|
||||
import {AddRoleToGroupComponent} from "@components/group-details/add-role-to-group/add-role-to-group.component";
|
||||
import {AclService} from "@services/acl.service";
|
||||
import {Endpoint} from "@models/api/endpoint";
|
||||
import {interval} from "rxjs";
|
||||
import {MatTableDataSource} from "@angular/material/table";
|
||||
|
||||
@Component({
|
||||
selector: 'app-group-details',
|
||||
@ -37,28 +43,43 @@ export class GroupDetailsComponent implements OnInit {
|
||||
editGroupForm: UntypedFormGroup;
|
||||
pageEvent: PageEvent | undefined;
|
||||
searchMembers: string;
|
||||
roles: Role[];
|
||||
aces: ACE[];
|
||||
aceDatasource = new MatTableDataSource<ACEDetailed>();
|
||||
public aceDisplayedColumns = ['endpoint', 'role', 'propagate', 'allowed'];
|
||||
|
||||
constructor(private route: ActivatedRoute,
|
||||
private dialog: MatDialog,
|
||||
private groupService: GroupService,
|
||||
private toastService: ToasterService) {
|
||||
private toastService: ToasterService,
|
||||
private aclService: AclService,
|
||||
private roleService: RoleService) {
|
||||
|
||||
this.editGroupForm = new UntypedFormGroup({
|
||||
groupname: new UntypedFormControl(''),
|
||||
});
|
||||
|
||||
this.route.data.subscribe((d: { controller: Controller; group: Group, members: User[], roles: Role[] }) => {
|
||||
this.route.data.subscribe((d: { controller: Controller; group: Group, members: User[], aces: ACE[] }) => {
|
||||
|
||||
this.controller = d.controller;
|
||||
this.group = d.group;
|
||||
this.roles = d.roles;
|
||||
this.aces = d.aces;
|
||||
this.members = d.members.sort((a: User, b: User) => a.username.toLowerCase().localeCompare(b.username.toLowerCase()));
|
||||
this.editGroupForm.setValue({groupname: this.group.name});
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.roleService.get(this.controller).subscribe((roles: Role[]) => {
|
||||
this.aclService.getEndpoints(this.controller).subscribe((endps: Endpoint[]) => {
|
||||
this.aceDatasource.data = this.aces.map((ace: ACE) => {
|
||||
const endpoint = endps.filter((endp: Endpoint) => endp.endpoint === ace.path)[0]
|
||||
const role = roles.filter((r: Role) => r.role_id === ace.role_id)[0]
|
||||
return {...ace, endpoint_name: endpoint.name, role_name: role.name}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@ -72,18 +93,6 @@ export class GroupDetailsComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
openAddRoleDialog() {
|
||||
this.dialog
|
||||
.open<AddRoleToGroupComponent>(AddRoleToGroupComponent,
|
||||
{
|
||||
width: '700px', height: '500px',
|
||||
data: {controller: this.controller, group: this.group}
|
||||
})
|
||||
.afterClosed()
|
||||
.subscribe(() => {
|
||||
this.reloadRoles();
|
||||
});
|
||||
}
|
||||
openAddUserDialog() {
|
||||
this.dialog
|
||||
.open<AddUserToGroupDialogComponent>(AddUserToGroupDialogComponent,
|
||||
@ -117,24 +126,6 @@ export class GroupDetailsComponent implements OnInit {
|
||||
}
|
||||
|
||||
|
||||
openRemoveRoleDialog(role: Role) {
|
||||
this.dialog.open<RemoveToGroupDialogComponent>(RemoveToGroupDialogComponent,
|
||||
{width: '500px', height: '200px', data: {name: role.name}})
|
||||
.afterClosed()
|
||||
.subscribe((confirm: string) => {
|
||||
if (confirm) {
|
||||
this.groupService.removeRole(this.controller, this.group, role)
|
||||
.subscribe(() => {
|
||||
this.toastService.success(`Role ${role.name} was removed`);
|
||||
this.reloadRoles();
|
||||
},
|
||||
(error) => {
|
||||
this.toastService.error(`Error while removing role ${role.name} from ${this.group.name}`);
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reloadMembers() {
|
||||
this.groupService.getGroupMember(this.controller, this.group.user_group_id)
|
||||
@ -143,10 +134,4 @@ export class GroupDetailsComponent implements OnInit {
|
||||
});
|
||||
}
|
||||
|
||||
reloadRoles() {
|
||||
this.groupService.getGroupRole(this.controller, this.group.user_group_id)
|
||||
.subscribe((roles: Role[]) => {
|
||||
this.roles = roles;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
[routerLink]="['/controller', controller.id, 'management', 'resourcePools']">
|
||||
<mat-icon aria-label="back to resource pools management">keyboard_arrow_left</mat-icon>
|
||||
</a>
|
||||
<h1 class="col">role {{pool.name}} details</h1>
|
||||
<h1 class="col">Pool {{pool.name}} details</h1>
|
||||
</div>
|
||||
<div class="main">
|
||||
<div class="details">
|
||||
@ -23,7 +23,7 @@
|
||||
<div>uuid: {{pool.resource_pool_id}}</div>
|
||||
<div mat-dialog-actions class="button-div">
|
||||
<button mat-button (click)="onUpdate()" tabindex="2" mat-raised-button color="primary">
|
||||
update role
|
||||
update pool
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -80,6 +80,37 @@
|
||||
</ul>
|
||||
</div>
|
||||
</mat-tab>
|
||||
|
||||
<mat-tab label="Aces">
|
||||
<div class="default-content">
|
||||
<table mat-table [dataSource]="aceDatasource" class="mat-elevation-z8">
|
||||
|
||||
<ng-container matColumnDef="endpoint">
|
||||
<th mat-header-cell *matHeaderCellDef> Endpoint </th>
|
||||
<td mat-cell *matCellDef="let element">{{element.endpoint_name}}</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="role">
|
||||
<th mat-header-cell *matHeaderCellDef > Role </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.role_name}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="propagate">
|
||||
<th mat-header-cell *matHeaderCellDef > Propagate </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.propagate}} </td>
|
||||
</ng-container>
|
||||
<ng-container matColumnDef="allowed">
|
||||
<th mat-header-cell *matHeaderCellDef> Allowed </th>
|
||||
<td mat-cell *matCellDef="let element"> {{element.allowed}} </td>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="aceDisplayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: aceDisplayedColumns;"></tr>
|
||||
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
|
||||
</div>
|
||||
|
@ -5,3 +5,7 @@
|
||||
.button-div {
|
||||
float: right;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
@ -8,11 +8,15 @@ import {Controller} from "@models/controller";
|
||||
import {userNameAsyncValidator} from "@components/user-management/add-user-dialog/userNameAsyncValidator";
|
||||
import {userEmailAsyncValidator} from "@components/user-management/add-user-dialog/userEmailAsyncValidator";
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {Role} from "@models/api/role";
|
||||
import {AddUserDialogComponent} from "@components/user-management/add-user-dialog/add-user-dialog.component";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {ChangeUserPasswordComponent} from "@components/user-management/user-detail/change-user-password/change-user-password.component";
|
||||
import {RemoveToGroupDialogComponent} from "@components/group-details/remove-to-group-dialog/remove-to-group-dialog.component";
|
||||
import {ACE, ACEDetailed} from "@models/api/ACE";
|
||||
import {MatTableDataSource} from "@angular/material/table";
|
||||
import {AclService} from "@services/acl.service";
|
||||
import {RoleService} from "@services/role.service";
|
||||
import {Role} from "@models/api/role";
|
||||
import {Endpoint} from "@models/api/endpoint";
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-user-detail',
|
||||
@ -27,12 +31,17 @@ export class UserDetailComponent implements OnInit {
|
||||
controller: Controller;
|
||||
user_id: string;
|
||||
changingPassword: boolean = false;
|
||||
aces: ACE[];
|
||||
aceDatasource = new MatTableDataSource<ACEDetailed>();
|
||||
public aceDisplayedColumns = ['endpoint', 'role', 'propagate', 'allowed'];
|
||||
|
||||
constructor(public userService: UserService,
|
||||
private toasterService: ToasterService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
public dialog: MatDialog) {
|
||||
public dialog: MatDialog,
|
||||
private aclService: AclService,
|
||||
private roleService: RoleService) {
|
||||
|
||||
}
|
||||
|
||||
@ -40,11 +49,22 @@ export class UserDetailComponent implements OnInit {
|
||||
this.controller = this.route.snapshot.data['controller'];
|
||||
if (!this.controller) this.router.navigate(['/controllers']);
|
||||
|
||||
this.route.data.subscribe((d: { controller: Controller; user: User, groups: Group[]}) => {
|
||||
this.route.data.subscribe((d: { controller: Controller; user: User, groups: Group[], aces: ACE[]}) => {
|
||||
this.user = d.user;
|
||||
this.user_id = this.user.user_id;
|
||||
this.groups = d.groups;
|
||||
this.aces = d.aces;
|
||||
this.initForm();
|
||||
|
||||
this.roleService.get(this.controller).subscribe((roles: Role[]) => {
|
||||
this.aclService.getEndpoints(this.controller).subscribe((endps: Endpoint[]) => {
|
||||
this.aceDatasource.data = this.aces.map((ace: ACE) => {
|
||||
const endpoint = endps.filter((endp: Endpoint) => endp.endpoint === ace.path)[0]
|
||||
const role = roles.filter((r: Role) => r.role_id === ace.role_id)[0]
|
||||
return {...ace, endpoint_name: endpoint.name, role_name: role.name}
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,10 @@ export enum AceType {
|
||||
user = "user"
|
||||
}
|
||||
|
||||
export interface ACEDetailed extends ACE{
|
||||
endpoint_name: string;
|
||||
role_name: string;
|
||||
}
|
||||
|
||||
export interface ACE {
|
||||
ace_id: string;
|
||||
|
41
src/app/resolvers/group-ace.resolver.ts.resolver.ts
Normal file
41
src/app/resolvers/group-ace.resolver.ts.resolver.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
Router, Resolve,
|
||||
RouterStateSnapshot,
|
||||
ActivatedRouteSnapshot
|
||||
} from '@angular/router';
|
||||
import {Observable,Subscriber} from 'rxjs';
|
||||
import {ACE} from "../models/api/ACE";
|
||||
import {ControllerService} from "../services/controller.service";
|
||||
import {AclService} from "../services/acl.service";
|
||||
import {Controller} from "../models/controller";
|
||||
import {UserService} from "@services/user.service";
|
||||
import {GroupService} from "@services/group.service";
|
||||
import {RoleService} from "@services/role.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class GroupAcesResolver implements Resolve<ACE[]> {
|
||||
|
||||
constructor(private controllerService: ControllerService,
|
||||
private aceService: AclService) {
|
||||
}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ACE[]> {
|
||||
return new Observable<ACE[]>((subscriber: Subscriber<ACE[]>) => {
|
||||
|
||||
const controllerId = route.paramMap.get('controller_id');
|
||||
const groupId = route.paramMap.get('user_group_id');
|
||||
|
||||
this.controllerService.get(+controllerId).then((controller: Controller) => {
|
||||
this.aceService.list(controller).subscribe((aces: ACE[]) => {
|
||||
const filter = aces.filter((ace: ACE) => ace.group_id === groupId)
|
||||
|
||||
subscriber.next(filter);
|
||||
subscriber.complete()
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
38
src/app/resolvers/user-aces.resolver.ts
Normal file
38
src/app/resolvers/user-aces.resolver.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
Router, Resolve,
|
||||
RouterStateSnapshot,
|
||||
ActivatedRouteSnapshot
|
||||
} from '@angular/router';
|
||||
import {Observable, of, Subscriber} from 'rxjs';
|
||||
import {ACE} from "@models/api/ACE";
|
||||
import {Controller} from "@models/controller";
|
||||
import {ControllerService} from "@services/controller.service";
|
||||
import {AclService} from "@services/acl.service";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class UserAcesResolver implements Resolve<ACE[]> {
|
||||
|
||||
constructor(private controllerService: ControllerService,
|
||||
private aceService: AclService) {
|
||||
}
|
||||
|
||||
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<ACE[]> {
|
||||
return new Observable<ACE[]>((subscriber: Subscriber<ACE[]>) => {
|
||||
|
||||
const controllerId = route.paramMap.get('controller_id');
|
||||
const userId = route.paramMap.get('user_id');
|
||||
|
||||
this.controllerService.get(+controllerId).then((controller: Controller) => {
|
||||
this.aceService.list(controller).subscribe((aces: ACE[]) => {
|
||||
const filter = aces.filter((ace: ACE) => ace.user_id === userId)
|
||||
|
||||
subscriber.next(filter);
|
||||
subscriber.complete()
|
||||
})
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user