Use confirm button for management list delete

This commit is contained in:
shamoon 2024-02-06 21:31:08 -08:00
parent d63692526a
commit 995563e4ae
3 changed files with 59 additions and 69 deletions

View File

@ -85,33 +85,39 @@
<div class="btn-group d-none d-sm-block"> <div class="btn-group d-none d-sm-block">
<button class="btn btn-sm btn-outline-secondary" (click)="filterDocuments(object); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Document }"> <button class="btn btn-sm btn-outline-secondary" (click)="filterDocuments(object); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Document }">
<i-bs width="1em" height="1em" name="filter"></i-bs>&nbsp;<ng-container i18n>Documents</ng-container> <i-bs width="1em" height="1em" name="filter"></i-bs>&nbsp;<ng-container i18n>Documents</ng-container>
</button> </button>
<button class="btn btn-sm btn-outline-secondary" (click)="openEditDialog(object); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Change, type: permissionType }" [disabled]="!userCanEdit(object)"> <button class="btn btn-sm btn-outline-secondary" (click)="openEditDialog(object); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Change, type: permissionType }" [disabled]="!userCanEdit(object)">
<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" (click)="openDeleteDialog(object); $event.stopPropagation();" *pngxIfPermissions="{ action: PermissionAction.Delete, type: permissionType }" [disabled]="!userCanDelete(object)"> <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
</div> (confirm)="deleteObject(object)"
</td> *pngxIfPermissions="{ action: PermissionAction.Delete, type: permissionType }"
</tr> [disabled]="!userCanDelete(object)"
} buttonClasses=" btn-sm btn-outline-danger"
</tbody> iconName="trash">
</table> </pngx-confirm-button>
</div>
@if (!isLoading) {
<div class="d-flex mb-2">
@if (collectionSize > 0) {
<div>
<ng-container i18n>{collectionSize, plural, =1 {One {{typeName}}} other {{{collectionSize || 0}} total {{typeNamePlural}}}}</ng-container>
@if (selectedObjects.size > 0) {
&nbsp;({{selectedObjects.size}} selected)
}
</div> </div>
} </td>
@if (collectionSize > 20) { </tr>
<ngb-pagination class="ms-auto" [pageSize]="25" [collectionSize]="collectionSize" [(page)]="page" [maxSize]="5" (pageChange)="reloadData()" size="sm" aria-label="Pagination"></ngb-pagination>
}
</div>
} }
</tbody>
</table>
</div>
@if (!isLoading) {
<div class="d-flex mb-2">
@if (collectionSize > 0) {
<div>
<ng-container i18n>{collectionSize, plural, =1 {One {{typeName}}} other {{{collectionSize || 0}} total {{typeNamePlural}}}}</ng-container>
@if (selectedObjects.size > 0) {
&nbsp;({{selectedObjects.size}} selected)
}
</div>
}
@if (collectionSize > 20) {
<ngb-pagination class="ms-auto" [pageSize]="25" [collectionSize]="collectionSize" [(page)]="page" [maxSize]="5" (pageChange)="reloadData()" size="sm" aria-label="Pagination"></ngb-pagination>
}
</div>
}

View File

@ -13,6 +13,7 @@ import {
NgbModalModule, NgbModalModule,
NgbModalRef, NgbModalRef,
NgbPaginationModule, NgbPaginationModule,
NgbPopoverModule,
} from '@ng-bootstrap/ng-bootstrap' } from '@ng-bootstrap/ng-bootstrap'
import { of, throwError } from 'rxjs' import { of, throwError } from 'rxjs'
import { Tag } from 'src/app/data/tag' import { Tag } from 'src/app/data/tag'
@ -37,6 +38,7 @@ import { MATCH_NONE } from 'src/app/data/matching-model'
import { MATCH_LITERAL } from 'src/app/data/matching-model' import { MATCH_LITERAL } from 'src/app/data/matching-model'
import { PermissionsDialogComponent } from '../../common/permissions-dialog/permissions-dialog.component' import { PermissionsDialogComponent } from '../../common/permissions-dialog/permissions-dialog.component'
import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons' import { NgxBootstrapIconsModule, allIcons } from 'ngx-bootstrap-icons'
import { ConfirmButtonComponent } from '../../common/confirm-button/confirm-button.component'
const tags: Tag[] = [ const tags: Tag[] = [
{ {
@ -75,6 +77,7 @@ describe('ManagementListComponent', () => {
SafeHtmlPipe, SafeHtmlPipe,
ConfirmDialogComponent, ConfirmDialogComponent,
PermissionsDialogComponent, PermissionsDialogComponent,
ConfirmButtonComponent,
], ],
providers: [ providers: [
{ {
@ -96,6 +99,7 @@ describe('ManagementListComponent', () => {
NgbModalModule, NgbModalModule,
RouterTestingModule.withRoutes(routes), RouterTestingModule.withRoutes(routes),
NgxBootstrapIconsModule.pick(allIcons), NgxBootstrapIconsModule.pick(allIcons),
NgbPopoverModule,
], ],
}).compileComponents() }).compileComponents()
@ -192,27 +196,23 @@ describe('ManagementListComponent', () => {
}) })
it('should support delete, show notification on error / success', () => { it('should support delete, show notification on error / success', () => {
let modal: NgbModalRef
modalService.activeInstances.subscribe((m) => (modal = m[m.length - 1]))
const toastErrorSpy = jest.spyOn(toastService, 'showError') const toastErrorSpy = jest.spyOn(toastService, 'showError')
const deleteSpy = jest.spyOn(tagService, 'delete') const deleteSpy = jest.spyOn(tagService, 'delete')
const reloadSpy = jest.spyOn(component, 'reloadData') const reloadSpy = jest.spyOn(component, 'reloadData')
const deleteButton = fixture.debugElement.queryAll(By.css('button'))[7] const deleteButton = fixture.debugElement.query(
deleteButton.triggerEventHandler('click') By.directive(ConfirmButtonComponent)
)
expect(modal).not.toBeUndefined()
const editDialog = modal.componentInstance as ConfirmDialogComponent
// fail first // fail first
deleteSpy.mockReturnValueOnce(throwError(() => new Error('error deleting'))) deleteSpy.mockReturnValueOnce(throwError(() => new Error('error deleting')))
editDialog.confirmClicked.emit() deleteButton.nativeElement.dispatchEvent(new Event('confirm'))
expect(toastErrorSpy).toHaveBeenCalled() expect(toastErrorSpy).toHaveBeenCalled()
expect(reloadSpy).not.toHaveBeenCalled() expect(reloadSpy).not.toHaveBeenCalled()
// succeed // succeed
deleteSpy.mockReturnValueOnce(of(true)) deleteSpy.mockReturnValueOnce(of(true))
editDialog.confirmClicked.emit() deleteButton.nativeElement.dispatchEvent(new Event('confirm'))
expect(reloadSpy).toHaveBeenCalled() expect(reloadSpy).toHaveBeenCalled()
}) })

View File

@ -15,10 +15,7 @@ import {
MATCH_NONE, MATCH_NONE,
} from 'src/app/data/matching-model' } from 'src/app/data/matching-model'
import { ObjectWithId } from 'src/app/data/object-with-id' import { ObjectWithId } from 'src/app/data/object-with-id'
import { import { ObjectWithPermissions } from 'src/app/data/object-with-permissions'
ObjectWithPermissions,
PermissionsObject,
} from 'src/app/data/object-with-permissions'
import { import {
SortableDirective, SortableDirective,
SortEvent, SortEvent,
@ -194,34 +191,21 @@ export abstract class ManagementListComponent<T extends ObjectWithId>
]) ])
} }
openDeleteDialog(object: T) { deleteObject(object: T) {
var activeModal = this.modalService.open(ConfirmDialogComponent, { this.service
backdrop: 'static', .delete(object)
}) .pipe(takeUntil(this.unsubscribeNotifier))
activeModal.componentInstance.title = $localize`Confirm delete` .subscribe({
activeModal.componentInstance.messageBold = this.getDeleteMessage(object) next: () => {
activeModal.componentInstance.message = $localize`Associated documents will not be deleted.` this.reloadData()
activeModal.componentInstance.btnClass = 'btn-danger' },
activeModal.componentInstance.btnCaption = $localize`Delete` error: (error) => {
activeModal.componentInstance.confirmClicked.subscribe(() => { this.toastService.showError(
activeModal.componentInstance.buttonsEnabled = false $localize`Error while deleting element`,
this.service error
.delete(object) )
.pipe(takeUntil(this.unsubscribeNotifier)) },
.subscribe({ })
next: () => {
activeModal.close()
this.reloadData()
},
error: (error) => {
activeModal.componentInstance.buttonsEnabled = true
this.toastService.showError(
$localize`Error while deleting element`,
error
)
},
})
})
} }
get nameFilter() { get nameFilter() {