Browse Source

se añadieron validaciones para marcar los campos de tipo de ticket, asunto y descripcion como obligatorios y tambien se puso un placeholder en el combo de los tipos de tickets con un texto de seleccionar un tipo

pull/1/head
parent
commit
0999b7862d
2 changed files with 124 additions and 114 deletions
  1. +120
    -110
      src/main/java/mx/gob/jumapacelaya/views/crearnuevoticket/CrearnuevoTicketView.java
  2. +4
    -4
      src/main/resources/application.properties

+ 120
- 110
src/main/java/mx/gob/jumapacelaya/views/crearnuevoticket/CrearnuevoTicketView.java View File

@ -33,8 +33,6 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import static org.atmosphere.annotation.AnnotationUtil.logger;
@Route(value = "", layout = MainLayout.class)
@PermitAll
@PageTitle("Nuevo ticket")
@ -50,15 +48,44 @@ public class CrearnuevoTicketView extends VerticalLayout {
this.api = api;
this.userService = service;
this.buffer = new MultiFileMemoryBuffer();
this.uploadFile = new Upload(buffer);
this.uploadFile.setMaxFiles(5); //Numero maximo de archivos permitido
this.uploadFile.setDropAllowed(true);
this.uploadFile.setAcceptedFileTypes("image/jpeg", "image/png", "application/pdf", "image/gif", "image/svg", "text/plain",
"application/zip", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); //Tipos de archivos permitidos
this.uploadFile = createUploadComponent();
RedmineUser user = userService.getRedmineUser();
ComboBox<String> tipoTickets = createTicketTypeComboBox();
TextField asunto = createTextField("Asunto", "700px");
TextArea descripcion = createTextArea("Descripcion", "1000px", "250px");
// Marcar campos como obligatorios
tipoTickets.setRequiredIndicatorVisible(true);
asunto.setRequiredIndicatorVisible(true);
descripcion.setRequiredIndicatorVisible(true);
uploadFile.addSucceededListener(event -> handleFileUpload(event.getFileName()));
Button createButton = new Button("Enviar ticket", event -> handleCreateButton(user, tipoTickets, asunto, descripcion));
createButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
VerticalLayout fieldsLayout = new VerticalLayout(descripcion, uploadFile);
fieldsLayout.setAlignItems(Alignment.CENTER);
HorizontalLayout firstFields = new HorizontalLayout(tipoTickets, asunto);
VerticalLayout buttonLayout = new VerticalLayout(createButton);
buttonLayout.setAlignItems(Alignment.END);
buttonLayout.setMargin(true);
add(new H2("Crear nuevo ticket"), firstFields, fieldsLayout, buttonLayout);
}
private Upload createUploadComponent() {
MultiFileMemoryBuffer buffer = new MultiFileMemoryBuffer();
Upload uploadFile = new Upload(buffer);
uploadFile.setMaxFiles(5);
uploadFile.setDropAllowed(true);
uploadFile.setAcceptedFileTypes("image/jpeg", "image/png", "application/pdf", "image/gif", "image/svg", "text/plain",
"application/zip", "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
UploadI18N i18N = new UploadI18N();
UploadI18N.Uploading uploading = i18N.getUploading();
if (uploading == null) {
@ -72,128 +99,107 @@ public class CrearnuevoTicketView extends VerticalLayout {
uploading.setError(error);
}
error.setUnexpectedServerError("No se pudo cargar el archivo. Por favor, intentalo de nuevo");
error.setServerUnavailable("El archivo es demasiado grande. El tamaño máximo permitido es de 10 MB.");
error.setForbidden("Archivo no permitido");
uploadFile.setI18n(i18N);
return uploadFile;
}
// ComboBox para los tipos de tickets
private ComboBox<String> createTicketTypeComboBox() {
ComboBox<String> tipoTickets = new ComboBox<>("Tipo de ticket");
tipoTickets.setPlaceholder("Seleccione un tipo de ticket");
Map<String, String> ticketTypesMap = api.getTicketTypes();
Set<String> ticketTypesSet = Set.of("Acceso/Permiso/Bajas","Soporte de Software", "Capacitacion de Software","Configuracion de Software",
"Digitalizacion GIS","Documento","Funcionalidad","Reporte","Soporte o Mantenimiento");
Set<String> ticketTypesSet = Set.of("Acceso/Permiso/Bajas", "Soporte de Software", "Capacitacion de Software",
"Configuracion de Software", "Digitalizacion GIS", "Documento", "Funcionalidad", "Reporte",
"Soporte o Mantenimiento");
List<String> filteredTicketTypes = ticketTypesMap.keySet().stream()
.filter(ticketTypesSet::contains)
.toList();
.filter(ticketTypesSet::contains)
.collect(Collectors.toList());
tipoTickets.setItems(filteredTicketTypes);
tipoTickets.addValueChangeListener(event -> selectedTrackerId = ticketTypesMap.get(event.getValue()));
return tipoTickets;
}
// Campo de texto para el asunto
TextField asunto = new TextField("Asunto");
asunto.setWidth("700px");
// Campo de texto para la descripcion
TextArea descripcion = new TextArea("Descripcion");
descripcion.setWidth("1000px");
descripcion.setHeight("250px");
// Listener para manejar el evento de subida exitosa de archivos
uploadFile.addSucceededListener(event -> {
String fileName = event.getFileName();
InputStream inputStream = buffer.getInputStream(fileName);
if (fileName != null && inputStream != null) {
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] bufferArray = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(bufferArray)) != -1) {
outputStream.write(bufferArray, 0, bytesRead);
}
byte[] fileContent = outputStream.toByteArray();
} catch (IOException e) {
Notification.show("Error al leer el archivo: " + e.getMessage(), 3000, Notification.Position.MIDDLE);
logger.error("Error al leer el archivo: " + e.getMessage());
} finally {
try {
inputStream.close();
} catch (IOException e) {
Notification.show("Error al cerrar el InputStream: " + e.getMessage())
.addThemeVariants(NotificationVariant.LUMO_ERROR);
}
}
} else {
Notification.show("Error: Nombre de archivo o contenido nulos", 3000, Notification.Position.MIDDLE);
logger.error("Error: Nombre de archivo o contenido nulos");
}
});
private TextField createTextField(String label, String width) {
TextField textField = new TextField(label);
textField.setWidth(width);
return textField;
}
private TextArea createTextArea(String label, String width, String height) {
TextArea textArea = new TextArea(label);
textArea.setWidth(width);
textArea.setHeight(height);
return textArea;
}
// Boton para crear los tickets
Button createButton = new Button("Enviar ticket", event -> {
if (user.getKey() == null || user.getKey().isEmpty()) {
Notification.show("No se encontró la API key en la sesión.", 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
private void handleFileUpload(String fileName) {
try (InputStream inputStream = buffer.getInputStream(fileName);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
// Obtener el tipo de ticket seleccionado
if (selectedTrackerId == null) {
Notification.show("Por favor seleccione un tipo de ticket.", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
byte[] bufferArray = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(bufferArray)) != -1) {
outputStream.write(bufferArray, 0, bytesRead);
}
} catch (IOException e) {
Notification.show("Error al leer el archivo: " + e.getMessage(), 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
}
}
Map<String, String> issueDetails = new HashMap<>();
issueDetails.put("project_id", "soporte-tecnico-t-i");
issueDetails.put("subject", asunto.getValue());
issueDetails.put("description", descripcion.getValue());
issueDetails.put("tracker_id", selectedTrackerId); // Añadir el tracker_id
// Process uploaded files
List<Map<String, String>> uploads = buffer.getFiles().stream()
.map(fileName -> {
Map<String, String> fileDetails = new HashMap<>();
try {
byte[] fileContent = buffer.getInputStream(fileName).readAllBytes();
String fileToken = api.uploadFile(fileContent, fileName);
fileDetails.put("token", fileToken);
fileDetails.put("filename", fileName);
fileDetails.put("content_type", buffer.getFileData(fileName).getMimeType());
} catch (IOException e) {
logger.error("Error al cargar el archivo: " + e.getMessage());
}
return fileDetails;
})
.collect(Collectors.toList());
JsonArray uploadsJsonArray = new JsonArray();
for (Map<String, String> upload : uploads) {
JsonObject uploadJson = new JsonObject();
uploadJson.addProperty("token", upload.get("token"));
uploadJson.addProperty("filename", upload.get("filename"));
uploadJson.addProperty("content_type", upload.get("content_type"));
uploadsJsonArray.add(uploadJson);
}
private void handleCreateButton(RedmineUser user, ComboBox<String> tipoTickets, TextField asunto, TextArea descripcion) {
if (user.getKey() == null || user.getKey().isEmpty()) {
Notification.show("No se encontró la API key en la sesión.", 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
return;
}
String response = api.createIssue(issueDetails, uploadsJsonArray, user.getKey());
if (selectedTrackerId == null) {
Notification.show("Por favor seleccione un tipo de ticket.", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
}
handleResponse(response, asunto, descripcion, tipoTickets);
});
if (asunto.isEmpty()) {
Notification.show("El asunto es obligatorio.", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
}
createButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
if (descripcion.isEmpty()) {
Notification.show("La descripción es obligatoria.", 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_WARNING);
return;
}
VerticalLayout fieldsLayout = new VerticalLayout(descripcion, uploadFile);
fieldsLayout.setAlignItems(Alignment.CENTER);
HorizontalLayout firstFields = new HorizontalLayout(tipoTickets, asunto);
VerticalLayout buttonLayout = new VerticalLayout(createButton);
buttonLayout.setAlignItems(Alignment.END);
buttonLayout.setMargin(true);
Map<String, String> issueDetails = new HashMap<>();
issueDetails.put("project_id", "soporte-tecnico-t-i");
issueDetails.put("subject", asunto.getValue());
issueDetails.put("description", descripcion.getValue());
issueDetails.put("tracker_id", selectedTrackerId);
JsonArray uploadsJsonArray = new JsonArray();
buffer.getFiles().forEach(fileName -> {
try (InputStream inputStream = buffer.getInputStream(fileName)) {
byte[] fileContent = inputStream.readAllBytes();
String fileToken = api.uploadFile(fileContent, fileName);
JsonObject uploadJson = new JsonObject();
uploadJson.addProperty("token", fileToken);
uploadJson.addProperty("filename", fileName);
uploadJson.addProperty("content_type", buffer.getFileData(fileName).getMimeType());
uploadsJsonArray.add(uploadJson);
} catch (IOException e) {
Notification.show("Error al cargar el archivo: " + e.getMessage(), 3000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
}
});
add(new H2("Crear nuevo ticket"), firstFields, fieldsLayout, buttonLayout);
String response = api.createIssue(issueDetails, uploadsJsonArray, user.getKey());
handleResponse(response, asunto, descripcion, tipoTickets);
}
private void handleResponse(String response, TextField asunto, TextArea descripcion, ComboBox<String> tipoTickets) {
@ -202,10 +208,9 @@ public class CrearnuevoTicketView extends VerticalLayout {
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("Error al enviar el ticket. No tiene los permisos necesarios", 5000, Notification.Position.MIDDLE)
Notification.show("Error al crear el ticket: " + response, 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
}
}
@ -214,6 +219,11 @@ public class CrearnuevoTicketView extends VerticalLayout {
asunto.clear();
descripcion.clear();
tipoTickets.clear();
asunto.setInvalid(false);
descripcion.setInvalid(false);
tipoTickets.setInvalid(false);
buffer = new MultiFileMemoryBuffer();
uploadFile.setReceiver(buffer);
uploadFile.clearFileList();


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

@ -18,13 +18,13 @@ spring.ldap.password=Dr3na%134$4guA
########PRODUCTIVO#################################
redmine.url=https://proyman.jumapacelaya.gob.mx/
redmine.api_key=9cc9e89cbbf08a6252045d56bd3d3ffec90adbad
#redmine.url=https://proyman.jumapacelaya.gob.mx/
#redmine.api_key=9cc9e89cbbf08a6252045d56bd3d3ffec90adbad
########LOCAL######################################
#redmine.url=http://localhost:3000
#redmine.api_key=9cc9e89cbbf08a6252045d56bd3d3ffec90adbad
redmine.url=http://localhost:3000
redmine.api_key=9cc9e89cbbf08a6252045d56bd3d3ffec90adbad
###CONFIGURACION DEL TAMANO MAXIMO PERMITIDO PARA ARCHIVOS###


Loading…
Cancel
Save