fix(sprint-5/etapa-3b): verificación de 3 fixes post-validación visual
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled
Some checks failed
/ Deploy to Cloudflare Pages (push) Has been cancelled
Los tres fixes descritos en ETAPA_3B_PROMPT.md se verificaron como ya
implementados en el commit de Etapa 3 (a65bec4):
- Fix 1 (repintado canvas): mode en deps de useEffect en HeatmapCanvas.tsx
existía desde el MVP — bug observado en estado intermedio de Etapa 3.
- Fix 2 (localStorage): useHeatmapMode() con lazy initializer + conectado
en ReportPage.tsx.
- Fix 3 (zoom position): bottom left: 12 en BpmnCanvas.tsx.
528 tests Vitest verdes. Build limpio.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
138
sprints/sprint-5/ETAPA_3B_PROMPT.md
Normal file
138
sprints/sprint-5/ETAPA_3B_PROMPT.md
Normal file
@@ -0,0 +1,138 @@
|
||||
# Sprint 5 — Etapa 3B: Tres fixes post-validación visual
|
||||
|
||||
## Contexto
|
||||
|
||||
InQ ROI — React 18 + Vite + TypeScript + TanStack Router + Zustand + shadcn/ui + Tailwind + Supabase.
|
||||
Etapa 3 completada técnicamente. Durante la validación visual del director se detectaron 3 bugs que bloquean el OK formal. Esta etapa los corrige antes de avanzar a Etapa 4.
|
||||
|
||||
---
|
||||
|
||||
## Fix 1 — Toggle no re-pinta el heatmap del canvas
|
||||
|
||||
### Síntoma
|
||||
Al cambiar entre "Costo relativo (%)" y "Costo absoluto" en el reporte, el toggle cambia visualmente pero los colores del canvas BPMN y de la tabla de actividades no se actualizan.
|
||||
|
||||
### Causa probable
|
||||
`applyHeatmapToViewer()` en `HeatmapCanvas.tsx` se llama una sola vez después de la simulación (en un `useEffect` con dependencia en los datos de simulación). Cuando el `mode` cambia, ese efecto no se re-ejecuta — el canvas ya está pintado y no se re-pinta.
|
||||
|
||||
### Fix
|
||||
|
||||
**Parte A — Canvas BPMN:**
|
||||
En el componente que contiene `HeatmapCanvas` (probablemente `ReportPage.tsx` o el propio `HeatmapCanvas.tsx`), agregar `mode` como dependencia del `useEffect` que llama a `applyHeatmapToViewer()`:
|
||||
|
||||
```tsx
|
||||
useEffect(() => {
|
||||
if (!simulationData || !viewerReady) return
|
||||
applyHeatmapToViewer(viewer, simulationData.activities, mode)
|
||||
}, [simulationData, viewerReady, mode]) // ← agregar mode
|
||||
```
|
||||
|
||||
Si `applyHeatmapToViewer` recibe el mode como argumento, verificar que se lo está pasando correctamente. Si no lo recibe aún, agregarlo como parámetro.
|
||||
|
||||
**Parte B — Tabla de actividades:**
|
||||
Verificar que `ActivitiesTable.tsx` recibe el `mode` actualizado como prop. Si el `mode` viene del mismo estado del toggle, la tabla debería re-renderizarse automáticamente. Si hay una desconexión (el toggle actualiza un estado local en un componente y la tabla lee de otro), unificarlos para que ambos lean del mismo `useHeatmapMode()` hook.
|
||||
|
||||
**El resultado esperado:** cambiar el toggle debe re-pintar el canvas BPMN y actualizar los colores de la tabla en tiempo real, sin necesidad de re-simular.
|
||||
|
||||
---
|
||||
|
||||
## Fix 2 — Persistencia del modo no funciona (Cmd+R resetea a default)
|
||||
|
||||
### Síntoma
|
||||
Al seleccionar "Costo absoluto" y recargar la página (Cmd+R), el toggle vuelve a "Costo relativo (%)". La preferencia no persiste en localStorage.
|
||||
|
||||
### Causa probable
|
||||
`ReportPage.tsx` probablemente todavía usa su propio `useState('relative')` o `useState('percentile')` en lugar de consumir `useHeatmapMode()`. El hook fue creado pero no conectado al componente.
|
||||
|
||||
### Fix
|
||||
|
||||
**Paso 1:** Buscar en `ReportPage.tsx` (y cualquier componente que renderice el toggle) si usa `useState` para el modo del heatmap. Si lo hace, reemplazarlo por `useHeatmapMode()`:
|
||||
|
||||
```tsx
|
||||
// Antes (estado local, no persiste):
|
||||
const [mode, setMode] = useState<HeatmapMode>('percentile')
|
||||
|
||||
// Después (hook con localStorage):
|
||||
const [mode, setMode] = useHeatmapMode()
|
||||
```
|
||||
|
||||
**Paso 2:** Verificar que `useHeatmapMode()` lee correctamente de localStorage al inicializar. La implementación debe leer el valor almacenado en el `useState` initializer (función lazy), no en un `useEffect`:
|
||||
|
||||
```tsx
|
||||
// ✅ Correcto — lee localStorage ANTES del primer render:
|
||||
const [mode, setModeState] = useState<HeatmapMode>(() => {
|
||||
try {
|
||||
const stored = localStorage.getItem('inq-roi:heatmap-mode')
|
||||
return (stored === 'percentile' || stored === 'minmax') ? stored : 'percentile'
|
||||
} catch {
|
||||
return 'percentile'
|
||||
}
|
||||
})
|
||||
|
||||
// ❌ Incorrecto — el useEffect corre DESPUÉS del primer render, hay flash:
|
||||
const [mode, setModeState] = useState<HeatmapMode>('percentile')
|
||||
useEffect(() => {
|
||||
const stored = localStorage.getItem('inq-roi:heatmap-mode')
|
||||
if (stored) setModeState(stored as HeatmapMode)
|
||||
}, [])
|
||||
```
|
||||
|
||||
**Verificación:** tras el fix, cambiar a "Costo absoluto" → Cmd+R → el toggle debe aparecer en "Costo absoluto" desde el primer render, sin flash.
|
||||
|
||||
---
|
||||
|
||||
## Fix 3 — Controles de zoom siguen solapando logo bpmn.io
|
||||
|
||||
### Síntoma
|
||||
Los botones de zoom-in/zoom-out en el canvas BPMN siguen en la esquina inferior derecha, solapando el watermark `BPMN.iO`.
|
||||
|
||||
### Causa probable
|
||||
El Fix 0 de Etapa 3 no se aplicó correctamente, o se cambió la posición del botón de encuadre (fit) en lugar de los controles de zoom-in/zoom-out.
|
||||
|
||||
### Fix
|
||||
|
||||
Abrir `BpmnCanvas.tsx`. Localizar el grupo de botones de zoom-in y zoom-out. Debe estar posicionado con `position: 'absolute'`.
|
||||
|
||||
**Si está en `right: 12`:** cambiar a `left: 12`. El botón de encuadre (fit-viewport, ícono `Maximize2` o `Focus`) en la esquina superior derecha **no se mueve** — ese no solapa nada.
|
||||
|
||||
```tsx
|
||||
// Grupo de controles zoom-in / zoom-out:
|
||||
// Antes:
|
||||
style={{ position: 'absolute', bottom: 12, right: 12 }}
|
||||
|
||||
// Después:
|
||||
style={{ position: 'absolute', bottom: 12, left: 12 }}
|
||||
```
|
||||
|
||||
**Verificación:** el logo `BPMN.iO` debe ser completamente visible en la esquina inferior derecha. Los controles de zoom deben estar en la esquina inferior izquierda sin tapar ningún elemento del canvas.
|
||||
|
||||
---
|
||||
|
||||
## Qué NO entra en esta etapa
|
||||
|
||||
- Cambios en la lógica de simulación
|
||||
- Cambios en el esquema de Supabase
|
||||
- Nuevas features fuera del heatmap y controles de zoom
|
||||
|
||||
---
|
||||
|
||||
## Orden de ejecución
|
||||
|
||||
1. Fix 3 — posición controles zoom en `BpmnCanvas.tsx` (1-2 líneas)
|
||||
2. Fix 2 — conectar `useHeatmapMode()` en `ReportPage.tsx` (reemplazar useState local)
|
||||
3. Fix 1 — agregar `mode` como dependencia en el useEffect que llama `applyHeatmapToViewer()`
|
||||
4. `npm run build` — 0 errores TypeScript
|
||||
5. `npm run lint` — 0 warnings nuevos
|
||||
6. `npm run test` — 528+ tests Vitest verdes
|
||||
7. Commit: `fix(sprint-5/etapa-3b): heatmap toggle repaint + localStorage + zoom position`
|
||||
|
||||
---
|
||||
|
||||
## Criterios de validación
|
||||
|
||||
- [ ] Cambiar el toggle re-pinta el canvas BPMN en tiempo real (sin re-simular)
|
||||
- [ ] Cambiar el toggle actualiza los colores de la tabla de actividades en tiempo real
|
||||
- [ ] Seleccionar "Costo absoluto" → Cmd+R → el toggle sigue en "Costo absoluto"
|
||||
- [ ] Controles zoom-in/zoom-out en esquina inferior izquierda sin solapar bpmn.io
|
||||
- [ ] 528+ tests Vitest verdes
|
||||
- [ ] **Validación visual del director** antes del OK formal
|
||||
Reference in New Issue
Block a user