mirror of
https://github.com/SuiteCRM/SuiteCRM-Core.git
synced 2025-08-29 11:00:40 +08:00
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:
parent
8ad9d8474b
commit
fc9fcfd2cf
3 changed files with 77 additions and 10 deletions
|
@ -143,6 +143,19 @@ export class RecordManager {
|
||||||
return deepClone(this.internalState);
|
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
|
* Get record cached Observable or call the backend
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import {Injectable} from '@angular/core';
|
import {Injectable} from '@angular/core';
|
||||||
import {RecordActionData, RecordActionHandler} from '@views/record/actions/record.action';
|
import {RecordActionData, RecordActionHandler} from '@views/record/actions/record.action';
|
||||||
import {ViewMode} from '@app-common/views/view.model';
|
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({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
|
@ -10,16 +13,47 @@ export class RecordCancelAction extends RecordActionHandler {
|
||||||
key = 'cancel';
|
key = 'cancel';
|
||||||
modes = ['edit' as ViewMode];
|
modes = ['edit' as ViewMode];
|
||||||
|
|
||||||
constructor() {
|
constructor(private modalService: NgbModal) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
run(data: RecordActionData): void {
|
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 {
|
shouldDisplay(): boolean {
|
||||||
return true;
|
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,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {moduleNameMapperMock} from '@services/navigation/module-name-mapper/module-name-mapper.service.spec.mock';
|
||||||
import {RecordSaveAction} from '@views/record/actions/save/record-save.action';
|
import {RecordSaveAction} from '@views/record/actions/save/record-save.action';
|
||||||
import {messageServiceMock} from '@services/message/message.service.spec.mock';
|
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 = {
|
const mockRouter = {
|
||||||
navigate: (
|
navigate: (commands: any[], extras?: NavigationExtras) => {
|
||||||
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
if (!extras || !commands) {
|
||||||
commands: any[],
|
return null;
|
||||||
// eslint-disable-next-line no-unused-vars, @typescript-eslint/no-unused-vars
|
}
|
||||||
extras?: NavigationExtras
|
|
||||||
) => null
|
return null;
|
||||||
|
}
|
||||||
} as Router;
|
} 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(
|
export const recordActionsManagerMock = new RecordActionManager(
|
||||||
new RecordEditAction(),
|
new RecordEditAction(),
|
||||||
new RecordCreateAction(moduleNameMapperMock, mockRouter),
|
new RecordCreateAction(moduleNameMapperMock, mockRouter),
|
||||||
new RecordToggleWidgetsAction(),
|
new RecordToggleWidgetsAction(),
|
||||||
new RecordCancelAction(),
|
new RecordCancelAction(new MockModal()),
|
||||||
new RecordSaveAction(messageServiceMock)
|
new RecordSaveAction(messageServiceMock)
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue