colorRenderer() {
+ return new ComponentRenderer<>(opt -> {
+ Div wrapper = new Div();
+ wrapper.getStyle().set("display","flex").set("align-items","center");
+
+ Div dot = new Div();
+ dot.getStyle()
+ .set("width","14px")
+ .set("height","14px")
+ .set("border-radius","50%")
+ .set("margin-right","8px")
+ .set("background-color", opt.getHexValue())
+ .set("border","1px solid var(--lumo-border-color)");
+
+ wrapper.add(dot);
+ wrapper.add(opt.getName());
+ return wrapper;
+ });
+ }
+
+ /* -------------------- MODEL -------------------- */
+
+ public static class ColorOptions {
+ private final String name;
+ private final String hexValue;
+
+ public ColorOptions(String name, String hexValue) {
+ this.name = name;
+ this.hexValue = hexValue;
+ }
+
+ public String getName() { return name; }
+ public String getHexValue() { return hexValue; }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+ }
+}
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java b/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java
index a06ec7f..b0b7205 100644
--- a/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java
+++ b/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java
@@ -9,11 +9,15 @@ import java.util.List;
import java.util.Map;
import com.vaadin.flow.component.UI;
+import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.html.*;
+import com.vaadin.flow.component.page.History;
import com.vaadin.flow.server.StreamRegistration;
import com.vaadin.flow.server.StreamResource;
import mx.gob.jumapacelaya.services.EmailService;
import mx.gob.jumapacelaya.services.ReportService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -53,6 +57,8 @@ import mx.gob.jumapacelaya.services.SecurityService;
@CssImport("./themes/sistema-mantenimiento/styles.css")
public class DetallesMantView extends VerticalLayout implements BeforeEnterObserver {
+ private static final Logger logger = LoggerFactory.getLogger(DetallesMantView.class);
+
@Value("${app.base-url}")
private String baseUrl;
@@ -75,6 +81,7 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser
private final Button btnCancelar;
private final Button btnGuardar;
private final Button btnEnviarEncuesta = new Button("Enviar encuesta", LineAwesomeIcon.ENVELOPE_SOLID.create());
+ private final Button btnVolverAtras = new Button(LineAwesomeIcon.ARROW_LEFT_SOLID.create());
private int planAnualIdActual;
private int mantenimientoIdActual;
private Dialog confirmDialog;
@@ -102,7 +109,6 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser
mainLayout.getStyle()
.set("box-shadow","0 4px 8px rgba(0,0,0,0.2)")
.set("border-radius", "12px")
- .set("background-color", "white")
.set("padding", "1rem")
.set("margin", "1rem auto");
@@ -197,9 +203,14 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser
gridActualizaciones.addThemeVariants(GridVariant.LUMO_ROW_STRIPES);
+ History history = UI.getCurrent().getPage().getHistory();
+ btnVolverAtras.addClickListener(e -> history.back());
+ btnVolverAtras.addThemeVariants(ButtonVariant.LUMO_TERTIARY_INLINE);
+ btnVolverAtras.setTooltipText("Volver a la lista de mantenimientos");
+
HorizontalLayout botonesHeaderLyt = new HorizontalLayout();
botonesHeaderLyt.setWidthFull();
- botonesHeaderLyt.add(btnImprimirRepo, btnEnviarEncuesta);
+ botonesHeaderLyt.add(btnVolverAtras, btnImprimirRepo, btnEnviarEncuesta);
HorizontalLayout botonesLayout = new HorizontalLayout();
botonesLayout.setWidthFull();
@@ -297,7 +308,7 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser
} catch (Exception ex) {
Notification.show("Error al generar el reporte: " + ex.getMessage(), 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
- ex.printStackTrace();
+ logger.error("Error al generar el reporte: ", ex);
}
});
@@ -542,7 +553,7 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser
String imagePath = "META-INF/resources/images/imgCorreo/imgEncuesta.png";
emailService.enviarCorreo(destinatario,asunto,cuerpo,imagePath);
- Notification.show("Encuesta enviada correctamente para el mantenimiento No. " + mantenimientoIdActual, 3000, Notification.Position.MIDDLE)
+ Notification.show("Encuesta enviada correctamente para el mantenimiento No. " + mantenimientoIdActual, 3000, Notification.Position.BOTTOM_END)
.addThemeVariants(NotificationVariant.LUMO_SUCCESS);
} else {
Notification.show("Por favor, seleccione un usuario destino", 3000, Notification.Position.MIDDLE);
@@ -580,7 +591,7 @@ public class DetallesMantView extends VerticalLayout implements BeforeEnterObser
layout.setAlignItems(Alignment.CENTER);
avisoEncuestaNtf = new Notification(layout);
- avisoEncuestaNtf.setPosition(Notification.Position.TOP_CENTER);
+ avisoEncuestaNtf.setPosition(Notification.Position.TOP_END);
avisoEncuestaNtf.addThemeVariants(NotificationVariant.LUMO_WARNING);
avisoEncuestaNtf.setDuration(5000);
avisoEncuestaNtf.open();
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/EncuestaView.java b/src/main/java/mx/gob/jumapacelaya/ui/EncuestaView.java
index 5ab657b..ae19ecd 100644
--- a/src/main/java/mx/gob/jumapacelaya/ui/EncuestaView.java
+++ b/src/main/java/mx/gob/jumapacelaya/ui/EncuestaView.java
@@ -10,6 +10,7 @@ import com.vaadin.flow.component.notification.NotificationVariant;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
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.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
@@ -32,11 +33,10 @@ public class EncuestaView extends VerticalLayout implements BeforeEnterObserver
private final DatabaseService encuestasDBService;
private int mantenimientoId = -1;
private final VerticalLayout mainLyt = new VerticalLayout();
- private final Span pregunta1Txt = new Span();
- private final RadioButtonGroup
pregunta1Rb = new RadioButtonGroup<>();
private final Button btnEnviar = new Button("Enviar");
private final TextField txtNumEmpl = new TextField("No. Empleado:");
private String token;
+ private final TextArea txtComentarios = new TextArea("Comentarios:");
private static class RespuestaComponente {
@@ -56,7 +56,6 @@ public class EncuestaView extends VerticalLayout implements BeforeEnterObserver
setSpacing(true);
setPadding(true);
- setSizeFull();
this.getStyle()
.set("background-image", "url('/images/LOGO_1024X768.jpg')")
@@ -65,9 +64,11 @@ public class EncuestaView extends VerticalLayout implements BeforeEnterObserver
.set("background-position", "center");
- mainLyt.setHeightFull();
+
mainLyt.setWidth("55%");
+ //mainLyt.setMaxHeight("90vh");
mainLyt.getStyle()
+ .set("overflow-y", "auto")
.set("box-shadow", "0 4px 8px rgba(0,0,0,0.2)")
.set("border-radius", "12px")
.set("background-color", "white")
@@ -119,6 +120,10 @@ public class EncuestaView extends VerticalLayout implements BeforeEnterObserver
respuestasUI.add(new RespuestaComponente(p,radios));
}
+ txtComentarios.setWidthFull();
+ txtComentarios.setMaxHeight("5rem");
+ preguntasLyt.add(txtComentarios);
+
HorizontalLayout gracias = new HorizontalLayout(new H3("¡Gracias!"));
gracias.setWidthFull();
gracias.setJustifyContentMode(JustifyContentMode.CENTER);
@@ -133,7 +138,7 @@ public class EncuestaView extends VerticalLayout implements BeforeEnterObserver
mainLyt.removeAll();
- mainLyt.add(titulos,preguntasLyt,gracias, btnEnviarLyt);
+ mainLyt.add(titulos,preguntasLyt ,gracias, btnEnviarLyt);
}
private void procesarRespuestas() {
@@ -155,11 +160,15 @@ public class EncuestaView extends VerticalLayout implements BeforeEnterObserver
rc.radios.getValue().equals("Si")
));
}
+ txtComentarios.getValue();
+ String comentarios = txtComentarios.isEmpty() ? null : txtComentarios.getValue();
+
encuestasDBService.insertRespuestas(
mantenimientoId,
respuestas,
empleadoId,
+ comentarios,
this.token
);
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java b/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java
index 08d4c1a..b6eb979 100644
--- a/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java
+++ b/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java
@@ -1,5 +1,6 @@
package mx.gob.jumapacelaya.ui;
+import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.applayout.AppLayout;
import com.vaadin.flow.component.applayout.DrawerToggle;
import com.vaadin.flow.component.button.Button;
@@ -13,12 +14,15 @@ import com.vaadin.flow.component.orderedlayout.Scroller;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.sidenav.SideNav;
import com.vaadin.flow.component.sidenav.SideNavItem;
+import com.vaadin.flow.router.BeforeEnterEvent;
+import com.vaadin.flow.router.BeforeEnterObserver;
+import com.vaadin.flow.server.menu.MenuConfiguration;
import com.vaadin.flow.theme.lumo.LumoUtility;
import mx.gob.jumapacelaya.services.SecurityService;
@CssImport("./themes/sistema-mantenimiento/styles.css")
-public class MainLayout extends AppLayout {
+public class MainLayout extends AppLayout implements BeforeEnterObserver {
private H2 viewTitle;
private final SecurityService securityService;
@@ -45,7 +49,7 @@ public class MainLayout extends AppLayout {
String u = securityService.getAuthenticatedUser();
Span usrNameLabel = new Span(u);
- usrNameLabel.getStyle().set("color", "#691b31");
+ //usrNameLabel.getStyle().set("color", "#691b31");
usrNameLabel.getStyle().set("font-weight", "bold");
usrNameLabel.getStyle().set("font-size", "20px");
@@ -70,7 +74,7 @@ public class MainLayout extends AppLayout {
headerLayout.setPadding(true);
headerLayout.setSpacing(false);
headerLayout.setAlignItems(FlexComponent.Alignment.CENTER);
- headerLayout.getStyle().set("background-color", "#DDC9A3");
+ //headerLayout.getStyle().set("background-color", "#DDC9A3");
Image imgLogo = new Image("images/LOGO_900X160.png", "Logo");
imgLogo.setWidthFull();
@@ -78,7 +82,7 @@ public class MainLayout extends AppLayout {
headerLayout.add(imgLogo);
Scroller scroller = new Scroller(createNavigation());
- scroller.getStyle().set("background-color", "#691b31");
+ //scroller.getStyle().set("background-color", "#691b31");
addToDrawer(headerLayout, scroller, createFooter());
}
@@ -89,9 +93,10 @@ public class MainLayout extends AppLayout {
nav.addItem(new SideNavItem("Plan Anual", PlanAnualView.class, VaadinIcon.CALENDAR.create()));
nav.addItem(new SideNavItem("Listado de Actividades", ActDiariaView.class, VaadinIcon.EDIT.create()));
nav.addItem(new SideNavItem("Mantenimiento Correctivo", MantCorrectivoView.class, VaadinIcon.WRENCH.create()));
- nav.getStyle().set("background-color", "white");
+ nav.addItem(new SideNavItem("Resultados de Encuestas", ResultEncuestasView.class, VaadinIcon.CLIPBOARD_TEXT.create()));
+ nav.addItem(new SideNavItem("Preferencias del Sistema", ConfiguracionView.class, VaadinIcon.COG.create()));
+
nav.getStyle().set("border-radius", "5px");
- nav.getStyle().set("opacity", "0.9");
return nav;
}
@@ -101,9 +106,25 @@ public class MainLayout extends AppLayout {
return layout;
}
+ private String getCurrentPageTitle() {
+ return MenuConfiguration.getPageHeader(getContent()).orElse("");
+ }
+
@Override
protected void afterNavigation() {
super.afterNavigation();
- viewTitle.setText("Mantenimiento de Hardware");
+ viewTitle.setText(getCurrentPageTitle());
+ }
+
+ @Override
+ public void beforeEnter(BeforeEnterEvent beforeEnterEvent) {
+ UI.getCurrent().getPage().executeJs("""
+ const theme = localStorage.getItem('appThemePreference');
+ if (theme === 'dark') {
+ document.documentElement.setAttribute('theme', 'dark');
+ } else {
+ document.documentElement.removeAttribute('theme');
+ }
+ """);
}
}
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/MantCorrectivoView.java b/src/main/java/mx/gob/jumapacelaya/ui/MantCorrectivoView.java
index 7763a5a..6d4c087 100644
--- a/src/main/java/mx/gob/jumapacelaya/ui/MantCorrectivoView.java
+++ b/src/main/java/mx/gob/jumapacelaya/ui/MantCorrectivoView.java
@@ -1,6 +1,5 @@
package mx.gob.jumapacelaya.ui;
-import com.vaadin.flow.component.Text;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
@@ -24,9 +23,6 @@ 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.data.renderer.ComponentRenderer;
-import com.vaadin.flow.function.ValueProvider;
-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 de.f0rce.signaturepad.SignaturePad;
@@ -36,6 +32,8 @@ import mx.gob.jumapacelaya.services.DatabaseService;
import mx.gob.jumapacelaya.services.EmailService;
import mx.gob.jumapacelaya.services.SecurityService;
import mx.gob.jumapacelaya.services.UserService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.vaadin.lineawesome.LineAwesomeIcon;
import java.time.LocalDate;
@@ -48,6 +46,8 @@ import java.util.*;
@CssImport("./themes/sistema-mantenimiento/styles.css")
public class MantCorrectivoView extends VerticalLayout {
+ private static final Logger logger = LoggerFactory.getLogger(MantCorrectivoView.class);
+
private VerticalLayout mainLayout;
private final SecurityService securityService;
private final VerticalLayout controlsLayout;
@@ -96,7 +96,6 @@ public class MantCorrectivoView extends VerticalLayout {
headerLayout.getStyle()
.set("box-shadow", "0 4px 8px rgba(0,0,0,0.2)")
.set("border-radius", "10px")
- .set("background-color", "white")
.set("padding", "1rem")
.set("margin", "1rem auto");
@@ -107,7 +106,6 @@ public class MantCorrectivoView extends VerticalLayout {
mainLayout.getStyle()
.set("box-shadow", "0 4px 8px rgba(0,0,0,0.2)")
.set("border-radius", "12px")
- .set("background-color", "white")
.set("padding", "1rem")
.set("margin", "1rem auto");
@@ -594,7 +592,7 @@ public class MantCorrectivoView extends VerticalLayout {
} catch (Exception e) {
Notification.show("Error al enviar el correo", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
- e.printStackTrace();
+ logger.error("Error al enviar correo: ", e);
}
// Limpiar campos
@@ -624,7 +622,7 @@ public class MantCorrectivoView extends VerticalLayout {
} catch (Exception ex) {
Notification.show("Ocurrio un error inesperado: " + ex.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
- ex.printStackTrace();
+ logger.error("Error al insertar mantenimiento: ", ex);
}
}
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java b/src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java
index 32c49a6..a11916b 100644
--- a/src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java
+++ b/src/main/java/mx/gob/jumapacelaya/ui/MantenimientoView.java
@@ -1,29 +1,24 @@
package mx.gob.jumapacelaya.ui;
-import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.UI;
+import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
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.dialog.Dialog;
-import com.vaadin.flow.component.html.H1;
-import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.html.Image;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.icon.VaadinIcon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.notification.NotificationVariant;
-import com.vaadin.flow.component.orderedlayout.FlexComponent;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.radiobutton.RadioButtonGroup;
-import com.vaadin.flow.component.textfield.NumberField;
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;
@@ -35,9 +30,8 @@ import mx.gob.jumapacelaya.services.DatabaseService;
import mx.gob.jumapacelaya.services.EmailService;
import mx.gob.jumapacelaya.services.SecurityService;
import mx.gob.jumapacelaya.services.UserService;
-import oracle.net.aso.h;
-
-import org.springframework.beans.factory.annotation.Autowired;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.vaadin.lineawesome.LineAwesomeIcon;
import java.time.LocalDate;
@@ -50,6 +44,8 @@ import java.util.*;
@CssImport("./themes/sistema-mantenimiento/styles.css")
public class MantenimientoView extends VerticalLayout implements BeforeEnterObserver {
+ private static final Logger logger = LoggerFactory.getLogger(MantenimientoView.class);
+
private final SecurityService securityService;
private final VerticalLayout controlsLayout;
private final DatabaseService databaseService;
@@ -98,7 +94,6 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
mainLayout.getStyle()
.set("box-shadow","0 4px 8px rgba(0,0,0,0.2)")
.set("border-radius", "12px")
- .set("background-color", "white")
.set("padding", "1rem")
.set("margin", "1rem auto");
@@ -718,7 +713,7 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
} catch (Exception e) {
Notification.show("Error al enviar el correo", 4000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
- e.printStackTrace();
+ logger.error("Error al enviar el correo", e);
}
// Limpiar campos
@@ -748,7 +743,7 @@ public class MantenimientoView extends VerticalLayout implements BeforeEnterObse
} catch (Exception ex) {
Notification.show("Ocurrio un error inesperado: " + ex.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
- ex.printStackTrace();
+ logger.error("Error al insertar mantenimiento", ex);
}
}
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java
index 752039d..0667bec 100644
--- a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java
+++ b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java
@@ -4,15 +4,12 @@ import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
-import com.vaadin.flow.component.checkbox.Checkbox;
import com.vaadin.flow.component.checkbox.CheckboxGroup;
import com.vaadin.flow.component.checkbox.CheckboxGroupVariant;
import com.vaadin.flow.component.combobox.ComboBox;
-import com.vaadin.flow.component.confirmdialog.ConfirmDialog;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.CssImport;
import com.vaadin.flow.component.dialog.Dialog;
-import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.grid.HeaderRow;
@@ -28,12 +25,11 @@ import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.popover.Popover;
import com.vaadin.flow.component.popover.PopoverPosition;
-import com.vaadin.flow.component.radiobutton.RadioButtonGroup;
import com.vaadin.flow.component.textfield.NumberField;
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.data.provider.ListDataProvider;
+import com.vaadin.flow.data.renderer.ComponentRenderer;
import com.vaadin.flow.data.value.ValueChangeMode;
import com.vaadin.flow.function.ValueProvider;
import com.vaadin.flow.router.PageTitle;
@@ -42,20 +38,24 @@ import com.vaadin.flow.server.StreamRegistration;
import com.vaadin.flow.server.StreamResource;
import jakarta.annotation.security.PermitAll;
import mx.gob.jumapacelaya.models.PlanAnual;
+import mx.gob.jumapacelaya.models.encuestas.MantenimientosSinEncuesta;
import mx.gob.jumapacelaya.services.DatabaseService;
+import mx.gob.jumapacelaya.services.EmailService;
import mx.gob.jumapacelaya.services.ReportService;
-import net.sf.jasperreports.engine.JasperFillManager;
-import net.sf.jasperreports.engine.JasperPrint;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.vaadin.lineawesome.LineAwesomeIcon;
-import java.io.*;
-import java.lang.reflect.Array;
-import java.sql.Date;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.time.LocalDate;
import java.time.Year;
import java.time.format.DateTimeFormatter;
@@ -70,6 +70,11 @@ import java.util.stream.IntStream;
@CssImport("./themes/sistema-mantenimiento/styles.css")
public class PlanAnualView extends VerticalLayout {
+ private static final Logger logger = LoggerFactory.getLogger(PlanAnualView.class);
+
+ private final EmailService emailService;
+ @Value("${app.base-url}")
+ private String baseUrl;
private final Environment env;
private final ReportService reportService;
@@ -90,7 +95,7 @@ public class PlanAnualView extends VerticalLayout {
private Popover reportePopover;
ComboBox yearFilter;
- public PlanAnualView(DatabaseService databaseService, Environment env, ReportService reportService) {
+ public PlanAnualView(DatabaseService databaseService, Environment env, ReportService reportService, EmailService emailService) {
this.databaseService = databaseService;
this.env = env;
this.reportService = reportService;
@@ -113,9 +118,14 @@ public class PlanAnualView extends VerticalLayout {
PlanAnualFilter planAnualFilter = new PlanAnualFilter(dataView);
planAnualFilter.setExcludeRealizado(true);
- yearFilter.addValueChangeListener(event ->
- planAnualFilter.setYear(event.getValue())
- );
+ // Aplicar el valor actual del ComboBox al filtro al inicializar
+ if (yearFilter != null && yearFilter.getValue() != null) {
+ planAnualFilter.setYear(yearFilter.getValue());
+ }
+
+ if (yearFilter != null) {
+ yearFilter.addValueChangeListener(event -> planAnualFilter.setYear(event.getValue()));
+ }
HeaderRow headerRow = planAnualGrid.appendHeaderRow();
/*headerRow.getCell(planAnualGrid.getColumnByKey("smtColumnKey"))
@@ -130,6 +140,9 @@ public class PlanAnualView extends VerticalLayout {
headerRow.getCell(planAnualGrid.getColumnByKey("mesplaneado"))
.setComponent(createFilterHeader("Mes Planeado", planAnualFilter::setMesPlaneado));
+ headerRow.getCell(planAnualGrid.getColumnByKey("encuesta"))
+ .setComponent(createFilterHeader("Encuesta", planAnualFilter::setEncuesta));
+
// MENU CONTEXTUAL DEL GRID
@@ -228,6 +241,7 @@ public class PlanAnualView extends VerticalLayout {
this.setSizeFull();
add(filtrosLayout, uploadLayout);
add(gridLayout);
+ this.emailService = emailService;
}
private void setupHeader() {
@@ -264,7 +278,6 @@ public class PlanAnualView extends VerticalLayout {
if ("PENDIENTE".equalsIgnoreCase(estado)) {
btn = new Button(new Icon(VaadinIcon.EDIT));
btn.setTooltipText("Realizar mantenimiento");
- btn.getStyle().set("color", "#A02142");
btn.addClickListener(event -> {
int idPlananual = planAnual.getNumero();
@@ -286,7 +299,6 @@ public class PlanAnualView extends VerticalLayout {
} else if ("REALIZADO".equalsIgnoreCase(estado)) {
btn = new Button(new Icon(VaadinIcon.EYE));
btn.setTooltipText("Ver detalles");
- btn.getStyle().set("color", "#A02142");
btn.addClickListener(event -> {
int idPlananual = planAnual.getNumero();
@@ -369,14 +381,8 @@ public class PlanAnualView extends VerticalLayout {
btnAddEquipo.setTooltipText("Agregar nuevo equipo");
btnEnviarEncuestas = new Button(VaadinIcon.ENVELOPE.create());
- ConfirmDialog enviarEncConfirm = new ConfirmDialog();
- enviarEncConfirm.setHeader("Enviar encuestas");
- enviarEncConfirm.setText("¿Deseas enviar las encuestas de satisfacción?, Esto enviara la encuesta solo a los mantenimientos realizados");
- enviarEncConfirm.setCancelable(true);
- enviarEncConfirm.addCancelListener(e -> enviarEncConfirm.close());
- enviarEncConfirm.setConfirmText("Enviar");
- enviarEncConfirm.addConfirmListener(e -> {});
- btnEnviarEncuestas.addClickListener(e -> enviarEncConfirm.open());
+ btnEnviarEncuestas.addClickListener(e -> showParametrosDialog());
+ btnEnviarEncuestas.setTooltipText("Enviar encuestas masivamente");
yearFilter = new ComboBox<>();
int currentYear = Year.now().getValue();
@@ -384,12 +390,14 @@ public class PlanAnualView extends VerticalLayout {
.boxed().collect(Collectors.toList());
yearFilter.setItems(years);
yearFilter.setPlaceholder("Año");
+ yearFilter.setValue(currentYear);
yearFilter.setClearButtonVisible(true);
+
List todosLosPlanes = databaseService.getPlanAnual();
- btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt, btnAddEquipo/*, btnEnviarEncuestas*/, yearFilter);
+ btnImprimirLayout = new HorizontalLayout(btnColumns, btnImprimirRpt, btnAddEquipo, btnEnviarEncuestas, yearFilter);
btnImprimirLayout.setAlignItems(Alignment.BASELINE);
HorizontalLayout columnSelectorLayout = new HorizontalLayout();
columnSelectorLayout.setAlignItems(Alignment.END);
@@ -541,6 +549,11 @@ public class PlanAnualView extends VerticalLayout {
private String equipo;
private String departamento;
private String mesPlaneado;
+ private LocalDate fechaProgramada;
+ private LocalDate fechaRealizacion;
+ private String encuesta;
+ private String estado;
+ private String situacion;
private Integer year;
private boolean excludeRealizado = true;
@@ -569,6 +582,11 @@ public class PlanAnualView extends VerticalLayout {
this.dataView.refreshAll();
}
+ public void setEncuesta(String encuesta) {
+ this.encuesta = encuesta;
+ this.dataView.refreshAll();
+ }
+
public void setYear(Integer year) {
this.year = year;
dataView.refreshAll();
@@ -586,6 +604,7 @@ public class PlanAnualView extends VerticalLayout {
boolean matchesEquipo = matches(planAnual.getNomEquipo(), equipo);
boolean matchesDepartamento = matches(planAnual.getDepartamento(), departamento);
boolean matchesMesPlaneado = matches(planAnual.getMesplaneado(), mesPlaneado);
+ boolean matchesEncuesta = matches(planAnual.getEncuesta(), encuesta);
boolean matchesYear = true;
if (year != null) {
@@ -608,7 +627,8 @@ public class PlanAnualView extends VerticalLayout {
&& matchesDepartamento
&& matchesMesPlaneado
&& matchesYear
- && matchesEstado;
+ && matchesEstado
+ && matchesEncuesta;
}
private boolean matches(String value, String serachTerm) {
@@ -689,7 +709,7 @@ public class PlanAnualView extends VerticalLayout {
} catch (Exception ex) {
Notification.show("Error al genrar el reporte: " + ex.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
- ex.printStackTrace();
+ logger.error("Error al generar el reporte", ex);
}
});
@@ -903,7 +923,7 @@ public class PlanAnualView extends VerticalLayout {
} catch (Exception ex) {
Notification.show("Error al generar el reporte: " + ex.getMessage(), 5000, Notification.Position.MIDDLE)
.addThemeVariants(NotificationVariant.LUMO_ERROR);
- ex.printStackTrace();
+ logger.error("Error al generar el reporte", ex);
}
});
@@ -1005,4 +1025,170 @@ public class PlanAnualView extends VerticalLayout {
dialog.getFooter().add(dialogFooter);
dialog.open();
}
+
+
+
+ private void showParametrosDialog() {
+ Dialog dialog = new Dialog();
+ dialog.setHeaderTitle("Ingresar periodo");
+
+ TextField txtMes = new TextField("Mes:");
+ txtMes.setPlaceholder("ENERO, FEBRERO, MARZO...");
+ txtMes.setClearButtonVisible(true);
+
+ TextField txtAnio = new TextField("Año");
+ txtAnio.setPlaceholder("Ej. 2025");
+
+ Button btnBuscar = new Button("Buscar", VaadinIcon.SEARCH.create(), e -> {
+ String mes = txtMes.getValue();
+ String anioTexto = txtAnio.getValue();
+
+ if (mes.isEmpty() || anioTexto.isEmpty()) {
+ Notification.show("Mes y año son requeridos.", 3000, Notification.Position.MIDDLE);
+ return;
+ }
+
+ int anio;
+ try {
+ anio = Integer.parseInt(anioTexto);
+ } catch (NumberFormatException ex) {
+ Notification.show("El año debe ser numérico.", 3000, Notification.Position.MIDDLE);
+ return;
+ }
+
+ dialog.close();
+ showEncuestasDialog(mes, anio);
+ });
+ btnBuscar.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
+
+ Button btnCancelar = new Button("Cancelar", VaadinIcon.CLOSE_CIRCLE.create(), e -> dialog.close());
+
+ HorizontalLayout actions = new HorizontalLayout(btnBuscar, btnCancelar);
+
+ VerticalLayout layout = new VerticalLayout(txtMes, txtAnio, actions);
+ layout.setPadding(false);
+ layout.setSpacing(true);
+
+ dialog.add(layout);
+ dialog.open();
+ }
+
+ private void showEncuestasDialog(String mes, int anio) {
+ Dialog dialog = new Dialog();
+ dialog.setWidth("95%");
+ dialog.setHeight("90%");
+ dialog.setHeaderTitle("Encuestas pendientes por enviar...");
+
+ Grid grid = new Grid<>(MantenimientosSinEncuesta.class, false);
+ grid.addColumn(MantenimientosSinEncuesta::getMantenimientoId)
+ .setHeader("ID")
+ .setAutoWidth(true);
+
+ grid.addColumn(item -> item.getFecha().format(DateTimeFormatter.ofPattern("dd/MM/yyyy")))
+ .setHeader("Fecha")
+ .setAutoWidth(true);
+
+ grid.addColumn(MantenimientosSinEncuesta::getPeriodo)
+ .setHeader("Periodo")
+ .setAutoWidth(true);
+
+ grid.addColumn(createStatusRender())
+ .setHeader("Encuesta");
+
+ grid.addColumn(MantenimientosSinEncuesta::getDepartamento)
+ .setHeader("Departamento");
+
+ grid.addColumn(MantenimientosSinEncuesta::getNomUsuario)
+ .setHeader("Usuario")
+ .setAutoWidth(true);
+
+ grid.addColumn(MantenimientosSinEncuesta::getEmail)
+ .setHeader("Correo")
+ .setAutoWidth(true);
+
+ grid.addComponentColumn(item -> {
+ Button btnEnviar = new Button(
+ "Enviar",
+ LineAwesomeIcon.ENVELOPE_SOLID.create()
+ );
+ btnEnviar.addThemeVariants(ButtonVariant.LUMO_PRIMARY,
+ ButtonVariant.LUMO_SUCCESS);
+
+ btnEnviar.addClickListener(e -> {
+ enviarEncuestaDesdeGrid(item);
+ btnEnviar.setEnabled(false);
+ });
+
+ return btnEnviar;
+ }).setHeader("Accion")
+ .setFrozen(true);
+
+ List lista = databaseService.getEncuestPendientes(mes, anio);
+
+ grid.setItems(lista);
+ grid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT);
+ dialog.add(grid);
+ dialog.getFooter().add(new Button("Cerrar", LineAwesomeIcon.TIMES_SOLID.create(), e -> dialog.close()));
+
+ dialog.open();
+ }
+
+ private void enviarEncuestaDesdeGrid(MantenimientosSinEncuesta item) {
+
+ if (item.getEmail() == null || item.getEmail().isBlank()) {
+ Notification.show("El usuario no tiene correo", 3000, Notification.Position.MIDDLE)
+ .addThemeVariants(NotificationVariant.LUMO_ERROR);
+ return;
+ }
+
+ int mantenimientoId = item.getMantenimientoId();
+
+ String token = databaseService.crearTokenEncuesta(mantenimientoId);
+ String linkEncuesta = baseUrl + "/encuesta?token=" + token;
+
+ String cuerpo = """
+
+
+
+
+
+
+
+ """.formatted(linkEncuesta);
+
+ String asunto = "Encuesta de satisfacción - Mantenimiento #" + mantenimientoId;
+ String imagePath = "META-INF/resources/images/imgCorreo/imgEncuesta.png";
+
+ emailService.enviarCorreo(
+ item.getEmail(),
+ asunto,
+ cuerpo,
+ imagePath
+ );
+
+ Notification.show("Encuesta enviada correctamente", 3000, Notification.Position.MIDDLE)
+ .addThemeVariants(NotificationVariant.LUMO_SUCCESS);
+ }
+
+ private ComponentRenderer createStatusRender() {
+ return new ComponentRenderer<>(encuesta -> {
+ Span span = new Span(encuesta.getEncuesta());
+
+ switch (encuesta.getEncuesta().toUpperCase()) {
+ case "N":
+ String theme1 = String.format("badge %s", "error");
+ span.getElement().setAttribute("theme", theme1);
+ break;
+ case "S":
+ String theme2 = String.format("badge %s", "success");
+ span.getElement().setAttribute("theme", theme2);
+ break;
+ default:
+ String theme3 = String.format("badge %s", "");
+ span.getElement().setAttribute("theme", theme3);
+ }
+
+ return span;
+ });
+ }
}
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java b/src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java
new file mode 100644
index 0000000..bf8e392
--- /dev/null
+++ b/src/main/java/mx/gob/jumapacelaya/ui/ResultEncuestasView.java
@@ -0,0 +1,200 @@
+package mx.gob.jumapacelaya.ui;
+
+import com.vaadin.flow.component.button.Button;
+import com.vaadin.flow.component.button.ButtonVariant;
+import com.vaadin.flow.component.dashboard.Dashboard;
+import com.vaadin.flow.component.dashboard.DashboardSection;
+import com.vaadin.flow.component.dashboard.DashboardWidget;
+import com.vaadin.flow.component.grid.Grid;
+import com.vaadin.flow.component.html.Div;
+import com.vaadin.flow.component.html.Span;
+import com.vaadin.flow.component.icon.Icon;
+import com.vaadin.flow.component.icon.SvgIcon;
+import com.vaadin.flow.component.icon.VaadinIcon;
+import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
+import com.vaadin.flow.component.orderedlayout.VerticalLayout;
+import com.vaadin.flow.router.PageTitle;
+import com.vaadin.flow.router.Route;
+import jakarta.annotation.security.PermitAll;
+import mx.gob.jumapacelaya.models.encuestas.ConteoEncuestas;
+import mx.gob.jumapacelaya.models.encuestas.ConteoRespuestas;
+import mx.gob.jumapacelaya.services.DatabaseService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.vaadin.lineawesome.LineAwesomeIcon;
+
+import java.util.List;
+
+@PermitAll
+@PageTitle("Resultados de Encuestas")
+@Route(value = "resultados-encuestas", layout = MainLayout.class)
+public class ResultEncuestasView extends VerticalLayout {
+
+ private static final Logger logger = LoggerFactory.getLogger(ResultEncuestasView.class);
+ private final DatabaseService databaseService;
+ private DashboardWidget totalEncu;
+ private DashboardWidget totalResp;
+ private DashboardWidget porcentajeResp;
+ private DashboardWidget pregunta1;
+ private DashboardWidget pregunta2;
+ private DashboardWidget pregunta3;
+ private DashboardWidget pregunta4;
+ private DashboardWidget pregunta5;
+ private DashboardWidget pregunta6;
+
+ public ResultEncuestasView(DatabaseService databaseService) {
+ this.databaseService = databaseService;
+ createToolbar();
+ createDashboard();
+ }
+
+ public HorizontalLayout createToolbar() {
+ Button btnExport = new Button("Exportar a PDF", LineAwesomeIcon.FILE_PDF.create());
+ btnExport.addThemeVariants(ButtonVariant.LUMO_SMALL);
+
+ HorizontalLayout toolbar = new HorizontalLayout(btnExport);
+ toolbar.setAlignItems(Alignment.BASELINE);
+ toolbar.setWidthFull();
+
+ add(toolbar);
+ return toolbar;
+ }
+
+ public Dashboard createDashboard() {
+ Dashboard dashboard = new Dashboard();
+ dashboard.setMinimumColumnWidth("150px");
+ dashboard.setMaximumColumnCount(3);
+
+ // Secciónes del dashboard
+ DashboardSection generalSection = dashboard.addSection("General");
+ DashboardSection preguntasSection = dashboard.addSection("Preguntas");
+
+ // Widgets para la sección General
+ totalEncu = new DashboardWidget("Total Encuestas");
+ totalResp = new DashboardWidget("Total Respuestas");
+ porcentajeResp = new DashboardWidget("Porcentaje de Respuestas");
+
+ generalSection.add(totalEncu);
+ generalSection.add(totalResp);
+ generalSection.add(porcentajeResp);
+
+
+ // Widget para la sección Preguntas
+ pregunta1 = new DashboardWidget("Pregunta 1");
+ pregunta2 = new DashboardWidget("Pregunta 2");
+ pregunta3 = new DashboardWidget("Pregunta 3");
+ pregunta4 = new DashboardWidget("Pregunta 4");
+ pregunta5 = new DashboardWidget("Pregunta 5");
+ pregunta6 = new DashboardWidget("Pregunta 6");
+
+ preguntasSection.add(pregunta1);
+ preguntasSection.add(pregunta2);
+ preguntasSection.add(pregunta3);
+ preguntasSection.add(pregunta4);
+ preguntasSection.add(pregunta5);
+ preguntasSection.add(pregunta6);
+
+ mostrarTotales();
+ mostrarPreguntas();
+ add(dashboard);
+ return dashboard;
+ }
+
+ private Div createDiv(String valor, LineAwesomeIcon icon, String color) {
+ Div content = new Div();
+ content.setClassName("dashboard-widget-content");
+ content.getStyle()
+ .set("display", "flex")
+ .set("align-items", "center")
+ .set("justify-content", "center")
+ .set("gap", "15px");
+
+ SvgIcon vIcon = icon.create();
+ vIcon.getStyle().set("color", color);
+ vIcon.setSize("40px");
+
+ Span text = new Span(valor);
+ text.getStyle().set("font-size", "2.2rem");
+ text.getStyle().set("font-weight", "800");
+
+ content.add(vIcon, text);
+ return content;
+ }
+
+ private Div createPreguntaContent(ConteoRespuestas data) {
+ Div container = new Div();
+ container.setClassName("pregunta-widget-container");
+ container.getStyle().set("padding", "10px");
+
+ Span txtPregunta = new Span(data.getPregunta());
+ txtPregunta.getStyle().set("font-size", "0.9em")
+ .set("display", "block")
+ .set("margin-bottom", "15px")
+ .set("height", "45px")
+ .set("overflow", "hidden");
+
+ HorizontalLayout metrics = new HorizontalLayout();
+ metrics.setJustifyContentMode(JustifyContentMode.BETWEEN);
+ metrics.setWidthFull();
+
+ metrics.add(
+ createStat("Si", String.valueOf(data.getTotalSi()), "#27ae60"),
+ createStat("No", String.valueOf(data.getTotalNo()), "#e74c3c"),
+ createStat("%", String.format("%.0f", data.getPorcentaje()), "#BC955B")
+ );
+
+ container.add(txtPregunta, metrics);
+ return container;
+ }
+
+ private VerticalLayout createStat(String label, String value, String color) {
+ Span l = new Span(label);
+ l.getStyle().set("font-size", "0.7em").set("color", "gray");
+ Span v = new Span(value);
+ v.getStyle().set("font-weight", "bold").set("color", color);
+
+ VerticalLayout vl = new VerticalLayout(l,v);
+ vl.setAlignItems(Alignment.CENTER);
+ vl.setSpacing(false);
+ vl.setPadding(false);
+ return vl;
+ }
+
+ public void mostrarTotales() {
+ List datos = databaseService.getTotalEncuestas();
+
+ if (!datos.isEmpty()) {
+ ConteoEncuestas totales = datos.get(0);
+
+ totalEncu.setContent(createDiv(
+ String.valueOf(totales.getTotalEnviadas()),
+ LineAwesomeIcon.CLIPBOARD_LIST_SOLID, "#BC955B"
+ ));
+
+ totalResp.setContent(createDiv(
+ String.valueOf(totales.getTotalRespondidas()),
+ LineAwesomeIcon.CHECK_CIRCLE, "#BC955B"
+ ));
+
+ porcentajeResp.setContent(createDiv(
+ String.valueOf(totales.getPorcentajeRespondidas()),
+ LineAwesomeIcon.PERCENT_SOLID, "#BC955B"
+ ));
+ }
+ }
+
+ public void mostrarPreguntas() {
+ List lista = databaseService.getTotalRespuestas();
+
+ DashboardWidget[] widgets = {pregunta1,pregunta2,pregunta3,pregunta4,pregunta5,pregunta6};
+
+ for (int i = 0; i < lista.size() && i < widgets.length; i++) {
+ ConteoRespuestas data = lista.get(i);
+ DashboardWidget widget = widgets[i];
+
+ widget.setTitle("Pregunta #" + data.getPreguntaId());
+
+ widget.setContent(createPreguntaContent(data));
+ }
+ }
+}
diff --git a/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java b/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java
index 13bb9ad..eb705b4 100644
--- a/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java
+++ b/src/main/java/mx/gob/jumapacelaya/ui/login/LoginView.java
@@ -22,9 +22,6 @@ public class LoginView extends VerticalLayout implements BeforeEnterObserver {
private static final Logger log = LoggerFactory.getLogger(LoginView.class);
private final LoginForm login = new LoginForm();
- // Usuario local para demostracion
- private final String localUser = "admin";
- private final String localPassword = "admin";
public LoginView(){
diff --git a/src/main/resources/META-INF/resources/images/LOGO_admon2.png b/src/main/resources/META-INF/resources/images/LOGO_admon2.png
new file mode 100644
index 0000000..da7a4af
Binary files /dev/null and b/src/main/resources/META-INF/resources/images/LOGO_admon2.png differ
diff --git a/src/main/resources/META-INF/resources/images/imgCorreo/imgEncuesta.png b/src/main/resources/META-INF/resources/images/imgCorreo/imgEncuesta.png
index fffa464..2cd9046 100644
Binary files a/src/main/resources/META-INF/resources/images/imgCorreo/imgEncuesta.png and b/src/main/resources/META-INF/resources/images/imgCorreo/imgEncuesta.png differ
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index f4b9471..0e7d86a 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,6 +1,7 @@
server.port=${PORT:8080}
logging.level.org.atmosphere = warn
spring.profiles.active=dev
+server.servlet.session.cookie.secure=true
# Launch the default browser when starting the application in development mode
vaadin.launch-browser=true
@@ -12,13 +13,15 @@ spring.jpa.defer-datasource-initialization = true
#Configuracion LDAP
-spring.ldap.urls=ldap://172.1.0.1:389
+spring.ldap.urls=ldap://172.16.0.1:389
+spring.ldap.url=ldap://172.16.0.1
+spring.ldap.domain=JUMAPACELAYA.GOB.MX
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.url=https://proyman.jumapacelaya.gob.mx
redmine.api_key=69be2a5df9bacce02722f566fdf0731d728a1b86
diff --git a/tsconfig.json b/tsconfig.json
index 02dd68b..e6840ae 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,7 +10,7 @@
"jsx": "react-jsx",
"inlineSources": true,
"module": "esNext",
- "target": "es2020",
+ "target": "es2022",
"moduleResolution": "bundler",
"strict": true,
"skipLibCheck": true,