mirror of
https://git.imnavajas.es/jjimenez/erp-imprimelibros.git
synced 2026-01-22 00:30:23 +00:00
implementados filtros y delete. falta los textos del delete
This commit is contained in:
@ -5,6 +5,7 @@ usuarios.add=Añadir usuario
|
||||
usuarios.eliminar=Eliminar usuario
|
||||
usuarios.confirmarEliminar=¿Está seguro de que desea eliminar este usuario?
|
||||
usuarios.guardar=Guardar
|
||||
usuarios.todos=Todos
|
||||
|
||||
usuarios.tabla.id=ID
|
||||
usuarios.tabla.nombre=Nombre
|
||||
@ -38,6 +39,10 @@ usuarios.error.password.requerida=La contraseña es obligatoria.
|
||||
usuarios.error.password.min=La contraseña debe tener al menos 6 caracteres.
|
||||
usuarios.error.confirmPassword.requerida=La confirmación de la contraseña es obligatoria.
|
||||
usuarios.error.password-coinciden=Las contraseñas no coinciden.
|
||||
usuarios.error.delete-relational-data=No se puede eliminar el usuario porque tiene datos relacionados.
|
||||
usuarios.error.delete-internal-error=No se puede eliminar: error interno.
|
||||
usuarios.error.delete-not-found=No se puede eliminar: usuario no encontrado.
|
||||
usuarios.error.delete-self=No se puede eliminar a sí mismo.
|
||||
|
||||
usuarios.exito.creado=Usuario creado con éxito.
|
||||
usuarios.exito.actualizado=Usuario actualizado con éxito.
|
||||
|
||||
@ -1,16 +1,37 @@
|
||||
$(() => {
|
||||
const language = document.documentElement.lang || 'es-ES';
|
||||
// CSRF global para AJAX
|
||||
const csrfToken = document.querySelector('meta[name="_csrf"]')?.getAttribute('content');
|
||||
const csrfHeader = document.querySelector('meta[name="_csrf_header"]')?.getAttribute('content');
|
||||
if (csrfToken && csrfHeader) {
|
||||
$.ajaxSetup({
|
||||
beforeSend: function (xhr) {
|
||||
xhr.setRequestHeader(csrfHeader, csrfToken);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const table = new DataTable('#users-datatable', {
|
||||
processing: true, serverSide: true, pageLength: 50,
|
||||
processing: true,
|
||||
serverSide: true,
|
||||
orderCellsTop: true,
|
||||
pageLength: 50,
|
||||
language: { url: '/assets/libs/datatables/i18n/' + language + '.json' },
|
||||
responsive: true,
|
||||
ajax: { url: '/users/datatable', method: 'GET' },
|
||||
order: [[0,'asc']],
|
||||
ajax: {
|
||||
url: '/users/datatable',
|
||||
method: 'GET',
|
||||
data: function (d) {
|
||||
d.f_role = $('#search-role').val() || ''; // 'USER' | 'ADMIN' | 'SUPERADMIN' | ''
|
||||
d.f_enabled = $('#search-status').val() || ''; // 'true' | 'false' | ''
|
||||
}
|
||||
},
|
||||
order: [[0, 'asc']],
|
||||
columns: [
|
||||
{ data: 'id', name: 'id' , orderable: true },
|
||||
{ data: 'fullName', name: 'fullName' , orderable: true },
|
||||
{ data: 'userName', name: 'userName' , orderable: true },
|
||||
{ data: 'id', name: 'id', orderable: true },
|
||||
{ data: 'fullName', name: 'fullName', orderable: true },
|
||||
{ data: 'userName', name: 'userName', orderable: true },
|
||||
{ data: 'roles', name: 'roleRank' },
|
||||
{ data: 'enabled', name: 'enabled', searchable: false },
|
||||
{ data: 'actions', name: 'actions' }
|
||||
@ -18,8 +39,21 @@ $(() => {
|
||||
columnDefs: [{ targets: -1, orderable: false, searchable: false }]
|
||||
});
|
||||
|
||||
table.on("keyup", ".user-filter", function () {
|
||||
const colName = $(this).data("col");
|
||||
const colIndex = table.settings()[0].aoColumns.findIndex(c => c.name === colName);
|
||||
|
||||
if (colIndex >= 0) {
|
||||
table.column(colIndex).search(this.value).draw();
|
||||
}
|
||||
});
|
||||
|
||||
table.on("change", ".user-filter-select", function () {
|
||||
table.draw();
|
||||
});
|
||||
|
||||
const modalEl = document.getElementById('userFormModal');
|
||||
const modal = bootstrap.Modal.getOrCreateInstance(modalEl);
|
||||
const modal = bootstrap.Modal.getOrCreateInstance(modalEl);
|
||||
|
||||
// Abrir "Crear"
|
||||
$('#addUserButton').on('click', (e) => {
|
||||
@ -36,7 +70,7 @@ $(() => {
|
||||
$(document).on('click', '.btn-edit-user', function (e) {
|
||||
e.preventDefault();
|
||||
const id = $(this).data('id');
|
||||
$.get('/users/form', { id }, function (html) {
|
||||
$.get('/users/form', { id }, function (html) {
|
||||
$('#userModalBody').html(html);
|
||||
const title = $('#userModalBody #userForm').data('edit');
|
||||
$('#userFormModal .modal-title').text(title);
|
||||
@ -44,6 +78,40 @@ $(() => {
|
||||
});
|
||||
});
|
||||
|
||||
// Botón "Eliminar"
|
||||
$(document).on('click', '.btn-delete-user', function (e) {
|
||||
e.preventDefault();
|
||||
const id = $(this).data('id');
|
||||
|
||||
Swal.fire({
|
||||
title: '¿Eliminar usuario?',
|
||||
text: 'Esta acción no se puede deshacer.',
|
||||
icon: 'warning',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: 'Sí, eliminar',
|
||||
cancelButtonText: 'Cancelar',
|
||||
reverseButtons: true
|
||||
}).then((result) => {
|
||||
if (!result.isConfirmed) return;
|
||||
|
||||
$.ajax({
|
||||
url: '/users/' + id,
|
||||
type: 'DELETE',
|
||||
success: function () {
|
||||
Swal.fire({ icon: 'success', title: 'Eliminado', timer: 1200, showConfirmButton: false });
|
||||
$('#users-datatable').DataTable().ajax.reload(null, false);
|
||||
},
|
||||
error: function (xhr) {
|
||||
// usa el mensaje del backend; fallback genérico por si no llega JSON
|
||||
const msg = (xhr.responseJSON && xhr.responseJSON.message)
|
||||
|| 'Error al eliminar el usuario.';
|
||||
Swal.fire({ icon: 'error', title: 'No se pudo eliminar', text: msg });
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// Submit del form en el modal
|
||||
$(document).on('submit', '#userForm', function (e) {
|
||||
e.preventDefault();
|
||||
@ -59,7 +127,7 @@ $(() => {
|
||||
if (typeof html === 'string' && html.indexOf('id="userForm"') !== -1 && html.indexOf('<html') === -1) {
|
||||
$('#userModalBody').html(html);
|
||||
const isEdit = $('#userModalBody #userForm input[name="_method"][value="PUT"]').length > 0;
|
||||
const title = $('#userModalBody #userForm').data(isEdit ? 'edit' : 'add');
|
||||
const title = $('#userModalBody #userForm').data(isEdit ? 'edit' : 'add');
|
||||
$('#userFormModal .modal-title').text(title);
|
||||
return;
|
||||
}
|
||||
@ -72,7 +140,7 @@ $(() => {
|
||||
if (xhr.status === 422 && xhr.responseText) {
|
||||
$('#userModalBody').html(xhr.responseText);
|
||||
const isEdit = $('#userModalBody #userForm input[name="_method"][value="PUT"]').length > 0;
|
||||
const title = $('#userModalBody #userForm').data(isEdit ? 'edit' : 'add');
|
||||
const title = $('#userModalBody #userForm').data(isEdit ? 'edit' : 'add');
|
||||
$('#userFormModal .modal-title').text(title);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2,9 +2,13 @@
|
||||
th:with="isAuth=${#authorization.expression('isAuthenticated()')}"
|
||||
th:attrappend="data-layout=${isAuth} ? 'semibox' : 'horizontal'" data-sidebar-visibility="show" data-topbar="light"
|
||||
data-sidebar="light" data-sidebar-size="lg" data-sidebar-image="none" data-preloader="disable"
|
||||
xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
xmlns:th="http://www.thymeleaf.org" xmlns:sec="http://www.thymeleaf.org/extras/spring-security"
|
||||
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
|
||||
|
||||
<head>
|
||||
<meta name="_csrf" th:content="${_csrf.token}" />
|
||||
<meta name="_csrf_header" th:content="${_csrf.headerName}" />
|
||||
|
||||
<th:block layout:fragment="pagetitle" />
|
||||
<th:block th:replace="~{imprimelibros/partials/head-css :: head-css}" />
|
||||
<link href="/assets/libs/sweetalert2/sweetalert2.min.css" rel="stylesheet" type="text/css" />
|
||||
|
||||
@ -49,6 +49,31 @@
|
||||
<th scope="col" th:text="#{usuarios.tabla.estado}">Estado</th>
|
||||
<th scope="col" th:text="#{usuarios.tabla.acciones}">Acciones</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><input type="text" class="form-control form-control-sm user-filter" data-col="id" />
|
||||
</th>
|
||||
<th><input type="text" class="form-control form-control-sm user-filter"
|
||||
data-col="fullName" /></th>
|
||||
<th><input type="text" class="form-control form-control-sm user-filter"
|
||||
data-col="userName" /></th>
|
||||
<th>
|
||||
<select class="form-select form-select-sm user-filter-select" id="search-role">
|
||||
<option value="" th:text="#{usuarios.todos}">Todos</option>
|
||||
<option value="USER" th:text="#{usuarios.rol.user}">Usuario</option>
|
||||
<option value="ADMIN" th:text="#{usuarios.rol.admin}">Administrador</option>
|
||||
<option value="SUPERADMIN" th:text="#{usuarios.rol.superadmin}">Super Administrador
|
||||
</option>
|
||||
</select>
|
||||
</th>
|
||||
<th>
|
||||
<select class="form-select form-select-sm user-filter-select" id="search-status">
|
||||
<option value="" th:text="#{usuarios.todos}">Todos</option>
|
||||
<option value="true" th:text="#{usuarios.tabla.activo}">Activo</option>
|
||||
<option value="false" th:text="#{usuarios.tabla.inactivo}">Inactivo</option>
|
||||
</select>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
|
||||
Reference in New Issue
Block a user