Implementación AnomalIA - Fix de dropdowns y permisos.
All checks were successful
Optimized Build and Deploy / remote-build-and-deploy (push) Successful in 5m17s
All checks were successful
Optimized Build and Deploy / remote-build-and-deploy (push) Successful in 5m17s
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
// src/layouts/MainLayout.tsx
|
||||
import React, { type ReactNode, useState, useEffect, useMemo } // << AÑADIR useMemo
|
||||
from 'react';
|
||||
import React, { type ReactNode, useState, useEffect, useMemo } from 'react';
|
||||
import {
|
||||
Box, AppBar, Toolbar, Typography, Tabs, Tab, Paper,
|
||||
IconButton, Menu, MenuItem, ListItemIcon, ListItemText, Divider,
|
||||
Button
|
||||
Button, Badge
|
||||
} from '@mui/material';
|
||||
import AccountCircle from '@mui/icons-material/AccountCircle';
|
||||
import LockResetIcon from '@mui/icons-material/LockReset';
|
||||
import LogoutIcon from '@mui/icons-material/Logout';
|
||||
import NotificationsIcon from '@mui/icons-material/Notifications';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import ChangePasswordModal from '../components/Modals/Usuarios/ChangePasswordModal';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
@@ -18,6 +17,16 @@ interface MainLayoutProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
// --- Helper para dar nombres legibles a los tipos de alerta ---
|
||||
const getTipoAlertaLabel = (tipoAlerta: string): string => {
|
||||
switch (tipoAlerta) {
|
||||
case 'DevolucionAnomala': return 'Devoluciones Anómalas';
|
||||
case 'ComportamientoSistema': return 'Anomalías del Sistema';
|
||||
case 'FaltaDeDatos': return 'Falta de Datos';
|
||||
default: return tipoAlerta;
|
||||
}
|
||||
};
|
||||
|
||||
// Definición original de módulos
|
||||
const allAppModules = [
|
||||
{ label: 'Inicio', path: '/', requiredPermission: null }, // Inicio siempre visible
|
||||
@@ -31,22 +40,36 @@ const allAppModules = [
|
||||
];
|
||||
|
||||
const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
|
||||
// Obtenemos todo lo necesario del AuthContext, INCLUYENDO LAS ALERTAS
|
||||
const {
|
||||
user, // user ya está disponible aquí
|
||||
logout,
|
||||
isAuthenticated,
|
||||
isPasswordChangeForced,
|
||||
showForcedPasswordChangeModal,
|
||||
setShowForcedPasswordChangeModal,
|
||||
passwordChangeCompleted
|
||||
user, logout, isAuthenticated, isPasswordChangeForced,
|
||||
showForcedPasswordChangeModal, setShowForcedPasswordChangeModal,
|
||||
passwordChangeCompleted,
|
||||
alertas
|
||||
} = useAuth();
|
||||
|
||||
const { tienePermiso, isSuperAdmin } = usePermissions(); // <<--- OBTENER HOOK DE PERMISOS
|
||||
|
||||
// El resto de los hooks locales no cambian
|
||||
const { tienePermiso, isSuperAdmin } = usePermissions();
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
const [selectedTab, setSelectedTab] = useState<number | false>(false);
|
||||
const [anchorElUserMenu, setAnchorElUserMenu] = useState<null | HTMLElement>(null);
|
||||
const [anchorElAlertasMenu, setAnchorElAlertasMenu] = useState<null | HTMLElement>(null);
|
||||
|
||||
// --- Agrupación de alertas para el menú ---
|
||||
const gruposDeAlertas = useMemo(() => {
|
||||
if (!alertas || !Array.isArray(alertas)) return [];
|
||||
|
||||
const groups = alertas.reduce((acc, alerta) => {
|
||||
const label = getTipoAlertaLabel(alerta.tipoAlerta);
|
||||
acc[label] = (acc[label] || 0) + 1;
|
||||
return acc;
|
||||
}, {} as Record<string, number>);
|
||||
|
||||
return Object.entries(groups); // Devuelve [['Devoluciones Anómalas', 5], ...]
|
||||
}, [alertas]);
|
||||
|
||||
const numAlertas = alertas.length;
|
||||
|
||||
const accessibleModules = useMemo(() => {
|
||||
if (!isAuthenticated) return [];
|
||||
@@ -92,6 +115,17 @@ const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
|
||||
setAnchorElUserMenu(null);
|
||||
};
|
||||
|
||||
// Handlers para el nuevo menú de alertas
|
||||
const handleOpenAlertasMenu = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setAnchorElAlertasMenu(event.currentTarget);
|
||||
};
|
||||
|
||||
const handleCloseAlertasMenu = () => {
|
||||
setAnchorElAlertasMenu(null);
|
||||
};
|
||||
|
||||
const handleNavigateToAlertas = () => { navigate('/anomalias/alertas'); handleCloseAlertasMenu(); };
|
||||
|
||||
const handleChangePasswordClick = () => {
|
||||
setShowForcedPasswordChangeModal(true);
|
||||
handleCloseUserMenu();
|
||||
@@ -133,7 +167,6 @@ const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Si no hay módulos accesibles después del login (y no es el cambio de clave forzado)
|
||||
// Esto podría pasar si un usuario no tiene permiso para NINGUNA sección, ni siquiera Inicio.
|
||||
// Deberías redirigir a login o mostrar un mensaje de "Sin acceso".
|
||||
@@ -162,6 +195,37 @@ const MainLayout: React.FC<MainLayoutProps> = ({ children }) => {
|
||||
)}
|
||||
{isAuthenticated && (
|
||||
<>
|
||||
<IconButton onClick={handleOpenAlertasMenu} color="inherit">
|
||||
<Badge badgeContent={numAlertas} color="error">
|
||||
<NotificationsIcon />
|
||||
</Badge>
|
||||
</IconButton>
|
||||
|
||||
<Menu
|
||||
id="alertas-menu"
|
||||
anchorEl={anchorElAlertasMenu}
|
||||
open={Boolean(anchorElAlertasMenu)}
|
||||
onClose={() => setAnchorElAlertasMenu(null)}
|
||||
>
|
||||
<MenuItem disabled>
|
||||
<ListItemText primary={`Tienes ${numAlertas} alertas pendientes.`} />
|
||||
</MenuItem>
|
||||
<Divider />
|
||||
|
||||
{gruposDeAlertas.map(([label, count]) => (
|
||||
<MenuItem key={label} onClick={handleNavigateToAlertas}>
|
||||
<ListItemIcon><Badge badgeContent={count} color="error" sx={{mr: 2}} /></ListItemIcon>
|
||||
<ListItemText>{label}</ListItemText>
|
||||
</MenuItem>
|
||||
))}
|
||||
|
||||
{numAlertas > 0 && <Divider />}
|
||||
|
||||
<MenuItem onClick={handleNavigateToAlertas}>
|
||||
<ListItemText sx={{textAlign: 'center'}}>Ver Todas las Alertas</ListItemText>
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
|
||||
<IconButton
|
||||
size="large"
|
||||
aria-label="Cuenta del usuario"
|
||||
|
||||
Reference in New Issue
Block a user