Browse Source

Se agrego la funcion para permitir adjuntar algun archivo a la peticion, ademas de correccion de algunos errores

pull/1/head
parent
commit
16c333e7df
2 changed files with 109 additions and 41 deletions
  1. +50
    -4
      src/main/java/com/example/application/api/ApiRedmine.java
  2. +59
    -37
      src/main/java/com/example/application/views/crearnuevoticket/CrearnuevoTicketView.java

+ 50
- 4
src/main/java/com/example/application/api/ApiRedmine.java View File

@ -6,7 +6,10 @@ import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ApiRedmine {
private static final String REDMINE_URL = "http://localhost:3000";
@ -14,12 +17,25 @@ public class ApiRedmine {
public static final Gson GSON = new Gson();
public static String createIssue(Map<String, String> issueDetails) {
return createIssue(issueDetails, null);
}
public static String createIssue(Map<String, String> issueDetails, String fileUploadToken) {
Map<String, Object> payload = new HashMap<>();
payload.put("issue", issueDetails);
if (fileUploadToken != null) {
List<Map<String, String>> uploads = new ArrayList<>();
Map<String, String> fileTokenMap = new HashMap<>();
fileTokenMap.put("token", fileUploadToken);
uploads.add(fileTokenMap);
payload.put("uploads", uploads);
}
String jsonPayload = GSON.toJson(payload);
try {
//Crear la solicitud HTTP POST
// Crear la solicitud HTTP POST
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/issues.json"))
.header("Content-Type", "application/json")
@ -27,14 +43,14 @@ public class ApiRedmine {
.POST(HttpRequest.BodyPublishers.ofString(jsonPayload))
.build();
//Enviar la solicitud
// Enviar la solicitud
HttpClient client = HttpClient.newHttpClient();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
} catch (Exception e) {
e.printStackTrace();
return "Error: "+e.getMessage();
return "Error: " + e.getMessage();
}
}
@ -72,4 +88,34 @@ public class ApiRedmine {
}
return names;
}
public static String uploadFile(byte[] fileContent, String fileName) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(REDMINE_URL + "/uploads.json"))
.header("Content-Type", "application/octet-stream")
.header("X-Redmine-API-Key", API_KEY)
.header("Content-Disposition", "attachment; filename=\"" + fileName + "\"")
.POST(HttpRequest.BodyPublishers.ofByteArray(fileContent))
.build();
try {
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 201) {
JsonObject jsonResponse = JsonParser.parseString(response.body()).getAsJsonObject();
return jsonResponse.get("upload").getAsJsonObject().get("token").getAsString();
} else {
System.err.println("Error en la subida del archivo: " + response.statusCode());
System.err.println("Response body: " + response.body());
return null;
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static String createIssueWithAttachment(Map<String, String> issueDetails, String fileUploadToken) {
return createIssue(issueDetails, fileUploadToken);
}
}

+ 59
- 37
src/main/java/com/example/application/views/crearnuevoticket/CrearnuevoTicketView.java View File

@ -20,95 +20,117 @@ import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
import com.vaadin.flow.router.Route;
import jakarta.annotation.security.PermitAll;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Route(value="", layout = MainLayout.class)
@Route(value = "", layout = MainLayout.class)
@PermitAll
public class CrearnuevoTicketView extends VerticalLayout {
public CrearnuevoTicketView() {
private MemoryBuffer buffer;
private Upload uploadFile;
//Combo de los tipos de tickets
public CrearnuevoTicketView() {
// Combo de los tipos de tickets
ComboBox<String> tipoTickets = new ComboBox<>("Tipo de ticket");
ApiRedmine api = new ApiRedmine();
List<String> types = api.getTicketTypes();
tipoTickets.setItems(types);
//Campo de texto para el asunto
// Campo de texto para el asunto
TextField asunto = new TextField("Asunto");
asunto.setWidth("700px");
//Campo de texto para la descripcion
// Campo de texto para la descripcion
TextArea descripcion = new TextArea("Descripcion");
descripcion.setWidth("1000px");
descripcion.setHeight("250px");
//Campo para adjuntar archivos
MemoryBuffer buffer = new MemoryBuffer();
Upload uploadFile = new Upload();
// Campo para adjuntar archivos
buffer = new MemoryBuffer();
uploadFile = new Upload(buffer);
uploadFile.setUploadButton(new Button("Cargar archivo"));
uploadFile.setMaxFiles(1);
uploadFile.addFailedListener(event -> {
Notification.show("Error al cargar el archivo: " + event.getReason().getMessage(), 5000, Notification.Position.MIDDLE);
});
//Respuestas Json para verificar posibles errores al enviar los nuevos tickets no visibles en la interfaz
// Respuestas Json para verificar posibles errores al enviar los nuevos tickets no visibles en la interfaz
TextArea jsonOutput = new TextArea("JSON Output");
jsonOutput.setReadOnly(true);
TextArea responseField = new TextArea("Response");
responseField.setReadOnly(true);
//Boton para crear los tickets
// Boton para crear los tickets
Button createButton = new Button("Enviar ticket", event -> {
Map<String, String> issueDetails = new HashMap<>();
issueDetails.put("project_id", "proyecto-de-prueba");
issueDetails.put("subject", asunto.getValue());
issueDetails.put("description", descripcion.getValue());
String response = ApiRedmine.createIssue(issueDetails);
if (response.startsWith("{\"issue\":")) {
//Aqui extraigo el numero del ticket de la respuesta json
JsonObject jsonResponse = JsonParser.parseString(response).getAsJsonObject();
int issueNumber = jsonResponse.getAsJsonObject("issue").get("id").getAsInt();
String notificationMessage = "¡Su ticket se ha enviado corrrectamente! Numero de ticket: #" + issueNumber;
Notification issueNtf = new Notification(notificationMessage, 5000, Notification.Position.MIDDLE);
issueNtf.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
issueNtf.open();
//Limpiando los campos
asunto.clear();
descripcion.clear();
tipoTickets.clear();
String fileUploadToken = null;
if (buffer.getFileData() != null) {
try {
byte[] fileContent = buffer.getInputStream().readAllBytes();
String fileName = buffer.getFileName();
fileUploadToken = ApiRedmine.uploadFile(fileContent, fileName);
} catch (IOException e) {
Notification.show("Error al cargar el archivo: " + e.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING);
}
}
String response;
if (fileUploadToken != null) {
response = ApiRedmine.createIssue(issueDetails, fileUploadToken);
} else {
Notification errNtf = Notification.show("Ha ocurrido un error al enviar el ticket: "+response, 5000, Notification.Position.MIDDLE);
errNtf.addThemeVariants(NotificationVariant.LUMO_ERROR);
response = ApiRedmine.createIssue(issueDetails, fileUploadToken);
}
handleResponse(response, asunto, descripcion, tipoTickets);
});
createButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
VerticalLayout fieldsLayout = new VerticalLayout(descripcion);
fieldsLayout.setAlignItems(Alignment.CENTER);
HorizontalLayout firstFields = new HorizontalLayout(tipoTickets, asunto);
VerticalLayout buttonLayout = new VerticalLayout(createButton);
buttonLayout.setAlignItems(Alignment.END);
buttonLayout.setMargin(true);
VerticalLayout uploadLayout = new VerticalLayout(uploadFile);
add(new H2("Crear nuevo ticket"), firstFields, fieldsLayout, uploadLayout, buttonLayout/*,jsonOutput,responseField*/);
}
private void handleResponse(String response, TextField asunto, TextArea descripcion, ComboBox<String> tipoTickets) {
if (response.startsWith("{\"issue\":")) {
JsonObject jsonResponse = JsonParser.parseString(response).getAsJsonObject();
int issueNumber = jsonResponse.getAsJsonObject("issue").get("id").getAsInt();
Notification.show("Su ticket se ha enviado correctamente! Numero de ticket: #" + issueNumber, 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
resetForm(asunto, descripcion, tipoTickets);
} else {
Notification.show("Ha ocurrido un error al enviar el ticket: " + response, 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
}
}
//Metodo para convertir un Map a json usando la libreria GSON
// Metodo para convertir un Map a json usando la libreria GSON
private static String mapToJson(Map<String, String> map) {
Gson gson = new Gson();
return gson.toJson(map);
}
// Metodo para resetear el formulario
private void resetForm(TextField asunto, TextArea descripcion, ComboBox<String> tipoTickets) {
asunto.clear();
descripcion.clear();
tipoTickets.clear();
buffer = new MemoryBuffer();
uploadFile.setReceiver(buffer);
uploadFile.clearFileList();
}
}

Loading…
Cancel
Save