Files
admin-edu-space/frontend/views/admin/roles/edit.html
T

195 lines
11 KiB
HTML

{% extends "base.html" %}
{% block title %}{% if role %}Editar Rol: {{ role.name }}{% else %}Nuevo Rol{% endif %} - Edu-Space Admin{% endblock %}
{% block content %}
<div class="container-fluid pt-5 mt-4">
<!-- Header -->
<div class="d-flex justify-content-between align-items-center mb-4 flex-wrap gap-2">
<div>
<h1 class="h3 mb-1">
<i class="bi bi-shield-lock text-primary me-2"></i>
{% if role %}Editar Rol y Permisos de Acceso{% else %}Crear Rol y Permisos de Acceso{% endif %}
</h1>
<p class="text-muted small mb-0">Configure permisos granulares por módulo con la matriz de acceso estilo FortiGate.</p>
</div>
<div>
<a href="/admin/roles_list" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left me-1"></i>Volver a Roles
</a>
</div>
</div>
<form method="POST">
{% if role %}
<input type="hidden" name="id" value="{{ role.id }}">
{% endif %}
<div class="row">
<!-- Left Column: Role Details -->
<div class="col-lg-4 mb-4">
<div class="card border-0 shadow-sm h-100">
<div class="card-header bg-body-tertiary py-3">
<h5 class="card-title h6 mb-0">
<i class="bi bi-person-badge text-primary me-2"></i>Información del Rol
</h5>
</div>
<div class="card-body">
<div class="mb-3">
<label for="name" class="form-label fw-semibold">Nombre del Rol <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="name" name="name"
value="{{ role.name if role else '' }}" required
placeholder="ej. Docente, Operador, Bedelía"
{% if role and role.is_system %}readonly title="El nombre del rol del sistema no se puede modificar"{% endif %}>
{% if role and role.is_system %}
<small class="text-muted d-block mt-1">
<i class="bi bi-info-circle me-1"></i>Rol del sistema protegido.
</small>
{% endif %}
</div>
<div class="mb-3">
<label for="description" class="form-label fw-semibold">Descripción</label>
<textarea class="form-control" id="description" name="description" rows="3"
placeholder="Describa las responsabilidades o alcance de este rol...">{{ role.description if role else '' }}</textarea>
</div>
<hr class="my-4">
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary py-2 fw-semibold">
<i class="bi bi-check-lg me-1"></i>Guardar Rol y Permisos
</button>
<a href="/admin/roles_list" class="btn btn-outline-secondary">
Cancelar
</a>
</div>
</div>
</div>
</div>
<!-- Right Column: FortiGate Permissions Matrix -->
<div class="col-lg-8 mb-4">
<div class="fg-permission-card">
<!-- Matrix Header -->
<div class="card-header d-flex justify-content-between align-items-center">
<span class="fw-bold text-primary">
<i class="bi bi-grid-3x3-gap-fill me-2"></i>Permisos de Acceso
</span>
<!-- Set All Action Dropdown (FortiGate style) -->
<div class="dropdown">
<button class="btn btn-fg-set-all dropdown-toggle" type="button" id="setAllDropdown" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-lightning-charge me-1"></i>Establecer Todos
</button>
<ul class="dropdown-menu dropdown-menu-end shadow-sm" aria-labelledby="setAllDropdown">
<li>
<button type="button" class="dropdown-item py-2" onclick="setAllPermissions('none')">
<i class="bi bi-slash-circle text-danger me-2"></i>Establecer Todos en Ninguno
</button>
</li>
<li>
<button type="button" class="dropdown-item py-2" onclick="setAllPermissions('read')">
<i class="bi bi-eye text-info me-2"></i>Establecer Todos en Solo Lectura
</button>
</li>
<li>
<button type="button" class="dropdown-item py-2" onclick="setAllPermissions('read_write')">
<i class="bi bi-pencil text-success me-2"></i>Establecer Todos en Lectura y Escritura
</button>
</li>
</ul>
</div>
</div>
<!-- Matrix Table -->
<div class="table-responsive">
<table class="fg-table">
<thead>
<tr>
<th style="width: 48%;">Módulo del Sistema</th>
<th style="width: 52%;" class="text-end pe-4">Nivel de Permiso</th>
</tr>
</thead>
<tbody>
{% for mod in modules %}
{% set cur_level = (current_perms[mod.id] if current_perms else (role.permissions[mod.id] if (role and role.permissions) else 'none')) or 'none' %}
<tr data-module-row="{{ mod.id }}">
<td>
<div class="d-flex align-items-center">
<div class="bg-primary bg-opacity-10 text-primary rounded p-2 me-3 d-inline-flex align-items-center justify-content-center" style="width: 36px; height: 36px;">
<i class="bi {{ mod.icon }} fs-6"></i>
</div>
<div>
<div class="fw-semibold">{{ mod.name }}</div>
<small class="text-muted d-block">{{ mod.description }}</small>
</div>
</div>
</td>
<td class="text-end pe-4">
<!-- Hidden Input to submit via POST -->
<input type="hidden" name="perm_{{ mod.id }}" id="input_perm_{{ mod.id }}" value="{{ cur_level }}">
<!-- FortiGate Segmented Control -->
<div class="fg-segmented-control" role="group" aria-label="Nivel de permiso para {{ mod.name }}">
<button type="button"
class="fg-seg-btn {% if cur_level == 'none' %}active{% endif %}"
data-val="none"
data-target="input_perm_{{ mod.id }}"
onclick="selectPerm(this, 'input_perm_{{ mod.id }}', 'none')">
<i class="bi bi-slash-circle"></i> Ninguno
</button>
<button type="button"
class="fg-seg-btn {% if cur_level == 'read' %}active{% endif %}"
data-val="read"
data-target="input_perm_{{ mod.id }}"
onclick="selectPerm(this, 'input_perm_{{ mod.id }}', 'read')">
<i class="bi bi-eye"></i> Lectura
</button>
<button type="button"
class="fg-seg-btn {% if cur_level == 'read_write' %}active{% endif %}"
data-val="read_write"
data-target="input_perm_{{ mod.id }}"
onclick="selectPerm(this, 'input_perm_{{ mod.id }}', 'read_write')">
<i class="bi bi-pencil"></i> Lectura/Escritura
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</form>
</div>
{% endblock %}
{% block extra_js %}
<script>
function selectPerm(btn, inputId, value) {
const input = document.getElementById(inputId);
if (input) {
input.value = value;
}
// Toggle active state in this segmented control
const parentControl = btn.closest('.fg-segmented-control');
if (parentControl) {
parentControl.querySelectorAll('.fg-seg-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
}
}
function setAllPermissions(level) {
document.querySelectorAll('.fg-segmented-control').forEach(control => {
const targetBtn = control.querySelector(`button[data-val="${level}"]`);
if (targetBtn) {
targetBtn.click();
}
});
}
</script>
{% endblock %}