diff --git a/src/main/bundles/prod.bundle b/src/main/bundles/prod.bundle index 2253e3a..09a1275 100644 Binary files a/src/main/bundles/prod.bundle and b/src/main/bundles/prod.bundle differ diff --git a/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java b/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java index fdf682f..e6d4ac7 100644 --- a/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java +++ b/src/main/java/mx/gob/jumapacelaya/api/RedmineClient.java @@ -5,6 +5,7 @@ import com.vaadin.flow.server.VaadinService; import mx.gob.jumapacelaya.models.JsonOrder; import mx.gob.jumapacelaya.models.RedmineUser; import mx.gob.jumapacelaya.models.Ticket; +import mx.gob.jumapacelaya.models.TicketComment; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -443,8 +444,8 @@ public class RedmineClient { } } - public List getTicketComments(int ticketId, RedmineUser user) { - List comments = new ArrayList<>(); + public List getTicketComments(int ticketId, RedmineUser user) { + List comments = new ArrayList<>(); HttpClient client = HttpClient.newHttpClient(); String url = REDMINE_URL + "/issues/" + ticketId + ".json?include=journals&key=" + user.getKey(); @@ -467,7 +468,12 @@ public class RedmineClient { if (journal.has("notes") && !journal.get("notes").isJsonNull()) { String note = journal.get("notes").getAsString().trim(); if (!note.isEmpty()) { - comments.add(note); + String date = ""; + if (journal.has("created_on") && !journal.get("created_on").isJsonNull()) { + date = journal.get("created_on").getAsString(); + } + + comments.add(new TicketComment(note, date)); } } } diff --git a/src/main/java/mx/gob/jumapacelaya/models/TicketComment.java b/src/main/java/mx/gob/jumapacelaya/models/TicketComment.java new file mode 100644 index 0000000..4665624 --- /dev/null +++ b/src/main/java/mx/gob/jumapacelaya/models/TicketComment.java @@ -0,0 +1,21 @@ +package mx.gob.jumapacelaya.models; + +public class TicketComment { + + private String comment; + private String date; + + public TicketComment(String comment, String date) { + this.comment = comment; + this.date = date; + } + + public String getComment() { + return comment; + } + + public String getDate() { + return date; + } + +} diff --git a/src/main/java/mx/gob/jumapacelaya/views/login/LoginView.java b/src/main/java/mx/gob/jumapacelaya/views/login/LoginView.java index 0c89e01..e1df626 100644 --- a/src/main/java/mx/gob/jumapacelaya/views/login/LoginView.java +++ b/src/main/java/mx/gob/jumapacelaya/views/login/LoginView.java @@ -11,8 +11,6 @@ import com.vaadin.flow.router.BeforeEnterObserver; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; import com.vaadin.flow.server.auth.AnonymousAllowed; -import mx.gob.jumapacelaya.api.RedmineClient; -import mx.gob.jumapacelaya.services.UserService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,7 +57,7 @@ public class LoginView extends VerticalLayout implements BeforeEnterObserver { i18nError.setMessage("Usuario o contraseña incorrectos, verifica tus credenciales"); i18n.setErrorMessage(i18nError); - i18n.setAdditionalInformation("Versión 2.0.0"); + i18n.setAdditionalInformation("Versión 2.1.0"); // Configuración del formulario de login login.setAction("login"); diff --git a/src/main/java/mx/gob/jumapacelaya/views/tickets/AllTicketsView.java b/src/main/java/mx/gob/jumapacelaya/views/tickets/AllTicketsView.java index c75c9cd..89ca795 100644 --- a/src/main/java/mx/gob/jumapacelaya/views/tickets/AllTicketsView.java +++ b/src/main/java/mx/gob/jumapacelaya/views/tickets/AllTicketsView.java @@ -19,10 +19,14 @@ import jakarta.annotation.security.PermitAll; import mx.gob.jumapacelaya.api.RedmineClient; import mx.gob.jumapacelaya.api.ServerPrpperties; import mx.gob.jumapacelaya.models.Ticket; +import mx.gob.jumapacelaya.models.TicketComment; import mx.gob.jumapacelaya.services.UserService; import mx.gob.jumapacelaya.views.MainLayout; import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; @@ -102,10 +106,10 @@ public class AllTicketsView extends VerticalLayout { textEditor.setReadOnly(true); - Button verNotas = new Button("Comentarios"); + Button verNotas = new Button("Comentarios", VaadinIcon.COMMENTS.create()); verNotas.addClickListener(event -> showComents(ticket)); - Button closeButton = new Button("Cerrar"); + Button closeButton = new Button("Cerrar", VaadinIcon.CLOSE_SMALL.create()); closeButton.addThemeVariants(ButtonVariant.LUMO_ERROR); closeButton.addClickListener(e -> dialog.close()); @@ -130,21 +134,43 @@ public class AllTicketsView extends VerticalLayout { layout.setSpacing(true); // Obtenemos los comentarios desde Proyman - List comentarios = redmineClient.getTicketComments(ticket.getId(), userService.getRedmineUser()); + List comentarios = redmineClient.getTicketComments(ticket.getId(), userService.getRedmineUser()); if (comentarios != null && !comentarios.isEmpty()) { - for (String comentario : comentarios) { - Span commentSpan = new Span(comentario); - commentSpan.getElement().getStyle().set("background", "#f1f1f1"); - commentSpan.getElement().getStyle().set("padding", "10px"); - commentSpan.getElement().getStyle().set("border-radius", "5px"); - layout.add(commentSpan); + DateTimeFormatter inputFormatter = DateTimeFormatter.ISO_DATE_TIME; + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + + for (TicketComment comentario : comentarios) { + String formattedDate = "Fecha desconocida"; + + try { + ZonedDateTime dateTime = ZonedDateTime.parse(comentario.getDate(), inputFormatter); + formattedDate = dateTime.withZoneSameInstant(ZoneId.systemDefault()).format(outputFormatter); + } catch (Exception e) { + System.err.println("Error al parsear la fecha: " + comentario.getDate()); + } + + VerticalLayout commentLayout = new VerticalLayout(); + commentLayout.getElement().getStyle().set("background", "#DDC9A3"); + commentLayout.getElement().getStyle().set("padding", "10px"); + commentLayout.getElement().getStyle().set("border-radius", "5px"); + commentLayout.getElement().getStyle().set("margin-bottom", "5px"); + + Span dateSpan = new Span("📆 " + formattedDate); + dateSpan.getElement().getStyle().set("font-weight", "bold"); + dateSpan.getElement().getStyle().set("color", "#333"); + + Span commentSpan = new Span(comentario.getComment()); + commentSpan.getElement().getStyle().set("margin-top", "5px"); + + commentLayout.add(dateSpan, commentSpan); + layout.add(commentLayout); } } else { layout.add(new Span("No hay comentarios para este ticket.")); } - Button closeButton = new Button("Cerrar", event -> comentDialog.close()); + Button closeButton = new Button("Cerrar", VaadinIcon.CLOSE_SMALL.create(), event -> comentDialog.close()); closeButton.addThemeVariants(ButtonVariant.LUMO_ERROR); layout.add(closeButton); diff --git a/src/main/java/mx/gob/jumapacelaya/views/tickets/MisTicketsView.java b/src/main/java/mx/gob/jumapacelaya/views/tickets/MisTicketsView.java index 5ef122c..75b43c9 100644 --- a/src/main/java/mx/gob/jumapacelaya/views/tickets/MisTicketsView.java +++ b/src/main/java/mx/gob/jumapacelaya/views/tickets/MisTicketsView.java @@ -20,11 +20,15 @@ import mx.gob.jumapacelaya.Application; import mx.gob.jumapacelaya.api.RedmineClient; import mx.gob.jumapacelaya.api.ServerPrpperties; import mx.gob.jumapacelaya.models.Ticket; +import mx.gob.jumapacelaya.models.TicketComment; import mx.gob.jumapacelaya.services.UserService; import mx.gob.jumapacelaya.views.MainLayout; import org.springframework.beans.factory.annotation.Autowired; import java.text.SimpleDateFormat; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; import java.util.Date; import java.util.List; @@ -105,10 +109,10 @@ public class MisTicketsView extends VerticalLayout { textEditor.setValue(ticket.getDescription()); textEditor.setReadOnly(true); - Button verNotas = new Button("Comentarios"); + Button verNotas = new Button("Comentarios", VaadinIcon.COMMENTS.create()); verNotas.addClickListener(event -> showComents(ticket)); - Button closeButton = new Button("Cerrar"); + Button closeButton = new Button("Cerrar", VaadinIcon.CLOSE_SMALL.create()); closeButton.addThemeVariants(ButtonVariant.LUMO_ERROR); closeButton.addClickListener(e -> dialog.close()); @@ -133,21 +137,43 @@ public class MisTicketsView extends VerticalLayout { layout.setSpacing(true); // Obtenemos los comentarios desde Proyman - List comentarios = redmineClient.getTicketComments(ticket.getId(), userService.getRedmineUser()); + List comentarios = redmineClient.getTicketComments(ticket.getId(), userService.getRedmineUser()); if (comentarios != null && !comentarios.isEmpty()) { - for (String comentario : comentarios) { - Span commentSpan = new Span(comentario); - commentSpan.getElement().getStyle().set("background", "#f1f1f1"); - commentSpan.getElement().getStyle().set("padding", "10px"); - commentSpan.getElement().getStyle().set("border-radius", "5px"); - layout.add(commentSpan); + DateTimeFormatter inputFormatter = DateTimeFormatter.ISO_DATE_TIME; + DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm"); + + for (TicketComment comentario : comentarios) { + String formattedDate = "Fecha desconocida"; + + try { + ZonedDateTime dateTime = ZonedDateTime.parse(comentario.getDate(), inputFormatter); + formattedDate = dateTime.withZoneSameInstant(ZoneId.systemDefault()).format(outputFormatter); + } catch (Exception e) { + System.err.println("Error al parsear la fecha: " + comentario.getDate()); + } + + VerticalLayout commentLayout = new VerticalLayout(); + commentLayout.getElement().getStyle().set("background", "#DDC9A3"); + commentLayout.getElement().getStyle().set("padding", "10px"); + commentLayout.getElement().getStyle().set("border-radius", "5px"); + commentLayout.getElement().getStyle().set("margin-bottom", "5px"); + + Span dateSpan = new Span("📆 " + formattedDate); + dateSpan.getElement().getStyle().set("font-weight", "bold"); + dateSpan.getElement().getStyle().set("color", "#333"); + + Span commentSpan = new Span(comentario.getComment()); + commentSpan.getElement().getStyle().set("margin-top", "5px"); + + commentLayout.add(dateSpan, commentSpan); + layout.add(commentLayout); } } else { layout.add(new Span("No hay comentarios para este ticket.")); } - Button closeButton = new Button("Cerrar", event -> comentDialog.close()); + Button closeButton = new Button("Cerrar", VaadinIcon.CLOSE_SMALL.create(), event -> comentDialog.close()); closeButton.addThemeVariants(ButtonVariant.LUMO_ERROR); layout.add(closeButton);