+
{reportes.length === 0 ? (
No hay reportes registrados. Crea uno nuevo.
@@ -27,7 +27,7 @@ export default function MenuReportes( {reportes, reporteAplicado, enableSectionR
settings
-
+
{reporte.nombre}
diff --git a/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx b/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx
index be3654df29be90d5aaaad689457f4a85a99f097e..66cba448402e3b6693b493fa5148cf0a68a4a38b 100644
--- a/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx
+++ b/cosiap_frontend/src/components/SolicitudesAdmin/Solicitudes.jsx
@@ -8,8 +8,10 @@ import MenuFiltros from "./MenuFiltros";
import Alert from "../common/ui/Alert";
import MenuReportes from "./MenuReportes";
import ModalConfirmation from "../common/ui/Modals/ModalConfirmation";
+import { useNavigate } from "react-router-dom";
export default function Solicitudes( {setViewPageLoader} ){
+
const [solicitudes, setSolicitudes] = useState([]);
const [columnas, setColumnas] = useState({});
const [columnasOcultas, setColumnasOcultas] = useState([]);
@@ -51,6 +53,14 @@ export default function Solicitudes( {setViewPageLoader} ){
const [sortConfig, setSortConfig] = useState({ key: null, direction: 'ascending' });
+ //Estado para lanzar el submenu de cada solicitud
+ const [selectedSolicitudId, setSelectedSolicitudId] = useState(null);
+ const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 });
+
+ //Ref para detectar clicks derechos fuera de las solicitudes
+ const solicitudRef = useRef(null);
+ const menuOpcionesRef = useRef(null);
+
function Regimen (value) {
switch (value) {
case "1":
@@ -141,6 +151,12 @@ export default function Solicitudes( {setViewPageLoader} ){
buttonMenuReportesRef.current && !buttonMenuReportesRef.current.contains(event.target)){
setViewMenuReportes(false);
}
+
+ //Declaramos nulo selectedSolicitudId si no se hace click dentro del menu de opciones o de las solicitudes
+ if (solicitudRef.current && !solicitudRef.current.contains(event.target) &&
+ menuOpcionesRef.current && !menuOpcionesRef.current.contains(event.target)){
+ setSelectedSolicitudId(null);
+ }
}
// Añade el event listener para detectar clics fuera de los elementos
@@ -342,9 +358,13 @@ export default function Solicitudes( {setViewPageLoader} ){
}
} else if (html_type === "textInput") {
if (lookups.icontains) {
- solicitudesFiltradas = solicitudesFiltradas.filter(solicitud =>
- solicitud[campo].toLowerCase().includes(lookups.icontains.toLowerCase())
- );
+ solicitudesFiltradas = solicitudesFiltradas.filter(solicitud => {
+ if (campo === "solicitante__nombre"){//Al haber unido el nombre y apellidos en la columna de solicitante
+ return (solicitud[campo]+ " " + solicitud["solicitante__ap_paterno"] + " " + (solicitud["solicitante__ap_materno"] || "")).toLowerCase().includes(lookups.icontains.toLowerCase())
+ }else{
+ return solicitud[campo].toLowerCase().includes(lookups.icontains.toLowerCase())
+ }
+ });
// Agregar a la lista de filtros aplicados
nuevosFiltrosAplicados.push({ filtro });
}
@@ -359,9 +379,14 @@ export default function Solicitudes( {setViewPageLoader} ){
});
// Aplicamos el término de búsqueda a todos los campos de cada solicitud
if (searchTerm !== '' && searchTerm !==null) {
- solicitudesFiltradas = solicitudesFiltradas.filter(solicitud => {
- return Object.values(solicitud).some(value =>
- value?.toString().toLowerCase().includes(searchTerm.toLowerCase())
+ solicitudesFiltradas = solicitudesFiltradas.filter(solicitud => {
+ return (
+ // Verificar si el término de búsqueda coincide en cualquier campo
+ Object.values(solicitud).some(value =>
+ value?.toString().toLowerCase().includes(searchTerm.toLowerCase())
+ ) ||
+ // Verificar coincidencia específica en la columna "Solicitante"
+ (solicitud.solicitante__nombre+ " " + solicitud.solicitante__ap_paterno+ " " + (solicitud.solicitante__ap_materno || ""))?.toString().toLowerCase().includes(searchTerm.toLowerCase())
);
});
}
@@ -502,9 +527,6 @@ export default function Solicitudes( {setViewPageLoader} ){
console.log('Actualización exitosa', response)
- //Actualizamos las solicitudes
- const responseSolicitudes = await api.solicitudes.get();
-
// Cambiamos en el arreglo de solicitudes, el registro
ChangeSolicitud(editingField.id_solicitud, editingField.key, editingValue)
@@ -725,6 +747,63 @@ export default function Solicitudes( {setViewPageLoader} ){
}
}),[reporteAplicado])
+ const handleRightClick = (e, id) => {
+ e.preventDefault(); // Bloquea el menú contextual del navegador
+ setSelectedSolicitudId(id);
+ setMenuPosition({ x: e.pageX, y: e.pageY });
+
+ // Declaramos las dimensiones que tiene el menu
+ const menuWidth = 48; // Ancho estimado del menú en píxeles
+ const menuHeight = 32; // Alto estimado del menú en píxeles
+
+ // Determinar posición inicial en base al clic
+ let x = e.pageX;
+ let y = e.pageY;
+
+ if (window.innerWidth <= 768) {
+ // Pantallas pequeñas: centra el menú horizontalmente
+ x = (window.innerWidth - menuWidth) / 2;
+ } else {
+ // Ajuste para no desbordar a la derecha en pantallas grandes
+ if (x + menuWidth > window.innerWidth) {
+ x = window.innerWidth - menuWidth;
+ }
+ }
+
+ // Ajuste para no desbordar hacia abajo
+ if (y + menuHeight > window.innerHeight) {
+ y = window.innerHeight - menuHeight;
+ }
+
+ // Establecer la posición final del menú
+ setMenuPosition({ x, y });
+ };
+
+ const handleEliminarSolicitud = async (id_solicitud) => {
+ try {
+ setViewPageLoader(true)
+ //hacemos la petición a la api para la eliminación del reporte
+ const response = await api.solicitudes.delete(id_solicitud);
+ console.log('Eliminación de solicitud exitosa ', response)
+ //Reestablecemos el estado del id solicitud seleccionada
+ setSelectedSolicitudId(null);
+ //Eliminamos de los arreglos correspondientes la solicitud
+ setSolicitudes(solicitudes.filter((solicitud) => solicitud.id !== id_solicitud));
+ setSolicitudesOriginales(solicitudes.filter((solicitud) => solicitud.id !== id_solicitud));
+ //Definimos el mensaje de la alerta
+ setAlertMessage('¡Eliminacion de solicitud exitosa!');
+ setShowAlertSuccesful(true)
+ } catch (error) {
+ console.error(error)
+ //Definimos el mensaje de la alerta
+ setAlertMessage('¡Ha ocurrido un error inesperado! Vuelve a intentarlo');
+ setShowAlertError(true)
+ }finally{
+ setViewPageLoader(false);
+ }
+ };
+
+
return (
<>
{showAlertSuccesful && (
@@ -745,125 +824,203 @@ export default function Solicitudes( {setViewPageLoader} ){
setIsVisible={setShowAlertError}
/>
)}
- {viewMenuColumnas && (
-
- )}
- {viewMenuFiltros && (
-
- )}
-
- {viewMenuReportes && (
-
- )}
-
-
-
-
-
-
-
- search
-
-
+
+ <>
+ {viewMenuColumnas && (
+
+ )}
+ {viewMenuFiltros && (
+
+ )}
+ {viewMenuReportes && (
+
+ )}
+
+
+
+
+
+
+
+ search
+
+
+
+
setViewMenuReportes(!viewMenuReportes)} buttonRef={buttonMenuReportesRef}/>
+ setViewMenuFiltros(!viewMenuFiltros)} buttonRef={buttonMenuFiltrosRef}/>
+ setViewMenuColumnas(!viewMenuColumnas)} buttonRef={buttonMenuColumnasRef}/>
-
setViewMenuReportes(!viewMenuReportes)} buttonRef={buttonMenuReportesRef}/>
- setViewMenuFiltros(!viewMenuFiltros)} buttonRef={buttonMenuFiltrosRef}/>
- setViewMenuColumnas(!viewMenuColumnas)} buttonRef={buttonMenuColumnasRef}/>
-
- {enableSectionReportes && (
-
- )}
-
-
-
-
-
-
-
- {(provided) => (
-
- {Object.entries(columnas).map(([key, value], index) => (
- !columnasOcultas.includes(key) && (
-
- {(provided, snapshot) => (
-
-
-
- {key === 'modalidad__nombre' ? "Modalidad" : key === 'solicitante__nombre' ? "Solicitante" : key === 'timestamp' ? "Fecha" : value}
-
-
- sortSolicitudes(key)} // Ordenar al hacer clic
- >
- {sortConfig.key === key ? (
- sortConfig.direction === 'ascending' ? 'keyboard_arrow_up' : 'keyboard_arrow_down'
- ) : (
- 'unfold_more'
- )}
-
-
-
- )}
-
- )
- ))}
- {provided.placeholder}
-
- )}
-
-
-
-
- {solicitudes.map((solicitud, index) => (
-
- {Object.entries(solicitud).map(([key, value], i) => (
- !columnasOcultas.includes(key) && (
- handleDoubleClick(solicitud.id, key, value) : null} //Le agregamos la funcion, solamente a los compos que se pueden editar
+ {enableSectionReportes && (
+
+ )}
+
+
+
+
+
+
+
+ {(provided) => (
+
- {editingField && editingField.id_solicitud === solicitud.id && editingField.key === key ? (
- inputEditingField(key)
- ) : (
- getEstiloCampo(key, value)
- )}
-
- )
- ))}
-
- ))}
-
-
+ {Object.entries(columnas).map(([key, value], index) => (
+ (!columnasOcultas.includes(key) && !['solicitante__ap_materno','solicitante__ap_paterno'].includes(key)) && (
+
+ {(provided, snapshot) => (
+
+
+
+ {key === 'modalidad__nombre' ? "Modalidad" : key === 'solicitante__nombre' ? "Solicitante" : key === 'timestamp' ? "Fecha" : value}
+
+
+ sortSolicitudes(key)} // Ordenar al hacer clic
+ >
+ {sortConfig.key === key ? (
+ sortConfig.direction === 'ascending' ? 'keyboard_arrow_up' : 'keyboard_arrow_down'
+ ) : (
+ 'unfold_more'
+ )}
+
+
+
+ )}
+
+ )
+ ))}
+ {provided.placeholder}
+
+ )}
+
+
+
+
+ {solicitudes.map((solicitud, index) => (
+
+ {Object.entries(solicitud).map(([key, value], i) => (
+ (!columnasOcultas.includes(key) && !['solicitante__ap_materno','solicitante__ap_paterno'].includes(key)) && (
+ handleRightClick(e, solicitud.id)}
+ onDoubleClick={AvailablesFieldsToEdit.includes(key) ? () => handleDoubleClick(solicitud.id, key, value) : null} //Le agregamos la funcion, solamente a los compos que se pueden editar
+ >
+ {editingField && editingField.id_solicitud === solicitud.id && editingField.key === key ? (
+ inputEditingField(key)
+ ) : (
+ key === 'solicitante__nombre' ? (getEstiloCampo(key, value+" "+solicitud.solicitante__ap_paterno+ " "+(solicitud.solicitante__ap_materno || ""))) : (getEstiloCampo(key, value))
+ )}
+
+ )
+ ))}
+
+ ))}
+ {/* Menu contextual para una solicitud seleccionada */}
+ {selectedSolicitudId && (
+
+ )}
+
+
+
+ {/* Menu contextual para una solicitud seleccionada */}
+ {selectedSolicitudId && (
+
+ )}
-
-
+
+
-
+ >
+
>
);
}
+const MenuOpcionesSolicitud = ( {selectedSolicitudId, menuPosition, handleEliminarSolicitud, menuRef} ) => {
+ const [showModal, setShowModal] = useState(false);
+ const navigate = useNavigate();
+
+ const handleDelete = () => {
+ setShowModal(false);
+ handleEliminarSolicitud(selectedSolicitudId);
+ };
+
+ return (
+
+ {showModal && (
+
+ setShowModal(false)}
+ >
+ Cancelar
+
+
+
+ Eliminar
+
+
+ )}
+
+
navigate(`detalles-solicitud/${selectedSolicitudId}`)}
+ >
+
+ visibility
+
+
+ Ver vista detallada
+
+
+
setShowModal(true)}
+ >
+
+ delete
+
+
+ Eliminar solicitud
+
+
+
+
+ );
+};
+
const ShowFilters = ({filtrosAplicados, setFiltrosAplicados, deleteFilter}) => {
function RegimenAbreviado (value) {
switch (value) {
diff --git a/cosiap_frontend/src/components/common/layouts/LayoutBaseNavigation.jsx b/cosiap_frontend/src/components/common/layouts/LayoutBaseNavigation.jsx
index 0db9c6f7a5f388f0d3c0873619945f01ac60824e..7e8c183d15a18fc684c74f249f06902aec4a8155 100644
--- a/cosiap_frontend/src/components/common/layouts/LayoutBaseNavigation.jsx
+++ b/cosiap_frontend/src/components/common/layouts/LayoutBaseNavigation.jsx
@@ -75,7 +75,7 @@ export default function LayoutBaseNavigation() {
setViewSettings(!viewSettings)}
>
diff --git a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Navbar.jsx b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Navbar.jsx
index b1cbe2d0f88c95bcbb13ec5ca0eede0e6315ea53..d8956ef096c189c25978aa0d843cfbde6528d526 100644
--- a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Navbar.jsx
+++ b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Navbar/Navbar.jsx
@@ -50,7 +50,7 @@ export default function Navbar({ linksItems, viewMenu, setViewMenu }) {
<>
{/* Contenedor de gradiente para pantallas pequeñas */}
-
+
{/* Contenedor principal del navbar */}
diff --git a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Sidebar.jsx b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Sidebar.jsx
index 753e2c0855c10bd3a7255b71848dc2463e57f2d3..37a098248107285126319465f3b0e9de198cb1f3 100644
--- a/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Sidebar.jsx
+++ b/cosiap_frontend/src/components/common/layouts/LayoutsNavigation/Sidebar/Sidebar.jsx
@@ -56,7 +56,7 @@ export default function Sidebar( {linksItems, viewMenu, setViewMenu} ){
<>