183 lines
4.4 KiB
JavaScript
183 lines
4.4 KiB
JavaScript
// RBAC permission matrix helpers for checkbox groups.
|
|
|
|
(function () {
|
|
function getPermissionSections() {
|
|
return Array.prototype.slice.call(document.querySelectorAll('[data-permission-section]'));
|
|
}
|
|
|
|
function getPermissionRows(container) {
|
|
return Array.prototype.slice.call(container.querySelectorAll('[data-permission-row]'));
|
|
}
|
|
|
|
function getRowCheckboxes(row) {
|
|
return Array.prototype.slice.call(row.querySelectorAll('input[name="permission_keys[]"]'));
|
|
}
|
|
|
|
function getPermissionKey(checkbox) {
|
|
return String((checkbox && (checkbox.getAttribute('data-permission-key') || checkbox.value)) || '').trim().toLowerCase();
|
|
}
|
|
|
|
function getActionKey(checkbox) {
|
|
var permissionKey = getPermissionKey(checkbox);
|
|
var parts = permissionKey.split('.');
|
|
if (parts.length !== 2) {
|
|
return '';
|
|
}
|
|
|
|
return String(parts[1] || '').trim().toLowerCase();
|
|
}
|
|
|
|
function syncPermissionRow(row) {
|
|
if (!row) {
|
|
return;
|
|
}
|
|
|
|
var checkboxes = getRowCheckboxes(row);
|
|
if (!checkboxes.length) {
|
|
return;
|
|
}
|
|
|
|
var readCheckbox = null;
|
|
var nonReadChecked = false;
|
|
|
|
checkboxes.forEach(function (checkbox) {
|
|
if (getActionKey(checkbox) === 'read') {
|
|
readCheckbox = checkbox;
|
|
return;
|
|
}
|
|
if (checkbox.checked) {
|
|
nonReadChecked = true;
|
|
}
|
|
});
|
|
|
|
if (!readCheckbox) {
|
|
return;
|
|
}
|
|
|
|
if (!readCheckbox.checked && nonReadChecked) {
|
|
readCheckbox.checked = true;
|
|
}
|
|
|
|
if (!readCheckbox.checked) {
|
|
checkboxes.forEach(function (checkbox) {
|
|
if (getActionKey(checkbox) !== 'read') {
|
|
checkbox.checked = false;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function setRowCheckboxes(row, checked) {
|
|
if (!row) {
|
|
return;
|
|
}
|
|
|
|
var checkboxes = getRowCheckboxes(row);
|
|
if (!checkboxes.length) {
|
|
return;
|
|
}
|
|
|
|
checkboxes.forEach(function (checkbox) {
|
|
checkbox.checked = Boolean(checked);
|
|
});
|
|
|
|
syncPermissionRow(row);
|
|
}
|
|
|
|
function toggleRowCheckboxes(row) {
|
|
if (!row) {
|
|
return;
|
|
}
|
|
|
|
var checkboxes = getRowCheckboxes(row);
|
|
if (!checkboxes.length) {
|
|
return;
|
|
}
|
|
|
|
var allChecked = checkboxes.every(function (checkbox) {
|
|
return Boolean(checkbox.checked);
|
|
});
|
|
|
|
setRowCheckboxes(row, !allChecked);
|
|
}
|
|
|
|
function findPermissionRow(targetId) {
|
|
return document.querySelector('[data-permission-row-id="' + targetId + '"]');
|
|
}
|
|
|
|
function handleRowChange(event) {
|
|
var checkbox = event.target && event.target.matches ? event.target : null;
|
|
if (!checkbox || checkbox.tagName !== 'INPUT' || checkbox.type !== 'checkbox') {
|
|
return;
|
|
}
|
|
|
|
var actionKey = getActionKey(checkbox);
|
|
var row = checkbox.closest('[data-permission-row]');
|
|
if (!row) {
|
|
return;
|
|
}
|
|
|
|
var checkboxes = getRowCheckboxes(row);
|
|
var readCheckbox = checkboxes.find(function (candidate) {
|
|
return getActionKey(candidate) === 'read';
|
|
}) || null;
|
|
|
|
if (!readCheckbox) {
|
|
return;
|
|
}
|
|
|
|
if (actionKey === 'read' && !checkbox.checked) {
|
|
checkboxes.forEach(function (candidate) {
|
|
if (candidate !== checkbox) {
|
|
candidate.checked = false;
|
|
}
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (actionKey !== 'read' && checkbox.checked) {
|
|
readCheckbox.checked = true;
|
|
}
|
|
}
|
|
|
|
function initPermissionGroups() {
|
|
getPermissionSections().forEach(function (section) {
|
|
getPermissionRows(section).forEach(function (row) {
|
|
syncPermissionRow(row);
|
|
});
|
|
});
|
|
|
|
document.addEventListener('click', function (event) {
|
|
var control = event.target && event.target.closest ? event.target.closest('[data-permission-row-toggle]') : null;
|
|
if (!control) {
|
|
return;
|
|
}
|
|
|
|
event.preventDefault();
|
|
|
|
var targetId = String(control.getAttribute('data-permission-row-target') || '').trim();
|
|
if (!targetId) {
|
|
return;
|
|
}
|
|
|
|
if (control.hasAttribute('data-permission-row-toggle')) {
|
|
toggleRowCheckboxes(findPermissionRow(targetId));
|
|
}
|
|
});
|
|
|
|
document.addEventListener('change', function (event) {
|
|
var checkbox = event.target;
|
|
if (!checkbox || checkbox.tagName !== 'INPUT' || checkbox.type !== 'checkbox') {
|
|
return;
|
|
}
|
|
if (String(checkbox.getAttribute('name') || '') !== 'permission_keys[]') {
|
|
return;
|
|
}
|
|
|
|
handleRowChange(event);
|
|
syncPermissionRow(checkbox.closest('[data-permission-row]'));
|
|
});
|
|
}
|
|
|
|
initPermissionGroups();
|
|
}()); |