Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete user #1121

Merged
merged 5 commits into from
Feb 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions ui/src/app/account/settings/settings.component.spec.ts
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ import { LanguageService } from 'src/app/shared/service/language.service'
import { AccountService } from '../service/account.service'
import { of } from 'rxjs'
import { FindLanguageFromKeyPipe } from 'src/app/shared/pipe/find-language-from-key'
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

describe('SettingsComponent', () => {
let component: SettingsComponent
@@ -36,6 +37,7 @@ describe('SettingsComponent', () => {
{ provide: LanguageService, useValue: languageServiceSpy },
{ provide: AccountService, useValue: accountServiceSpy },
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}).compileComponents()

fixture = TestBed.createComponent(SettingsComponent)
1 change: 1 addition & 0 deletions ui/src/app/app.constants.ts
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@ export enum AlertType {
SEND_ACTIVATION_FAILURE = 'Invite email couldn`t be sent.',
USER_CREATED = 'User created. Invite sent.',
USER_UPDATED = 'User updated successfully',
USER_DELETED = 'User deleted successfully',
}

export const EMAIL_NOT_FOUND_TYPE = 'https://www.jhipster.tech/problem/email-not-found'
10 changes: 6 additions & 4 deletions ui/src/app/shared/pipe/localize.ts
Original file line number Diff line number Diff line change
@@ -8,13 +8,15 @@ export class LocalizePipe implements PipeTransform {
transform(value: string, ...args: any[]): any {
switch (value) {
case AlertType.SEND_ACTIVATION_SUCCESS:
return $localize`:@@gatewayApp.msUserServiceMSUser.sendActivate.success.string:${AlertType.SEND_ACTIVATION_SUCCESS}`
return $localize`:@@gatewayApp.msUserServiceMSUser.sendActivate.success.string:Invite sent.`
case AlertType.SEND_ACTIVATION_FAILURE:
return $localize`:@@gatewayApp.msUserServiceMSUser.sendActivate.error.string:${AlertType.SEND_ACTIVATION_FAILURE}`
return $localize`:@@gatewayApp.msUserServiceMSUser.sendActivate.error.string:Invite email couldn't be sent.`
case AlertType.USER_CREATED:
return $localize`:@@userServiceApp.user.created.string:${AlertType.USER_CREATED}`
return $localize`:@@userServiceApp.user.created.string:User created. Invite sent.`
case AlertType.USER_UPDATED:
return $localize`:@@userServiceApp.user.updated.string:${AlertType.USER_UPDATED}`
return $localize`:@@userServiceApp.user.updated.string:User updated successfully`
case AlertType.USER_DELETED:
return $localize`:@@userServiceApp.user.deleted.string:User deleted successfully`
}
}
}
20 changes: 20 additions & 0 deletions ui/src/app/user/user-delete.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<form name="deleteForm" (ngSubmit)="confirmDelete(user?.id)">
<div class="modal-header">
<h4 class="modal-title" jhiTranslate="entity.delete.title.string">Confirm deletion</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="clear()">&times;</button>
</div>
<div class="modal-body">
<app-error-alert></app-error-alert>
<p id="jhi-delete-msUser-heading" jhiTranslate="gatewayApp.msUserServiceMSUser.delete.question.string">
{{ message }}
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-primary" data-dismiss="modal" (click)="clear()">
<fa-icon [icon]="faBan"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel.string">Cancel</span>
</button>
<button id="jhi-confirm-delete-msUser" type="submit" class="btn btn-danger">
<fa-icon [icon]="faTimes"></fa-icon>&nbsp;<span jhiTranslate="entity.action.delete.string">Delete</span>
</button>
</div>
</form>
25 changes: 25 additions & 0 deletions ui/src/app/user/user-delete.component.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing'

import { UserDeletePopupComponent } from './user-delete.component'
import { RouterTestingModule } from '@angular/router/testing'
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'

describe('UserDeleteComponent', () => {
let component: UserDeletePopupComponent
let fixture: ComponentFixture<UserDeletePopupComponent>

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [UserDeletePopupComponent],
imports: [RouterTestingModule],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
fixture = TestBed.createComponent(UserDeletePopupComponent)
component = fixture.componentInstance
fixture.detectChanges()
})

it('should create', () => {
expect(component).toBeTruthy()
})
})
88 changes: 88 additions & 0 deletions ui/src/app/user/user-delete.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { Component, OnDestroy, OnInit } from '@angular/core'
import { UserService } from './service/user.service'
import { AlertService } from '../shared/service/alert.service'
import { IUser } from './model/user.model'
import { NgbActiveModal, NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap'
import { EventService } from '../shared/service/event.service'
import { ActivatedRoute, Router } from '@angular/router'
import { Event } from '../shared/model/event.model'
import { AlertType, EventType } from '../app.constants'
import { faBan, faTimes } from '@fortawesome/free-solid-svg-icons'

@Component({
selector: 'app-user-delete-dialog',
templateUrl: './user-delete.component.html',
})
export class UserDeleteDialogComponent implements OnInit {
user: IUser | undefined
message = ''
faBan = faBan
faTimes = faTimes

constructor(
protected userService: UserService,
public activeModal: NgbActiveModal,
protected eventService: EventService,
private alertService: AlertService
) {}

clear() {
this.activeModal.dismiss('cancel')
}

confirmDelete(id: string | undefined) {
if (id) {
this.userService.delete(id).subscribe(() => {
this.eventService.broadcast({
type: EventType.USER_LIST_MODIFIED,
payload: 'Deleted a user',
} as Event)
this.activeModal.dismiss(true)
this.alertService.broadcast(AlertType.USER_DELETED)
})
}
}

ngOnInit(): void {
this.message = $localize`:@@gatewayApp.msUserServiceMSUser.delete.question.string:Are you sure you want to delete user ${this.user?.email}?`
}
}

@Component({
selector: 'app-user-delete-popup',
template: '',
})
export class UserDeletePopupComponent implements OnInit, OnDestroy {
protected ngbModalRef: NgbModalRef | undefined

constructor(
protected activatedRoute: ActivatedRoute,
protected router: Router,
protected modalService: NgbModal
) {}
ngOnInit() {
this.activatedRoute.data.subscribe(({ user }) => {
setTimeout(() => {
this.ngbModalRef = this.modalService.open(UserDeleteDialogComponent as Component, {
size: 'lg',
backdrop: 'static',
})
this.ngbModalRef.componentInstance.user = user
this.ngbModalRef.result.then(
(result) => {
this.router.navigate(['/users', { outlets: { popup: null } }])
this.ngbModalRef = undefined
},
(reason) => {
this.router.navigate(['/users', { outlets: { popup: null } }])
this.ngbModalRef = undefined
}
)
}, 0)
})
}

ngOnDestroy() {
this.ngbModalRef = undefined
}
}
Empty file.
1 change: 0 additions & 1 deletion ui/src/app/user/user-detail.component.ts
Original file line number Diff line number Diff line change
@@ -11,7 +11,6 @@ import { AlertType } from '../app.constants'
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.scss'],
})
export class UserDetailComponent {
user: IUser | null = null
Empty file.
1 change: 0 additions & 1 deletion ui/src/app/user/user-update.component.ts
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ import { AlertType, DATE_TIME_FORMAT, emailValidator } from '../app.constants'
@Component({
selector: 'app-user-update',
templateUrl: './user-update.component.html',
styleUrls: ['./user-update.component.scss'],
})
export class UserUpdateComponent {
isSaving = false
18 changes: 16 additions & 2 deletions ui/src/app/user/user.module.ts
Original file line number Diff line number Diff line change
@@ -8,9 +8,23 @@ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { UserUpdateComponent } from './user-update.component'
import { UserDetailComponent } from './user-detail.component'
import { UserDeleteDialogComponent, UserDeletePopupComponent } from './user-delete.component'

@NgModule({
declarations: [UsersComponent, UserUpdateComponent, UserDetailComponent],
imports: [CommonModule, SharedModule, RouterModule.forChild(routes), FontAwesomeModule, FormsModule, ReactiveFormsModule],
imports: [
CommonModule,
SharedModule,
RouterModule.forChild(routes),
FontAwesomeModule,
FormsModule,
ReactiveFormsModule,
],
declarations: [
UsersComponent,
UserUpdateComponent,
UserDetailComponent,
UserDeletePopupComponent,
UserDeleteDialogComponent,
],
})
export class UserModule {}
32 changes: 23 additions & 9 deletions ui/src/app/user/user.route.ts
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ import { User } from './model/user.model'
import { UserService } from './service/user.service'
import { Injectable, inject } from '@angular/core'
import { UserUpdateComponent } from './user-update.component'
import { UserDeletePopupComponent } from './user-delete.component'

export const UserResolver: ResolveFn<User | null> = (
route: ActivatedRouteSnapshot,
@@ -19,7 +20,6 @@ export const UserResolver: ResolveFn<User | null> = (
take(1)
)
} else {

return of(null)
}
}
@@ -35,6 +35,21 @@ export const routes: Routes = [
ascending: true,
},
canActivate: [AuthGuard],
children: [
{
path: ':id/delete',
component: UserDeletePopupComponent,
resolve: {
user: UserResolver,
},
data: {
authorities: ['ROLE_ADMIN', 'ROLE_ORG_OWNER', 'ROLE_CONSORTIUM_LEAD'],
pageTitle: 'gatewayApp.msUserServiceMSUser.home.title.string',
},
canActivate: [AuthGuard],
outlet: 'popup',
},
],
},
{
path: 'users/:id/view',
@@ -52,25 +67,24 @@ export const routes: Routes = [
path: 'users/new',
component: UserUpdateComponent,
resolve: {
user: UserResolver
user: UserResolver,
},
data: {
authorities: ['ROLE_ADMIN', 'ROLE_ORG_OWNER', 'ROLE_CONSORTIUM_LEAD'],
pageTitle: 'gatewayApp.msUserServiceMSUser.home.title.string'
pageTitle: 'gatewayApp.msUserServiceMSUser.home.title.string',
},
canActivate: [AuthGuard]
canActivate: [AuthGuard],
},
{
path: 'users/:id/edit',
component: UserUpdateComponent,
resolve: {
user: UserResolver
user: UserResolver,
},
data: {
authorities: ['ROLE_ADMIN', 'ROLE_ORG_OWNER', 'ROLE_CONSORTIUM_LEAD'],
pageTitle: 'gatewayApp.msUserServiceMSUser.home.title.string'
pageTitle: 'gatewayApp.msUserServiceMSUser.home.title.string',
},
canActivate: [AuthGuard]
}
canActivate: [AuthGuard],
},
]

1 change: 1 addition & 0 deletions ui/src/app/user/users.component.html
Original file line number Diff line number Diff line change
@@ -220,3 +220,4 @@ <h1 id="page-heading" class="mt-3" i18n="@@gatewayApp.msUserServiceMSUser.home.t
</div>
</div>
</div>
<router-outlet name="popup"></router-outlet>
4 changes: 4 additions & 0 deletions ui/src/content/scss/global.scss
Original file line number Diff line number Diff line change
@@ -513,3 +513,7 @@ div.success {
fa-icon {
margin-right: 0.25rem;
}

.modal {
z-index: 1500;
}
449 changes: 298 additions & 151 deletions ui/src/i18n/messages.cs.xlf

Large diffs are not rendered by default.

462 changes: 308 additions & 154 deletions ui/src/i18n/messages.es.xlf

Large diffs are not rendered by default.

472 changes: 315 additions & 157 deletions ui/src/i18n/messages.fr.xlf

Large diffs are not rendered by default.

461 changes: 306 additions & 155 deletions ui/src/i18n/messages.it.xlf

Large diffs are not rendered by default.

440 changes: 289 additions & 151 deletions ui/src/i18n/messages.ja.xlf

Large diffs are not rendered by default.

435 changes: 285 additions & 150 deletions ui/src/i18n/messages.ko.xlf

Large diffs are not rendered by default.

462 changes: 307 additions & 155 deletions ui/src/i18n/messages.pt.xlf

Large diffs are not rendered by default.

451 changes: 300 additions & 151 deletions ui/src/i18n/messages.ru.xlf

Large diffs are not rendered by default.

160 changes: 92 additions & 68 deletions ui/src/i18n/messages.xlf

Large diffs are not rendered by default.

428 changes: 280 additions & 148 deletions ui/src/i18n/messages.zh-CN.xlf

Large diffs are not rendered by default.

431 changes: 282 additions & 149 deletions ui/src/i18n/messages.zh-TW.xlf

Large diffs are not rendered by default.


Unchanged files with check annotations Beta

import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'

Check warning on line 1 in ui/src/app/account/activation/activation.component.spec.ts

GitHub Actions / format

'fakeAsync' is defined but never used

Check warning on line 1 in ui/src/app/account/activation/activation.component.spec.ts

GitHub Actions / format

'tick' is defined but never used
import { ActivationComponent } from './activation.component'
import { ActivationService } from './activation.service'
import { ActivatedRoute } from '@angular/router'
import { async, of, throwError } from 'rxjs'

Check warning on line 6 in ui/src/app/account/activation/activation.component.spec.ts

GitHub Actions / format

'async' is defined but never used
import { RouterTestingModule } from '@angular/router/testing'
describe('ActivationComponent', () => {
export class ActivationService {
constructor(private http: HttpClient) {}
get(key: string): Observable<any> {

Check warning on line 9 in ui/src/app/account/activation/activation.service.ts

GitHub Actions / format

Unexpected any. Specify a different type
return this.http.get('/services/userservice/api/activate', {
params: new HttpParams().set('key', key),
})
let component: LoginComponent
let fixture: ComponentFixture<LoginComponent>
let loginService: jasmine.SpyObj<LoginService>
let stateStorageService: jasmine.SpyObj<StateStorageService>

Check warning on line 14 in ui/src/app/account/login/login.component.spec.ts

GitHub Actions / format

'stateStorageService' is assigned a value but never used
let accountService: jasmine.SpyObj<AccountService>
beforeEach(() => {
this.loginService
.login({
username: this.loginForm.get('username')!.value!,

Check warning on line 75 in ui/src/app/account/login/login.component.ts

GitHub Actions / format

Forbidden non-null assertion

Check warning on line 75 in ui/src/app/account/login/login.component.ts

GitHub Actions / format

Forbidden non-null assertion
password: this.loginForm.get('password')!.value!,

Check warning on line 76 in ui/src/app/account/login/login.component.ts

GitHub Actions / format

Forbidden non-null assertion

Check warning on line 76 in ui/src/app/account/login/login.component.ts

GitHub Actions / format

Forbidden non-null assertion
mfaCode: this.loginForm.get('mfaCode')?.value,
})
.subscribe({
this.mfaSent = false
},
// TODO: review any type
error: (err) => {

Check warning on line 99 in ui/src/app/account/login/login.component.ts

GitHub Actions / format

'err' is defined but never used
this.loginService.logout()
this.authenticationError = true
},