Add record view cancel confirmation modal

- Check if the record is dirty when cancel is clicked
-- Use the formGroup dirty flag
- Launch message modal if dirty
- Only execute cancel if ok button is clicked
- Otherwise stay on page
- Adjust unit / karma tests
This commit is contained in:
Clemente Raposo 2021-01-11 17:44:42 +00:00 committed by Dillon-Brown
parent 8ad9d8474b
commit fc9fcfd2cf
3 changed files with 77 additions and 10 deletions

View file

@ -143,6 +143,19 @@ export class RecordManager {
return deepClone(this.internalState);
}
/**
* Is staging record dirty
*
* @returns {object} Record
*/
isDirty(): boolean {
if (!this.stagingState || !this.stagingState.formGroup) {
return false;
}
return this.stagingState.formGroup.dirty;
}
/**
* Get record cached Observable or call the backend
*

View file

@ -1,6 +1,9 @@
import {Injectable} from '@angular/core';
import {RecordActionData, RecordActionHandler} from '@views/record/actions/record.action';
import {ViewMode} from '@app-common/views/view.model';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {MessageModalComponent} from '@components/modal/components/message-modal/message-modal.component';
import {ModalButtonInterface} from '@app-common/components/modal/modal.model';
@Injectable({
providedIn: 'root'
@ -10,16 +13,47 @@ export class RecordCancelAction extends RecordActionHandler {
key = 'cancel';
modes = ['edit' as ViewMode];
constructor() {
constructor(private modalService: NgbModal) {
super();
}
run(data: RecordActionData): void {
data.store.recordManager.resetStaging();
data.store.setMode('detail' as ViewMode);
if (data.store.recordManager.isDirty()) {
this.showConfirmationModal(data);
return;
}
this.cancel(data);
}
shouldDisplay(): boolean {
return true;
}
protected cancel(data: RecordActionData): void {
data.store.recordManager.resetStaging();
data.store.setMode('detail' as ViewMode);
}
protected showConfirmationModal(data: RecordActionData): void {
const modal = this.modalService.open(MessageModalComponent);
modal.componentInstance.textKey = 'WARN_UNSAVED_CHANGES';
modal.componentInstance.buttons = [
{
labelKey: 'LBL_CANCEL',
klass: ['btn-secondary'],
onClick: activeModal => activeModal.dismiss()
} as ModalButtonInterface,
{
labelKey: 'LBL_OK',
klass: ['btn-main'],
onClick: activeModal => {
this.cancel(data);
activeModal.close();
}
} as ModalButtonInterface,
];
}
}

View file

@ -7,20 +7,40 @@ import {RecordActionManager} from '@views/record/actions/record-action-manager.s
import {moduleNameMapperMock} from '@services/navigation/module-name-mapper/module-name-mapper.service.spec.mock';
import {RecordSaveAction} from '@views/record/actions/save/record-save.action';
import {messageServiceMock} from '@services/message/message.service.spec.mock';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {NgbModalRef} from '@ng-bootstrap/ng-bootstrap/modal/modal-ref';
const mockRouter = {
navigate: (
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
commands: any[],
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
extras?: NavigationExtras
) => null
navigate: (commands: any[], extras?: NavigationExtras) => {
if (!extras || !commands) {
return null;
}
return null;
}
} as Router;
export class MockModal extends NgbModal {
constructor() {
super(null, null, null, null);
}
open(): NgbModalRef {
return {
componentInstance: {
textKey: '',
buttons: []
}
} as NgbModalRef;
}
}
export const recordActionsManagerMock = new RecordActionManager(
new RecordEditAction(),
new RecordCreateAction(moduleNameMapperMock, mockRouter),
new RecordToggleWidgetsAction(),
new RecordCancelAction(),
new RecordCancelAction(new MockModal()),
new RecordSaveAction(messageServiceMock)
);