lista de usuarios terminada

This commit is contained in:
2025-09-26 17:57:06 +02:00
parent 01a1ac4b71
commit 88b43847f0
29 changed files with 27681 additions and 138 deletions

View File

@ -4,43 +4,79 @@ import com.imprimelibros.erp.datatables.DataTablesResponse;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.context.MessageSource;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import com.imprimelibros.erp.datatables.DataTablesRequest;
import com.imprimelibros.erp.datatables.DataTablesParser;
import com.imprimelibros.erp.datatables.DataTable;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.List;
import java.util.Locale;
@Controller
@PreAuthorize("hasRole('ADMIN') or hasRole('SUPERADMIN')")
@RequestMapping("/users")
public class UserController {
public class UserController {
private UserDao repo;
private MessageSource messageSource;
public UserController(UserDao repo, UserService userService) {
public UserController(UserDao repo, UserService userService, MessageSource messageSource) {
this.repo = repo;
this.messageSource = messageSource;
}
@PreAuthorize("hasRole('ADMIN') or hasRole('SUPERADMIN')")
@GetMapping("/")
public DataTablesResponse<Map<String,Object>> datatable(HttpServletRequest request) {
DataTablesRequest dt = DataTablesParser.from(request);
@GetMapping
public String list(Model model, Authentication authentication, Locale locale) {
return "imprimelibros/users/users-list";
}
// IMPORTANTE: asegúrate de que el controller es @RestController O anota el
// método con @ResponseBody.
@GetMapping(value = "/datatable", produces = "application/json")
@ResponseBody
public DataTablesResponse<Map<String, Object>> datatable(HttpServletRequest request, Locale locale) {
DataTablesRequest dt = DataTablesParser.from(request); //
// OJO: en la whitelist mete solo columnas "reales" y escalares (no relaciones).
// Si 'role' es relación, sácalo de aquí:
List<String> whitelist = List.of("fullName", "userName", "enabled");
Specification<User> base = (root, query, cb) -> cb.conjunction();
long total = repo.count();
return DataTable
.of(repo, User.class, dt, List.of(
"username", "email", "role" // campos buscables
))
.where(base)
.toJson(total);
.of(repo, User.class, dt, whitelist) // 'searchable' en DataTable.java
.edit("enabled", (User u) -> {
if (u.isEnabled()) {
return "<span class=\"badge bg-success\" >" + messageSource.getMessage("usuarios.tabla.activo", null, locale) + "</span>";
} else {
return "<span class=\"badge bg-danger\" >" + messageSource.getMessage("usuarios.tabla.inactivo", null, locale) + "</span>";
}
})
// si 'role' es relación, crea una columna calculada “segura”:
// acciones virtuales:
.add("roles", (User u) -> u.getRoles().stream().map(Role::getName).collect(Collectors.joining(", ")))
.add("actions", (user) -> {
return "<div class=\"hstack gap-3 flex-wrap\">\n" +
" <a href=\"/users/" + user.getId() + "\" class=\"link-success fs-15\"><i class=\"ri-edit-2-line\"></i></a>\n" +
" <a href=\"javascript:void(0);\" data-id=\"" + user.getId() + "\" class=\"link-danger fs-15\"><i class=\"user-delete ri-delete-bin-line\"></i></a>\n" +
" </div>";
})
.where(base)
.toJson(total);
}
}