Browse Source

Se añadio otra vista que muestra todos los tickets que hay en general, ademas se modifico el grid para que el estatus cambie de color en base al estado que tiene

pull/1/head
parent
commit
da3c9b4660
12 changed files with 234 additions and 15 deletions
  1. +0
    -2
      .flow-node-tasks.lock
  2. +5
    -1
      pom.xml
  3. BIN
      src/main/bundles/prod.bundle
  4. +22
    -0
      src/main/java/com/example/application/Application.java
  5. +36
    -2
      src/main/java/com/example/application/api/RedmineClient.java
  6. +29
    -1
      src/main/java/com/example/application/models/Ticket.java
  7. +2
    -0
      src/main/java/com/example/application/views/MainLayout.java
  8. +2
    -0
      src/main/java/com/example/application/views/crearnuevoticket/CrearnuevoTicketView.java
  9. +79
    -0
      src/main/java/com/example/application/views/tickets/AllTicketsView.java
  10. +44
    -6
      src/main/java/com/example/application/views/tickets/MisTicketsView.java
  11. +3
    -3
      src/main/resources/application.properties
  12. +12
    -0
      src/main/resources/logback.xml

+ 0
- 2
.flow-node-tasks.lock View File

@ -1,2 +0,0 @@
19228

+ 5
- 1
pom.xml View File

@ -90,6 +90,10 @@
<artifactId>slf4j-api</artifactId>
<version>2.0.13</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
<build>
@ -179,7 +183,7 @@
<!-- Runs the integration tests (*IT) after the server is started -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<!--<artifactId>maven-failsafe-plugin</artifactId>-->
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>


BIN
src/main/bundles/prod.bundle View File


+ 22
- 0
src/main/java/com/example/application/Application.java View File

@ -1,8 +1,11 @@
package com.example.application;
import com.vaadin.flow.component.dependency.JsModule;
import com.vaadin.flow.component.html.Main;
import com.vaadin.flow.component.page.AppShellConfigurator;
import com.vaadin.flow.theme.Theme;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration;
@ -19,8 +22,27 @@ import org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConf
@JsModule("@vaadin/vaadin-lumo-styles/presets/compact.js")
public class Application implements AppShellConfigurator {
private static final Logger logger = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
logger.info("Inicio de la aplicacion");
conectToService("localhost:8080");
logger.info("Aplicacion iniciada con exito");
}
private static void conectToService(String url) {
logger.debug("Intentando conectar la aplicacion a {} ", url);
try {
Thread.sleep(2000);
logger.debug("Conexion exitosa a {}", url);
} catch (InterruptedException e) {
logger.error("Error en la conexion a {}", url, e);
}
}
}

+ 36
- 2
src/main/java/com/example/application/api/RedmineClient.java View File

@ -12,6 +12,7 @@ import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/*Esta clase se encarga de obtener los tickets desde redmine
para poder mostrarlo en la vista de visualizacion de tickets*/
@ -23,10 +24,13 @@ public class RedmineClient {
private static final int PAGE_SIZE = 25;
static String REDMINE_URL;
static String API_KEY;
//private final RestTemplate restTemplate;
public RedmineClient(String redmineUrl, String apiKey) {
REDMINE_URL = redmineUrl;
API_KEY = apiKey;
//this.restTemplate = new RestTemplate();
}
public List<Ticket> getTickets() {
@ -36,7 +40,7 @@ public class RedmineClient {
while (true) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/issues.json?limit=" + PAGE_SIZE + "&offset=" + offset))
.uri(URI.create(REDMINE_URL + "/issues.json?key=" + PAGE_SIZE + "&offset=" + offset))
.header("Content-Type", "application/json")
.header("X-Redmine-API-Key", API_KEY)
.build();
@ -60,6 +64,7 @@ public class RedmineClient {
break;
}
}
System.out.println("Total tickets obtenidos: " + tickets.size());
return tickets;
}
@ -73,8 +78,37 @@ public class RedmineClient {
String subject = issue.get("subject").getAsString();
String description = issue.has("description") ? issue.get("description").getAsString() : "";
String status = issue.getAsJsonObject("status").get("name").getAsString();
tickets.add(new Ticket(id, subject, description, status));
JsonObject authorJson = issue.getAsJsonObject("author");
Ticket.User author = null;
if (authorJson != null) {
String username = authorJson.get("name").getAsString();
author = new Ticket.User(username);
}
tickets.add(new Ticket(id, subject, description, status, author));
}
return tickets;
}
public List<Ticket> getTicketsCreatedBy(String username) {
List<Ticket> allTickets = getTickets();
List<Ticket> filteredTickets = allTickets.stream()
.filter(ticket -> ticket.getAuthor() != null && username.equals(ticket.getAuthor().getUsername()))
.collect(Collectors.toList());
System.out.println("Total de tickets creados por " + username + ": " + filteredTickets.size());
return filteredTickets;
}
private static class TicketResponse {
private List<Ticket> isues;
public List<Ticket> getIssues() {
return isues;
}
public void setIssues(List<Ticket> issues) {
this.isues = issues;
}
}
}

+ 29
- 1
src/main/java/com/example/application/models/Ticket.java View File

@ -2,18 +2,22 @@ package com.example.application.models;
/*Esta clase obtiene los detalles de los tickets*/
public class Ticket {
private int id;
private String subject;
private String description;
private String status;
private User author;
public Ticket(int id, String subject, String description, String status) {
public Ticket(int id, String subject, String description, String status, User author) {
this.id = id;
this.subject = subject;
this.description = description;
this.status = status;
this.author = author;
}
public int getId() {
@ -31,4 +35,28 @@ public class Ticket {
public String getStatus() {
return status;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
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;
}
}
}

+ 2
- 0
src/main/java/com/example/application/views/MainLayout.java View File

@ -2,6 +2,7 @@ package com.example.application.views;
import com.example.application.api.SecurityService;
import com.example.application.views.crearnuevoticket.CrearnuevoTicketView;
import com.example.application.views.tickets.AllTicketsView;
import com.example.application.views.tickets.MisTicketsView;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
@ -84,6 +85,7 @@ public class MainLayout extends AppLayout {
nav.addItem(new SideNavItem("Crear nuevo ticket", CrearnuevoTicketView.class, LineAwesomeIcon.EDIT.create()));
nav.addItem(new SideNavItem("Mis tickets", MisTicketsView.class, LineAwesomeIcon.TICKET_ALT_SOLID.create()));
nav.addItem(new SideNavItem("Todos los tickets", AllTicketsView.class, LineAwesomeIcon.TICKET_ALT_SOLID.create()));
return nav;


+ 2
- 0
src/main/java/com/example/application/views/crearnuevoticket/CrearnuevoTicketView.java View File

@ -18,6 +18,7 @@ import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.upload.Upload;
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll;
@ -28,6 +29,7 @@ import java.util.Map;
@Route(value = "", layout = MainLayout.class)
@PermitAll
@PageTitle("Nuevo ticket")
public class CrearnuevoTicketView extends VerticalLayout {
private MemoryBuffer buffer;


+ 79
- 0
src/main/java/com/example/application/views/tickets/AllTicketsView.java View File

@ -0,0 +1,79 @@
package com.example.application.views.tickets;
import com.example.application.api.RedmineClient;
import com.example.application.api.ServerPrpperties;
import com.example.application.models.Ticket;
import com.example.application.views.MainLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Span;
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 com.vaadin.flow.server.auth.AnonymousAllowed;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Route(value="tickets", layout = MainLayout.class)
@AnonymousAllowed
@PageTitle("Todos los tickets")
public class AllTicketsView extends VerticalLayout {
private final RedmineClient redmineClient;
private final Grid<Ticket> grid;
@Autowired
public AllTicketsView(ServerPrpperties prpperties) {
this.redmineClient = new RedmineClient(prpperties.REDMINE_URL, prpperties.API_KEY);
this.grid = new Grid<>(Ticket.class, false);
grid.addColumn(Ticket::getId).setHeader("No.")
.setWidth("4em").setFlexGrow(0);
grid.addColumn(Ticket::getSubject).setHeader("Asunto")
.setAutoWidth(true).setFlexGrow(1);
grid.addColumn(createStatusRender()).setHeader("Estado")
.setWidth("7em").setFlexGrow(1);
grid.addColumn(Ticket::getDescription).setHeader("Descripción")
.setAutoWidth(true).setFlexGrow(1);
// Ajustar tamaño del Grid y Layout
grid.setSizeFull();
setSizeFull();
setPadding(false);
setMargin(false);
setSpacing(false);
add(grid);
expand(grid);
loadTickets();
}
private void loadTickets() {
List<Ticket> tickets = redmineClient.getTickets();
grid.setItems(tickets);
}
private ComponentRenderer<Span, Ticket> createStatusRender() {
return new ComponentRenderer<>(ticket -> {
Span span = new Span(ticket.getStatus());
switch (ticket.getStatus().toLowerCase()) {
case "en curso":
span.getElement().getStyle().set("color","purple");
break;
case "comentarios":
span.getElement().getStyle().set("color","orange");
break;
case "resuelta":
span.getElement().getStyle().set("color","green");
break;
default:
span.getElement().getStyle().set("color","blue");
break;
}
return span;
});
}
}

+ 44
- 6
src/main/java/com/example/application/views/tickets/MisTicketsView.java View File

@ -1,34 +1,44 @@
package com.example.application.views.tickets;
import com.example.application.api.RedmineClient;
import com.example.application.api.SecurityService;
import com.example.application.api.ServerPrpperties;
import com.example.application.models.Ticket;
import com.example.application.views.MainLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.html.Span;
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 com.vaadin.flow.server.auth.AnonymousAllowed;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Route(value="mytickets", layout = MainLayout.class)
@AnonymousAllowed
@PageTitle("Mis tickets")
public class MisTicketsView extends VerticalLayout {
private final RedmineClient redmineClient;
private final Grid<Ticket> grid;
private final SecurityService securityService;
public MisTicketsView(ServerPrpperties prpperties) {
@Autowired
public MisTicketsView(ServerPrpperties prpperties, SecurityService securityService) {
this.redmineClient = new RedmineClient(prpperties.REDMINE_URL, prpperties.API_KEY);
this.grid = new Grid<>(Ticket.class, false);
this.securityService = securityService;
// Definir columnas en el orden deseado
grid.addColumn(Ticket::getId).setHeader("NO")
grid.addColumn(Ticket::getId).setHeader("No.")
.setWidth("4em").setFlexGrow(0);
grid.addColumn(Ticket::getSubject).setHeader("Asunto")
.setAutoWidth(true).setFlexGrow(1);
grid.addColumn(Ticket::getStatus).setHeader("Estado")
grid.addColumn(createStatusRender()).setHeader("Estado")
.setWidth("7em").setFlexGrow(1);
grid.addColumn(Ticket::getDescription).setHeader("Descripción")
.setAutoWidth(true).setFlexGrow(1);
@ -44,11 +54,39 @@ public class MisTicketsView extends VerticalLayout {
add(grid);
expand(grid);
loadTickets();
loadTickets(getAuthenticatedUsername());
}
private void loadTickets() {
List<Ticket> tickets = redmineClient.getTickets();
private void loadTickets(String authenticatedUsername) {
List<Ticket> tickets = redmineClient.getTicketsCreatedBy(authenticatedUsername );
System.out.println("Tickets para mostrar: " + tickets.size());
grid.setItems(tickets);
}
private String getAuthenticatedUsername() {
String username = securityService.getAuthenticatedUser().getUsername();
System.out.println("Usuario autenticado: " + username);
return username;
}
private ComponentRenderer<Span, Ticket> createStatusRender() {
return new ComponentRenderer<>(ticket -> {
Span span = new Span(ticket.getStatus());
switch (ticket.getStatus().toLowerCase()) {
case "open":
span.getElement().getStyle().set("color","green");
break;
case "closed":
span.getElement().getStyle().set("color","red");
break;
case "in progress":
span.getElement().getStyle().set("color","orange");
break;
default:
span.getElement().getStyle().set("color","green");
break;
}
return span;
});
}
}

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

@ -13,12 +13,12 @@ spring.jpa.defer-datasource-initialization = true
spring:
ldap:
urls: ldap://172.16.0.1:389
base: DC=JUMAPACELAYA, DC=GOB, DC=MX
base: DC=JUMAPACELAYA, DC=GOB, DC=MX
username: administrator
password: Dr3na%134$4guA
####################################################
redmine.url=http://localhost:3000
redmine.api_key=cf3be6168e66c99892c6212ea0bc64e8ab1c6848
redmine.url=http://localhost:3000/
redmine.api_key=35164d2320404b66a71df90d514107790bc1aed6

+ 12
- 0
src/main/resources/logback.xml View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="CONSOLE" />
</root>
</configuration>

Loading…
Cancel
Save