Browse Source

Se agrego la vista de el listado de actividades que lo obtiene directamente desde ProyMan y tambien se agrego de que la fecha se establezca automaticamente cuando le dan clic al boton de realizar

master
parent
commit
d97728efea
12 changed files with 803 additions and 61 deletions
  1. +288
    -0
      src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java
  2. +1
    -0
      src/main/java/mx/gob/jumapacelaya/api/SecurityService.java
  3. +13
    -0
      src/main/java/mx/gob/jumapacelaya/api/ServerProperties.java
  4. +84
    -0
      src/main/java/mx/gob/jumapacelaya/models/CustomUserDetails.java
  5. +72
    -0
      src/main/java/mx/gob/jumapacelaya/models/RedmineUser.java
  6. +98
    -0
      src/main/java/mx/gob/jumapacelaya/models/Ticket.java
  7. +46
    -0
      src/main/java/mx/gob/jumapacelaya/services/LdapService.java
  8. +81
    -0
      src/main/java/mx/gob/jumapacelaya/services/UserService.java
  9. +86
    -45
      src/main/java/mx/gob/jumapacelaya/ui/ActDiariaView.java
  10. +24
    -11
      src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java
  11. +7
    -4
      src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java
  12. +3
    -1
      src/main/resources/application.properties

+ 288
- 0
src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java View File

@ -0,0 +1,288 @@
package mx.gob.jumapacelaya.api;
import com.nimbusds.jose.shaded.gson.*;
import mx.gob.jumapacelaya.models.RedmineUser;
import mx.gob.jumapacelaya.models.Ticket;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class RedmineClient {
private static final int PAGE_SIZE = 25;
static String REDMINE_URL;
static String API_KEY;
public static final Gson GSON = new Gson();
public RedmineClient(@Value("${redmine.url}") String redmineUrl, @Value("${redmine.api_key}") String apiKey) {
REDMINE_URL = redmineUrl;
API_KEY = apiKey;
}
//AQUI OBTENGO LOS TICKETS DESDE REDMINE
public List<Ticket> getTickets(RedmineUser user, boolean includeClosed) {
List<Ticket> tickets = new ArrayList<>();
HttpClient client = HttpClient.newHttpClient();
int offset = 0;
// Si includeClose es true, incluira todos los tikets si no, incluira solo los que estan abiertos
String statusFilter = includeClosed ? "&status_id=*" : "&status_id=open";
while (true) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + statusFilter + "&offset=" + offset))
.header("Content-Type", "application/json")
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
String responseBody = response.body();
List<Ticket> pageTickets = parseTickets(responseBody);
tickets.addAll(pageTickets);
if (pageTickets.size() < PAGE_SIZE) {
break;
}
offset += PAGE_SIZE;
} else {
System.err.println("Error en la respuesta: " + response.statusCode());
break;
}
} catch (Exception e) {
e.printStackTrace();
break;
}
}
System.out.println("Total tickets obtenidos: " + tickets.size());
return tickets;
}
//AQUI OBTENGO LOS TICKETS DESDE REDMINE
public List<Ticket> getTicketsAuthor(RedmineUser user) {
List<Ticket> tickets = new ArrayList<>();
HttpClient client = HttpClient.newHttpClient();
int offset = 0;
while (true) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + user.getKey() + "&author_id=" + user.getId() + "&offset=" + offset))
.header("Content-Type", "application/json")
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
String responseBody = response.body();
List<Ticket> pageTickets = parseTickets(responseBody);
tickets.addAll(pageTickets);
if (pageTickets.size() < PAGE_SIZE) {
break;
}
offset += PAGE_SIZE;
} else {
System.err.println("Error en la respuesta: " + response.statusCode());
break;
}
} catch (Exception e) {
e.printStackTrace();
break;
}
}
System.out.println("Total tickets obtenidos: " + tickets.size());
return tickets;
}
// Aquí se parsean todos los tickets que existen y se les da un formato con los campos a mostrarse
private List<Ticket> parseTickets(String json) {
List<Ticket> tickets = new ArrayList<>();
try {
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
JsonArray issues = jsonObject.getAsJsonArray("issues");
if (issues != null) {
for (JsonElement issueElement : issues) {
JsonObject issue = issueElement.getAsJsonObject();
// Verifica y obtiene el ID
int id = issue.has("id") && !issue.get("id").isJsonNull() ? issue.get("id").getAsInt() : 0;
// Verifica y obtiene el subject
String subject = issue.has("subject") && !issue.get("subject").isJsonNull() ? issue.get("subject").getAsString() : "";
// Verifica y obtiene la descripción
String description = issue.has("description") && !issue.get("description").isJsonNull() ? issue.get("description").getAsString() : "";
// Verifica y obtiene el status
String status = "Unknown";
if (issue.has("status") && !issue.get("status").isJsonNull()) {
JsonObject statusObject = issue.getAsJsonObject("status");
if (statusObject.has("name") && !statusObject.get("name").isJsonNull()) {
status = statusObject.get("name").getAsString();
}
}
// Verifica y obtiene la fecha de creación
String dateString = issue.has("created_on") && !issue.get("created_on").isJsonNull() ? issue.get("created_on").getAsString() : "";
LocalDate date = null;
if (!dateString.isEmpty()) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ISO_DATE_TIME;
date = LocalDate.parse(dateString, formatter);
} catch (DateTimeParseException e) {
System.err.println("Error al parsear la fecha: " + dateString);
e.printStackTrace();
}
}
//Verifica y obtiene el ID del tipo de ticket
Integer trackerId = null;
if (issue.has("tracker") && !issue.get("tracker").isJsonNull()) {
JsonObject trackerObject = issue.getAsJsonObject("tracker");
if (trackerObject.has("id") && !trackerObject.get("id").isJsonNull()) {
trackerId = trackerObject.get("id").getAsInt();
}
}
// Agrega el ticket a la lista
tickets.add(new Ticket(id, subject, description, status, date != null ? date.toString() : "", trackerId));
}
} else {
System.out.println("La respuesta JSON no contiene la clave 'issues'");
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Ocurrió un error al parsear los tickets: " + e.getMessage());
}
return tickets;
}
public RedmineUser getMyAccount(String username) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/my/account.json"))
.header("Content-Type", "application/json")
.header("X-Redmine-Switch-User", username)
.header("X-Redmine-API-Key", API_KEY)
.GET()
.build();
try {
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject();
JsonObject userJson = jsonObject.get("user").getAsJsonObject();
RedmineUser user = new RedmineUser();
user.setId(userJson.get("id").getAsInt());
user.setLogin(userJson.get("login").getAsString());
user.setFirstname(userJson.get("firstname").getAsString());
user.setLastname(userJson.get("lastname").getAsString());
user.setMail(userJson.get("mail").getAsString());
user.setKey(userJson.get("api_key").getAsString());
return user;
//return response.body();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
return null;
}
}
public static RedmineUser createRedmineUser(String username, String firstname, String lastname, String mail) {
HttpClient client = HttpClient.newHttpClient();
Map<String, Object> user = new HashMap<>();
user.put("login", username);
user.put("firstname", firstname);
user.put("lastname", lastname);
user.put("mail", mail);
user.put("auth_source_id", "1");
Map<String, Object> payload = new HashMap<>();
payload.put("user", user);
String jsonPayload = new Gson().toJson(payload);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/users.json"))
.header("Content-Type", "application/json")
.header("X-Redmine-API-Key", API_KEY)
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonObject jsonObject = JsonParser.parseString(response.body()).getAsJsonObject();
JsonObject userJson = jsonObject.get("user").getAsJsonObject();
RedmineUser newUser = new RedmineUser();
newUser.setId(userJson.get("id").getAsInt());
newUser.setLogin(userJson.get("login").getAsString());
newUser.setFirstname(userJson.get("firstname").getAsString());
newUser.setLastname(userJson.get("lastname").getAsString());
newUser.setMail(userJson.get("mail").getAsString());
return newUser;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//AQUI OBTENGO A LOS USUARIOS
//Se devuelven en formato Json
public RedmineUser getUserByUsername(String username) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/users.json?name=" + username ))
.header("Content-Type", "application/json")
.header("X-Redmine-API-Key", API_KEY)
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 200) {
String responseBody = response.body();
System.out.println("Datos del usuario " + responseBody);
return parseUser(responseBody);
} else {
System.err.println("Error en la respuesta: " + response.statusCode());
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//Aqui se parsean a los usuarios y se les da un formato con los campos a mostrarse
private RedmineUser parseUser(String json) {
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
JsonObject userJson = jsonObject.getAsJsonArray("users").get(0).getAsJsonObject();
RedmineUser user = new RedmineUser();
user.setId(userJson.get("id").getAsInt());
user.setLogin(userJson.get("login").getAsString());
user.setFirstname(userJson.get("firstname").getAsString());
user.setLastname(userJson.get("lastname").getAsString());
user.setMail(userJson.get("mail").getAsString());
//user.setKey(userJson.get("key").getAsString());
return user;
}
}

+ 1
- 0
src/main/java/mx/gob/jumapacelaya/api/SecurityService.java View File

@ -0,0 +1 @@
package mx.gob.jumapacelaya.api;

+ 13
- 0
src/main/java/mx/gob/jumapacelaya/api/ServerProperties.java View File

@ -0,0 +1,13 @@
package mx.gob.jumapacelaya.api;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ServerProperties {
@Value("${redmine.url}")
public String REDMINE_URL;
@Value("${redmine.api_key}")
public String API_KEY;
}

+ 84
- 0
src/main/java/mx/gob/jumapacelaya/models/CustomUserDetails.java View File

@ -0,0 +1,84 @@
package mx.gob.jumapacelaya.models;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class CustomUserDetails implements UserDetails {
private String username;
private String firstName;
private String lastName;
private String email;
private Collection<? extends GrantedAuthority> authorities;
private String password;
public CustomUserDetails(String username, String firstName, String lastName, String email, Collection<? extends GrantedAuthority> authorities, String password) {
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.authorities = authorities;
this.password = password;
}
// Getters and setters
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return authorities;
}
@Override
public String getPassword() {
return password;
}
@Override
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return true;
}
}

+ 72
- 0
src/main/java/mx/gob/jumapacelaya/models/RedmineUser.java View File

@ -0,0 +1,72 @@
package mx.gob.jumapacelaya.models;
public class RedmineUser {
private int id;
private String login;
private String firstname;
private String lastname;
private String mail;
private String key;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@Override
public String toString() {
return "RedmineUser{" +
"id=" + id +
", login='" + login + '\'' +
", firstname='" + firstname + '\'' +
", lastname='" + lastname + '\'' +
", mail='" + mail + '\'' +
", key='" + key + '\'' +
'}';
}
}

+ 98
- 0
src/main/java/mx/gob/jumapacelaya/models/Ticket.java View File

@ -0,0 +1,98 @@
package mx.gob.jumapacelaya.models;
import java.sql.Date;
import java.time.LocalDate;
public class Ticket {
private int id;
private String subject;
private String description;
private String status;
private LocalDate dateCreate;
private User author;
private Integer trackerId;
public Ticket(int id, String subject, String description, String status, String dateCreate, Integer trackerId) {
this.id = id;
this.subject = subject;
this.description = description;
this.status = status;
this.dateCreate = LocalDate.parse(dateCreate);
this.author = author;
this.trackerId = trackerId;
}
public int getId() {
return id;
}
public String getSubject() {
return subject;
}
public String getDescription() {
return description;
}
public String getStatus() {
return status;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
public Date getDateCreate() {
return java.sql.Date.valueOf(this.dateCreate);
}
public Integer getTrackerId() {
return trackerId;
}
public void setTrackerId(Integer tipoId) {
this.trackerId = trackerId;
}
public static class User {
private String username;
public User(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
public String tiempoEst(Integer trackerId) {
if (trackerId == null) {
return "Desconocido";
}
switch (trackerId) {
case 5,16,17:
return "2 horas max.";
case 4,13,14:
return "2 a 6 horas";
case 6,7,9,10,11,15:
return "1 a 2 Dias";
default:
return "N/A";
}
}
}

+ 46
- 0
src/main/java/mx/gob/jumapacelaya/services/LdapService.java View File

@ -0,0 +1,46 @@
package mx.gob.jumapacelaya.services;
import mx.gob.jumapacelaya.models.CustomUserDetails;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.stereotype.Service;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import java.util.List;
@Service
public class LdapService {
private final LdapTemplate ldapTemplate;
public LdapService(LdapTemplate ldapTemplate) {
this.ldapTemplate = ldapTemplate;
}
public CustomUserDetails getUserDetails(String username) {
EqualsFilter filter = new EqualsFilter("sAMAccountName", username);
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
searchControls.setReturningAttributes(new String[]{"givenName", "sn", "mail"});
searchControls.setReturningObjFlag(true);
List<CustomUserDetails> result = ldapTemplate.search("", filter.encode(), searchControls, (Attributes attrs) -> {
String firstName = getAttribute(attrs, "givenName");
String lastName = getAttribute(attrs, "sn");
String email = getAttribute(attrs, "mail");
return new CustomUserDetails(username, firstName, lastName, email, null, null); // Ajustar los últimos dos parámetros si es necesario
});
return result.isEmpty() ? null : result.get(0);
}
private String getAttribute(Attributes attributes, String attributeName) {
try {
return attributes.get(attributeName) != null ? attributes.get(attributeName).get().toString(): null;
} catch (NamingException e) {
return null;
}
}
}

+ 81
- 0
src/main/java/mx/gob/jumapacelaya/services/UserService.java View File

@ -1,8 +1,89 @@
package mx.gob.jumapacelaya.services;
import com.vaadin.flow.server.VaadinService;
import mx.gob.jumapacelaya.api.RedmineClient;
import mx.gob.jumapacelaya.services.SecurityService;
import mx.gob.jumapacelaya.models.CustomUserDetails;
import mx.gob.jumapacelaya.models.RedmineUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final SecurityService securityService;
private final RedmineClient redmineClient;
private static final Logger logger = LoggerFactory.getLogger(UserService.class);
private final LdapService ldpaService;
public UserService(SecurityService securityService, RedmineClient redmineClient, LdapService ldpaService) {
this.securityService = securityService;
this.redmineClient = redmineClient;
this.ldpaService = ldpaService;
}
public RedmineUser getAuthenticatedRedmineUser() {
try {
String username = securityService.getAuthenticatedUser();
logger.info("Usuario autenticado: " + username);
if (username != null) {
RedmineUser user = redmineClient.getUserByUsername(username);
if (user == null) {
CustomUserDetails userDetails = ldpaService.getUserDetails(username);
if (userDetails != null) {
if (userDetails.getEmail() == null || userDetails.getEmail().isEmpty()) {
logger.error("El usuario: " + username + " no tiene correo electronico.");
return null;
}
RedmineUser newUser = RedmineClient.createRedmineUser(
username,
userDetails.getFirstName(),
userDetails.getLastName(),
userDetails.getEmail()
);
if (newUser != null) {
logger.info("Usuario creado en Redmine: " + newUser);
return newUser;
} else {
logger.error("Error al crear el usuario en Redmine");
}
} else {
logger.error("No se encontraron detalles del usuario en LDAP");
}
} else {
logger.info("Usuario autenticado en Redmine: " + user);
}
return user;
}
} catch (Exception e) {
logger.error("Error al obtener al usuario autenticado en Redmine", e);
}
return null;
}
public RedmineUser getRedmineUser() {
RedmineUser userclient = (RedmineUser) VaadinService.getCurrentRequest().getWrappedSession().getAttribute("myaccount");
if (userclient == null) {
RedmineUser user = getAuthenticatedRedmineUser();
if (user != null) {
RedmineUser myAccount = redmineClient.getMyAccount(user.getLogin());
if (myAccount != null && !myAccount.getKey().isEmpty()) {
userclient = myAccount;
VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount);
} else {
// Crear un nuevo usuario si no existe
myAccount = RedmineClient.createRedmineUser(user.getLogin(), user.getFirstname(), user.getLastname(), user.getMail());
if (myAccount != null && !myAccount.getKey().isEmpty()) {
userclient = myAccount;
VaadinService.getCurrentRequest().getWrappedSession().setAttribute("myaccount", myAccount);
}
}
}
}
return userclient;
}
}

+ 86
- 45
src/main/java/mx/gob/jumapacelaya/ui/ActDiariaView.java View File

@ -3,13 +3,21 @@ package mx.gob.jumapacelaya.ui;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.api.RedmineClient;
import mx.gob.jumapacelaya.api.ServerProperties;
import mx.gob.jumapacelaya.models.ActividadDiaria;
import mx.gob.jumapacelaya.models.Ticket;
import mx.gob.jumapacelaya.services.LdapService;
import mx.gob.jumapacelaya.services.UserService;
import java.text.SimpleDateFormat;
@ -22,52 +30,85 @@ import java.util.*;
@CssImport("./themes/sistema-mantenimiento/styles.css")
public class ActDiariaView extends VerticalLayout {
//Variables globales
SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
HorizontalLayout header = new HorizontalLayout();
H3 titulo = new H3();
Button btnCorrectivo = new Button("Correctivo");
Grid<ActividadDiaria> grdColumnas = new Grid<>(ActividadDiaria.class,false);
List<ActividadDiaria> people = Arrays.asList(
new ActividadDiaria(11, "Soprote", "Confi", "Sol", "Urgente",new Date(), new Date()),
new ActividadDiaria(12, "Soprote", "Confi", "Sol", "Urgente",new Date(), new Date()),
new ActividadDiaria(13, "Soprote", "Confi", "Sol", "Urgente",new Date(), new Date()));
//new ActividadDiaria("Johannes Kepler", 1571));
public ActDiariaView() {
VerticalLayout headerLayout = new VerticalLayout();
headerLayout.addClassName("act-diaria-header");
headerLayout.add(titulo);
titulo.setText("Listado de Actividades por Atender - Área de Soporte Mantenimiento Técnico");
titulo.addClassName("act-diaria-titulo");
header.setAlignSelf(Alignment.CENTER, titulo);
VerticalLayout gridLayout = new VerticalLayout();
gridLayout.addClassName("act-diaria-grid");
gridLayout.add(grdColumnas);
//Tabla echa con un grid
grdColumnas.addColumn(ActividadDiaria::getNumero).setHeader("Numero");
grdColumnas.addColumn(ActividadDiaria::getProyecto).setHeader("Proyecto");
grdColumnas.addColumn(ActividadDiaria::getTipo).setHeader("Tipo");
grdColumnas.addColumn(ActividadDiaria::getEstado).setHeader("Estado");
grdColumnas.addColumn(ActividadDiaria::getAsunto).setHeader("Asunto");
grdColumnas.addColumn(date->{
return formato.format(date.getFechaInicial());
}).setHeader("Fecha de Inicio");
grdColumnas.addColumn(date->{
return formato.format(date.getFechaCierre());
}).setHeader("Fecha de cierre");
grdColumnas.setItems(people);
// add(titulo, header, grdColumnas);
this.setPadding(false);
this.setMargin(false);
this.setSpacing(false);
add(headerLayout, gridLayout);
private final RedmineClient redmineClient;
private final UserService userService;
private final Grid<Ticket> grid;
public ActDiariaView(ServerProperties properties, RedmineClient redmineClient, UserService userService) {
this.userService = userService;
this.redmineClient = redmineClient;
this.grid = new Grid<>(Ticket.class, false);
// Configuración de columnas del grid
grid.addColumn(Ticket::getId).setHeader("No.")
.setAutoWidth(true).setFlexGrow(0).setSortable(true);
grid.addColumn(Ticket::getSubject).setHeader("Asunto")
.setAutoWidth(true);
grid.addColumn(createStatusRender()).setHeader("Estado");
grid.addColumn(ticket -> {
Date date = ticket.getDateCreate();
if (date != null) {
SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
return formatter.format(date);
} else {
return "";
}
}).setHeader("Fecha creacion");
grid.addColumn(ticket -> ticket.tiempoEst(ticket.getTrackerId())).setHeader("Tiempo estimado de atencion").setAutoWidth(false);
grid.addColumn(Ticket::getDescription).setHeader("Descripción").setWidth("25em");
grid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT);
grid.getStyle().set("opacity", "0.8");
grid.setAllRowsVisible(true);
// Ajustar tamaño del Grid y Layout
//grid.setSizeFull();
//setSizeFull();
add(grid);
expand(grid);
setMargin(false);
loadTickets();
}
private void loadTickets() {
try {
List<Ticket> tickets = redmineClient.getTicketsAuthor(userService.getRedmineUser());
grid.setItems(tickets);
} catch (Exception e) {
e.printStackTrace();
// Manejo de error al cargar los tickets
}
}
private ComponentRenderer<Span, Ticket> createStatusRender() {
return new ComponentRenderer<>(ticket -> {
// Creamos un Span para mostrar el estado
Span span = new Span(ticket.getStatus());
// Estilos basados en el estado del ticket
switch (ticket.getStatus().toLowerCase()) {
case "análisis":
span.getElement().getStyle().set("color", "purple");
break;
case "desarrollo":
span.getElement().getStyle().set("color", "green");
break;
default:
span.getElement().getStyle().set("color", "blue");
break;
}
return span;
});
}
}

+ 24
- 11
src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java View File

@ -5,9 +5,6 @@ import com.vaadin.flow.component.checkbox.CheckboxGroup;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
@ -18,12 +15,13 @@ import com.vaadin.flow.component.radiobutton.RadioButtonGroup;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.services.DatabaseService;
import java.awt.*;
import java.time.LocalDate;
import java.util.List;
@ -32,12 +30,13 @@ import java.util.List;
@PageTitle("Mantenimiento")
@Route(value = "mantenimiento", layout = MainLayout.class)
@CssImport("./themes/sistema-mantenimiento/styles.css")
public class MantenimientoView extends VerticalLayout {
public class MantenimientoView extends VerticalLayout implements BeforeEnterObserver {
private final VerticalLayout controlsLayout;
private final DatabaseService databaseService;
private final VerticalLayout actualizacionesLayout;
private final VerticalLayout etiquetaLayout;
private DatePicker fecha;
public MantenimientoView() {
this.databaseService = new DatabaseService();
@ -56,8 +55,9 @@ public class MantenimientoView extends VerticalLayout {
otras.addClassName("mantenimiento-text-field");
//Selector de fecha
DatePicker fecha = new DatePicker("Fecha");
// fecha.setPlaceholder("Fecha");
this.fecha = new DatePicker("Fecha");
//fecha.setPlaceholder("Fecha");
//ComboBox Tipo de Mantenimiento
@ -74,18 +74,18 @@ public class MantenimientoView extends VerticalLayout {
//Si el tipo es preventivo se establecera la fecha automaticamente a la fecha del sistema
if ("PREVENTIVO".equals(tipoSeleccionado)) {
fecha.setValue(LocalDate.now());
this.fecha.setValue(LocalDate.now());
etiquetaLayout.setVisible(false);
} else {
fecha.clear();
this.fecha.clear();
etiquetaLayout.setVisible(true);
}
} else {
nomenclatura.clear();
fecha.clear();
this.fecha.clear();
}
});
fechaLayout.add(fecha);
fechaLayout.add(this.fecha);
fechaLayout.addAndExpand(new HorizontalLayout());
fechaLayout.add(tipoMantt, nomenclatura);
fechaLayout.setWidthFull();
@ -294,4 +294,17 @@ public class MantenimientoView extends VerticalLayout {
etiquetaLayout.add(Titulo, model, hard);
}
@Override
public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
String fechaParam = beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("fecha") != null ? beforeEnterEvent.getLocation().getQueryParameters().getParameters().get("fecha").stream().findFirst().orElse(null) : null;
if (fechaParam != null) {
try {
LocalDate fechaActual = LocalDate.parse(fechaParam);
this.fecha.setValue(fechaActual); // Establece la fecha en el DatePicker
} catch (Exception e) {
Notification.show("Error al establecer la fecha: " + e.getMessage(), 3000, Notification.Position.MIDDLE);
}
}
}
}

+ 7
- 4
src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java View File

@ -17,6 +17,7 @@ import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.models.PlanAnual;
import java.lang.reflect.Array;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
@ -63,15 +64,17 @@ public class PlanAnualView extends VerticalLayout {
planAnualGrid.addComponentColumn(plan -> getIcon(plan.getMiniPrint())).setHeader("MiniPrint").setAutoWidth(true);
planAnualGrid.addComponentColumn(plan -> getIcon(plan.getLaptop())).setHeader("Laptop").setAutoWidth(true);
planAnualGrid.addComponentColumn(plan -> getIcon(plan.getEscaner())).setHeader("Escáner").setAutoWidth(true);
planAnualGrid.addColumn(PlanAnual::getFecha).setHeader("Realizar").setAutoWidth(true);
planAnualGrid.addColumn(PlanAnual::getFecha).setHeader("Fecha Programada").setAutoWidth(true);
planAnualGrid.addColumn(PlanAnual::getSmt).setHeader("Smt").setAutoWidth(true);
planAnualGrid.addColumn(PlanAnual::getEstado).setHeader("Estado").setAutoWidth(true);
planAnualGrid.addColumn(PlanAnual::getFechaRealizado).setHeader("Mes Realizacion").setAutoWidth(true);
planAnualGrid.addColumn(PlanAnual::getFechaRealizado).setHeader("Fecha Realizado").setAutoWidth(true);
planAnualGrid.addComponentColumn(plan -> {
Button btnRealizar = new Button("Realizar");
btnRealizar.addClickListener(event -> {
btnRealizar.getUI().ifPresent(ui -> ui.navigate(MantenimientoView.class));
LocalDate fechaSistem = LocalDate.now();
String fechaStr = fechaSistem.toString();
btnRealizar.getUI().ifPresent(ui -> ui.navigate("mantenimiento?fecha=" + fechaStr));
});
return btnRealizar;
}).setHeader("Realizar").setAutoWidth(true);
@ -84,7 +87,7 @@ public class PlanAnualView extends VerticalLayout {
new PlanAnual(1, "INFORM15","T.I", "No", "Logitech", "Logitech", "APC", "si", "HP", "No", "Dell", "Canon", "01-01-2024", "Hector", "Pendiente", "02-01-2024"),
new PlanAnual(2, "ATENCI01", "Atencion", "si", "Dell", "no", "APC", "AMD", "Brother", "Sí", "HP", "no", "15-01-2024", "JuanPI", "Realizado", "16-01-2024"),
new PlanAnual(3, "MEDCAT08", "T.I", "si", "Dell", "no", "APC", "AMD", "Brother", "Sí", "HP", "no", "15-01-2024", "JuanPI", "Cancelado", "16-01-2024"),
new PlanAnual(4, "CALAGUA03", "T.I", "si", "Dell", "no", "APC", "AMD", "Brother", "Sí", "HP", "no", "15-01-2024", "JuanPI", "Pendiente", "16-01-2024")
new PlanAnual(4, "CALAGUA03", "T.I", "si", "Dell", "no", "APC", "AMD", "Brother", "Sí", "HP", "no", "15-01-2024", "Hector", "Realizado", "16-01-2024")
);
planAnualGrid.setItems(planes);


+ 3
- 1
src/main/resources/application.properties View File

@ -15,7 +15,9 @@ spring.ldap.base=DC=JUMAPACELAYA,DC=GOB,DC=MX
spring.ldap.username=administrator
spring.ldap.password=Dr3na%134$4guA
########PRODUCTIVO#################################
redmine.url=https://proyman.jumapacelaya.gob.mx/
redmine.api_key=ce4dc8b6b531c818017e6831a5732ccc15b8faf6
#Conexion a la base de datos Mantenimientos
#MySQL Configuration


Loading…
Cancel
Save