mirror of
https://github.com/GNS3/gns3-web-ui.git
synced 2025-03-11 15:04:29 +00:00
group management, add create new group functionality
This commit is contained in:
parent
2ea79aaa27
commit
7219f02783
@ -275,6 +275,7 @@ import { UserService } from './services/user.service';
|
||||
import { LoggedUserComponent } from './components/users/logged-user/logged-user.component';
|
||||
import { GroupManagementComponent } from './components/group-management/group-management.component';
|
||||
import { GroupFilterPipe } from './filters/group-filter.pipe';
|
||||
import { AddGroupDialogComponent } from './components/group-management/add-group-dialog/add-group-dialog.component';
|
||||
import { AddUserDialogComponent } from './components/user-management/add-user-dialog/add-user-dialog.component';
|
||||
import { UserFilterPipe } from './filters/user-filter.pipe';
|
||||
|
||||
@ -465,6 +466,7 @@ import { UserFilterPipe } from './filters/user-filter.pipe';
|
||||
EditNetworkConfigurationDialogComponent,
|
||||
UserManagementComponent,
|
||||
ProjectReadmeComponent,
|
||||
AddGroupDialogComponent,
|
||||
GroupFilterPipe,
|
||||
GroupManagementComponent,
|
||||
AddUserDialogComponent,
|
||||
|
@ -0,0 +1,14 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
@Injectable()
|
||||
export class GroupNameValidator {
|
||||
get(groupName) {
|
||||
const pattern = new RegExp(/[~`!#$%\^&*+=\[\]\\';,/{}|\\":<>\?]/);
|
||||
|
||||
if (!pattern.test(groupName.value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return { invalidName: true };
|
||||
}
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
<h1 mat-dialog-title>Create new group</h1>
|
||||
<form [formGroup]="groupNameForm" class="file-name-form">
|
||||
<mat-form-field class="file-name-form-field">
|
||||
<input
|
||||
matInput
|
||||
(keydown)="onKeyDown($event)"
|
||||
type="text"
|
||||
formControlName="groupName"
|
||||
[ngClass]="{ 'is-invalid': form.groupName?.errors }"
|
||||
placeholder="Please enter group name"
|
||||
/>
|
||||
<mat-error *ngIf="form.groupName?.touched && form.groupName?.errors && form.groupName?.errors.required"
|
||||
>Group name is required</mat-error
|
||||
>
|
||||
<mat-error *ngIf="form.groupName?.errors && form.groupName?.errors.invalidName"
|
||||
>Group name is incorrect</mat-error
|
||||
>
|
||||
<mat-error *ngIf="form.groupName?.errors && form.groupName?.errors.projectExist"
|
||||
>Group with this name exists</mat-error
|
||||
>
|
||||
</mat-form-field>
|
||||
<div mat-dialog-actions>
|
||||
<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">
|
||||
Add group
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
@ -0,0 +1,7 @@
|
||||
.file-name-form-field {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.project-snackbar {
|
||||
background: #2196f3;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { AddGroupDialogComponent } from './add-group-dialog.component';
|
||||
|
||||
describe('AddGroupDialogComponent', () => {
|
||||
let component: AddGroupDialogComponent;
|
||||
let fixture: ComponentFixture<AddGroupDialogComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ AddGroupDialogComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AddGroupDialogComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
@ -0,0 +1,57 @@
|
||||
import {Component, Inject, OnInit} from '@angular/core';
|
||||
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
|
||||
import {FormBuilder, FormControl, FormGroup, Validators} from "@angular/forms";
|
||||
import {groupNameAsyncValidator} from "@components/group-management/add-group-dialog/groupNameAsyncValidator";
|
||||
import {GroupNameValidator} from "@components/group-management/add-group-dialog/GroupNameValidator";
|
||||
import {GroupService} from "../../../services/group.service";
|
||||
import {Server} from "../../../models/server";
|
||||
|
||||
@Component({
|
||||
selector: 'app-add-group-dialog',
|
||||
templateUrl: './add-group-dialog.component.html',
|
||||
styleUrls: ['./add-group-dialog.component.scss'],
|
||||
providers: [GroupNameValidator]
|
||||
})
|
||||
export class AddGroupDialogComponent implements OnInit {
|
||||
|
||||
groupNameForm: FormGroup;
|
||||
|
||||
constructor(private dialogRef: MatDialogRef<AddGroupDialogComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: { server: Server },
|
||||
private formBuilder: FormBuilder,
|
||||
private groupNameValidator: GroupNameValidator,
|
||||
private groupService: GroupService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.groupNameForm = this.formBuilder.group({
|
||||
groupName: new FormControl(
|
||||
null,
|
||||
[Validators.required, this.groupNameValidator.get],
|
||||
[groupNameAsyncValidator(this.data.server, this.groupService)]
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
onKeyDown(event) {
|
||||
if (event.key === 'Enter') {
|
||||
this.onAddClick();
|
||||
}
|
||||
}
|
||||
|
||||
get form() {
|
||||
return this.groupNameForm.controls;
|
||||
}
|
||||
|
||||
onAddClick() {
|
||||
if (this.groupNameForm.invalid) {
|
||||
return;
|
||||
}
|
||||
const groupName = this.groupNameForm.controls['groupName'].value;
|
||||
this.dialogRef.close(groupName);
|
||||
}
|
||||
|
||||
onNoClick() {
|
||||
this.dialogRef.close();
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import { FormControl } from '@angular/forms';
|
||||
import { timer } from 'rxjs';
|
||||
import {map, switchMap, tap} from 'rxjs/operators';
|
||||
import {Server} from "../../../models/server";
|
||||
import {GroupService} from "../../../services/group.service";
|
||||
|
||||
export const groupNameAsyncValidator = (server: Server, groupService: GroupService) => {
|
||||
return (control: FormControl) => {
|
||||
return timer(500).pipe(
|
||||
switchMap(() => groupService.getGroups(server)),
|
||||
map((response) => {
|
||||
console.log(response);
|
||||
return (response.find((n) => n.name === control.value) ? { projectExist: true } : null);
|
||||
})
|
||||
);
|
||||
};
|
||||
};
|
@ -2,6 +2,9 @@
|
||||
<div class="default-header">
|
||||
<div class="row">
|
||||
<h1 class="col">Groups management</h1>
|
||||
<button class="col" mat-raised-button color="primary" (click)="addGroup()" class="add-group-button">
|
||||
Add group
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -8,3 +8,8 @@ table {
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.add-group-button {
|
||||
height: 40px;
|
||||
width: 160px;
|
||||
margin: 20px;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ import {GroupService} from "../../services/group.service";
|
||||
import {Server} from "../../models/server";
|
||||
import {Group} from "../../models/groups/group";
|
||||
import {Sort} from "@angular/material/sort";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {AddGroupDialogComponent} from "@components/group-management/add-group-dialog/add-group-dialog.component";
|
||||
|
||||
@Component({
|
||||
selector: 'app-group-management',
|
||||
@ -37,6 +39,7 @@ export class GroupManagementComponent implements OnInit {
|
||||
private serverService: ServerService,
|
||||
private toasterService: ToasterService,
|
||||
public groupService: GroupService,
|
||||
public dialog: MatDialog
|
||||
) {
|
||||
}
|
||||
|
||||
@ -72,4 +75,24 @@ export class GroupManagementComponent implements OnInit {
|
||||
return (a < b ? -1 : 1) * (isAsc ? 1 : -1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
addGroup() {
|
||||
this.dialog
|
||||
.open(AddGroupDialogComponent, {width: '250px', height: '250px', data: {server: this.server}})
|
||||
.afterClosed()
|
||||
.subscribe((name: string) => {
|
||||
if (name) {
|
||||
this.groupService.addGroup(this.server, name)
|
||||
.subscribe(() => {
|
||||
this.groupService.getGroups(this.server).subscribe((groups: Group[]) => {
|
||||
this.groups = groups;
|
||||
this.sortedGroups = groups;
|
||||
});
|
||||
}, (error) => {
|
||||
this.toasterService.error(`An error occur while trying to create new group ${name}`);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -10,11 +10,12 @@
|
||||
*
|
||||
* Author: Sylvain MATHIEU, Elise LEBEAU
|
||||
*/
|
||||
import { Injectable } from '@angular/core';
|
||||
import {Injectable} from '@angular/core';
|
||||
import {HttpServer} from "./http-server.service";
|
||||
import {Server} from "../models/server";
|
||||
import {Group} from "../models/groups/group";
|
||||
import {User} from "../models/users/user";
|
||||
import {Observable} from "rxjs";
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@ -23,7 +24,8 @@ export class GroupService {
|
||||
|
||||
constructor(
|
||||
private httpServer: HttpServer
|
||||
) { }
|
||||
) {
|
||||
}
|
||||
|
||||
getGroups(server: Server) {
|
||||
return this.httpServer.get<Group[]>(server, '/groups');
|
||||
@ -32,4 +34,8 @@ export class GroupService {
|
||||
getGroupMember(server: Server, groupId: string) {
|
||||
return this.httpServer.get<User[]>(server, `/groups/${groupId}/members`);
|
||||
}
|
||||
|
||||
addGroup(server: Server, name: string): Observable<Group> {
|
||||
return this.httpServer.post<Group>(server, `/groups`, {name});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user