diff --git a/public/src/admin/manage/privileges.js b/public/src/admin/manage/privileges.js index 7bf9137d19..5371f2d0f4 100644 --- a/public/src/admin/manage/privileges.js +++ b/public/src/admin/manage/privileges.js @@ -6,7 +6,8 @@ define('admin/manage/privileges', [ 'benchpress', 'categorySelector', 'mousetrap', -], function (autocomplete, translator, Benchpress, categorySelector, mousetrap) { + 'admin/modules/checkboxRowSelector', +], function (autocomplete, translator, Benchpress, categorySelector, mousetrap, checkboxRowSelector) { var Privileges = {}; var cid; @@ -14,6 +15,8 @@ define('admin/manage/privileges', [ Privileges.init = function () { cid = isNaN(parseInt(ajaxify.data.selectedCategory.cid, 10)) ? 'admin' : ajaxify.data.selectedCategory.cid; + checkboxRowSelector.init('.privilege-table-container'); + categorySelector.init($('[component="category-selector"]'), function (category) { cid = parseInt(category.cid, 10); cid = isNaN(cid) ? 'admin' : cid; @@ -52,12 +55,14 @@ define('admin/manage/privileges', [ wrapperEl.attr('data-delta', delta); Privileges.exposeAssumedPrivileges(); } + checkboxRowSelector.updateState(checkboxEl); } else { app.alertError('[[error:invalid-data]]'); } }); Privileges.exposeAssumedPrivileges(); + checkboxRowSelector.updateAll(); Privileges.addEvents(); // events with confirmation modals }; @@ -145,6 +150,7 @@ define('admin/manage/privileges', [ }, function (html) { $('.privilege-table-container').html(html); Privileges.exposeAssumedPrivileges(); + checkboxRowSelector.updateAll(); hightlightRowByDataAttr('data-group-name', groupToHighlight); }); @@ -158,7 +164,7 @@ define('admin/manage/privileges', [ this arrangement in the table */ var privs = []; - $('.privilege-table tr[data-group-name="registered-users"] td input[type="checkbox"]').parent().each(function (idx, el) { + $('.privilege-table tr[data-group-name="registered-users"] td input[type="checkbox"]:not(.checkbox-helper)').parent().each(function (idx, el) { if ($(el).find('input').prop('checked')) { privs.push(el.getAttribute('data-privilege')); } diff --git a/public/src/admin/modules/checkboxRowSelector.js b/public/src/admin/modules/checkboxRowSelector.js new file mode 100644 index 0000000000..e1d6c75ec9 --- /dev/null +++ b/public/src/admin/modules/checkboxRowSelector.js @@ -0,0 +1,49 @@ +'use strict'; + +define('admin/modules/checkboxRowSelector', function () { + const self = {}; + let $tableContainer; + + self.toggling = false; + + self.init = function (tableCssSelector) { + $tableContainer = $(tableCssSelector); + $tableContainer.on('change', 'input.checkbox-helper', handleChange); + }; + + self.updateAll = function () { + $tableContainer.find('input.checkbox-helper').each((idx, el) => { + self.updateState($(el)); + }); + }; + + self.updateState = function ($checkboxEl) { + if (self.toggling) { + return; + } + const checkboxes = $checkboxEl.closest('tr').find('input:not([disabled])').toArray(); + const $toggler = $(checkboxes.shift()); + const rowState = checkboxes.every(el => el.checked); + $toggler.prop('checked', rowState); + }; + + function handleChange(ev) { + const $checkboxEl = $(ev.target); + toggleAll($checkboxEl); + } + + function toggleAll($checkboxEl) { + self.toggling = true; + const state = $checkboxEl.prop('checked'); + $checkboxEl.closest('tr').find('input:not(.checkbox-helper)').each((idx, el) => { + const $checkbox = $(el); + if ($checkbox.prop('checked') === state) { + return; + } + $checkbox.click(); + }); + self.toggling = false; + } + + return self; +}); diff --git a/src/views/admin/partials/privileges/global.tpl b/src/views/admin/partials/privileges/global.tpl index ad36cdca16..2c704ea7b4 100644 --- a/src/views/admin/partials/privileges/global.tpl +++ b/src/views/admin/partials/privileges/global.tpl @@ -3,6 +3,7 @@ [[admin/manage/categories:privileges.section-group]] + Select/Clear All {privileges.labels.groups.name} @@ -18,6 +19,7 @@ {privileges.groups.name} + {function.spawnPrivilegeStates, privileges.groups.name, ../privileges} @@ -45,6 +47,7 @@ [[admin/manage/categories:privileges.section-user]] + Select/Clear All {privileges.labels.users.name} @@ -61,6 +64,7 @@ {privileges.users.username} + {function.spawnPrivilegeStates, privileges.users.username, ../privileges}