feat(sprint-3): biblioteca, recursos TO-BE, ROI mejorado e identidad de marca

Sprint 3 completo — 7 etapas:

- Etapa 1-2: biblioteca de procesos con agrupación por cliente (Dexie v4,
  LibraryPage, library-store, groupId/tags en Process)
- Etapa 3: modal de configuración global por proceso (horizonte, frecuencia,
  inversión, moneda) con validación y persistencia
- Etapa 4: panel de recursos rediseñado con soporte de unidades y minutos
  de utilización (utilizationMinutes + units)
- Etapa 5: recursos en escenario automatizado — motor de simulación,
  UI de edición en ActivityPanel, comparación AS-IS/TO-BE en reporte
- Etapa 6: PDF recursos automatizados, automatedAssignedResources requerido,
  561 tests pasando
- Etapa 7: identidad de marca — AppHeader gradiente naranja/magenta con logo
  InQuality en 5 páginas, favicon con logo real, logo/marca navegan a home

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 11:49:43 -03:00
parent d2746f07d1
commit 67e259e6ed
57 changed files with 4372 additions and 82 deletions

View File

@@ -1,5 +1,6 @@
import { useEffect, useRef, useCallback } from 'react'
import BpmnViewer from 'bpmn-js/lib/Viewer'
import { Maximize2 } from 'lucide-react'
export type BpmnElementCategory = 'activity' | 'gateway' | 'other'
@@ -152,5 +153,34 @@ export function BpmnCanvas({
}
}, [selectedElementId])
return <div ref={containerRef} className={className} style={{ width: '100%', height: '100%' }} />
return (
<div className={className} style={{ position: 'relative', width: '100%', height: '100%' }}>
<div ref={containerRef} style={{ width: '100%', height: '100%' }} />
<button
onClick={() => {
const canvas = viewerRef.current?.get('canvas') as any
canvas?.zoom('fit-viewport')
}}
title="Encuadrar diagrama"
style={{
position: 'absolute',
top: 12,
right: 12,
width: 32,
height: 32,
borderRadius: 6,
background: 'hsl(var(--background))',
border: '1px solid hsl(var(--border))',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
cursor: 'pointer',
boxShadow: '0 1px 3px rgba(0,0,0,0.1)',
zIndex: 10,
}}
>
<Maximize2 className="h-4 w-4 text-muted-foreground" />
</button>
</div>
)
}