Para arrancar este proyecto hay que ejecutar npm run start
en la raíz.
Una vez arrancado, navegar a http://localhost:4200/
.
La API está mockeada en https://apimocha.com/challenge-rooms/rooms
. Devuelve un JSON con dos plantas y sus respectivas salas.
Con la imagen recibida en el email, he identificado varios componentes reutilizables:
- Select
- Text Input
- Button
- Card
- Dialog (para añadir salas y el filtrado)
Las carpetas se dividen como se describen a continuación:
- Carpeta
shared
para implementar estos componentes e utilizarlos en las diferentes vistas. - Carpeta
services
con un servicio para tratar la API con los datos de las plantas y las salas. - Carpeta
pipes
con unpipe
para filtrar el listado de las plantas según capacidad y ocupación. - Carpeta
components
para las vistas de la aplicación. - Carpeta
models
que contiene los modelos de datos de la aplicación. Ya que en Angular se utilizantypes
, creé varios modelos de datos y poder utilizar esta ventaja de tipado. Los tipos principales sonFloor
yRoom
:
Floor = {
floor: number; //número de la planta, utilizado como ID único.
rooms: Room[]; //listado de las salas de la planta
}
Room = {
room: number; //número de la sala, utilizado como ID único.
max_capacity: number; //capacidad máxima de la sala
occupation: number; //ocupación de la sala
}
Dentro de la carpeta components
hay tres componentes:
room-filter
: contiene el diálogo y elform
para hacer el filtrado.room-form
: contiene el diálogo y elform
para añadir salas a la planta seleccionada.room-list
: página principal que lista las salas según la planta seleccionada en el select.
Recalcar que utilizo reactive forms para mejorar el rendimiento de los forms utilizados en la aplicación.
Para controlar los datos de entrada de la aplicación, utilizo Behaviour Subject
de rxjs
ya que es una herramienta útil para controlar el estado actual y compartir los datos entre componentes.
Me he encontrado con dos dificultades:
Card
component: He querido hacer todos los componentes lo más genéricos y reutilizables posibles (como elbutton
o eldialog
) para poder utilizarlos con las props correspondientes o introducir los children que sean necesarios conng-content
. En el caso de lascards
no he podido hacer esto del todo. Mi implementación ideal de lascards
hubiera sido utilizando compound components (card-title
,card-content
ycard-action
). Sin embargo, ya que cadacard
tiene su propioform
para modificar los datos de cada una, el código iba a quedar poco legible desde el componente deroom-list
(porque habría que controlar losform
de cadacard
por separado). Por tanto, la implementación delform
de modificación está en la propiacard
.- Filtrado: He tenido varios problemas con el filtrado ya que Angular no detectaba ningún cambio cuando se modificaba la variable para el lista de las salas (el
pipe
en elngFor
no se ejecutaba cuando debía). Para solucionarlo, utilicé la propiedadpure
en el decorador depipe
para que lo ejecute en cada ciclo de detección de cambios.