Use confirm button for custom fields list delete

This commit is contained in:
shamoon 2024-02-06 22:22:33 -08:00
parent 5e68a51ae9
commit 3fd10deadf
3 changed files with 33 additions and 43 deletions

View File

@ -29,16 +29,21 @@
<div class="btn-group"> <div class="btn-group">
<button *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.CustomField }" class="btn btn-sm btn-outline-secondary" type="button" (click)="editField(field)"> <button *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.CustomField }" class="btn btn-sm btn-outline-secondary" type="button" (click)="editField(field)">
<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 *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.CustomField }" class="btn btn-sm btn-outline-danger" type="button" (click)="deleteField(field)"> <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)="deleteField(field)"
</div> *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.CustomField }"
buttonClasses="btn-sm btn-outline-danger"
iconName="trash">
</pngx-confirm-button>
</div> </div>
</li> </div>
} </div>
@if (fields.length === 0) { </li>
<li class="list-group-item" i18n>No fields defined.</li> }
} @if (fields.length === 0) {
</ul> <li class="list-group-item" i18n>No fields defined.</li>
}
</ul>

View File

@ -21,6 +21,7 @@ import { ConfirmDialogComponent } from '../../common/confirm-dialog/confirm-dial
import { PageHeaderComponent } from '../../common/page-header/page-header.component' import { PageHeaderComponent } from '../../common/page-header/page-header.component'
import { CustomFieldEditDialogComponent } from '../../common/edit-dialog/custom-field-edit-dialog/custom-field-edit-dialog.component' import { CustomFieldEditDialogComponent } from '../../common/edit-dialog/custom-field-edit-dialog/custom-field-edit-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 fields: CustomField[] = [ const fields: CustomField[] = [
{ {
@ -49,6 +50,7 @@ describe('CustomFieldsComponent', () => {
IfPermissionsDirective, IfPermissionsDirective,
PageHeaderComponent, PageHeaderComponent,
ConfirmDialogComponent, ConfirmDialogComponent,
ConfirmButtonComponent,
], ],
providers: [ providers: [
{ {
@ -137,27 +139,22 @@ describe('CustomFieldsComponent', () => {
}) })
it('should support delete, show notification on error / success', () => { it('should support delete, show notification on error / success', () => {
let modal: NgbModalRef const deleteButton = fixture.debugElement.query(
modalService.activeInstances.subscribe((m) => (modal = m[m.length - 1])) By.directive(ConfirmButtonComponent)
)
const toastErrorSpy = jest.spyOn(toastService, 'showError') const toastErrorSpy = jest.spyOn(toastService, 'showError')
const deleteSpy = jest.spyOn(customFieldsService, 'delete') const deleteSpy = jest.spyOn(customFieldsService, 'delete')
const reloadSpy = jest.spyOn(component, 'reload') const reloadSpy = jest.spyOn(component, 'reload')
const deleteButton = fixture.debugElement.queryAll(By.css('button'))[4]
deleteButton.triggerEventHandler('click')
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

@ -65,27 +65,15 @@ export class CustomFieldsComponent
} }
deleteField(field: CustomField) { deleteField(field: CustomField) {
const modal = this.modalService.open(ConfirmDialogComponent, { this.customFieldsService.delete(field).subscribe({
backdrop: 'static', next: () => {
}) this.toastService.showInfo($localize`Deleted field`)
modal.componentInstance.title = $localize`Confirm delete field` this.customFieldsService.clearCache()
modal.componentInstance.messageBold = $localize`This operation will permanently delete this field.` this.reload()
modal.componentInstance.message = $localize`This operation cannot be undone.` },
modal.componentInstance.btnClass = 'btn-danger' error: (e) => {
modal.componentInstance.btnCaption = $localize`Proceed` this.toastService.showError($localize`Error deleting field.`, e)
modal.componentInstance.confirmClicked.subscribe(() => { },
modal.componentInstance.buttonsEnabled = false
this.customFieldsService.delete(field).subscribe({
next: () => {
modal.close()
this.toastService.showInfo($localize`Deleted field`)
this.customFieldsService.clearCache()
this.reload()
},
error: (e) => {
this.toastService.showError($localize`Error deleting field.`, e)
},
})
}) })
} }