Added ability to have different user roles

This commit is contained in:
Pinga 2025-02-04 14:31:17 +02:00
parent 9504733dbf
commit d07fa5481c
4 changed files with 157 additions and 22 deletions

View file

@ -93,7 +93,7 @@
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Role</label>
<label class="form-label">Type</label>
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" id="role-toggle" name="role" value="admin">
<label class="form-check-label" for="role-toggle" id="role-label">Registrar</label>

View file

@ -94,24 +94,66 @@
<!-- Role -->
<div class="row">
<div class="col-md-12">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">{{ __('Role') }}</label>
<label class="form-label">{{ __('Type') }}</label>
<div class="form-control-plaintext">
{% if user.roles_mask == 0 %}
{{ __('Admin') }}
{% elseif user.roles_mask == 4 %}
{{ __('Registrar') }}
{% if user_asso is defined and user_asso is not null %}
- {{ __('Associated with Registrar') }} {{ registrar_name }}
{% endif %}
{{ __('Admin') }}
{% else %}
{{ __('Unknown Role') }}
{# Display Assigned Roles #}
{% set assigned_roles = [] %}
{% if roles_new['4'] %}
{% set assigned_roles = assigned_roles | merge([__('Registrar')]) %}
{% endif %}
{% if roles_new['8'] %}
{% set assigned_roles = assigned_roles | merge([__('Accountant')]) %}
{% endif %}
{% if roles_new['16'] %}
{% set assigned_roles = assigned_roles | merge([__('Support')]) %}
{% endif %}
{% if roles_new['32'] %}
{% set assigned_roles = assigned_roles | merge([__('Auditor')]) %}
{% endif %}
{% if roles_new['64'] %}
{% set assigned_roles = assigned_roles | merge([__('Sales')]) %}
{% endif %}
{{ assigned_roles | join(', ') }}
{# Show association if the user is a Registrar and associated with another registrar #}
{% if roles_new['4'] and user_asso is defined and user_asso is not null %}
- {{ __('Associated with Registrar') }} {{ registrar_name }}
{% endif %}
{% endif %}
</div>
</div>
</div>
{% if user.roles_mask != 0 %}
{% if user.roles_mask == 4 %}
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">{{ __('Roles') }}</label>
<span class="badge bg-blue-lt">{{ __('Registrar Administrator') }}</span>
</div>
</div>
{% else %}
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">{{ __('Manage Roles') }}</label>
<select class="form-select" id="select-roles" name="roles_mask[]" multiple>
<option value="8" {{ roles_new['8'] ? 'selected' : '' }}>{{ __('Accountant') }}</option>
<option value="16" {{ roles_new['16'] ? 'selected' : '' }}>{{ __('Support') }}</option>
<option value="32" {{ roles_new['32'] ? 'selected' : '' }}>{{ __('Auditor') }}</option>
<option value="64" {{ roles_new['64'] ? 'selected' : '' }}>{{ __('Sales') }}</option>
</select>
</div>
</div>
{% endif %}
{% endif %}
</div>
</div>
<div class="card-footer text-end">
@ -126,4 +168,51 @@
</div>
{% include 'partials/footer.twig' %}
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
var el;
window.TomSelect && (new TomSelect(el = document.getElementById('select-roles'), {
copyClassesToDropdown: false,
dropdownParent: 'body',
controlInput: '<input>',
render:{
item: function(data,escape) {
if( data.customProperties ){
return '<div><span class="dropdown-item-indicator">' + data.customProperties + '</span>' + escape(data.text) + '</div>';
}
return '<div>' + escape(data.text) + '</div>';
},
option: function(data,escape){
if( data.customProperties ){
return '<div><span class="dropdown-item-indicator">' + data.customProperties + '</span>' + escape(data.text) + '</div>';
}
return '<div>' + escape(data.text) + '</div>';
},
},
}));
});
document.querySelector('form').addEventListener('submit', function (e) {
const select = document.getElementById('select-roles');
let rolesMask = 0;
// Loop through selected options and combine their values using bitwise OR
for (const option of select.selectedOptions) {
rolesMask |= parseInt(option.value);
}
// Create a hidden input to send the combined roles_mask to the server
const hiddenInput = document.createElement('input');
hiddenInput.type = 'hidden';
hiddenInput.name = 'roles_mask';
hiddenInput.value = rolesMask;
// Append the hidden input to the form
this.appendChild(hiddenInput);
// Optional: Disable the select to avoid sending duplicate data
select.disabled = true;
});
</script>
<script src="/assets/libs/tom-select/dist/js/tom-select.base.min.js" defer></script>
{% endblock %}

View file

@ -7,7 +7,7 @@
var table;
document.addEventListener("DOMContentLoaded", function(){
function userLinkFormatter(cell){
function emailLinkFormatter(cell){
var value = cell.getValue();
return `<span style="font-weight:bold;">${value}</a>`;
}
@ -28,14 +28,33 @@
function roleLabelFormatter(cell) {
var value = cell.getValue();
// Define role mappings with labels and styles
var roles = [
{ bit: 0, label: 'Administrator', class: 'status status-purple' },
{ bit: 4, label: 'Registrar', class: 'status status-indigo' },
{ bit: 8, label: 'Accountant', class: 'status status-green' },
{ bit: 16, label: 'Support', class: 'status status-azure' },
{ bit: 32, label: 'Auditor', class: 'status status-orange' },
{ bit: 64, label: 'Sales', class: 'status status-teal' }
];
// Special case for Administrator (no roles assigned)
if (value === 0) {
return '<span class="status status-purple">Administrator</span>';
} else if (value === 4) {
return '<span class="status status-indigo">Registrar</span>';
} else if (value === 6) {
return '<span class="status status-azure">Registrar Assistant</span>';
}
return value; // If the value is neither 0 nor 4, return it as is
// Check assigned roles using bitmask
var assignedRoles = roles
.filter(function (role) {
return role.bit !== 0 && (value & role.bit);
})
.map(function (role) {
return '<span class="' + role.class + '">' + role.label + '</span>';
});
// Join assigned roles with separators
return assignedRoles.length > 0 ? assignedRoles.join(', ') : '<span class="status status-secondary">Unknown Role</span>';
}
function verifiedFormatter(cell) {
@ -144,10 +163,10 @@
placeholder: "{{ __('No Data') }}",
columns:[
{formatter:"responsiveCollapse", width:30, minWidth:30, hozAlign:"center", resizable:false, headerSort:false, responsive:0},
{title:"{{ __('Name') }}", field:"username", width:200, resizable:false, headerSort:true, formatter: userLinkFormatter, responsive:0},
{title:"{{ __('Email') }}", field:"email", width:300, resizable:false, headerSort:true, responsive:2},
{title:"{{ __('Roles') }}", field:"roles_mask", width:200, resizable:false, headerSort:true, formatter: roleLabelFormatter, responsive:2},
{title:"{{ __('Verified') }}", field:"verified", width:200, resizable:false, headerSort:true, formatter: verifiedFormatter, responsive:2},
{title:"{{ __('Email') }}", field:"email", width:300, resizable:false, headerSort:true, formatter: emailLinkFormatter, responsive:0},
{title:"{{ __('User Name') }}", field:"username", width:200, resizable:false, headerSort:true, responsive:2},
{title:"{{ __('Roles') }}", field:"roles_mask", width:300, resizable:false, headerSort:true, formatter: roleLabelFormatter, responsive:2},
{title:"{{ __('Verified') }}", field:"verified", width:150, resizable:false, headerSort:true, formatter: verifiedFormatter, responsive:2},
{title:"{{ __('Status') }}", field:"status", width:200, resizable:false, headerSort:true, formatter: statusBadgeFormatter, responsive:2},
{title: "{{ __('Actions') }}", formatter: actionsFormatter, responsive:0, headerSort: false, download:false, hozAlign: "center", cellClick:function(e, cell){ e.stopPropagation(); }},
]