group management, add create new group functionality

This commit is contained in:
Sylvain MATHIEU 2021-12-09 15:23:57 +01:00
parent 2ea79aaa27
commit 7219f02783
11 changed files with 189 additions and 2 deletions

View File

@ -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,

View File

@ -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 };
}
}

View File

@ -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>

View File

@ -0,0 +1,7 @@
.file-name-form-field {
width: 100%;
}
.project-snackbar {
background: #2196f3;
}

View File

@ -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();
});
});

View File

@ -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();
}
}

View File

@ -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);
})
);
};
};

View File

@ -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>

View File

@ -8,3 +8,8 @@ table {
left: 50%;
}
.add-group-button {
height: 40px;
width: 160px;
margin: 20px;
}

View File

@ -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}`);
});
}
});
}
}

View File

@ -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});
}
}