Diseño de un AuditoriaController con un patrón para añadir endpoints de historial para diferentes entidades. Implementación de la lógica de servicio y repositorio para obtener datos de las tablas _H para: Usuarios (gral_Usuarios_H) Pagos de Distribuidores (cue_PagosDistribuidor_H) Notas de Crédito/Débito (cue_CreditosDebitos_H) Entradas/Salidas de Distribuidores (dist_EntradasSalidas_H) Entradas/Salidas de Canillitas (dist_EntradasSalidasCanillas_H) Novedades de Canillitas (dist_dtNovedadesCanillas_H) Ajustes Manuales de Saldo (cue_SaldoAjustesHistorial) Tipos de Pago (cue_dtTipopago_H) Canillitas (Maestro) (dist_dtCanillas_H) Distribuidores (Maestro) (dist_dtDistribuidores_H) Empresas (Maestro) (dist_dtEmpresas_H) DTOs específicos para cada tipo de historial, incluyendo NombreUsuarioModifico. Frontend: Servicio auditoriaService.ts con métodos para llamar a cada endpoint de historial. Página AuditoriaGeneralPage.tsx con: Selector de "Tipo de Entidad a Auditar". Filtros comunes (Fechas, Usuario Modificador, Tipo de Modificación, ID Entidad). Un DataGrid que muestra las columnas dinámicamente según el tipo de entidad seleccionada. Lógica para cargar los datos correspondientes. DTOs de historial en TypeScript. Actualizaciones en AppRoutes.tsx y MainLayout.tsx para la nueva sección de Auditoría (restringida a SuperAdmin).
		
			
				
	
	
		
			271 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // src/routes/AppRoutes.tsx
 | |
| import React, { type JSX } from 'react';
 | |
| import { BrowserRouter, Routes, Route, Navigate, Outlet } from 'react-router-dom';
 | |
| import LoginPage from '../pages/LoginPage';
 | |
| import HomePage from '../pages/HomePage';
 | |
| import { useAuth } from '../contexts/AuthContext';
 | |
| import MainLayout from '../layouts/MainLayout';
 | |
| import { Typography } from '@mui/material';
 | |
| import SectionProtectedRoute from './SectionProtectedRoute';
 | |
| 
 | |
| // Distribución
 | |
| import DistribucionIndexPage from '../pages/Distribucion/DistribucionIndexPage';
 | |
| import GestionarCanillitasPage from '../pages/Distribucion/GestionarCanillitasPage';
 | |
| import GestionarDistribuidoresPage from '../pages/Distribucion/GestionarDistribuidoresPage';
 | |
| import GestionarPublicacionesPage from '../pages/Distribucion/GestionarPublicacionesPage';
 | |
| import GestionarSeccionesPublicacionPage from '../pages/Distribucion/GestionarSeccionesPublicacionPage';
 | |
| import GestionarPreciosPublicacionPage from '../pages/Distribucion/GestionarPreciosPublicacionPage';
 | |
| import GestionarRecargosPublicacionPage from '../pages/Distribucion/GestionarRecargosPublicacionPage';
 | |
| import GestionarPorcentajesPagoPage from '../pages/Distribucion/GestionarPorcentajesPagoPage';
 | |
| import GestionarPorcMonCanillaPage from '../pages/Distribucion/GestionarPorcMonCanillaPage';
 | |
| import GestionarOtrosDestinosPage from '../pages/Distribucion/GestionarOtrosDestinosPage';
 | |
| import GestionarZonasPage from '../pages/Distribucion/GestionarZonasPage';
 | |
| import GestionarEmpresasPage from '../pages/Distribucion/GestionarEmpresasPage';
 | |
| import GestionarSalidasOtrosDestinosPage from '../pages/Distribucion/GestionarSalidasOtrosDestinosPage';
 | |
| import GestionarEntradasSalidasDistPage from '../pages/Distribucion/GestionarEntradasSalidasDistPage';
 | |
| import GestionarEntradasSalidasCanillaPage from '../pages/Distribucion/GestionarEntradasSalidasCanillaPage';
 | |
| import GestionarControlDevolucionesPage from '../pages/Distribucion/GestionarControlDevolucionesPage';
 | |
| import GestionarParadasCanillaPage from '../pages/Distribucion/GestionarParadasCanillaPage';
 | |
| 
 | |
| // Impresión
 | |
| import ImpresionIndexPage from '../pages/Impresion/ImpresionIndexPage';
 | |
| import GestionarPlantasPage from '../pages/Impresion/GestionarPlantasPage';
 | |
| import GestionarTiposBobinaPage from '../pages/Impresion/GestionarTiposBobinaPage';
 | |
| import GestionarEstadosBobinaPage from '../pages/Impresion/GestionarEstadosBobinaPage';
 | |
| import GestionarStockBobinasPage from '../pages/Impresion/GestionarStockBobinasPage';
 | |
| import GestionarTiradasPage from '../pages/Impresion/GestionarTiradasPage';
 | |
| 
 | |
| // Contables
 | |
| import ContablesIndexPage from '../pages/Contables/ContablesIndexPage';
 | |
| import GestionarTiposPagoPage from '../pages/Contables/GestionarTiposPagoPage';
 | |
| import GestionarPagosDistribuidorPage from '../pages/Contables/GestionarPagosDistribuidorPage';
 | |
| import GestionarNotasCDPage from '../pages/Contables/GestionarNotasCDPage';
 | |
| import GestionarSaldosPage from '../pages/Contables/GestionarSaldosPage';
 | |
| 
 | |
| // Usuarios
 | |
| import UsuariosIndexPage from '../pages/Usuarios/UsuariosIndexPage'; // Crear este componente
 | |
| import GestionarPerfilesPage from '../pages/Usuarios/GestionarPerfilesPage';
 | |
| import GestionarPermisosPage from '../pages/Usuarios/GestionarPermisosPage';
 | |
| import AsignarPermisosAPerfilPage from '../pages/Usuarios/AsignarPermisosAPerfilPage';
 | |
| import GestionarUsuariosPage from '../pages/Usuarios/GestionarUsuariosPage';
 | |
| 
 | |
| // Radios
 | |
| import RadiosIndexPage from '../pages/Radios/RadiosIndexPage';
 | |
| import GestionarRitmosPage from '../pages/Radios/GestionarRitmosPage';
 | |
| import GestionarCancionesPage from '../pages/Radios/GestionarCancionesPage';
 | |
| import GenerarListasRadioPage from '../pages/Radios/GenerarListasRadioPage';
 | |
| 
 | |
| // Reportes
 | |
| import ReportesIndexPage from '../pages/Reportes/ReportesIndexPage';
 | |
| import ReporteExistenciaPapelPage from '../pages/Reportes/ReporteExistenciaPapelPage';
 | |
| import ReporteMovimientoBobinasPage from '../pages/Reportes/ReporteMovimientoBobinasPage';
 | |
| import ReporteMovimientoBobinasEstadoPage from '../pages/Reportes/ReporteMovimientoBobinasEstadoPage';
 | |
| import ReporteListadoDistribucionGeneralPage from '../pages/Reportes/ReporteListadoDistribucionGeneralPage';
 | |
| import ReporteListadoDistribucionCanillasPage from '../pages/Reportes/ReporteListadoDistribucionCanillasPage';
 | |
| import ReporteListadoDistribucionCanillasImportePage from '../pages/Reportes/ReporteListadoDistribucionCanillasImportePage';
 | |
| import ReporteVentaMensualSecretariaPage from '../pages/Reportes/ReporteVentaMensualSecretariaPage';
 | |
| import ReporteDetalleDistribucionCanillasPage from '../pages/Reportes/ReporteDetalleDistribucionCanillasPage';
 | |
| import ReporteTiradasPublicacionesSeccionesPage from '../pages/Reportes/ReporteTiradasPublicacionesSeccionesPage';
 | |
| import ReporteConsumoBobinasSeccionPage from '../pages/Reportes/ReporteConsumoBobinasSeccionPage';
 | |
| import ReporteConsumoBobinasPublicacionPage from '../pages/Reportes/ReporteConsumoBobinasPublicacionPage';
 | |
| import ReporteComparativaConsumoBobinasPage from '../pages/Reportes/ReporteComparativaConsumoBobinasPage';
 | |
| import ReporteCuentasDistribuidoresPage from '../pages/Reportes/ReporteCuentasDistribuidoresPage';
 | |
| import ReporteListadoDistribucionPage from '../pages/Reportes/ReporteListadoDistribucionPage';
 | |
| import ReporteControlDevolucionesPage from '../pages/Reportes/ReporteControlDevolucionesPage';
 | |
| import GestionarNovedadesCanillaPage from '../pages/Distribucion/GestionarNovedadesCanillaPage';
 | |
| import ReporteNovedadesCanillasPage from '../pages/Reportes/ReporteNovedadesCanillasPage';
 | |
| import ReporteListadoDistMensualPage from '../pages/Reportes/ReporteListadoDistMensualPage';
 | |
| 
 | |
| // Auditorias
 | |
| import GestionarAuditoriaUsuariosPage from '../pages/Usuarios/Auditoria/GestionarAuditoriaUsuariosPage';
 | |
| import AuditoriaGeneralPage from '../pages/Auditoria/AuditoriaGeneralPage';
 | |
| 
 | |
| 
 | |
| // --- ProtectedRoute y PublicRoute SIN CAMBIOS ---
 | |
| const ProtectedRoute: React.FC<{ children: JSX.Element }> = ({ children }) => {
 | |
|   const { isAuthenticated, isLoading } = useAuth();
 | |
|   // console.log("ProtectedRoute Check:", { path: window.location.pathname, isAuthenticated, isLoading });
 | |
|   if (isLoading) return null;
 | |
|   if (!isAuthenticated) {
 | |
|     //    console.log("ProtectedRoute: Not authenticated, redirecting to /login");
 | |
|     return <Navigate to="/login" replace />;
 | |
|   }
 | |
|   // console.log("ProtectedRoute: Authenticated, rendering children");
 | |
|   return children;
 | |
| };
 | |
| const PublicRoute: React.FC<{ children: JSX.Element }> = ({ children }) => {
 | |
|   const { isAuthenticated, isLoading } = useAuth();
 | |
|   // console.log("PublicRoute Check:", { path: window.location.pathname, isAuthenticated, isLoading });
 | |
|   if (isLoading) return null;
 | |
|   if (isAuthenticated) {
 | |
|     // console.log("PublicRoute: Authenticated, redirecting to /");
 | |
|     return <Navigate to="/" replace />;
 | |
|   }
 | |
|   // console.log("PublicRoute: Not authenticated, rendering children");
 | |
|   return children;
 | |
| };
 | |
| // --- Fin Protected/Public ---
 | |
| 
 | |
| const MainLayoutWrapper: React.FC = () => (
 | |
|   <MainLayout>
 | |
|     <Outlet />
 | |
|   </MainLayout>
 | |
| );
 | |
| 
 | |
| const AppRoutes = () => {
 | |
|   return (
 | |
|     <BrowserRouter>
 | |
|       <Routes>
 | |
|         <Route path="/login" element={<PublicRoute><LoginPage /></PublicRoute>} />
 | |
| 
 | |
|         {/* Rutas Protegidas que usan el MainLayout */}
 | |
|         <Route
 | |
|           path="/" // La ruta padre para todas las secciones protegidas
 | |
|           element={
 | |
|             <ProtectedRoute>
 | |
|               <MainLayoutWrapper />
 | |
|             </ProtectedRoute>
 | |
|           }
 | |
|         >
 | |
|           {/* Rutas hijas que se renderizarán en el Outlet de MainLayoutWrapper */}
 | |
|           <Route index element={<HomePage />} /> {/* Para la ruta exacta "/" */}
 | |
| 
 | |
|           {/* Módulo de Distribución (anidado) */}
 | |
|           <Route
 | |
|             path="distribucion"
 | |
|             element={
 | |
|               <SectionProtectedRoute requiredPermission="SS001" sectionName="Distribución">
 | |
|                 <DistribucionIndexPage />
 | |
|               </SectionProtectedRoute>
 | |
|             }
 | |
|           >
 | |
|             <Route index element={<Navigate to="es-canillas" replace />} />
 | |
|             <Route path="es-canillas" element={<GestionarEntradasSalidasCanillaPage />} />
 | |
|             <Route path="control-devoluciones" element={<GestionarControlDevolucionesPage />} />
 | |
|             <Route path="es-distribuidores" element={<GestionarEntradasSalidasDistPage />} />
 | |
|             <Route path="salidas-otros-destinos" element={<GestionarSalidasOtrosDestinosPage />} />
 | |
|             <Route path="canillas" element={<GestionarCanillitasPage />} />
 | |
|             <Route path="canillas/:idCanilla/novedades" element={<GestionarNovedadesCanillaPage />} />
 | |
|             <Route path="canillas/:idCanilla/paradas" element={<GestionarParadasCanillaPage />} />
 | |
|             <Route path="distribuidores" element={<GestionarDistribuidoresPage />} />
 | |
|             <Route path="otros-destinos" element={<GestionarOtrosDestinosPage />} />
 | |
|             <Route path="zonas" element={<GestionarZonasPage />} />
 | |
|             <Route path="empresas" element={<GestionarEmpresasPage />} />
 | |
|             {/* Rutas para Publicaciones y sus detalles */}
 | |
|             <Route path="publicaciones" element={<Outlet />}> {/* Contenedor para sub-rutas de publicaciones */}
 | |
|               <Route index element={<GestionarPublicacionesPage />} /> {/* Lista de publicaciones */}
 | |
|               <Route path=":idPublicacion/precios" element={<GestionarPreciosPublicacionPage />} />
 | |
|               <Route path=":idPublicacion/recargos" element={<GestionarRecargosPublicacionPage />} />
 | |
|               <Route path=":idPublicacion/porcentajes-pago-dist" element={<GestionarPorcentajesPagoPage />} />
 | |
|               <Route path=":idPublicacion/porcentajes-mon-canilla" element={<GestionarPorcMonCanillaPage />} />
 | |
|               <Route path=":idPublicacion/secciones" element={<GestionarSeccionesPublicacionPage />} />
 | |
|             </Route>
 | |
|           </Route>
 | |
| 
 | |
|           {/* Módulo Contable (anidado) */}
 | |
|           <Route
 | |
|             path="contables"
 | |
|             element={
 | |
|               <SectionProtectedRoute requiredPermission="SS002" sectionName="Contables">
 | |
|                 <ContablesIndexPage />
 | |
|               </SectionProtectedRoute>
 | |
|             }
 | |
|           >
 | |
|             <Route index element={<Navigate to="tipos-pago" replace />} />
 | |
|             <Route path="tipos-pago" element={<GestionarTiposPagoPage />} />
 | |
|             <Route path="pagos-distribuidores" element={<GestionarPagosDistribuidorPage />} />
 | |
|             <Route path="notas-cd" element={<GestionarNotasCDPage />} />
 | |
|             <Route path="gestion-saldos" element={<GestionarSaldosPage />} />
 | |
|           </Route>
 | |
| 
 | |
|           {/* Módulo de Impresión (anidado) */}
 | |
|           <Route path="impresion"
 | |
|             element={
 | |
|               <SectionProtectedRoute requiredPermission="SS003" sectionName="Impresión">
 | |
|                 <ImpresionIndexPage />
 | |
|               </SectionProtectedRoute>}
 | |
|           >
 | |
|             <Route index element={<Navigate to="plantas" replace />} />
 | |
|             <Route path="plantas" element={<GestionarPlantasPage />} />
 | |
|             <Route path="tipos-bobina" element={<GestionarTiposBobinaPage />} />
 | |
|             <Route path="estados-bobina" element={<GestionarEstadosBobinaPage />} />
 | |
|             <Route path="stock-bobinas" element={<GestionarStockBobinasPage />} />
 | |
|             <Route path="tiradas" element={<GestionarTiradasPage />} />
 | |
|           </Route>
 | |
| 
 | |
|           {/* Módulo de Reportes */}
 | |
|           <Route path="reportes"
 | |
|             element={
 | |
|               <SectionProtectedRoute requiredPermission="SS004" sectionName="Reportes">
 | |
|                 <ReportesIndexPage />
 | |
|               </SectionProtectedRoute>}
 | |
|           >
 | |
|             <Route index element={<Typography sx={{ p: 2 }}>Seleccione un reporte del menú lateral.</Typography>} /> {/* Placeholder */}
 | |
|             <Route path="existencia-papel" element={<ReporteExistenciaPapelPage />} />
 | |
|             <Route path="movimiento-bobinas" element={<ReporteMovimientoBobinasPage />} />
 | |
|             <Route path="movimiento-bobinas-estado" element={<ReporteMovimientoBobinasEstadoPage />} />
 | |
|             <Route path="listado-distribucion-general" element={<ReporteListadoDistribucionGeneralPage />} />
 | |
|             <Route path="listado-distribucion-canillas" element={<ReporteListadoDistribucionCanillasPage />} />
 | |
|             <Route path="listado-distribucion-canillas-importe" element={<ReporteListadoDistribucionCanillasImportePage />} />
 | |
|             <Route path="venta-mensual-secretaria" element={<ReporteVentaMensualSecretariaPage />} />
 | |
|             <Route path="detalle-distribucion-canillas" element={<ReporteDetalleDistribucionCanillasPage />} />
 | |
|             <Route path="tiradas-publicaciones-secciones" element={<ReporteTiradasPublicacionesSeccionesPage />} />
 | |
|             <Route path="consumo-bobinas-seccion" element={<ReporteConsumoBobinasSeccionPage />} />
 | |
|             <Route path="consumo-bobinas-publicacion" element={<ReporteConsumoBobinasPublicacionPage />} />
 | |
|             <Route path="comparativa-consumo-bobinas" element={<ReporteComparativaConsumoBobinasPage />} />
 | |
|             <Route path="cuentas-distribuidores" element={<ReporteCuentasDistribuidoresPage />} />
 | |
|             <Route path="listado-distribucion-distribuidores" element={<ReporteListadoDistribucionPage />} />
 | |
|             <Route path="control-devoluciones" element={<ReporteControlDevolucionesPage />} />
 | |
|             <Route path="novedades-canillas" element={<ReporteNovedadesCanillasPage />} />
 | |
|             <Route path="listado-distribucion-mensual" element={<ReporteListadoDistMensualPage />} />
 | |
|           </Route>
 | |
| 
 | |
|           {/* Módulo de Radios (anidado) */}
 | |
|           <Route path="radios"
 | |
|             element={
 | |
|               <SectionProtectedRoute requiredPermission="SS005" sectionName="Radios">
 | |
|                 <RadiosIndexPage />
 | |
|               </SectionProtectedRoute>}
 | |
|           >
 | |
|             <Route index element={<Navigate to="ritmos" replace />} />
 | |
|             <Route path="ritmos" element={<GestionarRitmosPage />} />
 | |
|             <Route path="canciones" element={<GestionarCancionesPage />} />
 | |
|             <Route path="generar-listas" element={<GenerarListasRadioPage />} />
 | |
|           </Route>
 | |
| 
 | |
|           {/* Módulo de Usuarios (anidado) */}
 | |
|           <Route path="usuarios"
 | |
|             element={
 | |
|               <SectionProtectedRoute requiredPermission="SS006" sectionName="Usuarios">
 | |
|                 <UsuariosIndexPage />
 | |
|               </SectionProtectedRoute>}
 | |
|           >
 | |
|             <Route index element={<Navigate to="perfiles" replace />} /> {/* Redirigir a la primera subpestaña */}
 | |
|             <Route path="perfiles" element={<GestionarPerfilesPage />} />
 | |
|             <Route path="permisos" element={<GestionarPermisosPage />} />
 | |
|             <Route path="perfiles/:idPerfil/permisos" element={<AsignarPermisosAPerfilPage />} />
 | |
|             <Route path="gestion-usuarios" element={<GestionarUsuariosPage />} />
 | |
|             <Route path="auditoria-usuarios" element={<GestionarAuditoriaUsuariosPage />} />
 | |
|           </Route>
 | |
| 
 | |
|           {/* Módulo de Auditoías (anidado) */}
 | |
|           <Route path="auditoria"
 | |
|             element={
 | |
|               <SectionProtectedRoute onlySuperAdmin={true} sectionName="Auditoría">
 | |
|                 <Outlet />
 | |
|               </SectionProtectedRoute>
 | |
|             }
 | |
|           >
 | |
|             <Route index element={<Navigate to="general" replace />} />
 | |
|             <Route path="general" element={<AuditoriaGeneralPage />} />
 | |
|           </Route>
 | |
|           {/* Ruta catch-all DENTRO del layout protegido */}
 | |
|           <Route path="*" element={<Navigate to="/" replace />} />
 | |
|         </Route> {/* Cierre de la ruta padre "/" */}
 | |
| 
 | |
|       </Routes>
 | |
|     </BrowserRouter>
 | |
|   );
 | |
| };
 | |
| 
 | |
| export default AppRoutes; |