diff --git a/src/main/bundles/dev.bundle b/src/main/bundles/dev.bundle index be01550..25c2d3a 100644 Binary files a/src/main/bundles/dev.bundle and b/src/main/bundles/dev.bundle differ diff --git a/src/main/bundles/prod.bundle b/src/main/bundles/prod.bundle index b2e7a73..5736c40 100644 Binary files a/src/main/bundles/prod.bundle and b/src/main/bundles/prod.bundle differ diff --git a/src/main/frontend/themes/sistema-mantenimiento/styles.css b/src/main/frontend/themes/sistema-mantenimiento/styles.css index d80724a..972bbb6 100644 --- a/src/main/frontend/themes/sistema-mantenimiento/styles.css +++ b/src/main/frontend/themes/sistema-mantenimiento/styles.css @@ -10,7 +10,6 @@ /* Estilos para el encabezado */ .header-content { - background-color: #bc955b; height: 64px; display: flex; align-items: center; diff --git a/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java b/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java index 4c6a2c4..90c219a 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/DetallesMantView.java @@ -7,7 +7,6 @@ import org.springframework.security.core.Authentication; import org.springframework.cglib.core.Local; import org.springframework.security.core.context.SecurityContextHolder; import org.vaadin.lineawesome.LineAwesomeIcon; - import com.nimbusds.jose.proc.SecurityContext; import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; diff --git a/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java b/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java index deb643d..6627c72 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/MainLayout.java @@ -73,7 +73,7 @@ public class MainLayout extends AppLayout { headerLayout.getStyle().set("background-color", "#DDC9A3"); Image imgLogo = new Image("images/900X160.png", "Logo"); - imgLogo.setWidth("300px");; + imgLogo.setWidthFull(); headerLayout.add(imgLogo); @@ -104,6 +104,6 @@ public class MainLayout extends AppLayout { @Override protected void afterNavigation() { super.afterNavigation(); - viewTitle.setText("Sistema de Mantenimiento de Hardware"); + viewTitle.setText("Mantenimiento de Hardware"); } } diff --git a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java index fb631c4..9f0703d 100644 --- a/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java +++ b/src/main/java/mx/gob/jumapacelaya/ui/PlanAnualView.java @@ -18,6 +18,7 @@ import com.vaadin.flow.component.notification.Notification; 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.TextField; import com.vaadin.flow.component.upload.Upload; import com.vaadin.flow.component.upload.receivers.MemoryBuffer; @@ -59,25 +60,35 @@ public class PlanAnualView extends VerticalLayout { private byte[] fileContent; VerticalLayout gridLayout = new VerticalLayout(); HorizontalLayout uploadLayout = new HorizontalLayout(); + HorizontalLayout checkLayout = new HorizontalLayout(); public PlanAnualView() { setupHeader(); Grid planAnualGrid = setupGrid(); - // Obtenemos la lista de items y establecemos un GridListDataView para gestionar los datos + // Obtenemos la lista de items y establecemos un GridListDataView para gestionar + // los datos List planAnualItems = databaseService.getPlanAnual(); GridListDataView dataView = planAnualGrid.setItems(planAnualItems); + + // Se crea el filtro para el grid. PlanAnualFilter planAnualFilter = new PlanAnualFilter(dataView); planAnualFilter.setExcludeRealizado(true); - HeaderRow headerRow = planAnualGrid.appendHeaderRow(); headerRow.getCell(planAnualGrid.getColumnByKey("smtColumnKey")) - .setComponent(createFilterHeader("S.M.T", planAnualFilter::setSmt)); + .setComponent(createFilterHeader("S.M.T", planAnualFilter::setSmt)); + + headerRow.getCell(planAnualGrid.getColumnByKey("equipoColumnKey")) + .setComponent(createFilterHeader("Equipo", planAnualFilter::setEquipo)); + headerRow.getCell(planAnualGrid.getColumnByKey("departamentoColumnKey")) + .setComponent(createFilterHeader("Departamento", planAnualFilter::setDepartamento)); + + // Componente UPLOAD para subir archivos MemoryBuffer buffer = new MemoryBuffer(); Upload upload = new Upload(buffer); @@ -89,7 +100,7 @@ public class PlanAnualView extends VerticalLayout { try { // Almacena el contenido del archivo en un arreglo de bytes try (InputStream inputStream = buffer.getInputStream(); - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()) { inputStream.transferTo(byteArrayOutputStream); fileContent = byteArrayOutputStream.toByteArray(); @@ -117,7 +128,6 @@ public class PlanAnualView extends VerticalLayout { HorizontalLayout notificationLayout = new HorizontalLayout(errorMessage, closeButton); ntfError.add(notificationLayout); - ntfError.open(); // Abrir la notificación en pantalla // Ocultar el botón de insertar si hay errores @@ -140,21 +150,32 @@ public class PlanAnualView extends VerticalLayout { uploadLayout.add(upload, btnInsertar); toggleLayouts(dataView); - Checkbox chkMostrarTodos = new Checkbox("Mostrar todos los registros"); - chkMostrarTodos.addValueChangeListener(event -> { - planAnualFilter.setExcludeRealizado(!event.getValue()); + RadioButtonGroup radioFiltro = new RadioButtonGroup<>(); + radioFiltro.setItems("Ver realizados", "Ver pendientes"); + radioFiltro.setValue("Ver pendientes"); + + radioFiltro.addValueChangeListener(event -> { + String value = event.getValue(); + if ("Ver pendientes".equals(value)) { + planAnualFilter.setExcludeRealizado(true); + } else if ("Ver solo hechos".equals(value)) { + planAnualFilter.setExcludeRealizado(false); + } }); - chkMostrarTodos.setValue(true); + checkLayout = new HorizontalLayout(radioFiltro); + checkLayout.setWidthFull(); + checkLayout.setMargin(false); + checkLayout.setSpacing(true); + checkLayout.setJustifyContentMode(JustifyContentMode.CENTER); this.setPadding(false); this.setMargin(false); this.setSpacing(false); this.setSizeFull(); - add(header, chkMostrarTodos, gridLayout, uploadLayout); + add(header, checkLayout, gridLayout, uploadLayout); } - private void setupHeader() { VerticalLayout headerLayout = new VerticalLayout(); headerLayout.addClassName("plan-anual-header"); @@ -169,7 +190,6 @@ public class PlanAnualView extends VerticalLayout { nomenclaturaTxt.setReadOnly(true); nomenclaturaTxt.addClassName("nomenclatura-txt"); - header.setAlignSelf(Alignment.CENTER, titulo, titulo1); headerLayout.add(titulo, titulo1); add(headerLayout); @@ -177,99 +197,98 @@ public class PlanAnualView extends VerticalLayout { private Grid setupGrid() { - Grid planAnualGrid = new Grid<>(PlanAnual.class, false); - - planAnualGrid.addColumn((ValueProvider) PlanAnual::getNumero) - .setHeader("No.").setSortable(true); - - planAnualGrid.addColumn((ValueProvider) PlanAnual::getNomEquipo) - .setHeader("Equipo").setAutoWidth(true); - - planAnualGrid.addColumn((ValueProvider) PlanAnual::getDepartamento) - .setHeader("Departamento").setAutoWidth(true); - - planAnualGrid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT); - - // Iconos en columnas booleanas - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMonitor())).setHeader("Monitor"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isTeclado())).setHeader("Teclado"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMouse())).setHeader("Mouse"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isRegulador())).setHeader("Regulador"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isCpu())).setHeader("CPU"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isImpresora())).setHeader("Impresora"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMiniPrint())).setHeader("MiniPrint"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isLaptop())).setHeader("Laptop"); - planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isEscaner())).setHeader("Escáner"); - - // Fechas formateadas - planAnualGrid.addColumn(planAnual -> { - LocalDate fecha = planAnual.getFechaProgramada(); - return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : "No programada"; - }).setHeader("Fecha Programada").setAutoWidth(true).setSortable(true); - - planAnualGrid.addColumn(planAnual -> { - LocalDate fecha = planAnual.getFechaMantenimiento(); - return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : ""; - }).setHeader("Fecha Realización").setAutoWidth(true).setSortable(true); - - planAnualGrid.addColumn((ValueProvider) PlanAnual::getEstado) - .setHeader("Estado").setAutoWidth(true); - - planAnualGrid.addColumn((ValueProvider) PlanAnual::getSmt) - .setHeader("S.M.T").setKey("smtColumnKey"); - - // Botón condicional - planAnualGrid.addComponentColumn(planAnual -> { - String estado = planAnual.getEstado(); - Button btn; - - 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(); - LocalDate fechaSistema = LocalDate.now(); - String nomEquipo = planAnual.getNomEquipo(); - String departamento = planAnual.getDepartamento(); - - btn.getUI().ifPresent(ui -> ui.navigate( - "mantenimiento?id=" + idPlananual + - "&fecha=" + fechaSistema + - "&tipo=1" + - "&nomEquipo=" + nomEquipo + - "&departamento=" + departamento - )); - }); - - } 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(); - btn.getUI().ifPresent(ui -> ui.navigate( - "detalles?id=" + idPlananual - )); - }); - } else { - btn = new Button("N/A"); - btn.setEnabled(false); - } - - return btn; - }); - - // Cargar datos - planAnualGrid.setItems(databaseService.getPlanAnual()); - return planAnualGrid; -} + Grid planAnualGrid = new Grid<>(PlanAnual.class, false); + + planAnualGrid.addColumn((ValueProvider) PlanAnual::getNumero) + .setHeader("No.").setSortable(true); + + // Botón condicional + planAnualGrid.addComponentColumn(planAnual -> { + String estado = planAnual.getEstado(); + Button btn; + + 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(); + LocalDate fechaSistema = LocalDate.now(); + String nomEquipo = planAnual.getNomEquipo(); + String departamento = planAnual.getDepartamento(); + + btn.getUI().ifPresent(ui -> ui.navigate( + "mantenimiento?id=" + idPlananual + + "&fecha=" + fechaSistema + + "&tipo=1" + + "&nomEquipo=" + nomEquipo + + "&departamento=" + departamento)); + }); + + } 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(); + btn.getUI().ifPresent(ui -> ui.navigate( + "detalles?id=" + idPlananual)); + }); + } else { + btn = new Button("N/A"); + btn.setEnabled(false); + } + return btn; + }); + planAnualGrid.addColumn((ValueProvider) PlanAnual::getNomEquipo) + .setHeader("Equipo").setAutoWidth(true).setKey("equipoColumnKey"); + + planAnualGrid.addColumn((ValueProvider) PlanAnual::getDepartamento) + .setHeader("Departamento").setAutoWidth(true).setKey("departamentoColumnKey"); + + planAnualGrid.addThemeVariants(GridVariant.LUMO_WRAP_CELL_CONTENT); + + // Fechas formateadas + planAnualGrid.addColumn(planAnual -> { + LocalDate fecha = planAnual.getFechaProgramada(); + return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : "No programada"; + }).setHeader("Fecha Programada").setAutoWidth(true).setSortable(true); + + planAnualGrid.addColumn(planAnual -> { + LocalDate fecha = planAnual.getFechaMantenimiento(); + return fecha != null ? fecha.format(DateTimeFormatter.ofPattern("dd/MM/yyyy")) : ""; + }).setHeader("Fecha Realización").setAutoWidth(true).setSortable(true); + + planAnualGrid.addColumn((ValueProvider) PlanAnual::getEstado) + .setHeader("Estado").setAutoWidth(true); + + planAnualGrid.addColumn((ValueProvider) PlanAnual::getSmt) + .setHeader("S.M.T").setKey("smtColumnKey"); + + // Iconos en columnas booleanas + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMonitor())).setHeader("Monitor"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isTeclado())).setHeader("Teclado"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMouse())).setHeader("Mouse"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isRegulador())).setHeader("Regulador"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isCpu())).setHeader("CPU"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isImpresora())).setHeader("Impresora"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isMiniPrint())).setHeader("MiniPrint"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isLaptop())).setHeader("Laptop"); + planAnualGrid.addComponentColumn(planAnual -> getIcon(planAnual.isEscaner())).setHeader("Escáner"); + + // Cargar datos + planAnualGrid.setItems(databaseService.getPlanAnual()); + return planAnualGrid; + } - /* (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * SUSTITUIR VALORES BOOLEANOS POR UN ICONO (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * */ + /* + * (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * SUSTITUIR VALORES BOOLEANOS POR UN ICONO (∩ ͡° ͜ʖ + * ͡°)⊃━☆゚. * + */ private Icon getIcon(boolean value) { if (value) { return new Icon(VaadinIcon.CHECK_CIRCLE); @@ -278,8 +297,10 @@ public class PlanAnualView extends VerticalLayout { } } - - /* (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * METODO PARA VALIDAR QUE EL ARCHIOVO TENGA LA ESTRUCTURA CORRECTA (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * */ + /* + * (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * METODO PARA VALIDAR QUE EL ARCHIOVO TENGA LA ESTRUCTURA + * CORRECTA (∩ ͡° ͜ʖ ͡°)⊃━☆゚. * + */ private List validarExcel(InputStream inputStream) throws IOException { List errores = new ArrayList<>(); Workbook workbook = WorkbookFactory.create(inputStream); @@ -329,9 +350,8 @@ public class PlanAnualView extends VerticalLayout { return errores; } - - - // Valida que haya un archivo cargado en el UPLOAD y si si, llama al metodo para insertar el archivo en la base de datos + // Valida que haya un archivo cargado en el UPLOAD y si si, llama al metodo para + // insertar el archivo en la base de datos private void insertarDatos() { if (fileContent == null) { Notification.show("Error: No hay archivo cargado.").addThemeVariants(NotificationVariant.LUMO_ERROR); @@ -348,8 +368,6 @@ public class PlanAnualView extends VerticalLayout { } } - - private static Component createFilterHeader(String labelText, Consumer filterChangeConsumer) { TextField textField = new TextField(); textField.setPlaceholder("Buscar..."); @@ -364,10 +382,11 @@ public class PlanAnualView extends VerticalLayout { return layout; } - private static class PlanAnualFilter { - private final GridListDataView dataView; + private final GridListDataView dataView; private String smt; + private String equipo; + private String departamento; private boolean excludeRealizado = true; public PlanAnualFilter(GridListDataView dataView) { @@ -380,6 +399,16 @@ public class PlanAnualView extends VerticalLayout { this.dataView.refreshAll(); } + public void setEquipo(String equipo) { + this.equipo = equipo; + this.dataView.refreshAll(); + } + + public void setDepartamento(String departamento) { + this.departamento = departamento; + this.dataView.refreshAll(); + } + public void setExcludeRealizado(boolean excludeRealizado) { this.excludeRealizado = excludeRealizado; this.dataView.refreshAll(); @@ -391,23 +420,28 @@ public class PlanAnualView extends VerticalLayout { } boolean matchesSmt = matches(planAnual.getSmt(), smt); - boolean isNoRealizado = !excludeRealizado || - (planAnual.getEstado() != null && - !"REALIZADO".equalsIgnoreCase(planAnual.getEstado())); - - return matchesSmt && isNoRealizado; + boolean matchesEquipo = matches(planAnual.getNomEquipo(), equipo); + boolean matchesDepartamento = matches(planAnual.getDepartamento(), departamento); + + if (excludeRealizado) { + // Mostrar solo los pendientes + return matchesSmt && matchesEquipo && matchesDepartamento + && (planAnual.getEstado() == null || !"REALIZADO".equalsIgnoreCase(planAnual.getEstado())); + } else { + // Mostrar solo realizados + return matchesSmt && matchesEquipo && matchesDepartamento + && "REALIZADO".equalsIgnoreCase(planAnual.getEstado()); + } } - private boolean matches(String value, String searchTerm) { return searchTerm == null || searchTerm.isEmpty() || value.toLowerCase().contains(searchTerm.toLowerCase()); } } - - - //Aqui validamos que haya registros en el plan anual y si no hay muestra el upload para cargar un nuevo plan anual + // Aqui validamos que haya registros en el plan anual y si no hay muestra el + // upload para cargar un nuevo plan anual private void toggleLayouts(GridListDataView dataView) { boolean hasItems = dataView.getItemCount() > 0;