Add 'confirm_mass_selection' action attribute to either provide or require a confirmation prompt on checkbox actions with more than 20 selections

This commit is contained in:
nathangray 2019-03-12 11:33:17 -06:00
parent 21962bdfe4
commit c96831adc3
3 changed files with 91 additions and 3 deletions

View File

@ -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

View File

@ -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, []);

View File

@ -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(