Saltar a contenido

Reglas de componentes — Frontend

Componentes reutilizables del proyecto

Componentes compartidos entre varias pantallas o flujos. Ubicación y uso:

Componente Ruta Uso
pin-modal app/components/pin-modal/ Modal de código PIN (teclado numérico). Usado en Dashboard (elegir empleado, ajustes, informes), Time-control (iniciar/finalizar jornada), Staff (verificar PIN para editar/configurar).
address-modal app/dashboard/address-modal/ Modal de dirección (mapa/geocoding). Usado en Dashboard (editar lugar) y Create-place (nuevo establecimiento).
settings-modal app/dashboard/settings-modal/ Modal de Ajustes del lugar (licencia, idioma, bloqueo, etc.). Solo desde Dashboard.
create-place app/dashboard/create-place/ Formulario/modal para crear un nuevo establecimiento. Solo desde Dashboard (selector de lugar).
edit-shift-modal app/reports/edit-shift-modal/ Modal para editar una jornada (fecha/hora, motivo) en Informes. Solo desde Reports.

Al añadir un componente que vaya a usarse en más de un feature, valorar ponerlo en app/components/ (como pin-modal) y documentarlo aquí.


Componentes nuevos

  • Ubicación: páginas bajo app/<feature>/; componentes reutilizables bajo app/components/ (ej. pin-modal). Un componente por carpeta con *.component.ts|html|scss.
  • Naming: selector con prefijo app-, clase PascalCase + Component. Ej: app-pin-modalPinModalComponent.
  • Estilos: usar solo variables de theme/variables.scss y --ion-*; sin hex/rgb en el SCSS del componente (ver styles.md).
  • Data-testid: en elementos interactivos o clave para tests, usar data-testid="gk-<componente>-<elemento>" (ver testing.md).

Observables y memoria

  • En páginas y componentes que suscriban a Observable o a servicios que exponen streams: usar takeUntil(this.destroy$) y en ngOnDestroy() llamar this.destroy$.next(); this.destroy$.complete();. No dejar suscripciones sin cancelar.

Prohibido

ngOnInit() {
  this.api.getPlaces().subscribe({ next: (p) => this.places = p });
}
// Sin ngOnDestroy → fuga si el componente se destruye
Correcto
private destroy$ = new Subject<void>();
ngOnInit() {
  this.api.getPlaces().pipe(takeUntil(this.destroy$)).subscribe({ next: (p) => this.places = p });
}
ngOnDestroy() {
  this.destroy$.next();
  this.destroy$.complete();
}

  • Si el componente no tiene ngOnDestroy, no debe tener suscripciones de larga duración (o debe usar async pipe en template).

Servicios nuevos

  • providedIn: 'root' salvo que el ámbito sea claramente un módulo/feature.
  • Exponer datos por Observable cuando varios consumidores deban reaccionar; por método cuando sea una acción única (ej. login, uploadPhoto).
  • Documentar en el servicio si devuelve observables que el llamador debe cancelar (y en ese caso usar takeUntil en el componente).

Checklist rápido

  • Selector y clase con convención (app-, Component).
  • Estilos con variables Ionic; sin colores hardcodeados.
  • Suscripciones con takeUntil(destroy$) y ngOnDestroy.
  • Data-testid en botones/inputs críticos si el flujo se va a testear.