impr confirm leave out, collapse modal ref

This commit is contained in:
Yuri Kuznetsov
2025-03-20 16:59:02 +02:00
parent 45ab1653a4
commit c742c0859b
7 changed files with 131 additions and 14 deletions
+3 -3
View File
@@ -1213,13 +1213,13 @@ class App {
break;
}
if (this.auth && this.router && !this.router.confirmLeaveOut) {
if (this.auth && this.router && !this.router.hasConfirmLeaveOut()) {
this.logout(true);
break;
}
if (this.auth && this.router && this.router.confirmLeaveOut) {
if (this.auth && this.router && this.router.hasConfirmLeaveOut()) {
Ui.error(this.language.translate('loggedOutLeaveOut', 'messages'), true);
this.router.trigger('logout');
@@ -1441,7 +1441,7 @@ class App {
}
if (event.data === 'logged-out' && this.started) {
if (this.auth && this.router.confirmLeaveOut) {
if (this.auth && this.router.hasConfirmLeaveOut()) {
Ui.error(this.language.translate('loggedOutLeaveOut', 'messages'), true);
this.router.trigger('logout');
+9 -3
View File
@@ -75,6 +75,7 @@ class RecordModalHelper {
* afterDestroy?: function(import('model').default),
* beforeRender?: function(import('views/modals/detail').default),
* onClose?: function(),
* collapseDisabled: boolean,
* }} params
* @return {Promise<import('views/modals/detail').default>}
*/
@@ -99,7 +100,7 @@ class RecordModalHelper {
Espo.Ui.notifyWait();
/** @type {module:views/modals/detail~options} */
/** @type {module:views/modals/detail~options & module:views/modal~Options} */
const options = {
entityType: entityType,
model: model,
@@ -110,6 +111,7 @@ class RecordModalHelper {
layoutName: params.layoutName,
fullFormDisabled: params.fullFormDisabled,
fullFormUrl: params.fullFormUrl,
collapseDisabled: params.collapseDisabled,
};
Espo.Ui.notifyWait();
@@ -166,6 +168,7 @@ class RecordModalHelper {
* action: string|null,
* options: {isReturn?: boolean} & Record,
* },
* collapseDisabled: boolean,
* }} params
* @return {Promise<import('views/modals/edit').default>}
* @since 9.1.0
@@ -178,7 +181,7 @@ class RecordModalHelper {
const viewName = this.metadata.get(`clientDefs.${entityType}.modalViews.edit`) ||
'views/modals/edit';
/** @type {module:views/modals/edit~options} */
/** @type {module:views/modals/edit~options & module:views/modal~Options} */
const options = {
entityType: entityType,
id: id,
@@ -188,6 +191,7 @@ class RecordModalHelper {
returnDispatchParams: params.returnDispatchParams,
layoutName: params.layoutName,
fullFormUrl: params.fullFormUrl,
collapseDisabled: params.collapseDisabled,
};
if (params.rootUrl) {
@@ -245,6 +249,7 @@ class RecordModalHelper {
* action: string|null,
* options: {isReturn?: boolean} & Record,
* },
* collapseDisabled: boolean,
* }} params
* @return {Promise<import('views/modals/edit').default>}
* @since 9.1.0
@@ -255,7 +260,7 @@ class RecordModalHelper {
const viewName = this.metadata.get(`clientDefs.${entityType}.modalViews.edit`) ||
'views/modals/edit';
/** @type {module:views/modals/edit~options} */
/** @type {module:views/modals/edit~options & module:views/modal~Options} */
const options = {
entityType: entityType,
fullFormDisabled: params.fullFormDisabled,
@@ -266,6 +271,7 @@ class RecordModalHelper {
focusForCreate: params.focusForCreate,
layoutName: params.layoutName,
fullFormUrl: params.fullFormUrl,
collapseDisabled: params.collapseDisabled,
};
if (params.rootUrl) {
+78 -6
View File
@@ -261,17 +261,33 @@ const Router = Backbone.Router.extend(/** @lends Router# */ {
this.history.push(Backbone.history.fragment);
});
window.addEventListener('beforeunload', (e) => {
e = e || window.event;
window.addEventListener('beforeunload', event => {
event = event || window.event;
if (this.confirmLeaveOut) {
e.preventDefault();
if (
this.confirmLeaveOut ||
this._leaveOutMap.size ||
this._windowLeaveOutMap.size
) {
event.preventDefault();
e.returnValue = this.confirmLeaveOutMessage;
event.returnValue = this.confirmLeaveOutMessage;
return this.confirmLeaveOutMessage;
}
});
/**
* @private
* @type {Map<Object, true>}
*/
this._leaveOutMap = new Map();
/**
* @private
* @type {Map<Object, true>}
*/
this._windowLeaveOutMap = new Map();
},
/**
@@ -283,6 +299,60 @@ const Router = Backbone.Router.extend(/** @lends Router# */ {
return '#' + Backbone.history.fragment;
},
/**
* Whether there's any confirm-leave-out.
*
* @since 9.1.0
* @return {boolean}
*/
hasConfirmLeaveOut() {
return this.confirmLeaveOut || this._leaveOutMap.size || this._windowLeaveOutMap.size;
},
/**
* Refer an object (usually a view). Page won't be possible to close or change if there's at least one object.
*
* @param {Object} object
* @since 9.1.0
* @internal
*/
addLeaveOutObject(object) {
this._leaveOutMap.set(object, true);
},
/**
* Un-refer an object.
*
* @param {Object} object
* @since 9.1.0
* @internal
*/
removeLeaveOutObject(object) {
this._leaveOutMap.delete(object);
},
/**
* Refer an object (usually a view). Window won't be possible to close if there's at least one object.
*
* @param {Object} object
* @since 9.1.0
* @internal
*/
addWindowLeaveOutObject(object) {
this._windowLeaveOutMap.set(object, true);
},
/**
* Un-refer an object.
*
* @param {Object} object
* @since 9.1.0
* @internal
*/
removeWindowLeaveOutObject(object) {
this._windowLeaveOutMap.delete(object);
},
/**
* @callback module:router~checkConfirmLeaveOutCallback
*/
@@ -305,7 +375,7 @@ const Router = Backbone.Router.extend(/** @lends Router# */ {
context = context || this;
if (this.confirmLeaveOut) {
if (this.confirmLeaveOut || this._leaveOutMap.size) {
this.confirmLeaveOutDisplayed = true;
this.confirmLeaveOutCanceled = false;
@@ -327,6 +397,8 @@ const Router = Backbone.Router.extend(/** @lends Router# */ {
this.confirmLeaveOutDisplayed = false;
this.confirmLeaveOut = false;
this._leaveOutMap.clear();
if (!this.confirmLeaveOutCanceled) {
callback.call(context);
}
+5
View File
@@ -70,6 +70,7 @@ class ModalView extends View {
* @property {'static'|boolean} [backdrop] A backdrop.
* @property {module:views/modal~Button} [buttonList] Buttons.
* @property {module:views/modal~Button} [dropdownItemList] Buttons.
* @property {boolean} [collapseDisabled] Not collapsable. As of v9.1.0.
*/
/**
@@ -315,6 +316,10 @@ class ModalView extends View {
this.shortcutKeys = Espo.Utils.cloneDeep(this.shortcutKeys);
}
if (this.options.collapseDisabled) {
this.isCollapsable = false;
}
this.on('render', () => {
if (this.dialog) {
this.dialog.close();
+4 -1
View File
@@ -639,10 +639,12 @@ class DetailModalView extends ModalView {
const helper = new RecordModal();
// noinspection UnnecessaryLocalVariableJS
const modalView = await helper.showEdit(this, {
entityType: this.entityType,
id: this.id,
fullFormDisabled: this.fullFormDisabled,
collapseDisabled: true,
afterSave: (model, o) => {
this.model.set(model.getClonedAttributes());
@@ -661,7 +663,8 @@ class DetailModalView extends ModalView {
},
});
this.dialog.hide();
// Not to hidden as it interferes with the collapsable modal.
//this.dialog.hide();
return modalView;
}
+27
View File
@@ -52,6 +52,12 @@ class EditModalView extends ModalView {
/** @protected */
bottomDisabled = false
/**
* @private
* @type {boolean}
*/
wasModified = false
/**
* @private
* @type {string}
@@ -242,6 +248,12 @@ class EditModalView extends ModalView {
this.createRecordView(model);
});
this.listenTo(this.model, 'change', (m, o) => {
if (o.ui) {
this.wasModified = true;
}
});
}
/**
@@ -478,6 +490,21 @@ class EditModalView extends ModalView {
this.trigger('leave');
this.dialog.close();
}
async beforeCollapse() {
if (this.wasModified) {
this.getRecordView().setConfirmLeaveOut(false);
this.getRouter().addWindowLeaveOutObject(this);
}
}
afterExpand() {
if (this.wasModified) {
this.getRecordView().setConfirmLeaveOut(true);
}
this.getRouter().removeWindowLeaveOutObject(this);
}
}
export default EditModalView;
+5 -1
View File
@@ -510,7 +510,11 @@ class BaseRecordView extends View {
return;
}
this.getRouter().confirmLeaveOut = value;
if (value) {
this.getRouter().addLeaveOutObject(this);
} else {
this.getRouter().removeLeaveOutObject(this);
}
}
/**