diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index c83e3179..b3d367d1 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -57,6 +57,7 @@ import { ServerResolve } from './resolvers/server-resolve'; import { UserManagementComponent } from './components/user-management/user-management.component'; import { LoggedUserComponent } from './components/users/logged-user/logged-user.component'; import {GroupManagementComponent} from "./components/group-management/group-management.component"; +import {UserDetailComponent} from "@components/user-management/user-detail/user-detail.component"; const routes: Routes = [ { @@ -83,6 +84,12 @@ const routes: Routes = [ canActivate: [LoginGuard], resolve: { server: ServerResolve }, }, + { + path: 'server/:server_id/user_management/:user_id', + component: UserDetailComponent, + canActivate: [LoginGuard], + resolve: { server: ServerResolve }, + }, { path: 'installed-software', component: InstalledSoftwareComponent }, { path: 'server/:server_id/systemstatus', component: SystemStatusComponent, canActivate: [LoginGuard] }, diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 11aff1fc..d64b149b 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -280,6 +280,7 @@ import { GroupFilterPipe } from './filters/group-filter.pipe'; import { AddGroupDialogComponent } from './components/group-management/add-group-dialog/add-group-dialog.component'; import { DeleteGroupDialogComponent } from './components/group-management/delete-group-dialog/delete-group-dialog.component'; import { DeleteUserDialogComponent } from './components/user-management/delete-user-dialog/delete-user-dialog.component'; +import { UserDetailComponent } from './components/user-management/user-detail/user-detail.component'; @NgModule({ declarations: [ @@ -475,6 +476,7 @@ import { DeleteUserDialogComponent } from './components/user-management/delete-u UserFilterPipe, DeleteGroupDialogComponent, DeleteUserDialogComponent, + UserDetailComponent ], imports: [ BrowserModule, diff --git a/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.html b/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.html deleted file mode 100644 index 8b1e6e1c..00000000 --- a/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.html +++ /dev/null @@ -1,42 +0,0 @@ -

Update user

-
- - - Username is required - Username is incorrect - User with this username exists - - - - - - - Email is required - Email is invalid - User with this email exists - - - - - - Password must be between 6 and 100 characters - - - - Is active - -
- - -
-
diff --git a/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.scss b/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.scss deleted file mode 100644 index 469c3dda..00000000 --- a/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.scss +++ /dev/null @@ -1,8 +0,0 @@ -.input-field { - width: 100%; -} - - -.button-div { - float: right; -} diff --git a/src/app/components/user-management/user-detail/user-detail.component.html b/src/app/components/user-management/user-detail/user-detail.component.html new file mode 100644 index 00000000..5d24dc14 --- /dev/null +++ b/src/app/components/user-management/user-detail/user-detail.component.html @@ -0,0 +1,74 @@ +
+
+
+ +

User Details

+
+
+
+
+

Update user

+
+
+ + + Username is required + Username is incorrect + User with this username exists + + + + + + + Email is required + Email is invalid + User with this email exists + + + + + + Password must be between 6 and 100 characters + + + + Is active + +
+ +
+
+
+ +
+ +
+
Groups
+ +
+
+
+ + diff --git a/src/app/components/user-management/user-detail/user-detail.component.scss b/src/app/components/user-management/user-detail/user-detail.component.scss new file mode 100644 index 00000000..a1d07ca9 --- /dev/null +++ b/src/app/components/user-management/user-detail/user-detail.component.scss @@ -0,0 +1,16 @@ +.input-field { + width: 100%; +} + +.button-div { + float: right; +} + +.user-edit , +.user-groups { + flex: 1; +} + +.default-content { + display: flex; +} diff --git a/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.spec.ts b/src/app/components/user-management/user-detail/user-detail.component.spec.ts similarity index 52% rename from src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.spec.ts rename to src/app/components/user-management/user-detail/user-detail.component.spec.ts index 7c6e36da..66c3622e 100644 --- a/src/app/components/user-management/edit-user-dialog/edit-user-dialog.component.spec.ts +++ b/src/app/components/user-management/user-detail/user-detail.component.spec.ts @@ -1,20 +1,20 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { EditUserDialogComponent } from './edit-user-dialog.component'; +import { UserDetailComponent } from './user-detail.component'; -describe('EditUserDialogComponent', () => { - let component: EditUserDialogComponent; - let fixture: ComponentFixture; +describe('UserDetailComponent', () => { + let component: UserDetailComponent; + let fixture: ComponentFixture; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [ EditUserDialogComponent ] + declarations: [ UserDetailComponent ] }) .compileComponents(); }); beforeEach(() => { - fixture = TestBed.createComponent(EditUserDialogComponent); + fixture = TestBed.createComponent(UserDetailComponent); component = fixture.componentInstance; fixture.detectChanges(); }); diff --git a/src/app/components/user-management/user-detail/user-detail.component.ts b/src/app/components/user-management/user-detail/user-detail.component.ts new file mode 100644 index 00000000..9e206946 --- /dev/null +++ b/src/app/components/user-management/user-detail/user-detail.component.ts @@ -0,0 +1,103 @@ +import {Component, Inject, OnInit} from '@angular/core'; +import {FormControl, FormGroup, Validators} from "@angular/forms"; +import {Group} from "@models/groups/group"; +import {UserService} from "@services/user.service"; +import {ToasterService} from "@services/toaster.service"; +import {User} from "@models/users/user"; +import {Server} from "@models/server"; +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"; + +@Component({ + selector: 'app-user-detail', + templateUrl: './user-detail.component.html', + styleUrls: ['./user-detail.component.scss'] +}) +export class UserDetailComponent implements OnInit { + + editUserForm: FormGroup; + groups: Group[]; + user: User; + server: Server; + user_id: string; + + constructor(public userService: UserService, + private toasterService: ToasterService, + private route: ActivatedRoute, + private router: Router) { + + } + + ngOnInit(): void { + this.server = this.route.snapshot.data['server']; + if (!this.server) this.router.navigate(['/servers']); + + this.user_id = this.route.snapshot.paramMap.get('user_id'); + this.userService.get(this.server, this.user_id).subscribe((user: User) => { + console.log(user) + this.user = user; + this.userService.getGroupsByUserId(this.server, this.user.user_id).subscribe( + (groups: Group[]) => { + this.groups = groups; + }); + this.initForm(); + }) + } + + initForm() { + this.editUserForm = new FormGroup({ + username: new FormControl(this.user.username, [ + Validators.required, + Validators.minLength(3), + Validators.pattern("[a-zA-Z0-9_-]+$")], + [userNameAsyncValidator(this.server, this.userService, this.user.username)]), + full_name: new FormControl(this.user.full_name), + email: new FormControl(this.user.email, + [Validators.email, Validators.required], + [userEmailAsyncValidator(this.server, this.userService, this.user.email)]), + password: new FormControl(null, + [Validators.minLength(6), Validators.maxLength(100)]), + is_active: new FormControl(this.user.is_active) + }); + } + + get form() { + return this.editUserForm.controls; + } + + onEditClick() { + if (!this.editUserForm.valid) { + return; + } + + const updatedUser = this.getUpdatedValues(); + updatedUser['user_id'] = this.user.user_id; + + this.userService.update(this.server, updatedUser) + .subscribe((user: User) => { + console.log("Done ", user) + this.toasterService.success(`User ${user.username} updated`); + }, + (error) => { + this.toasterService.error('Cannot update user : ' + error); + }) + } + + getUpdatedValues() { + let dirtyValues = {}; + + Object.keys(this.editUserForm.controls) + .forEach(key => { + const currentControl = this.editUserForm.get(key); + + if (currentControl.dirty && currentControl.value !== this.user[key] && currentControl.value !== '') { + dirtyValues[key] = currentControl.value; + } + }); + + return dirtyValues; + } + + +} diff --git a/src/app/components/user-management/user-management.component.html b/src/app/components/user-management/user-management.component.html index 72cc8dbb..6ab59098 100644 --- a/src/app/components/user-management/user-management.component.html +++ b/src/app/components/user-management/user-management.component.html @@ -38,7 +38,8 @@ Username - {{ row.username }} + {{ row.username }} diff --git a/src/app/components/user-management/user-management.component.ts b/src/app/components/user-management/user-management.component.ts index 98631aaa..cdfa47ad 100644 --- a/src/app/components/user-management/user-management.component.ts +++ b/src/app/components/user-management/user-management.component.ts @@ -13,20 +13,17 @@ import {Component, OnInit, ViewChild} from '@angular/core'; import {ActivatedRoute, Router} from "@angular/router"; import {Server} from "@models/server"; -import {MatSort, MatSortable, Sort} from "@angular/material/sort"; +import {MatSort} from "@angular/material/sort"; import {UserService} from "@services/user.service"; import {ProgressService} from "../../common/progress/progress.service"; import {User} from "@models/users/user"; -import {BehaviorSubject, merge, Observable} from "rxjs"; -import {DataSource, SelectionModel} from "@angular/cdk/collections"; -import {map} from "rxjs/operators"; +import {SelectionModel} from "@angular/cdk/collections"; import {AddUserDialogComponent} from "@components/user-management/add-user-dialog/add-user-dialog.component"; 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"; -import {EditUserDialogComponent} from "@components/user-management/edit-user-dialog/edit-user-dialog.component"; @Component({ selector: 'app-user-management', @@ -144,13 +141,4 @@ export class UserManagementComponent implements OnInit { }); } - - onEdit(user: User) { - this.dialog - .open(EditUserDialogComponent, {width: '500px', data: {user: user, server: this.server}}) - .afterClosed() - .subscribe(() => { - this.refresh(); - }); - } } diff --git a/src/app/services/user.service.ts b/src/app/services/user.service.ts index 72ca9ab3..e0540d59 100644 --- a/src/app/services/user.service.ts +++ b/src/app/services/user.service.ts @@ -4,6 +4,7 @@ import { Server } from '../models/server'; import { HttpServer } from './http-server.service'; import { User } from '../models/users/user'; import {Project} from "@models/project"; +import {Group} from "@models/groups/group"; @Injectable() export class UserService { @@ -15,6 +16,10 @@ export class UserService { return this.httpServer.get(server, '/users/me/'); } + get(server:Server, user_id: string) { + return this.httpServer.get(server, `/users/${user_id}`); + } + list(server: Server) { return this.httpServer.get(server, '/users'); } @@ -27,7 +32,11 @@ export class UserService { return this.httpServer.delete(server, `/users/${user_id}`); } - update(server: Server, user: User): Observable { + update(server: Server, user: any): Observable { return this.httpServer.put(server, `/users/${user.user_id}`, user); } + + getGroupsByUserId(server: Server, user_id: string) { + return this.httpServer.get(server, `/users/${user_id}/groups`); + } }