206 lines
6.0 KiB
Markdown
206 lines
6.0 KiB
Markdown
# Full Width Optimization - Dynamic Dashboard
|
|
|
|
## 🔍 El Problema: PageContainer
|
|
|
|
### PageContainer (componente wrapper)
|
|
```tsx
|
|
// 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:
|
|
1. El `ScrollArea` que puede agregar restricciones
|
|
2. El wrapper `div` que puede heredar limitaciones del layout padre
|
|
3. Potencialmente el `SidebarInset` del layout principal que tiene clases de ancho máximo
|
|
|
|
## ✅ La Solución: Padding Directo
|
|
|
|
### Antes (se veía a la mitad):
|
|
```tsx
|
|
<PageContainer>
|
|
<div className="flex flex-col gap-6">
|
|
{/* Header */}
|
|
{/* Dashboard Grid */}
|
|
</div>
|
|
</PageContainer>
|
|
```
|
|
|
|
### Después (ancho completo):
|
|
```tsx
|
|
<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**:
|
|
```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**:
|
|
```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:
|
|
|
|
```tsx
|
|
// 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:
|
|
|
|
1. **Tienen tablas y cards que se ven mejor con ancho contenido**
|
|
2. **No tienen grids de 12 columnas** que necesiten expandirse
|
|
3. **El contenido es vertical** (lista/tabla), no horizontal (grid dashboard)
|
|
|
|
**Dynamic Dashboard necesita ancho completo** porque:
|
|
|
|
1. **Grid de 12 columnas** (react-grid-layout) que necesita espacio horizontal
|
|
2. **Widgets de diferentes tamaños** que ocupan 4, 6, 12 columnas
|
|
3. **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
|
|
|
|
1. **PageContainer es ideal para contenido tipo "documento"** (tablas, listas, forms)
|
|
2. **Contenido tipo "canvas" necesita ancho completo** (dashboards, editors, diseñadores)
|
|
3. **`flex flex-1` es tu amigo** cuando necesitas ocupar todo el espacio disponible
|
|
4. **El padding se puede aplicar directamente** sin necesidad de componentes wrapper
|
|
5. **Consistencia en estados**: Loading, Error, Empty deben usar la misma estructura que el estado normal
|
|
|
|
## 🚀 Archivos Modificados
|
|
|
|
1. `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
|
|
|
|
2. `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-6` consistentemente
|
|
- 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
|