Un dashboard moderno construido con Angular 20 siguiendo los principios de Arquitectura Limpia (Clean Architecture) y utilizando NgRx Signals para el manejo de estado reactivo.
- 📊 Dashboard interactivo con métricas en tiempo real
- 📈 Gráficos responsivos con ECharts
- 🌙 Cambio de tema oscuro/claro
- 📱 Diseño responsive para móviles
- ⚡ Carga rápida con signals reactivos
- Demo
- Características
- Tecnologías
- Arquitectura
- Estructura del Proyecto
- Instalación
- Ejecución Local
- Testing
- API Endpoints
- Estados de la UI
- Scripts Disponibles
- 🏗️ Arquitectura Limpia: Separación clara de responsabilidades entre capas
- ⚡ NgRx Signals: Estado reactivo y performante
- 📊 ECharts: Gráficos interactivos y responsivos
- 🎨 Tailwind CSS: Estilos modernos y utilitarios
- 🧪 Jest: Testing unitario completo
- 🚀 Cypress: Testing end-to-end robusto
- 📱 Responsive Design: Optimizado para todos los dispositivos
- 🌙 Tema Oscuro/Claro: Soporte para múltiples temas
- Angular 20.1.0 - Framework principal
- TypeScript 5.8.2 - Lenguaje de programación
- NgRx Signals 20.0.0 - Manejo de estado reactivo
- RxJS 7.8.0 - Programación reactiva
- Tailwind CSS 4.1.11 - Framework de CSS utilitario
- ECharts 6.0.0 - Biblioteca de gráficos
- ngx-echarts 20.0.1 - Integración de ECharts con Angular
- Material Design Icons - Iconografía
- Jest 29.5.0 - Framework de testing unitario
- jest-preset-angular 14.0.0 - Preset para Angular
- jest-html-reporter 4.3.0 - Reportes HTML de tests
- Cypress 14.5.4 - Framework de testing end-to-end
- @cypress/schematic 4.1.0 - Integración de Cypress con Angular
- eslint-plugin-cypress 5.1.1 - Linting para tests de Cypress
- ESLint 9.29.0 - Linter de código
- Prettier 3.6.2 - Formateador de código
- PostCSS 8.5.6 - Procesador de CSS
- start-server-and-test 2.0.13 - Orquestación de tests E2E
Este proyecto implementa Arquitectura Limpia con las siguientes capas:
UI Component → Store → Use Case → Port → Adapter → API
↑ ↓
└───────────┘
Consume Data
- Interfaces: Contratos de datos (
*.interface.ts
) - Models: Entidades de dominio (
*.ts
) - Ports: Abstracciones de infraestructura (
*.port.ts
)
- Use Cases: Lógica de negocio (
*.usecase.ts
) - Store: Manejo de estado con NgRx Signals (
*.store.ts
)
- Adapters: Implementaciones concretas (
*.adapter.ts
) - DTOs: Objetos de transferencia de datos (
*.ts
)
- Components: Componentes de presentación
- Shared Components: Componentes reutilizables
- Enums: Constantes y enumeraciones
src/app/dashboard/
├── domain/ # Capa de dominio
│ ├── interfaces/ # Contratos de datos
│ ├── models/ # Entidades de dominio
│ └── ports/ # Abstracciones de infraestructura
├── application/ # Capa de aplicación
│ ├── store/ # Stores con NgRx Signals
│ └── use-case/ # Casos de uso
├── infrastructure/ # Capa de infraestructura
│ ├── adapters/ # Implementaciones concretas
│ └── dtos/ # Objetos de transferencia
└── ui/ # Capa de presentación
├── components/ # Componentes específicos
│ ├── sales-metrics/ # Métricas de ventas
│ ├── sales-overview/ # Resumen de ventas
│ ├── sales-by-region/ # Ventas por región
│ ├── registered-users/ # Usuarios registrados
│ ├── list-integration/ # Lista de integraciones
│ └── shared/ # Componentes compartidos
│ ├── card-metric/ # Tarjeta de métrica
│ ├── donut-chart/ # Gráfico de dona
│ ├── line-chart/ # Gráfico de líneas
│ └── radar-chart/ # Gráfico de radar
└── enums/ # Constantes y enumeraciones
Este proyecto consume datos de la API DummyJSON (https://dummyjson.com
) para simular datos reales del dashboard.
https://dummyjson.com
Endpoint | Método | Descripción | ID JSON |
---|---|---|---|
https://dummyjson.com/c/1dbe-8a86-4247-8d53 |
GET |
Métricas de ventas | 1dbe-8a86-4247-8d53 |
https://dummyjson.com/c/66ff-e4d9-4d77-80c1 |
GET |
Resumen general de ventas | 66ff-e4d9-4d77-80c1 |
https://dummyjson.com/c/7e36-14ca-4b32-a6b4 |
GET |
Ventas por región | 7e36-14ca-4b32-a6b4 |
https://dummyjson.com/c/e3d8-2efc-4e24-a7bc |
GET |
Usuarios registrados | e3d8-2efc-4e24-a7bc |
https://dummyjson.com/c/3bde-f00f-4eb3-a567 |
GET |
Integraciones disponibles | 3bde-f00f-4eb3-a567 |
Todos los endpoints devuelven datos en el siguiente formato:
{
"stats": [...], // Para métricas de ventas
"salesOverview": {...}, // Para resumen de ventas
"regionStats": [...], // Para ventas por región
"users": {...}, // Para usuarios registrados
"integrations": [...] // Para integraciones
}
La URL base se configura en el archivo de environment:
// src/environments/environment.ts
export const environment = {
production: false,
apiUrl: 'https://dummyjson.com',
};
-
Clona el repositorio
git clone <url-del-repositorio> cd dashboard
-
Instala las dependencias
npm install
npm start
# o
ng serve
La aplicación estará disponible en http://localhost:4200/
npm run build
npm run watch
npm test
npm run test:watch
npm run test:coverage
Los reportes de cobertura se generan en reports/test-report.html
src/app/dashboard/
├── domain/models/test/ # Tests de modelos
├── application/store/test/ # Tests de stores
├── application/use-case/test/ # Tests de casos de uso
├── infrastructure/adapters/test/ # Tests de adaptadores
└── ui/components/test/ # Tests de componentes
# Ejecutar tests en modo headless
npm run e2e
# Ejecutar tests con interfaz gráfica
npm run e2e:open
# Ejecutar Cypress directamente
npm run cypress:open
npm run cypress:run
El proyecto incluye una configuración completa de Cypress con:
- Base URL:
http://localhost:4200
- Viewport: 1280x720
- Timeouts: 10 segundos para comandos y requests
- Screenshots: Automáticos en fallos
- Videos: Deshabilitados para optimizar velocidad
cypress/
├── e2e/ # Tests end-to-end
│ ├── dashboard.cy.ts # Tests del dashboard principal
│ ├── app.cy.ts # Tests básicos de la aplicación
│ ├── 1-getting-started/ # Tests de introducción
│ └── 2-advanced-examples/ # Tests avanzados
├── fixtures/ # Datos de prueba
├── support/ # Archivos de soporte
│ ├── commands.ts # Comandos personalizados
│ ├── component.ts # Soporte para testing de componentes
│ └── e2e.ts # Configuración E2E
└── component/ # Tests de componentes (opcional)
Tests del Dashboard:
- ✅ Verificación de carga inicial con skeletons
- ✅ Validación de métricas de ventas
- ✅ Manejo de estados de error
- ✅ Interacción con gráficos
- ✅ Responsive design testing
- ✅ Cambio de tema oscuro/claro
Comandos Personalizados:
cy.waitForAngular()
- Espera a que Angular esté listocy.get('[data-test-id="..."]')
- Selectores consistentes- Interceptación de APIs para testing de errores
describe('Dashboard - Sales Metrics', () => {
beforeEach(() => {
cy.visit('/');
});
it('should display sales metrics after loading', () => {
// Verificar estado de carga
cy.get('[data-test-id="loading-skeleton-container"]').should('be.visible');
// Esperar a que se carguen las métricas
cy.get('[data-test-id="metric-card"]', { timeout: 10000 }).should('be.visible');
// Verificar contenido de las métricas
cy.get('[data-test-id="metric-title"]').should('not.be.empty');
cy.get('[data-test-id="metric-value"]').should('not.be.empty');
});
});
Los adaptadores manejan automáticamente:
- ✅ Respuestas exitosas (200)
- ❌ Errores de red
- ⏱️ Timeouts de conexión
- 🔄 Reintentos automáticos
- Datos Simulados: Todos los datos son simulados para propósitos de demostración
- Sin Autenticación: La API no requiere tokens de autenticación
- Rate Limiting: Respeta los límites de la API de DummyJSON
- CORS: Configurado para permitir peticiones desde localhost
El dashboard implementa un sistema de carga elegante utilizando ngx-skeleton-loader que proporciona una experiencia de usuario fluida mientras se cargan los datos.
Características del Skeleton Loading:
- ⚡ Carga Inmediata: Los skeletons aparecen instantáneamente
- 🎯 Forma Realista: Mantiene la estructura visual del contenido final
- 🌊 Animación Suave: Efecto de pulso que indica actividad
- 📱 Responsive: Se adapta a diferentes tamaños de pantalla
- 🎨 Tema Consistente: Coincide con el diseño del dashboard
Cuando ocurre un error en la carga de datos, el dashboard muestra un estado de error informativo y amigable.
Características del Estado de Error:
- ❌ Mensaje Claro: Información específica sobre el error
- 🔄 Opción de Reintento: Botón para intentar cargar nuevamente
- 🎨 Diseño Consistente: Mantiene la estética del dashboard
- 📱 Responsive: Se adapta a dispositivos móviles
- 🎯 UX Amigable: No interrumpe la experiencia del usuario
Comando | Descripción |
---|---|
npm start |
Inicia el servidor de desarrollo |
npm run build |
Construye la aplicación para producción |
npm run watch |
Construye en modo watch |
npm test |
Ejecuta tests unitarios con Jest |
npm run test:watch |
Ejecuta tests unitarios en modo watch |
npm run test:coverage |
Ejecuta tests unitarios con cobertura |
npm run e2e |
Ejecuta tests end-to-end (headless) |
npm run e2e:open |
Ejecuta tests end-to-end con interfaz gráfica |
npm run cypress:open |
Abre Cypress Test Runner |
npm run cypress:run |
Ejecuta Cypress en modo headless |
npm run lint |
Ejecuta el linter |
npm run lint:fix |
Corrige errores del linter automáticamente |
- Fork el proyecto
- Crea una rama para tu feature (
git checkout -b feature/AmazingFeature
) - Commit tus cambios (
git commit -m 'Add some AmazingFeature'
) - Push a la rama (
git push origin feature/AmazingFeature
) - Abre un Pull Request
Este proyecto está bajo la Licencia MIT. Ver el archivo LICENSE
para más detalles.
Desarrollado con ❤️ usando Angular y Arquitectura Limpia