From fdd37f64d9bb802d046ad6c7bf7d3fbf22b91c5c Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Fri, 18 Oct 2024 09:23:40 +0200 Subject: [PATCH] refs #918. Image component finish --- .../create-image/create-image.component.css | 77 ++++++----- .../create-image/create-image.component.html | 17 ++- .../create-image/create-image.component.ts | 123 ++++++++++-------- .../src/app/components/images/data.service.ts | 54 ++++++++ .../components/images/images.component.css | 2 - .../components/images/images.component.html | 29 ++++- .../app/components/images/images.component.ts | 56 ++++++-- .../app/layout/sidebar/sidebar.component.html | 14 +- 8 files changed, 252 insertions(+), 120 deletions(-) create mode 100644 ogWebconsole/src/app/components/images/data.service.ts diff --git a/ogWebconsole/src/app/components/images/create-image/create-image.component.css b/ogWebconsole/src/app/components/images/create-image/create-image.component.css index a39bfaa..a25f952 100644 --- a/ogWebconsole/src/app/components/images/create-image/create-image.component.css +++ b/ogWebconsole/src/app/components/images/create-image/create-image.component.css @@ -1,47 +1,46 @@ .dialog-content { - display: flex; - flex-direction: column; - gap: 16px; /* Espacio entre los elementos del formulario */ - } - - .image-form { - width: 100%; - display: flex; - flex-direction: column; - } - + display: flex; + flex-direction: column; + gap: 16px; /* Espacio entre los elementos del formulario */ +} + +.image-form { + width: 100%; + display: flex; + flex-direction: column; +} + +.form-field { + width: 100%; + margin-bottom: 16px; +} + +/* Botones alineados al final, con margen superior */ +.dialog-actions { + display: flex; + justify-content: flex-end; + margin-top: 24px; +} + +button { + margin-left: 8px; /* Espacio entre los botones */ +} + +/* Responsividad para pantallas pequeñas */ +@media (max-width: 600px) { .form-field { width: 100%; - margin-bottom: 16px; } - - /* Botones alineados al final, con margen superior */ + + /* Alineación vertical para botones en pantallas pequeñas */ .dialog-actions { - display: flex; - justify-content: flex-end; - margin-top: 24px; + flex-direction: column; + align-items: stretch; } - + button { - margin-left: 8px; /* Espacio entre los botones */ + width: 100%; + margin-left: 0; + margin-bottom: 8px; } - - /* Responsividad para pantallas pequeñas */ - @media (max-width: 600px) { - .form-field { - width: 100%; - } - - /* Alineación vertical para botones en pantallas pequeñas */ - .dialog-actions { - flex-direction: column; - align-items: stretch; - } - - button { - width: 100%; - margin-left: 0; - margin-bottom: 8px; - } - } - \ No newline at end of file +} diff --git a/ogWebconsole/src/app/components/images/create-image/create-image.component.html b/ogWebconsole/src/app/components/images/create-image/create-image.component.html index 8c13383..243b9b9 100644 --- a/ogWebconsole/src/app/components/images/create-image/create-image.component.html +++ b/ogWebconsole/src/app/components/images/create-image/create-image.component.html @@ -1,30 +1,37 @@

Añadir nueva imagen

-
+ Nombre de la imagen - + Descripción - + Comentarios - + Perfil de software - + {{ profile.description }} + + + Remote Pc +
diff --git a/ogWebconsole/src/app/components/images/create-image/create-image.component.ts b/ogWebconsole/src/app/components/images/create-image/create-image.component.ts index 9939531..8610c67 100644 --- a/ogWebconsole/src/app/components/images/create-image/create-image.component.ts +++ b/ogWebconsole/src/app/components/images/create-image/create-image.component.ts @@ -1,22 +1,9 @@ -import { Component, OnInit } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; +import {Component, Inject, OnInit} from '@angular/core'; +import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; import { HttpClient } from '@angular/common/http'; import { ToastrService } from 'ngx-toastr'; - -interface ImagePayload { - [key: string]: any; - name: string | null; - description: string | null; - comments: string | null; - type: string | null; - path: string | null; - revision: string | null; - info: string | null; - size: number | null; - client: string | null; - softwareProfile: string | null; -} - +import {FormBuilder, FormGroup, Validators} from "@angular/forms"; +import {DataService} from "../data.service"; @Component({ selector: 'app-create-image', templateUrl: './create-image.component.html', @@ -24,33 +11,54 @@ interface ImagePayload { }) export class CreateImageComponent implements OnInit { baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; - imagePayload: ImagePayload = { - name: null, - description: null, - comments: null, - type: null, - path: null, - revision: null, - info: null, - size: null, - client: null, - softwareProfile: null - }; - + imageForm: FormGroup; + imageId: string | null = null; softwareProfiles: any[] = []; constructor( - public dialogRef: MatDialogRef, + private fb: FormBuilder, private http: HttpClient, - private toastService: ToastrService - ) {} + public dialogRef: MatDialogRef, + private toastService: ToastrService, + private dataService: DataService, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.imageForm = this.fb.group({ + name: ['', Validators.required], + description: [''], + comments: [''], + remotePc: [false], + softwareProfile: ['', Validators.required], + }); + } ngOnInit() { + if (this.data) { + this.load() + } this.fetchSoftwareProfiles(); } + load(): void { + this.dataService.getImage(this.data).subscribe({ + next: (response) => { + this.imageForm = this.fb.group({ + name: [response.name, Validators.required], + description: [response.description], + comments: [response.comments], + remotePc: [response.remotePc], + softwareProfile: [response.softwareProfile, Validators.required], + }); + this.imageId = response['@id']; + }, + error: (err) => { + console.error('Error fetching remote calendar:', err); + } + }); + } + fetchSoftwareProfiles() { - const url = 'http://127.0.0.1:8001/software-profiles?page=1&itemsPerPage=30'; + const url = `${this.baseUrl}/software-profiles`; this.http.get(url).subscribe({ next: (response: any) => { this.softwareProfiles = response['hydra:member']; @@ -63,24 +71,37 @@ export class CreateImageComponent implements OnInit { } saveImage(): void { - const payload = { ...this.imagePayload }; - Object.keys(payload).forEach(key => { - if (payload[key] == null) { - delete payload[key]; - } - }); + const payload = { + name: this.imageForm.value.name, + description: this.imageForm.value.description, + comments: this.imageForm.value.comments, + remotePc: this.imageForm.value.remotePc, + softwareProfile: this.imageForm.value.softwareProfile + }; - console.log('Payload:', payload); - this.http.post(`${this.baseUrl}/images`, payload).subscribe({ - next: () => { - this.toastService.success('Imagen creada con éxito'); - this.dialogRef.close(true); - }, - error: (error) => { - console.error('Error al crear la imagen:', error); - this.toastService.error('Error al crear la imagen'); - } - }); + if (this.imageId) { + this.http.put(`${this.baseUrl}${this.imageId}`, payload).subscribe( + (response) => { + this.toastService.success('Imagen editada correctamente'); + this.dialogRef.close(); + }, + (error) => { + this.toastService.error(error['error']['hydra:description']); + console.error('Error al editar la imagen', error); + } + ); + } else { + this.http.post(`${this.baseUrl}/images`, payload).subscribe( + (response) => { + this.toastService.success('Imagen añadida correctamente'); + this.dialogRef.close(); + }, + (error) => { + this.toastService.error(error['error']['hydra:description']); + console.error('Error al añadir la imagen', error); + } + ); + } } close(): void { diff --git a/ogWebconsole/src/app/components/images/data.service.ts b/ogWebconsole/src/app/components/images/data.service.ts new file mode 100644 index 0000000..1b9debe --- /dev/null +++ b/ogWebconsole/src/app/components/images/data.service.ts @@ -0,0 +1,54 @@ + +import { Injectable } from '@angular/core'; +import {HttpClient, HttpParams} from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class DataService { + baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; + private apiUrl = `${this.baseUrl}/images?page=1&itemsPerPage=1000`; + + constructor(private http: HttpClient) {} + + getImages(filters: { [key: string]: string }): Observable<{ totalItems: any; data: any }> { + const params = new HttpParams({ fromObject: filters }); + + return this.http.get(this.apiUrl, { params }).pipe( + map(response => { + if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { + return { + data: response['hydra:member'], + totalItems: response['hydra:totalItems'] + } + } else { + throw new Error('Unexpected response format'); + } + }), + catchError(error => { + console.error('Error fetching commands', error); + return throwError(error); + }) + ); + } + + getImage(id: string): Observable { + return this.http.get(`${this.baseUrl}${id}`).pipe( + map(response => { + if (response.name) { + return response; + } else { + throw new Error('Unexpected response format'); + } + }), + catchError(error => { + console.error('Error fetching user group', error); + return throwError(error); + }) + ); + } + + +} diff --git a/ogWebconsole/src/app/components/images/images.component.css b/ogWebconsole/src/app/components/images/images.component.css index 07e92bc..5b7e163 100644 --- a/ogWebconsole/src/app/components/images/images.component.css +++ b/ogWebconsole/src/app/components/images/images.component.css @@ -69,9 +69,7 @@ table { display: flex; justify-content: space-between; align-items: center; - height: 100px; padding: 10px; - margin-top: 16px; } .mat-elevation-z8 { diff --git a/ogWebconsole/src/app/components/images/images.component.html b/ogWebconsole/src/app/components/images/images.component.html index fff28b7..b75972e 100644 --- a/ogWebconsole/src/app/components/images/images.component.html +++ b/ogWebconsole/src/app/components/images/images.component.html @@ -5,7 +5,7 @@ - +
Buscar nombre de imagen @@ -14,17 +14,35 @@ Pulsar 'enter' para buscar
- + - + + + + + + -
{{ column.header }} {{ column.cell(image) }} + + + {{ image[column.columnDef] ? 'check_circle' : 'cancel' }} + + + + {{ column.cell(image) }} + + Acciones + + +
- +
- \ No newline at end of file diff --git a/ogWebconsole/src/app/components/images/images.component.ts b/ogWebconsole/src/app/components/images/images.component.ts index 9d6fa8c..b646ea5 100644 --- a/ogWebconsole/src/app/components/images/images.component.ts +++ b/ogWebconsole/src/app/components/images/images.component.ts @@ -5,6 +5,8 @@ import { MatTableDataSource } from '@angular/material/table'; import { ToastrService } from 'ngx-toastr'; import { DatePipe } from '@angular/common'; import { CreateImageComponent } from './create-image/create-image.component'; +import {CreateCommandComponent} from "../commands/main-commands/create-command/create-command.component"; +import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component"; @Component({ selector: 'app-images', @@ -16,15 +18,15 @@ export class ImagesComponent implements OnInit { dataSource = new MatTableDataSource(); length: number = 0; itemsPerPage: number = 10; - page: number = 1; + page: number = 0; loading: boolean = false; filters: { [key: string]: string } = {}; datePipe: DatePipe = new DatePipe('es-ES'); columns = [ { - columnDef: 'uuid', - header: 'UUID', - cell: (image: any) => `${image.uuid}` + columnDef: 'id', + header: 'Id', + cell: (image: any) => `${image.id}` }, { columnDef: 'name', @@ -32,9 +34,14 @@ export class ImagesComponent implements OnInit { cell: (image: any) => `${image.name}` }, { - columnDef: 'downloadUrl', - header: 'Url descarga', - cell: (image: any) => `${image.downloadUrl}` + columnDef: 'softwareProfile', + header: 'Perfil de software', + cell: (image: any) => `${image.softwareProfile?.description}` + }, + { + columnDef: 'remotePc', + header: 'Acceso remoto', + cell: (image: any) => `${image.remotePc}` }, { columnDef: 'createdAt', @@ -42,7 +49,7 @@ export class ImagesComponent implements OnInit { cell: (image: any) => `${this.datePipe.transform(image.createdAt, 'dd/MM/yyyy hh:mm:ss')}` } ]; - displayedColumns = [...this.columns.map(column => column.columnDef)]; + displayedColumns = [...this.columns.map(column => column.columnDef), 'actions']; private apiUrl = `${this.baseUrl}/images`; @@ -58,7 +65,7 @@ export class ImagesComponent implements OnInit { addImage(): void { const dialogRef = this.dialog.open(CreateImageComponent, { - width: '400px' + width: '600px' }); dialogRef.afterClosed().subscribe(() => { @@ -68,7 +75,7 @@ export class ImagesComponent implements OnInit { search(): void { this.loading = true; - this.http.get(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}&filters=${JSON.stringify(this.filters)}`).subscribe( + this.http.get(`${this.apiUrl}?page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe( data => { this.dataSource.data = data['hydra:member']; this.length = data['hydra:totalItems']; @@ -81,9 +88,38 @@ export class ImagesComponent implements OnInit { ); } + editImage(event: MouseEvent, image: any): void { + event.stopPropagation(); + this.dialog.open(CreateImageComponent, { + width: '600px', + data: image['@id'] + }).afterClosed().subscribe(() => this.search()); + } + + deleteImage(event: MouseEvent,command: any): void { + event.stopPropagation(); + this.dialog.open(DeleteModalComponent, { + width: '300px', + data: { name: command.name }, + }).afterClosed().subscribe((result) => { + if (result) { + this.http.delete(`${this.apiUrl}/${command.uuid}`).subscribe({ + next: () => { + this.toastService.success('Imagen eliminada con éxito'); + this.search(); + }, + error: (error) => { + console.error('Error al eliminar la imagen:', error); + } + }); + } + }); + } + onPageChange(event: any): void { this.page = event.pageIndex; this.itemsPerPage = event.pageSize; + this.length = event.length; this.search(); } } diff --git a/ogWebconsole/src/app/layout/sidebar/sidebar.component.html b/ogWebconsole/src/app/layout/sidebar/sidebar.component.html index 14dd2fe..626af03 100644 --- a/ogWebconsole/src/app/layout/sidebar/sidebar.component.html +++ b/ogWebconsole/src/app/layout/sidebar/sidebar.component.html @@ -148,6 +148,13 @@ + + + photo + imágenes + + + warehouse @@ -155,13 +162,6 @@ - - - photo - imágenes - - - list