Skip to content
Snippets Groups Projects
Commit 12fe7db2 authored by migudel's avatar migudel :speech_balloon:
Browse files

Merge branch 'dev/update/disgregar_acceso_servicios_angular' into 'develop'

Cambios en entorno y componentes para trabajar con nuevas especificaciones

See merge request !12
parents 3a99c6fa 190a99c5
No related branches found
No related tags found
2 merge requests!26Revert "Funciona register",!12Cambios en entorno y componentes para trabajar con nuevas especificaciones
Showing
with 360 additions and 126 deletions
......@@ -44,8 +44,8 @@
"budgets": [
{
"type": "initial",
"maximumWarning": "500kB",
"maximumError": "1MB"
"maximumWarning": "1.2MB",
"maximumError": "1.3MB"
},
{
"type": "anyComponentStyle",
......@@ -55,6 +55,22 @@
],
"outputHashing": "all"
},
"monolith": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.monolith.ts"
}
]
},
"microservices": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.microservices.ts"
}
]
},
"development": {
"optimization": false,
"extractLicenses": false,
......@@ -71,6 +87,12 @@
},
"development": {
"buildTarget": "RestClient:build:development"
},
"monolith": {
"buildTarget": "RestClient:build:monolith"
},
"microservices": {
"buildTarget": "RestClient:build:microservices"
}
},
"defaultConfiguration": "development"
......@@ -102,8 +124,5 @@
}
}
}
},
"cli": {
"analytics": false
}
}
......@@ -8,11 +8,11 @@ import { FormsModule } from '@angular/forms';
import { MatInputModule } from '@angular/material/input';
import { MatSelectModule } from '@angular/material/select';
import { Hotel, Room, RoomType, roomTypeArray } from '../../../../../types';
import { Router } from '@angular/router';
import { MatCardModule } from '@angular/material/card';
import { MatChipsModule } from '@angular/material/chips';
import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
import { LocalStorageService } from '../../../../shared/local-storage.service';
import { HotelClientService } from '../../../../shared/hotel-client.service';
type SelectableRoomType = 'All' | RoomType;
const selectableRoomTypeArray: SelectableRoomType[] = ['All', ...roomTypeArray];
......@@ -45,14 +45,18 @@ export class BookingListComponent {
rooms: Room[] = [];
trateRooms: Room[] = [];
constructor(private router: Router, private client: ClienteApiRestService) {}
constructor(
private router: Router,
private hotelClient: HotelClientService,
private storage: LocalStorageService
) {}
ngOnInit() {
this.getHotels();
}
getHotels() {
this.client.getAllHotels().subscribe({
this.hotelClient.getAllHotels().subscribe({
next: (resp) => {
if (resp != null) this.hotels = [...resp];
},
......@@ -72,7 +76,7 @@ export class BookingListComponent {
}
search() {
this.client
this.hotelClient
.getRoomsAvailableInDateRange(
this.hotelSelected!.id,
this.start!,
......@@ -95,14 +99,11 @@ export class BookingListComponent {
}
bookingRoom(roomId: number) {
localStorage.setItem(
'booking-data',
JSON.stringify({
this.storage.save('booking-data', {
roomId,
startDate: this.start,
endDate: this.end,
})
);
});
this.router.navigate(['/bookings', 'new'], { queryParams: { roomId } });
}
}
......@@ -6,10 +6,17 @@ import {
Validators,
} from '@angular/forms';
import { BookingService } from '../../../../shared/booking.service'; // Asegúrate de que el servicio exista
import { ActivatedRoute, Router } from '@angular/router';
import { Booking, User } from '../../../../../types';
import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
import { LocalStorageService } from '../../../../shared/local-storage.service';
import { BookingClientService } from '../../../../shared/booking-client.service';
import { UserClientService } from '../../../../shared/user-client.service';
type communication = {
roomId: number;
startDate: Date;
endDate: Date;
};
@Component({
standalone: true,
......@@ -21,15 +28,20 @@ import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.servi
export class BookingComponent implements OnInit {
users: User[] = [];
bookingForm: FormGroup;
bookingLocal: { roomId: number; startDate: Date; endDate: Date };
bookingLocal: { roomId: number; startDate: Date; endDate: Date } = {
roomId: 0,
endDate: new Date(),
startDate: new Date(),
};
roomId: number = 0;
constructor(
private router: Router,
private route: ActivatedRoute,
private fb: FormBuilder,
private bookingService: BookingService,
private client: ClienteApiRestService
private bookingClient: BookingClientService,
private userClient: UserClientService,
private storage: LocalStorageService
) {
// Inicialización del formulario con validaciones
this.bookingForm = this.fb.group({
......@@ -38,21 +50,22 @@ export class BookingComponent implements OnInit {
startDate: ['', Validators.required],
endDate: ['', Validators.required],
});
const localBookingStr = localStorage.getItem('booking-data');
if (localBookingStr === null) {
const localBooking = storage.read<communication | null>('booking-data');
if (localBooking === null) {
this.router.navigate(['/booking', 'search']);
return;
}
const localBooking = JSON.parse(localBookingStr!);
this.bookingLocal = localBooking;
this.bookingLocal = localBooking!;
this.route.queryParams.subscribe((params) => {
const roomId = Number(params['roomId']);
this.roomId = roomId;
if (localBooking.roomId !== roomId) {
if (this.bookingLocal.roomId !== roomId) {
this.router.navigate(['/bookings', 'search']);
this.loadBooking(localBooking);
return;
}
this.loadBooking();
});
this.client.getAllUsers().subscribe({
this.userClient.getAllUsers().subscribe({
next: (resp) => {
this.users = resp;
},
......@@ -67,10 +80,12 @@ export class BookingComponent implements OnInit {
}
ngOnInit() {
this.loadBooking(this.bookingLocal);
this.loadBooking();
}
loadBooking(booking: { roomId: number; startDate: Date; endDate: Date }) {
loadBooking() {
const booking = this.bookingLocal;
if (!booking) return;
const start = new Date(booking.startDate).toISOString().split('T')[0];
const end = new Date(booking.endDate).toISOString().split('T')[0];
this.bookingForm = this.fb.group({
......@@ -95,11 +110,11 @@ export class BookingComponent implements OnInit {
};
// Llama al servicio para crear una nueva reserva
this.bookingService.createBooking(bookingRequest).subscribe({
this.bookingClient.createBooking(bookingRequest).subscribe({
next: (response) => {
console.log('Reserva creada con éxito', response);
// Llama al servicio para actualizar el estado del usuario
this.client
this.userClient
.alterUserStatus(userId, 'WITH_ACTIVE_BOOKINGS')
.subscribe({
next: (response) => {
......@@ -107,7 +122,7 @@ export class BookingComponent implements OnInit {
'Estado de usuario actualizado con exito',
response
);
localStorage.removeItem('booking-data');
this.storage.remove('booking-data');
this.router.navigate(['/user', userId, 'bookings']);
},
error: (error) => {
......
......
......@@ -12,7 +12,7 @@ import { MatSlideToggle } from '@angular/material/slide-toggle';
import { MatTable, MatTableModule } from '@angular/material/table';
import { MatButton } from '@angular/material/button';
import { NgbAccordionModule } from '@ng-bootstrap/ng-bootstrap';
import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
import { HotelClientService } from '../../../../shared/hotel-client.service';
@Component({
selector: 'app-hotel-list',
......@@ -38,14 +38,17 @@ export class HotelListComponent {
mostrarMensaje!: boolean;
mensaje!: string;
constructor(private router: Router, private client: ClienteApiRestService) {}
constructor(
private router: Router,
private hotelClient: HotelClientService
) {}
ngOnInit() {
this.getHotels();
}
getHotels() {
this.client.getAllHotels().subscribe({
this.hotelClient.getAllHotels().subscribe({
next: (resp) => {
if (!!resp || (resp as never[]).length != 0) this.hotels = [...resp];
},
......@@ -59,7 +62,7 @@ export class HotelListComponent {
deleteHotel(id: number) {
if (!confirm(`Borrar hotel con id ${id}. Continuar?`)) return;
this.client.deleteHotel(id).subscribe({
this.hotelClient.deleteHotel(id).subscribe({
next: (resp) => {
if (resp.status < 400) {
this.mostrarMensaje = true;
......@@ -82,7 +85,9 @@ export class HotelListComponent {
roomId: number,
availability: boolean
) {
this.client.alterRoomAvailability(hotelId, roomId, availability).subscribe({
this.hotelClient
.alterRoomAvailability(hotelId, roomId, availability)
.subscribe({
next: (resp) => {
if (resp.status < 400) {
this.mostrarMensaje = true;
......
......
......@@ -13,9 +13,9 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatSelectModule } from '@angular/material/select';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { CommonModule } from '@angular/common';
import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
import { Address, Hotel, Room } from '../../../../../types';
import { ActivatedRoute, Router } from '@angular/router';
import { HotelClientService } from '../../../../shared/hotel-client.service';
const emptyRoom: Room = {
id: 0,
......@@ -59,7 +59,7 @@ export class HotelRegisterComponent {
private router: Router,
private route: ActivatedRoute,
private fb: FormBuilder,
private client: ClienteApiRestService
private hotelClient: HotelClientService
) {
this.hotelForm = this.setHotelForm();
this.editMode = false;
......@@ -68,7 +68,7 @@ export class HotelRegisterComponent {
const id = Number(params.get('id'));
this.editMode = id !== 0;
if (this.editMode) {
this.client.getHotel(id).subscribe({
this.hotelClient.getHotel(id).subscribe({
next: (h) => this.setHotelForm(h),
error: (error) => {
this.router.navigate(['/hotels/new']);
......@@ -102,7 +102,7 @@ export class HotelRegisterComponent {
onSubmit(): void {
if (this.hotelForm.valid) {
const hotel = this.hotelForm.value as Hotel;
this.client.addHotel(hotel).subscribe({
this.hotelClient.addHotel(hotel).subscribe({
next: (resp) => {
if (resp.status < 400) {
alert('Hotel guardado correctamente');
......
......
// main-page.component.ts
import { Component, OnInit } from '@angular/core';
import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
import { User, UserStateFilter } from '../../../../../types';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import users from '../../../../../mocks/users.json';
import { RouterModule } from '@angular/router';
import { UserClientService } from '../../../../shared/user-client.service';
@Component({
standalone: true,
imports: [FormsModule, CommonModule, RouterModule],
......@@ -18,11 +18,11 @@ export class MainPageComponent implements OnInit {
filteredUsers: User[] = [];
selectedStatus: UserStateFilter = 'All';
constructor(private ClienteApiRestService: ClienteApiRestService) {}
constructor(private userClient: UserClientService) {}
ngOnInit(): void {
this.users = users as unknown as User[];
this.ClienteApiRestService.getAllUsers().subscribe((data: User[]) => {
this.userClient.getAllUsers().subscribe((data: User[]) => {
this.users = data;
this.filteredUsers = data; // Inicialmente, muestra todos los usuarios
});
......
......
import { Component } from '@angular/core';
import { ClienteApiRestService } from '../../../../shared/cliente-api-rest.service';
import { Booking, User } from '../../../../../types';
import { ActivatedRoute, RouterModule } from '@angular/router';
import { MatSelectModule } from '@angular/material/select';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { BookingService } from '../../../../shared/booking.service';
import { UserClientService } from '../../../../shared/user-client.service';
import { BookingClientService } from '../../../../shared/booking-client.service';
type state = 'all' | 'active' | 'inactive';
......@@ -24,8 +24,8 @@ export class UserBookingListComponent {
user?: User;
constructor(
private client: ClienteApiRestService,
private bookingClient: BookingService,
private userClient: UserClientService,
private bookingClient: BookingClientService,
private route: ActivatedRoute
) {
this.route.paramMap.subscribe({
......@@ -34,7 +34,7 @@ export class UserBookingListComponent {
this.updateBookings();
},
});
this.client
this.userClient
.getUser(this.userId)
.subscribe({ next: (user) => (this.user = user) });
}
......@@ -44,7 +44,7 @@ export class UserBookingListComponent {
}
updateBookings() {
this.client.getUserBookings(this.userId).subscribe({
this.bookingClient.getUserBookings(this.userId).subscribe({
next: (bookings) => {
this.search = true;
switch (this.selectedState) {
......@@ -88,7 +88,7 @@ export class UserBookingListComponent {
}
updateUserStatus() {
this.client.getUserBookings(this.userId).subscribe({
this.bookingClient.getUserBookings(this.userId).subscribe({
next: (bookings) => {
const withActive = bookings.find(
(booking) => this.genBookingState(booking) === 'Reserva activa'
......@@ -97,7 +97,7 @@ export class UserBookingListComponent {
(booking) => this.genBookingState(booking) === 'Reserva inactiva'
);
if (withActive) {
this.client
this.userClient
.alterUserStatus(this.userId, 'WITH_ACTIVE_BOOKINGS')
.subscribe({
next: (response) => {
......@@ -108,7 +108,7 @@ export class UserBookingListComponent {
},
});
} else if (withInactive) {
this.client
this.userClient
.alterUserStatus(this.userId, 'WITH_INACTIVE_BOOKINGS')
.subscribe({
next: (response) => {
......@@ -123,7 +123,9 @@ export class UserBookingListComponent {
},
});
} else {
this.client.alterUserStatus(this.userId, 'NO_BOOKINGS').subscribe({
this.userClient
.alterUserStatus(this.userId, 'NO_BOOKINGS')
.subscribe({
next: (response) => {
console.log(
'Cambio de estado en el usuario a sin reservas correcto'
......
......
import { TestBed } from '@angular/core/testing';
import { BookingService } from './booking.service';
import { AuthClientService } from './auth-client.service';
describe('BookingService', () => {
let service: BookingService;
describe('AuthClientService', () => {
let service: AuthClientService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(BookingService);
service = TestBed.inject(AuthClientService);
});
it('should be created', () => {
......
......
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
@Injectable({
providedIn: 'root',
})
export class AuthClientService {
private readonly URI = environment.authAPI;
constructor() {}
}
import { TestBed } from '@angular/core/testing';
import { ClienteApiRestService } from './cliente-api-rest.service';
import { BookingClientService } from './booking-client.service';
describe('ClienteApiRestService', () => {
let service: ClienteApiRestService;
describe('BookingClientService', () => {
let service: BookingClientService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(ClienteApiRestService);
service = TestBed.inject(BookingClientService);
});
it('should be created', () => {
......
......
// booking.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { environment } from '../../environments/environment';
import { Booking } from '../../types/Booking'; // Ajusta la ruta a tu modelo Booking
import { User, UserState } from '../../types';
@Injectable({
providedIn: 'root', // Esto hace que el servicio esté disponible en toda la aplicación
providedIn: 'root',
})
export class BookingService {
private apiUrl = 'http://localhost:8080/bookings';
export class BookingClientService {
private URI = environment.bookingAPI;
constructor(private http: HttpClient) {}
// Método para crear una nueva reserva
createBooking(bookingRequest: Booking): Observable<Booking> {
return this.http.post<Booking>(this.apiUrl, bookingRequest, {
return this.http.post<Booking>(this.URI, bookingRequest, {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
......@@ -25,16 +23,21 @@ export class BookingService {
// Método para obtener todas las reservas
getAllBookings(): Observable<Booking[]> {
return this.http.get<Booking[]>(this.apiUrl);
return this.http.get<Booking[]>(this.URI);
}
// Método para obtener una reserva por ID
getBookingById(id: number): Observable<Booking> {
return this.http.get<Booking>(`${this.apiUrl}/${id}`);
return this.http.get<Booking>(`${this.URI}/${id}`);
}
getUserBookings(userId: number) {
// TODO revisar tras división en microservicios
return this.http.get<Booking[]>(`${this.URI}/${userId}/bookings`);
}
// Método para eliminar una reserva
deleteBooking(id: number) {
return this.http.delete(`${this.apiUrl}/${id}`);
return this.http.delete(`${this.URI}/${id}`);
}
}
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class DataService {
private message = new BehaviorSubject('hotel list');
currentMessage = this.message.asObservable();
private showMessage = new BehaviorSubject<boolean>(false);
showCurrentMessage = this.showMessage.asObservable();
constructor() {}
setMessage(message: string) {
this.message.next(message);
}
setShowCurrentMessage(valor: boolean) {
this.showMessage.next(valor);
}
}
import { TestBed } from '@angular/core/testing';
import { HotelClientService } from './hotel-client.service';
describe('HotelClientService', () => {
let service: HotelClientService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(HotelClientService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Hotel, Booking, Room, UserState } from '../../types';
import { User } from '../../types';
import { environment } from '../../environments/environment';
import { HttpClient } from '@angular/common/http';
import { Hotel, Room } from '../../types';
@Injectable({
providedIn: 'root',
})
export class ClienteApiRestService {
private static readonly BASE_URI = 'http://localhost:8080';
private static readonly HOTEL_URI = `${ClienteApiRestService.BASE_URI}/hotels`;
private static readonly USER_URI = `${ClienteApiRestService.BASE_URI}/users`;
export class HotelClientService {
private readonly URI = environment.hotelAPI;
constructor(private http: HttpClient) {}
getHotel(id: number) {
const url = `${ClienteApiRestService.HOTEL_URI}/${id}`;
const url = `${this.URI}/${id}`;
return this.http.get<Hotel>(url);
}
getAllHotels() {
const url = `${ClienteApiRestService.HOTEL_URI}`;
const url = `${this.URI}`;
return this.http.get<Hotel[]>(url);
}
deleteHotel(id: number) {
const url = `${ClienteApiRestService.HOTEL_URI}/${id}`;
const url = `${this.URI}/${id}`;
return this.http.delete(url, { observe: 'response', responseType: 'text' });
}
addHotel(hotel: Hotel) {
const url = `${ClienteApiRestService.HOTEL_URI}`;
const url = `${this.URI}`;
return this.http.post(url, hotel, {
observe: 'response',
responseType: 'text',
......@@ -40,7 +38,7 @@ export class ClienteApiRestService {
roomId: number,
availability: boolean
) {
const url = `${ClienteApiRestService.HOTEL_URI}/${hotelId}/rooms/${roomId}`;
const url = `${this.URI}/${hotelId}/rooms/${roomId}`;
return this.http.patch(
url,
{ available: availability },
......@@ -51,43 +49,10 @@ export class ClienteApiRestService {
);
}
createBooking(bookingRequest: Booking) {
return this.http.post('http://localhost:8080/bookings', bookingRequest);
}
getRoomsAvailableInDateRange(hotelId: number, start: Date, end: Date) {
const startStr = start.toISOString().split('T')[0];
const endStr = end.toISOString().split('T')[0];
const url = `${ClienteApiRestService.HOTEL_URI}/${hotelId}/rooms?start=${startStr}&end=${endStr}`;
const url = `${this.URI}/${hotelId}/rooms?start=${startStr}&end=${endStr}`;
return this.http.get<Room[]>(url);
}
getUser(userId: number) {
return this.http.get<User>(`http://localhost:8080/users/${userId}`);
}
getAllUsers() {
return this.http.get<User[]>('http://localhost:8080/users', {
observe: 'body',
});
}
getUserBookings(userId: number) {
return this.http.get<Booking[]>(
`${ClienteApiRestService.BASE_URI}/users/${userId}/bookings`
);
}
alterUserStatus(userId: number, status: UserState) {
return this.http.patch(
`${ClienteApiRestService.BASE_URI}/users/${userId}`,
{
status,
},
{
observe: 'response',
responseType: 'text',
}
);
}
}
import { TestBed } from '@angular/core/testing';
import { LocalStorageService } from './local-storage.service';
describe('LocalStorageService', () => {
let service: LocalStorageService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(LocalStorageService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});
import { isPlatformBrowser } from '@angular/common';
import { Inject, Injectable, PLATFORM_ID } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class LocalStorageService {
// isBrowser: boolean;
// constructor(@Inject(PLATFORM_ID) private platformId: Object) {
// this.isBrowser = isPlatformBrowser(this.platformId);
// }
save(key: string, value: any) {
// if (!this.isBrowser) return;
localStorage.setItem(key, JSON.stringify(value));
}
read<T>(key: string) {
// if (!this.isBrowser) return null;
const json = localStorage.getItem(key);
const ret = json ? (JSON.parse(json) as T) : null;
return ret;
}
consume<T>(key: string) {
// if (!this.isBrowser) return null;
const value = this.read<T>(key);
if (value !== null) {
this.remove(key);
}
return value;
}
remove(key: string) {
// if (!this.isBrowser) return;
localStorage.removeItem(key);
}
}
import { TestBed } from '@angular/core/testing';
import { DataService } from './data.service';
import { UserClientService } from './user-client.service';
describe('DataService', () => {
let service: DataService;
describe('UserClientService', () => {
let service: UserClientService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DataService);
service = TestBed.inject(UserClientService);
});
it('should be created', () => {
......
......
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { User, UserState } from '../../types';
@Injectable({
providedIn: 'root',
})
export class UserClientService {
private readonly URI = environment.userAPI;
constructor(private http: HttpClient) {}
getUser(userId: number) {
return this.http.get<User>(`${this.URI}/${userId}`);
}
getAllUsers() {
return this.http.get<User[]>(this.URI, {
observe: 'body',
});
}
alterUserStatus(userId: number, status: UserState) {
return this.http.patch(
`${this.URI}/${userId}`,
{
status,
},
{
observe: 'response',
responseType: 'text',
}
);
}
}
// Simple -> Un servicio fachada / monolito
const hostname = 'http://localhost:8080';
export const environment = {
production: false,
authAPI: `${hostname}/auth`,
userAPI: `${hostname}/users`,
hotelAPI: `${hostname}/hotels`,
bookingAPI: `${hostname}/bookings`,
};
// Disgregado en microservicios
export const environment = {
production: true,
authAPI: 'http://auth-api:8080',
userAPI: 'http://user-api:8080',
hotelAPI: 'http://hotels-api:8080',
bookingAPI: 'http://bookings-api:8080',
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment