From c96831adc36042a21e6a53885a5d782d6efa6e62 Mon Sep 17 00:00:00 2001 From: nathangray Date: Tue, 12 Mar 2019 11:33:17 -0600 Subject: [PATCH] Add 'confirm_mass_selection' action attribute to either provide or require a confirmation prompt on checkbox actions with more than 20 selections --- api/js/egw_action/egw_action.js | 77 +++++++++++++++++++++++++-- api/js/egw_action/egw_action_popup.js | 11 ++++ infolog/inc/class.infolog_ui.inc.php | 6 +++ 3 files changed, 91 insertions(+), 3 deletions(-) diff --git a/api/js/egw_action/egw_action.js b/api/js/egw_action/egw_action.js index b1cf18a7a8..65897aec70 100644 --- a/api/js/egw_action/egw_action.js +++ b/api/js/egw_action/egw_action.js @@ -269,8 +269,8 @@ egwAction.prototype.getActionsByAttr = function(_attr, _val) { var _actions = []; - // If the current action object has the given attr AND value, return it - if (typeof this[_attr] != "undefined" && this[_attr] === _val) + // If the current action object has the given attr AND value, or no value was provided, return it + if (typeof this[_attr] != "undefined" && (this[_attr] === _val || typeof _val === "undefined" && this[_attr] !== null)) { _actions.push(this); } @@ -589,11 +589,82 @@ egwAction.prototype.setDefaultExecute = function(_value) */ egwAction.prototype.execute = function(_senders, _target) { - if (typeof _target == "undefined") + if (typeof _target === "undefined") { _target = null; } + if(!this._check_confirm_mass_selections(_senders, _target)) + { + this._check_confirm(_senders, _target); + } +}; + +/** + * If this action needs to confirm mass selections (attribute confirm_mass_selection = true), + * check for any checkboxes that have a confirmation prompt (confirm_mass_selection is a string) + * and are unchecked. We then show the prompt, and set the checkbox to their answer. + * + * * This is only considered if there are more than 20 entries selected. + * + * * Only the first confirmation prompt / checkbox action will be used, others + * will be ignored. + * + * @param {type} _senders + * @param {type} _target + * @returns {Boolean} + */ +egwAction.prototype._check_confirm_mass_selections = function(_senders, _target) +{ + var obj_manager = egw_getObjectManager(this.getManager().parent.id, false); + if (!obj_manager) + { + return false; + } + + // Action needs to care about mass selection - check for parent that cares too + var confirm_mass_needed = false; + var action = this; + while(action && action !== obj_manager.manager && !confirm_mass_needed) + { + confirm_mass_needed = action.confirm_mass_selection; + action = action.parent; + } + if(!confirm_mass_needed) return false; + + // Check for confirm mass selection checkboxes + var confirm_mass_selections = obj_manager.manager.getActionsByAttr("confirm_mass_selection"); + confirm_mass_needed = _senders.length > 20; + var self = this; + + // Find & show prompt + for (var i = 0; confirm_mass_needed && i < confirm_mass_selections.length; i++) + { + var check = confirm_mass_selections[i]; + if(check.checkbox === false || check.checked === true) continue; + + // Show the mass selection prompt + var msg = egw.lang(check.confirm_mass_selection, obj_manager.getAllSelected() ? egw.lang('all') : _senders.length); + var callback = function(_button) + { + // YES = unchecked, NO = checked + check.set_checked(_button === et2_dialog.NO_BUTTON); + if(_button !== et2_dialog.CANCEL_BUTTON) + { + self._check_confirm(self, _senders, _target); + } + }; + et2_dialog.show_dialog(callback, msg, self.data.hint, {}, et2_dialog.BUTTONS_YES_NO_CANCEL, et2_dialog.QUESTION_MESSAGE); + return true; + } + return false; +}; + +/** + * Check to see if action needs to be confirmed by user before we do it + */ +egwAction.prototype._check_confirm = function(_senders, _target) +{ // check if actions needs to be confirmed first if (this.data && (this.data.confirm || this.data.confirm_multiple) && this.onExecute.fcnt != window.nm_action && typeof et2_dialog != 'undefined') // let old eTemplate run it's own confirmation from nextmatch_action.js diff --git a/api/js/egw_action/egw_action_popup.js b/api/js/egw_action/egw_action_popup.js index c9cd4bea62..f5d082a41d 100644 --- a/api/js/egw_action/egw_action_popup.js +++ b/api/js/egw_action/egw_action_popup.js @@ -34,6 +34,7 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult action.checkbox = false; action.radioGroup = 0; action.checked = false; + action.confirm_mass_selection = null; action.shortcut = null; action.set_default = function(_value) { @@ -61,6 +62,16 @@ function egwPopupAction(_id, _handler, _caption, _icon, _onExecute, _allowOnMult action.checked = _value; }; + /** + * Set either a confirmation prompt, or TRUE to indicate that this action + * cares about large selections and to ask the confirmation prompt(s) + * + * @param {String|Boolean} _value + */ + action.set_confirm_mass_selection = function(_value) { + action.confirm_mass_selection = _value; + }; + // Allow checkbox to be set from context using the given function action.set_isChecked = function(_value) { action.isChecked = new egwFnct(this, null, []); diff --git a/infolog/inc/class.infolog_ui.inc.php b/infolog/inc/class.infolog_ui.inc.php index 0f80e07835..cb87f39841 100644 --- a/infolog/inc/class.infolog_ui.inc.php +++ b/infolog/inc/class.infolog_ui.inc.php @@ -1123,6 +1123,7 @@ class infolog_ui 'no_notifications' => array( 'caption' => 'Do not notify', 'checkbox' => true, + 'confirm_mass_selection' => "You are going to change %1 entries: Are you sure you want to send notifications about this change?", 'hint' => 'Do not notify of these changes', 'group' => $group, ), @@ -1132,6 +1133,7 @@ class infolog_ui 'group' => ++$group, 'icon' => 'edit', 'disableClass' => 'rowNoEdit', + 'confirm_mass_selection' => true, 'children' => array( 'type' => array( 'caption' => 'Type', @@ -1187,6 +1189,7 @@ class infolog_ui 'icon' => 'done', 'group' => $group, 'disableClass' => 'rowNoClose', + 'confirm_mass_selection' => true, ), 'close_all' => array( 'caption' => 'Close all', @@ -1195,6 +1198,7 @@ class infolog_ui 'hint' => 'Sets the status of this entry and its subs to done', 'allowOnMultiple' => false, 'disableClass' => 'rowNoCloseAll', + 'confirm_mass_selection' => true, ), 'print' => array( 'caption' => 'Print', @@ -1283,6 +1287,7 @@ class infolog_ui 'group' => ++$group, 'disableClass' => 'rowNoDelete', 'onExecute' => 'javaScript:app.infolog.confirm_delete', + 'confirm_mass_selection' => true, ); if ($query['col_filter']['info_status'] == 'deleted') { @@ -1291,6 +1296,7 @@ class infolog_ui 'group' => $group, 'icon' => 'revert', 'disableClass' => 'rowNoUndelete', + 'confirm_mass_selection' => true, ); } $actions['info_drop_mail'] = array(