Use confirm button for users / groups delete

This commit is contained in:
shamoon 2024-02-06 22:14:30 -08:00
parent 5bd1bf37f3
commit 5e68a51ae9
3 changed files with 102 additions and 115 deletions

View File

@ -34,9 +34,14 @@
<button class="btn btn-sm btn-outline-secondary" type="button" (click)="editUser(user)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.User }"> <button class="btn btn-sm btn-outline-secondary" type="button" (click)="editUser(user)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.User }">
<i-bs width="1em" height="1em" name="pencil"></i-bs>&nbsp;<ng-container i18n>Edit</ng-container> <i-bs width="1em" height="1em" name="pencil"></i-bs>&nbsp;<ng-container i18n>Edit</ng-container>
</button> </button>
<button class="btn btn-sm btn-outline-danger" type="button" (click)="deleteUser(user)" *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.User }"> <pngx-confirm-button
<i-bs width="1em" height="1em" name="trash"></i-bs>&nbsp;<ng-container i18n>Delete</ng-container> label="Delete"
</button> i18n-label
(confirm)="deleteUser(user)"
*pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.User }"
buttonClasses="btn-sm btn-outline-danger"
iconName="trash">
</pngx-confirm-button>
</div> </div>
</div> </div>
</div> </div>
@ -73,9 +78,14 @@
<button class="btn btn-sm btn-outline-secondary" type="button" (click)="editGroup(group)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Group }"> <button class="btn btn-sm btn-outline-secondary" type="button" (click)="editGroup(group)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.Group }">
<i-bs width="1em" height="1em" name="pencil"></i-bs>&nbsp;<ng-container i18n>Edit</ng-container> <i-bs width="1em" height="1em" name="pencil"></i-bs>&nbsp;<ng-container i18n>Edit</ng-container>
</button> </button>
<button class="btn btn-sm btn-outline-danger" type="button" (click)="deleteGroup(group)" *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.Group }"> <pngx-confirm-button
<i-bs width="1em" height="1em" name="trash"></i-bs>&nbsp;<ng-container i18n>Delete</ng-container> label="Delete"
</button> i18n-label
(confirm)="deleteGroup(group)"
*pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.Group }"
buttonClasses="btn-sm btn-outline-danger"
iconName="trash">
</pngx-confirm-button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -44,6 +44,8 @@ import { UsersAndGroupsComponent } from './users-groups.component'
import { User } from 'src/app/data/user' import { User } from 'src/app/data/user'
import { Group } from 'src/app/data/group' import { Group } from 'src/app/data/group'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons' import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { By } from '@angular/platform-browser'
import { ConfirmButtonComponent } from '../../common/confirm-button/confirm-button.component'
const users = [ const users = [
{ id: 1, username: 'user1', is_superuser: false }, { id: 1, username: 'user1', is_superuser: false },
@ -83,6 +85,7 @@ describe('UsersAndGroupsComponent', () => {
PermissionsUserComponent, PermissionsUserComponent,
PermissionsGroupComponent, PermissionsGroupComponent,
IfOwnerDirective, IfOwnerDirective,
ConfirmButtonComponent,
], ],
providers: [CustomDatePipe, DatePipe, PermissionsGuard], providers: [CustomDatePipe, DatePipe, PermissionsGuard],
imports: [ imports: [
@ -160,10 +163,9 @@ describe('UsersAndGroupsComponent', () => {
it('should support delete user, show error if needed', () => { it('should support delete user, show error if needed', () => {
completeSetup() completeSetup()
let modal: NgbModalRef const deleteButton = fixture.debugElement.query(
modalService.activeInstances.subscribe((refs) => (modal = refs[0])) By.directive(ConfirmButtonComponent)
component.deleteUser(users[0]) )
const deleteDialog = modal.componentInstance as ConfirmDialogComponent
const deleteSpy = jest.spyOn(userService, 'delete') const deleteSpy = jest.spyOn(userService, 'delete')
const toastErrorSpy = jest.spyOn(toastService, 'showError') const toastErrorSpy = jest.spyOn(toastService, 'showError')
const toastInfoSpy = jest.spyOn(toastService, 'showInfo') const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
@ -171,10 +173,10 @@ describe('UsersAndGroupsComponent', () => {
deleteSpy.mockReturnValueOnce( deleteSpy.mockReturnValueOnce(
throwError(() => new Error('error deleting user')) throwError(() => new Error('error deleting user'))
) )
deleteDialog.confirm() deleteButton.nativeElement.dispatchEvent(new Event('confirm'))
expect(toastErrorSpy).toBeCalled() expect(toastErrorSpy).toHaveBeenCalled()
deleteSpy.mockReturnValueOnce(of(true)) deleteSpy.mockReturnValueOnce(of(true))
deleteDialog.confirm() deleteButton.nativeElement.dispatchEvent(new Event('confirm'))
expect(listAllSpy).toHaveBeenCalled() expect(listAllSpy).toHaveBeenCalled()
expect(toastInfoSpy).toHaveBeenCalledWith('Deleted user') expect(toastInfoSpy).toHaveBeenCalledWith('Deleted user')
}) })
@ -218,10 +220,9 @@ describe('UsersAndGroupsComponent', () => {
it('should support delete group, show error if needed', () => { it('should support delete group, show error if needed', () => {
completeSetup() completeSetup()
let modal: NgbModalRef const deleteButton = fixture.debugElement.queryAll(
modalService.activeInstances.subscribe((refs) => (modal = refs[0])) By.directive(ConfirmButtonComponent)
component.deleteGroup(users[0]) )[2]
const deleteDialog = modal.componentInstance as ConfirmDialogComponent
const deleteSpy = jest.spyOn(groupService, 'delete') const deleteSpy = jest.spyOn(groupService, 'delete')
const toastErrorSpy = jest.spyOn(toastService, 'showError') const toastErrorSpy = jest.spyOn(toastService, 'showError')
const toastInfoSpy = jest.spyOn(toastService, 'showInfo') const toastInfoSpy = jest.spyOn(toastService, 'showInfo')
@ -229,10 +230,10 @@ describe('UsersAndGroupsComponent', () => {
deleteSpy.mockReturnValueOnce( deleteSpy.mockReturnValueOnce(
throwError(() => new Error('error deleting group')) throwError(() => new Error('error deleting group'))
) )
deleteDialog.confirm() deleteButton.nativeElement.dispatchEvent(new Event('confirm'))
expect(toastErrorSpy).toBeCalled() expect(toastErrorSpy).toHaveBeenCalled()
deleteSpy.mockReturnValueOnce(of(true)) deleteSpy.mockReturnValueOnce(of(true))
deleteDialog.confirm() deleteButton.nativeElement.dispatchEvent(new Event('confirm'))
expect(listAllSpy).toHaveBeenCalled() expect(listAllSpy).toHaveBeenCalled()
expect(toastInfoSpy).toHaveBeenCalledWith('Deleted group') expect(toastInfoSpy).toHaveBeenCalledWith('Deleted group')
}) })

View File

@ -108,19 +108,8 @@ export class UsersAndGroupsComponent
} }
deleteUser(user: User) { deleteUser(user: User) {
let modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.title = $localize`Confirm delete user account`
modal.componentInstance.messageBold = $localize`This operation will permanently delete this user account.`
modal.componentInstance.message = $localize`This operation cannot be undone.`
modal.componentInstance.btnClass = 'btn-danger'
modal.componentInstance.btnCaption = $localize`Proceed`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
this.usersService.delete(user).subscribe({ this.usersService.delete(user).subscribe({
next: () => { next: () => {
modal.close()
this.toastService.showInfo($localize`Deleted user`) this.toastService.showInfo($localize`Deleted user`)
this.usersService.listAll().subscribe((r) => { this.usersService.listAll().subscribe((r) => {
this.users = r.results this.users = r.results
@ -130,7 +119,6 @@ export class UsersAndGroupsComponent
this.toastService.showError($localize`Error deleting user.`, e) this.toastService.showError($localize`Error deleting user.`, e)
}, },
}) })
})
} }
editGroup(group: Group = null) { editGroup(group: Group = null) {
@ -158,19 +146,8 @@ export class UsersAndGroupsComponent
} }
deleteGroup(group: Group) { deleteGroup(group: Group) {
let modal = this.modalService.open(ConfirmDialogComponent, {
backdrop: 'static',
})
modal.componentInstance.title = $localize`Confirm delete user group`
modal.componentInstance.messageBold = $localize`This operation will permanently delete this user group.`
modal.componentInstance.message = $localize`This operation cannot be undone.`
modal.componentInstance.btnClass = 'btn-danger'
modal.componentInstance.btnCaption = $localize`Proceed`
modal.componentInstance.confirmClicked.subscribe(() => {
modal.componentInstance.buttonsEnabled = false
this.groupsService.delete(group).subscribe({ this.groupsService.delete(group).subscribe({
next: () => { next: () => {
modal.close()
this.toastService.showInfo($localize`Deleted group`) this.toastService.showInfo($localize`Deleted group`)
this.groupsService.listAll().subscribe((r) => { this.groupsService.listAll().subscribe((r) => {
this.groups = r.results this.groups = r.results
@ -180,7 +157,6 @@ export class UsersAndGroupsComponent
this.toastService.showError($localize`Error deleting group.`, e) this.toastService.showError($localize`Error deleting group.`, e)
}, },
}) })
})
} }
getGroupName(id: number): string { getGroupName(id: number): string {