6.0 KiB
6.0 KiB
Full Width Optimization - Dynamic Dashboard
🔍 El Problema: PageContainer
PageContainer (componente wrapper)
// src/components/layout/page-container.tsx
export default function PageContainer({ children, scrollable = true }) {
return (
<ScrollArea className='h-[calc(100dvh-52px)]'>
<div className='flex flex-1 p-4 md:px-6'>{children}</div>
</ScrollArea>
);
}
El issue: Aunque PageContainer solo tiene p-4 md:px-6, cuando lo usas dentro de un componente, el contenido queda limitado por:
- El
ScrollAreaque puede agregar restricciones - El wrapper
divque puede heredar limitaciones del layout padre - Potencialmente el
SidebarInsetdel layout principal que tiene clases de ancho máximo
✅ La Solución: Padding Directo
Antes (se veía a la mitad):
<PageContainer>
<div className="flex flex-col gap-6">
{/* Header */}
{/* Dashboard Grid */}
</div>
</PageContainer>
Después (ancho completo):
<div className="flex flex-1 flex-col">
{/* Header - Padding custom */}
<div className="px-4 md:px-6 py-4 space-y-4">
{/* DashboardHeader */}
{/* Alerts */}
</div>
{/* Grid - Mismo padding que PageContainer */}
<div className="flex flex-1 p-4 md:px-6">
{/* ResponsiveGridLayout */}
</div>
</div>
🎯 Cambios Específicos
1. DynamicDashboardClient.tsx:
// ❌ ANTES (cortado)
return (
<PageContainer>
<div className="flex flex-col gap-6">
<DashboardHeader />
<Grid />
</div>
</PageContainer>
);
// ✅ DESPUÉS (ancho completo)
return (
<div className="flex flex-1 flex-col">
<div className="px-4 md:px-6 py-4"> {/* Header con padding */}
<DashboardHeader />
</div>
<div className="flex flex-1 p-4 md:px-6"> {/* Grid con padding */}
<Grid />
</div>
</div>
);
2. DashboardListView.tsx:
// ❌ ANTES (cortado)
return (
<PageContainer>
<div className="space-y-6">
<Header />
<Cards Grid />
</div>
</PageContainer>
);
// ✅ DESPUÉS (ancho completo)
return (
<div className="flex flex-1 flex-col p-4 md:px-6">
<div className="space-y-6">
<Header />
<Cards Grid />
</div>
</div>
);
3. Estados de Loading, Error, Empty:
Todos los estados también fueron actualizados con la misma estructura:
// Loading state
if (!mounted || isInitialLoad) {
return (
<div className="flex flex-1 flex-col">
<div className="px-4 md:px-6 py-4 space-y-4">
{/* Header skeleton */}
</div>
<div className="flex flex-1 p-4 md:px-6">
{/* Content skeleton */}
</div>
</div>
);
}
// Error state
if (isDashboardError) {
return (
<div className="flex flex-1 flex-col">
<div className="px-4 md:px-6 py-4 space-y-4">
{/* Header + Alert */}
</div>
</div>
);
}
📊 ¿Por qué Roles y Schedule Emails sí funcionan con PageContainer?
Roles y Schedule Emails usan PageContainer SIN problema porque:
- Tienen tablas y cards que se ven mejor con ancho contenido
- No tienen grids de 12 columnas que necesiten expandirse
- El contenido es vertical (lista/tabla), no horizontal (grid dashboard)
Dynamic Dashboard necesita ancho completo porque:
- Grid de 12 columnas (react-grid-layout) que necesita espacio horizontal
- Widgets de diferentes tamaños que ocupan 4, 6, 12 columnas
- Diseño tipo "canvas" donde el usuario arrastra y redimensiona
🔑 La Diferencia Clave
flex flex-1 = "ocupar todo el espacio disponible del padre"
Al usar flex flex-1 directamente sin el wrapper de PageContainer, el componente le dice al navegador:
"Dame TODO el ancho disponible que tenga el padre (SidebarInset)"
Con PageContainer, había una capa extra que limitaba el ancho.
📝 Resumen de Cambios
| Aspecto | Antes | Después | Resultado |
|---|---|---|---|
| Wrapper | PageContainer | Padding directo | Ancho completo |
| Padding | Heredado | p-4 md:px-6 explícito |
Control total |
| Flex | Limitado por wrapper | flex flex-1 directo |
Grid expansible |
| Apariencia | Contenido "a la mitad" | Usa todo el viewport | ✅ Perfecto |
🎨 Estructura Final
SidebarInset (layout principal)
└── DynamicDashboardClient
└── <div className="flex flex-1 flex-col">
├── Header Section (px-4 md:px-6 py-4)
│ ├── DashboardHeader
│ └── Alert Components
└── Content Section (flex flex-1 p-4 md:px-6)
└── ResponsiveGridLayout
└── Widgets (12 columnas)
💡 Lecciones Aprendidas
- PageContainer es ideal para contenido tipo "documento" (tablas, listas, forms)
- Contenido tipo "canvas" necesita ancho completo (dashboards, editors, diseñadores)
flex flex-1es tu amigo cuando necesitas ocupar todo el espacio disponible- El padding se puede aplicar directamente sin necesidad de componentes wrapper
- Consistencia en estados: Loading, Error, Empty deben usar la misma estructura que el estado normal
🚀 Archivos Modificados
-
src/SplashPage.Web.Ui/src/app/dashboard/dynamicDashboard/DynamicDashboardClient.tsx- Removido PageContainer del return principal
- Aplicado padding directo en Header y Content sections
- Actualizado loading, error, y empty states
-
src/SplashPage.Web.Ui/src/app/dashboard/dynamicDashboard/_components/DashboardListView.tsx- Removido PageContainer de todos los estados
- Aplicado
flex flex-1 flex-col p-4 md:px-6consistentemente - Removido import de PageContainer
✅ Resultado Final
- ✅ Dashboard de widgets ocupa ancho completo
- ✅ Lista de dashboards ocupa ancho completo
- ✅ Todos los estados (loading, error, empty) son consistentes
- ✅ Padding uniforme en todas las vistas
- ✅ Grid de 12 columnas funciona perfectamente
- ✅ Widgets se pueden arrastrar y redimensionar usando todo el espacio disponible