diff --git a/README.md b/README.md index 981baaf..af6a4df 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,39 @@ -# CronogramasPrimeng +# Cronogramas PrimeNG Application -This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.2.9. +Este proyecto es una aplicación Angular 19 utilizando PrimeNG para la gestión de cronogramas. + +## Estructura de Interfaces + +Se han creado las siguientes interfaces para los modelos de datos: + +- **Cronograma**: Modelo base para todos los cronogramas +- **Empresa**: Modelo para empresas +- **TipoCarga**: Modelo para tipos de carga +- **EstadoAprobacion**: Modelo para estados de aprobación +- **ActualizacionPd**: Modelo para actualizaciones de PD +- **AjustePd**: Modelo para ajustes de PD +- **UnidadInformacion**: Modelo para unidades de información + +## Servicios + +Los servicios implementados permiten conectarse a un backend mediante HTTP: + +- **CronogramaService**: CRUD para cronogramas +- **EmpresaService**: CRUD para empresas +- **ActualizacionPdService**: CRUD para actualizaciones de PD +- **AjustePdService**: CRUD para ajustes de PD +- **UnidadInformacionService**: CRUD para unidades de información +- **TipoCargaService**: Consulta de tipos de carga +- **EstadoAprobacionService**: Consulta de estados de aprobación +- **AuthService**: Autenticación y gestión de tokens + +## Seguridad + +La aplicación incluye: + +- Interceptor HTTP para añadir tokens de autenticación +- Guard para proteger rutas +- Login y sistema de autenticación ## Development server @@ -12,20 +45,6 @@ ng serve Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files. -## Code scaffolding - -Angular CLI includes powerful code scaffolding tools. To generate a new component, run: - -```bash -ng generate component component-name -``` - -For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run: - -```bash -ng generate --help -``` - ## Building To build the project run: @@ -36,24 +55,6 @@ ng build This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed. -## Running unit tests - -To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command: - -```bash -ng test -``` - -## Running end-to-end tests - -For end-to-end (e2e) testing, run: - -```bash -ng e2e -``` - -Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs. - ## Additional Resources For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page. diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 6119fcd..8b3ddeb 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -1,16 +1,19 @@ import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; import { provideRouter } from '@angular/router'; +import { provideHttpClient, withFetch, withInterceptors } from '@angular/common/http'; import { routes } from './app.routes'; import { provideAnimations } from '@angular/platform-browser/animations'; import { providePrimeNG } from 'primeng/config'; import Aura from '@primeng/themes/aura'; +import { authInterceptor } from './interceptors/auth.interceptor'; export const appConfig: ApplicationConfig = { providers: [ provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes), provideAnimations(), + provideHttpClient(withFetch(), withInterceptors([authInterceptor])), providePrimeNG({ theme: { preset: Aura, @@ -18,7 +21,6 @@ export const appConfig: ApplicationConfig = { darkModeSelector: false || 'none' } } - }) ] }; diff --git a/src/app/app.routes.ts b/src/app/app.routes.ts index dc7d429..4026757 100644 --- a/src/app/app.routes.ts +++ b/src/app/app.routes.ts @@ -8,6 +8,7 @@ import { ActualizacionPdComponent } from './pages/actualizacion-pd/actualizacion import { AjustePdComponent } from './pages/ajuste-pd/ajuste-pd.component'; import { ResumenComponent } from './pages/resumen/resumen.component'; import { UnidadInformacionComponent } from './pages/unidad-informacion/unidad-informacion.component'; +import { authGuard } from './guards/auth.guard'; export const routes: Routes = [ { path: 'login', component: LoginComponent }, @@ -15,6 +16,7 @@ export const routes: Routes = [ { path: '', component: LayoutComponent, + canActivate: [authGuard], children: [ { path: '', redirectTo: 'inicio', pathMatch: 'full' }, { path: 'inicio', component: HomeComponent, data: { title: 'Inicio' } }, diff --git a/src/app/components/navbar/navbar.component.html b/src/app/components/navbar/navbar.component.html index 067dce9..f01f31b 100644 --- a/src/app/components/navbar/navbar.component.html +++ b/src/app/components/navbar/navbar.component.html @@ -12,7 +12,7 @@ @@ -22,8 +22,12 @@ + + + + diff --git a/src/app/components/navbar/navbar.component.ts b/src/app/components/navbar/navbar.component.ts index 85ec99c..713e70b 100644 --- a/src/app/components/navbar/navbar.component.ts +++ b/src/app/components/navbar/navbar.component.ts @@ -1,21 +1,40 @@ -import { Component, EventEmitter, Output } from '@angular/core'; +import { Component, EventEmitter, Output, OnInit } from '@angular/core'; import { RouterLink } from '@angular/router'; import { ButtonModule } from 'primeng/button'; -import { ConfirmationService } from 'primeng/api'; +import { ConfirmationService, MessageService } from 'primeng/api'; import { ActivatedRoute, NavigationEnd, Router } from '@angular/router'; import { filter, map, mergeMap } from 'rxjs/operators'; +import { CommonModule } from '@angular/common'; +import { ConfirmDialogModule } from 'primeng/confirmdialog'; +import { ToastModule } from 'primeng/toast'; +import { AuthService } from '../../services/auth.service'; @Component({ selector: 'app-navbar', - imports: [RouterLink, ButtonModule], + imports: [ + CommonModule, + RouterLink, + ButtonModule, + ConfirmDialogModule, + ToastModule + ], + providers: [ConfirmationService, MessageService], templateUrl: './navbar.component.html', styleUrl: './navbar.component.scss', standalone: true }) -export class NavbarComponent { +export class NavbarComponent implements OnInit { @Output() sidebarToggle = new EventEmitter(); pageTitle: string = 'Starter Pages'; - constructor(private confirmationService: ConfirmationService,private router: Router, private activatedRoute: ActivatedRoute) { + userName: string = ''; + + constructor( + private confirmationService: ConfirmationService, + private messageService: MessageService, + private router: Router, + private activatedRoute: ActivatedRoute, + private authService: AuthService + ) { this.router.events.pipe( filter(event => event instanceof NavigationEnd), map(() => { @@ -30,7 +49,17 @@ export class NavbarComponent { this.pageTitle = data['title'] || 'Sin título'; }); } - + + ngOnInit() { + // Obtener nombre de usuario del usuario logueado + this.authService.user$.subscribe(user => { + if (user) { + this.userName = user.name || user.username || 'Usuario'; + } else { + this.userName = 'Usuario'; + } + }); + } toggleSidebar() { this.sidebarToggle.emit(); @@ -46,13 +75,21 @@ export class NavbarComponent { acceptButtonStyleClass: 'p-button-danger', rejectButtonStyleClass: 'p-button-secondary', accept: () => { - console.log('Sesión cerrada'); + this.logout(); }, reject: () => { console.log('Canceló cierre de sesión'); } }); } - - + + logout() { + this.authService.logout(); + this.messageService.add({ + severity: 'success', + summary: 'Sesión cerrada', + detail: 'Has cerrado sesión exitosamente' + }); + this.router.navigate(['/login']); + } } diff --git a/src/app/guards/auth.guard.ts b/src/app/guards/auth.guard.ts new file mode 100644 index 0000000..c21a7e0 --- /dev/null +++ b/src/app/guards/auth.guard.ts @@ -0,0 +1,16 @@ +import { inject } from '@angular/core'; +import { CanActivateFn, Router } from '@angular/router'; +import { AuthService } from '../services/auth.service'; + +export const authGuard: CanActivateFn = () => { + const authService = inject(AuthService); + const router = inject(Router); + + if (authService.isLoggedIn()) { + return true; + } + + // Redirect to login if not authenticated + router.navigate(['/login']); + return false; +}; \ No newline at end of file diff --git a/src/app/interceptors/auth.interceptor.ts b/src/app/interceptors/auth.interceptor.ts new file mode 100644 index 0000000..858d5d8 --- /dev/null +++ b/src/app/interceptors/auth.interceptor.ts @@ -0,0 +1,46 @@ +import { inject } from '@angular/core'; +import { + HttpRequest, + HttpHandlerFn, + HttpInterceptorFn, + HttpErrorResponse +} from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError } from 'rxjs/operators'; +import { AuthService } from '../services/auth.service'; +import { Router } from '@angular/router'; + +export const authInterceptor: HttpInterceptorFn = ( + request: HttpRequest, + next: HttpHandlerFn +): Observable => { + const authService = inject(AuthService); + const router = inject(Router); + + // Get the auth token + const token = authService.getToken(); + + // Clone the request and add the token if it exists + if (token) { + const authRequest = request.clone({ + setHeaders: { + Authorization: `Bearer ${token}` + } + }); + + // Handle the authenticated request + return next(authRequest).pipe( + catchError((error: HttpErrorResponse) => { + // Handle 401 Unauthorized errors by logging out and redirecting to login + if (error.status === 401) { + authService.logout(); + router.navigate(['/login']); + } + return throwError(() => error); + }) + ); + } + + // If no token, just pass the request through + return next(request); +}; \ No newline at end of file diff --git a/src/app/models/actualizacion-pd.model.ts b/src/app/models/actualizacion-pd.model.ts new file mode 100644 index 0000000..90ff6d8 --- /dev/null +++ b/src/app/models/actualizacion-pd.model.ts @@ -0,0 +1,10 @@ +import { Cronograma } from './cronograma.model'; + +export interface ActualizacionPd extends Cronograma { + dato9?: string; + dato10?: string; + dato11?: string; + dato12?: string; + dato13?: string; + dato14?: string; +} diff --git a/src/app/models/ajuste-pd.model.ts b/src/app/models/ajuste-pd.model.ts new file mode 100644 index 0000000..7431e0e --- /dev/null +++ b/src/app/models/ajuste-pd.model.ts @@ -0,0 +1,12 @@ +import { Cronograma } from './cronograma.model'; + +export interface AjustePd extends Cronograma { + dato9?: string; + dato10?: string; + dato13?: string; + dato14?: string; + dato15?: string; + dato16?: string; + dato17?: string; + dato18?: string; +} diff --git a/src/app/models/cronograma.model.ts b/src/app/models/cronograma.model.ts new file mode 100644 index 0000000..3e7c39d --- /dev/null +++ b/src/app/models/cronograma.model.ts @@ -0,0 +1,11 @@ +export interface Cronograma { + id?: number; + empresa: string; + codigoCronograma: string; + codigoCronogramaAjuste: string; + tipoCarga: string; + estadoRevision?: string; + analista?: string; + fechaIngreso?: string; + semaforo?: 'green' | 'yellow' | 'red'; +} diff --git a/src/app/models/empresa.model.ts b/src/app/models/empresa.model.ts new file mode 100644 index 0000000..6f134d2 --- /dev/null +++ b/src/app/models/empresa.model.ts @@ -0,0 +1,4 @@ +export interface Empresa { + id?: number; + name: string; +} diff --git a/src/app/models/estado-aprobacion.model.ts b/src/app/models/estado-aprobacion.model.ts new file mode 100644 index 0000000..0c79473 --- /dev/null +++ b/src/app/models/estado-aprobacion.model.ts @@ -0,0 +1,4 @@ +export interface EstadoAprobacion { + id?: number; + name: string; +} diff --git a/src/app/models/index.ts b/src/app/models/index.ts new file mode 100644 index 0000000..ee573f3 --- /dev/null +++ b/src/app/models/index.ts @@ -0,0 +1,7 @@ +export * from './cronograma.model'; +export * from './empresa.model'; +export * from './tipo-carga.model'; +export * from './estado-aprobacion.model'; +export * from './actualizacion-pd.model'; +export * from './ajuste-pd.model'; +export * from './unidad-informacion.model'; diff --git a/src/app/models/tipo-carga.model.ts b/src/app/models/tipo-carga.model.ts new file mode 100644 index 0000000..109fcf9 --- /dev/null +++ b/src/app/models/tipo-carga.model.ts @@ -0,0 +1,4 @@ +export interface TipoCarga { + id?: number; + name: string; +} diff --git a/src/app/models/unidad-informacion.model.ts b/src/app/models/unidad-informacion.model.ts new file mode 100644 index 0000000..9a95674 --- /dev/null +++ b/src/app/models/unidad-informacion.model.ts @@ -0,0 +1,6 @@ +import { Cronograma } from './cronograma.model'; + +export interface UnidadInformacion extends Cronograma { + dato5?: string; + dato6?: string; +} diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html index 3cc4f7e..784169c 100644 --- a/src/app/pages/home/home.component.html +++ b/src/app/pages/home/home.component.html @@ -1,5 +1,3 @@ - -
diff --git a/src/app/pages/login/login.component.html b/src/app/pages/login/login.component.html index 6488d88..b95a560 100644 --- a/src/app/pages/login/login.component.html +++ b/src/app/pages/login/login.component.html @@ -12,10 +12,11 @@
+ + - - -
+ +
- - + + diff --git a/src/app/pages/login/login.component.ts b/src/app/pages/login/login.component.ts index 49197c4..e224fa3 100644 --- a/src/app/pages/login/login.component.ts +++ b/src/app/pages/login/login.component.ts @@ -8,7 +8,12 @@ import { InputTextModule } from 'primeng/inputtext'; import { ButtonModule } from 'primeng/button'; import { PasswordModule } from 'primeng/password'; import { DividerModule } from 'primeng/divider'; +import { MessagesModule } from 'primeng/messages'; +import { MessageModule } from 'primeng/message'; +import { ToastModule } from 'primeng/toast'; +import { MessageService } from 'primeng/api'; import { FooterComponent } from "../../components/footer/footer.component"; +import { AuthService } from '../../services/auth.service'; @Component({ selector: 'app-login', @@ -20,20 +25,50 @@ import { FooterComponent } from "../../components/footer/footer.component"; ButtonModule, PasswordModule, DividerModule, + MessagesModule, + MessageModule, + ToastModule, FooterComponent -], + ], + providers: [MessageService], templateUrl: './login.component.html', styleUrl: './login.component.scss' }) export class LoginComponent { email: string = ''; password: string = ''; + loading: boolean = false; + errorMessage: string = ''; + + constructor( + private router: Router, + private authService: AuthService, + private messageService: MessageService + ) { } - constructor(private router: Router) { } onLogin() { - // Aquí iría la lógica de autenticación - // Por ahora, solo navegamos a la página de inicio - this.router.navigate(['/inicio']); + this.loading = true; + this.errorMessage = ''; + + // Llamar al servicio auth + this.authService.login({ email: this.email, password: this.password }) + .subscribe({ + next: () => { + console.log('Login exitoso'); + this.loading = false; + this.router.navigate(['/inicio']); + }, + error: (error) => { + console.error('Error en login:', error); + this.loading = false; + this.errorMessage = 'Credenciales incorrectas'; + this.messageService.add({ + severity: 'error', + summary: 'Error', + detail: 'Credenciales incorrectas' + }); + } + }); } } diff --git a/src/app/services/actualizacion-pd.service.ts b/src/app/services/actualizacion-pd.service.ts new file mode 100644 index 0000000..192b4dd --- /dev/null +++ b/src/app/services/actualizacion-pd.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { ActualizacionPd } from '../models/actualizacion-pd.model'; + +@Injectable({ + providedIn: 'root' +}) +export class ActualizacionPdService { + private apiUrl = 'api/actualizaciones'; + + constructor(private http: HttpClient) {} + + getActualizaciones(): Observable { + return this.http.get(this.apiUrl); + } + + getActualizacionById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + createActualizacion(actualizacion: ActualizacionPd): Observable { + return this.http.post(this.apiUrl, actualizacion); + } + + updateActualizacion(actualizacion: ActualizacionPd): Observable { + return this.http.put(`${this.apiUrl}/${actualizacion.id}`, actualizacion); + } + + deleteActualizacion(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } + + aprobarActualizacion(id: number): Observable { + return this.http.patch(`${this.apiUrl}/${id}/aprobar`, {}); + } + + rechazarActualizacion(id: number, motivo: string): Observable { + return this.http.patch(`${this.apiUrl}/${id}/rechazar`, { motivo }); + } +} diff --git a/src/app/services/ajuste-pd.service.ts b/src/app/services/ajuste-pd.service.ts new file mode 100644 index 0000000..4c57f18 --- /dev/null +++ b/src/app/services/ajuste-pd.service.ts @@ -0,0 +1,41 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { AjustePd } from '../models/ajuste-pd.model'; + +@Injectable({ + providedIn: 'root' +}) +export class AjustePdService { + private apiUrl = 'api/ajustes'; + + constructor(private http: HttpClient) {} + + getAjustes(): Observable { + return this.http.get(this.apiUrl); + } + + getAjusteById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + createAjuste(ajuste: AjustePd): Observable { + return this.http.post(this.apiUrl, ajuste); + } + + updateAjuste(ajuste: AjustePd): Observable { + return this.http.put(`${this.apiUrl}/${ajuste.id}`, ajuste); + } + + deleteAjuste(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } + + aprobarAjuste(id: number): Observable { + return this.http.patch(`${this.apiUrl}/${id}/aprobar`, {}); + } + + rechazarAjuste(id: number, motivo: string): Observable { + return this.http.patch(`${this.apiUrl}/${id}/rechazar`, { motivo }); + } +} diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts new file mode 100644 index 0000000..a69b102 --- /dev/null +++ b/src/app/services/auth.service.ts @@ -0,0 +1,111 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable, BehaviorSubject, of, throwError } from 'rxjs'; +import { tap, delay } from 'rxjs/operators'; + +interface LoginCredentials { + username?: string; + password?: string; + email?: string; +} + +interface AuthResponse { + token: string; + user: { + id: number; + username: string; + name: string; + role: string; + email?: string; + }; +} + +@Injectable({ + providedIn: 'root' +}) +export class AuthService { + private apiUrl = 'api/auth'; + private userSubject = new BehaviorSubject(null); + public user$ = this.userSubject.asObservable(); + + // Usuarios de prueba para simular login + private mockUsers = [ + { + email: 'admin@example.com', + password: 'admin123', + user: { + id: 1, + username: 'admin', + name: 'Administrador', + role: 'admin', + email: 'admin@example.com' + } + }, + { + email: 'user@example.com', + password: 'user123', + user: { + id: 2, + username: 'user', + name: 'Usuario', + role: 'user', + email: 'user@example.com' + } + } + ]; + + constructor(private http: HttpClient) { + // Check if user is already logged in on service initialization + const user = localStorage.getItem('user'); + if (user) { + this.userSubject.next(JSON.parse(user)); + } + } + + login(credentials: LoginCredentials): Observable { + // Simular login con usuarios de prueba + const user = this.mockUsers.find(u => + u.email === credentials.email && u.password === credentials.password); + + if (user) { + // Generar token falso + const mockResponse: AuthResponse = { + token: 'mock-jwt-token-' + Math.random().toString(36).substring(2, 15), + user: user.user + }; + + return of(mockResponse).pipe( + // Simular retraso de red + delay(800), + tap(response => { + // Store token and user info + localStorage.setItem('token', response.token); + localStorage.setItem('user', JSON.stringify(response.user)); + this.userSubject.next(response.user); + }) + ); + } else { + // Simular error de credenciales inválidas + return throwError(() => new Error('Credenciales incorrectas')); + } + } + + logout(): void { + // Clear storage and update subject + localStorage.removeItem('token'); + localStorage.removeItem('user'); + this.userSubject.next(null); + } + + isLoggedIn(): boolean { + return !!localStorage.getItem('token'); + } + + getToken(): string | null { + return localStorage.getItem('token'); + } + + getCurrentUser(): any { + return this.userSubject.value; + } +} \ No newline at end of file diff --git a/src/app/services/cronograma.service.ts b/src/app/services/cronograma.service.ts new file mode 100644 index 0000000..78c6c98 --- /dev/null +++ b/src/app/services/cronograma.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Cronograma } from '../models/cronograma.model'; + +@Injectable({ + providedIn: 'root' +}) +export class CronogramaService { + private apiUrl = 'api/cronogramas'; + + constructor(private http: HttpClient) {} + + getCronogramas(): Observable { + return this.http.get(this.apiUrl); + } + + getCronogramaById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + createCronograma(cronograma: Cronograma): Observable { + return this.http.post(this.apiUrl, cronograma); + } + + updateCronograma(cronograma: Cronograma): Observable { + return this.http.put(`${this.apiUrl}/${cronograma.id}`, cronograma); + } + + deleteCronograma(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } +} diff --git a/src/app/services/empresa.service.ts b/src/app/services/empresa.service.ts new file mode 100644 index 0000000..0bbadb3 --- /dev/null +++ b/src/app/services/empresa.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { Empresa } from '../models/empresa.model'; + +@Injectable({ + providedIn: 'root' +}) +export class EmpresaService { + private apiUrl = 'api/empresas'; + + constructor(private http: HttpClient) {} + + getEmpresas(): Observable { + return this.http.get(this.apiUrl); + } + + getEmpresaById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + createEmpresa(empresa: Empresa): Observable { + return this.http.post(this.apiUrl, empresa); + } + + updateEmpresa(empresa: Empresa): Observable { + return this.http.put(`${this.apiUrl}/${empresa.id}`, empresa); + } + + deleteEmpresa(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } +} diff --git a/src/app/services/estado-aprobacion.service.ts b/src/app/services/estado-aprobacion.service.ts new file mode 100644 index 0000000..d718b0a --- /dev/null +++ b/src/app/services/estado-aprobacion.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { EstadoAprobacion } from '../models/estado-aprobacion.model'; + +@Injectable({ + providedIn: 'root' +}) +export class EstadoAprobacionService { + private apiUrl = 'api/estadosAprobacion'; + + constructor(private http: HttpClient) {} + + getEstadosAprobacion(): Observable { + return this.http.get(this.apiUrl); + } +} diff --git a/src/app/services/index.ts b/src/app/services/index.ts new file mode 100644 index 0000000..c26dd2a --- /dev/null +++ b/src/app/services/index.ts @@ -0,0 +1,7 @@ +export * from './cronograma.service'; +export * from './empresa.service'; +export * from './actualizacion-pd.service'; +export * from './ajuste-pd.service'; +export * from './unidad-informacion.service'; +export * from './tipo-carga.service'; +export * from './estado-aprobacion.service'; diff --git a/src/app/services/tipo-carga.service.ts b/src/app/services/tipo-carga.service.ts new file mode 100644 index 0000000..48d5d75 --- /dev/null +++ b/src/app/services/tipo-carga.service.ts @@ -0,0 +1,17 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { TipoCarga } from '../models/tipo-carga.model'; + +@Injectable({ + providedIn: 'root' +}) +export class TipoCargaService { + private apiUrl = 'api/tiposCarga'; + + constructor(private http: HttpClient) {} + + getTiposCarga(): Observable { + return this.http.get(this.apiUrl); + } +} diff --git a/src/app/services/unidad-informacion.service.ts b/src/app/services/unidad-informacion.service.ts new file mode 100644 index 0000000..5056adb --- /dev/null +++ b/src/app/services/unidad-informacion.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { Observable } from 'rxjs'; +import { UnidadInformacion } from '../models/unidad-informacion.model'; + +@Injectable({ + providedIn: 'root' +}) +export class UnidadInformacionService { + private apiUrl = 'api/unidades'; + + constructor(private http: HttpClient) {} + + getUnidades(): Observable { + return this.http.get(this.apiUrl); + } + + getUnidadById(id: number): Observable { + return this.http.get(`${this.apiUrl}/${id}`); + } + + createUnidad(unidad: UnidadInformacion): Observable { + return this.http.post(this.apiUrl, unidad); + } + + updateUnidad(unidad: UnidadInformacion): Observable { + return this.http.put(`${this.apiUrl}/${unidad.id}`, unidad); + } + + deleteUnidad(id: number): Observable { + return this.http.delete(`${this.apiUrl}/${id}`); + } +}