salix/front/core/directives/acl.js

102 lines
3.4 KiB
JavaScript

import ngModule from '../module';
function vnAcl(aclService, $timeout) {
let acls = [];
function getMaterialType(className) {
let type = '';
if (className) {
type = className.replace('mdl-', '').replace('__input', '');
type = type.charAt(0).toUpperCase() + type.slice(1);
}
return type;
}
function updateMaterial(input) {
if (input && input.className) {
let find = input.className.match(/mdl-[\w]+input/g);
if (find && find.length && find[0]) {
let type = getMaterialType(find[0]);
if (type && input.parentNode[`Material${type}`] && input.parentNode[`Material${type}`].updateClasses_)
input.parentNode[`Material${type}`].updateClasses_();
}
}
}
function getDynamicConditions($attrs) {
let atributes = $attrs.$attr;
let conditions = {};
Object.keys(atributes).forEach(atribute => {
if (atribute.startsWith('aclConditionalTo')) {
let role = atributes[atribute].split('-').slice(-1)[0];
conditions[atribute] = {
role: role
};
}
});
return conditions;
}
function permissionElement($element, action) {
if (!aclService.hasAny(acls)) {
if (action === 'disabled') {
let input = $element[0];
let selector = 'input, textarea, button, submit';
if (!input.matches(selector))
input = input.querySelector(selector);
if (input) {
$timeout(() => {
input.setAttribute('disabled', 'true');
updateMaterial(input);
});
$element[0].querySelectorAll('vn-drop-down').forEach(element => {
element.parentNode.removeChild(element);
});
}
} else
$element.remove();
}
}
function updateAcls(role, toAdd) {
let position = acls.indexOf(role);
if (!toAdd && position > -1)
acls.splice(position, 1);
// todo: add acl and enabled element if previusly was disabled
}
return {
restrict: 'A',
priority: -1,
link: function($scope, $element, $attrs) {
acls = $attrs.vnAcl.split(',').map(i => i.trim());
let action = $attrs.vnAclAction || 'disabled';
let conditions = getDynamicConditions($attrs);
permissionElement($element, action);
if (Object.keys(conditions).length) {
let watchConditions = $scope.$watch(() => {
Object.keys(conditions).forEach(attrName => {
let hasPermission = $scope.$eval($attrs[attrName]);
if (!hasPermission) {
updateAcls(conditions[attrName].role, hasPermission);
permissionElement($element, action);
delete conditions[attrName];
}
});
if (Object.keys(conditions).length === 0) {
// unWacth
watchConditions();
}
});
}
}
};
}
vnAcl.$inject = ['aclService', '$timeout'];
ngModule.directive('vnAcl', vnAcl);