From 16c367e7700d8ce828a9980e0732615aa114e823 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Tue, 11 Mar 2025 17:10:04 +0100 Subject: [PATCH] refs #1693. Convert Image --- ogWebconsole/src/app/app.module.ts | 4 +- .../convert-image/convert-image.component.css | 39 +++++++++++++++ .../convert-image.component.html | 15 ++++++ .../convert-image.component.spec.ts | 23 +++++++++ .../convert-image/convert-image.component.ts | 50 +++++++++++++++++++ .../import-image/import-image.component.html | 23 ++------- .../import-image/import-image.component.ts | 32 +++--------- .../repository-images.component.css | 11 ++-- .../repository-images.component.html | 10 ++++ .../repository-images.component.ts | 34 ++++++++++++- ogWebconsole/src/locale/en.json | 4 +- ogWebconsole/src/locale/es.json | 2 + 12 files changed, 195 insertions(+), 52 deletions(-) create mode 100644 ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.css create mode 100644 ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.html create mode 100644 ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.spec.ts create mode 100644 ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.ts diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 277d682..132fde0 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -129,6 +129,7 @@ import { AddClientsToSubnetComponent } from "./components/ogdhcp/add-clients-to- import { ShowClientsComponent } from './components/ogdhcp/show-clients/show-clients.component'; import { OperationResultDialogComponent } from './components/ogdhcp/operation-result-dialog/operation-result-dialog.component'; import { ManageClientComponent } from './components/groups/shared/clients/manage-client/manage-client.component'; +import { ConvertImageComponent } from './components/repositories/convert-image/convert-image.component'; export function HttpLoaderFactory(http: HttpClient) { return new TranslateHttpLoader(http, './locale/', '.json'); } @@ -213,7 +214,8 @@ export function HttpLoaderFactory(http: HttpClient) { ManageOrganizationalUnitComponent, BackupImageComponent, ShowClientsComponent, - OperationResultDialogComponent + OperationResultDialogComponent, + ConvertImageComponent ], bootstrap: [AppComponent], imports: [BrowserModule, diff --git a/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.css b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.css new file mode 100644 index 0000000..bdecbfa --- /dev/null +++ b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.css @@ -0,0 +1,39 @@ +.loading-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100px; +} + +mat-form-field { + width: 100%; +} + +mat-dialog-actions { + display: flex; + justify-content: flex-end; +} + +.checkbox-group { + display: flex; + flex-direction: column; + gap: 10px; +} + +.selected-list ul { + list-style: none; + padding: 0; +} + +.selected-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px; + border-bottom: 1px solid #ccc; +} + +.selected-item button { + margin-left: 10px; +} diff --git a/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.html b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.html new file mode 100644 index 0000000..7962e6f --- /dev/null +++ b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.html @@ -0,0 +1,15 @@ +

Convertir imagene virtual hacia {{ data.name }}

+ + + + Imagen + + El nombre de la imagen tiene que ir con la extensión. + + + + + + + diff --git a/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.spec.ts b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.spec.ts new file mode 100644 index 0000000..21b0b05 --- /dev/null +++ b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ConvertImageComponent } from './convert-image.component'; + +describe('ConvertImageComponent', () => { + let component: ConvertImageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ConvertImageComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ConvertImageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.ts b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.ts new file mode 100644 index 0000000..ebab8e9 --- /dev/null +++ b/ogWebconsole/src/app/components/repositories/convert-image/convert-image.component.ts @@ -0,0 +1,50 @@ +import {Component, Inject} from '@angular/core'; +import {HttpClient} from "@angular/common/http"; +import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; +import {ToastrService} from "ngx-toastr"; +import {Router} from "@angular/router"; + +@Component({ + selector: 'app-convert-image', + templateUrl: './convert-image.component.html', + styleUrl: './convert-image.component.css' +}) +export class ConvertImageComponent { + baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; + loading: boolean = true; + imageName: string = ''; + + constructor( + private http: HttpClient, + public dialogRef: MatDialogRef, + private toastService: ToastrService, + private router: Router, + @Inject(MAT_DIALOG_DATA) public data: { repositoryUuid: any, name: string } + ) { + + } + + ngOnInit(): void { + this.loading = true; + } + + save() { + console.log(this.data?.repositoryUuid) + this.http.post(`${this.baseUrl}/image-repositories/${this.data?.repositoryUuid}/convert-image`, { + name: this.imageName + }).subscribe({ + next: (response) => { + this.toastService.success('Peticion de conversion de imagen enviada correctamente'); + this.dialogRef.close(); + this.router.navigate(['/commands-logs']); + }, + error: error => { + this.toastService.error(error.error['hydra:description']); + } + }); + } + + close() { + this.dialogRef.close(); + } +} diff --git a/ogWebconsole/src/app/components/repositories/import-image/import-image.component.html b/ogWebconsole/src/app/components/repositories/import-image/import-image.component.html index 82bc9fd..d5b1658 100644 --- a/ogWebconsole/src/app/components/repositories/import-image/import-image.component.html +++ b/ogWebconsole/src/app/components/repositories/import-image/import-image.component.html @@ -1,25 +1,12 @@ -

Importar imagenes a {{data.repository?.name}}

+

Importar imagenes a {{ data.name }}

- Seleccione imagenes a importar - - {{ image.name }} - + Imagen + + El nombre de la imagen tiene que ir sin la extensión. - -
-

Imágenes seleccionadas:

-
    -
  • - {{ getImageName(imageId) }} - -
  • -
-
-
diff --git a/ogWebconsole/src/app/components/repositories/import-image/import-image.component.ts b/ogWebconsole/src/app/components/repositories/import-image/import-image.component.ts index 8db695a..74fea91 100644 --- a/ogWebconsole/src/app/components/repositories/import-image/import-image.component.ts +++ b/ogWebconsole/src/app/components/repositories/import-image/import-image.component.ts @@ -12,46 +12,26 @@ import {Router} from "@angular/router"; export class ImportImageComponent implements OnInit{ baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; loading: boolean = true; - images: any[] = []; - selectedClients: any[] = []; + imageName: string = ''; constructor( private http: HttpClient, public dialogRef: MatDialogRef, private toastService: ToastrService, private router: Router, - @Inject(MAT_DIALOG_DATA) public data: { repository: any } + @Inject(MAT_DIALOG_DATA) public data: { repositoryUuid: any, name: string } ) { } ngOnInit(): void { this.loading = true; - this.loadImages(); - } - - loadImages() { - this.http.get(`${this.baseUrl}/images?page=1&itemsPerPage=50`).subscribe( - response => { - this.images = response['hydra:member']; - this.loading = false; - }, - error => console.error('Error fetching organizational units:', error) - ); - } - - getImageName(imageId: string): string { - const image = this.images.find(img => img['@id'] === imageId); - return image ? image.name : 'Desconocido'; - } - - removeImage(imageId: string) { - this.selectedClients = this.selectedClients.filter(id => id !== imageId); } save() { - this.http.post(`${this.baseUrl}${this.data.repository['@id']}/import-image`, { - images: this.selectedClients + console.log(this.data?.repositoryUuid) + this.http.post(`${this.baseUrl}/image-repositories/${this.data?.repositoryUuid}/import-image`, { + name: this.imageName }).subscribe({ next: (response) => { this.toastService.success('Peticion de importacion de imagen enviada correctamente'); @@ -59,7 +39,7 @@ export class ImportImageComponent implements OnInit{ this.router.navigate(['/commands-logs']); }, error: error => { - this.toastService.error('Error al importar imagenes'); + this.toastService.error(error.error['hydra:description']); } }); } diff --git a/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.css b/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.css index 5dd3535..ecb91dd 100644 --- a/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.css +++ b/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.css @@ -1,8 +1,3 @@ -.images-button-row { - display: flex; - justify-content: flex-start; - margin-top: 16px; -} table { width: 100%; @@ -94,3 +89,9 @@ table { margin-left: 1em; } +.images-button-row { + display: flex; + gap: 15px; + padding: 5px; +} + diff --git a/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.html b/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.html index 5bec694..308009b 100644 --- a/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.html +++ b/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.html @@ -9,6 +9,16 @@ {{ 'imagesTitle' | translate }} en {{ repository?.name }} +
+ +
+
+ +
diff --git a/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.ts b/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.ts index 85e7ee6..31ee10b 100644 --- a/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.ts +++ b/ogWebconsole/src/app/components/repositories/repository-images/repository-images.component.ts @@ -1,4 +1,4 @@ -import {Component, Input, OnInit} from '@angular/core'; +import {Component, Input, isDevMode, OnInit} from '@angular/core'; import {MatTableDataSource} from "@angular/material/table"; import {DatePipe} from "@angular/common"; import {MatDialog} from "@angular/material/dialog"; @@ -10,6 +10,8 @@ import {DeleteModalComponent} from "../../../shared/delete_modal/delete-modal/de import {ExportImageComponent} from "../../images/export-image/export-image.component"; import {BackupImageComponent} from "../backup-image/backup-image.component"; import {ServerInfoDialogComponent} from "../../ogdhcp/server-info-dialog/server-info-dialog.component"; +import {ImportImageComponent} from "../import-image/import-image.component"; +import {ConvertImageComponent} from "../convert-image/convert-image.component"; @Component({ selector: 'app-repository-images', @@ -162,6 +164,34 @@ export class RepositoryImagesComponent implements OnInit { ); } + importImage(): void { + this.dialog.open(ImportImageComponent, { + width: '600px', + data: { + repositoryUuid: this.repositoryUuid, + name: this.repository.name + } + }).afterClosed().subscribe((result) => { + if (result) { + this.search(); + } + }); + } + + convertImage(): void { + this.dialog.open(ConvertImageComponent, { + width: '600px', + data: { + repositoryUuid: this.repositoryUuid, + name: this.repository.name + } + }).afterClosed().subscribe((result) => { + if (result) { + this.search(); + } + }); + } + toggleAction(image: any, action:string): void { switch (action) { case 'get-aux': @@ -301,4 +331,6 @@ export class RepositoryImagesComponent implements OnInit { themeColor: '#3f51b5' }); } + + protected readonly isDevMode = isDevMode; } diff --git a/ogWebconsole/src/locale/en.json b/ogWebconsole/src/locale/en.json index 5cff44c..424a881 100644 --- a/ogWebconsole/src/locale/en.json +++ b/ogWebconsole/src/locale/en.json @@ -308,6 +308,8 @@ "noResultsMessage": "No results to display.", "imagesTitle": "Manage images", "addImageButton": "Add image", + "importImageButton": "Import image", + "convertImageButton": "Convert virtual image", "searchNameDescription": "Search images by name to quickly find a specific image.", "searchDefaultDescription": "Filter images to show only default or non-default images.", "searchDefaultLabel": "Default image", @@ -460,4 +462,4 @@ "organizationalUnitsStepText": "List of Organizational Units. Click on one to view details.", "defaultMenuLabel": "Main menu", "noClients": "No clients" -} \ No newline at end of file +} diff --git a/ogWebconsole/src/locale/es.json b/ogWebconsole/src/locale/es.json index 950ed2b..e9f04b6 100644 --- a/ogWebconsole/src/locale/es.json +++ b/ogWebconsole/src/locale/es.json @@ -239,6 +239,8 @@ "organizationalUnitLabel": "Padre", "ogLiveLabel": "OgLive", "imageNameLabel": "Nombre de la imagen", + "importImageButton": "Importar imagen", + "convertImageButton": "Convertir imagen virtual", "repositoryLabel": "Repositorios", "serialNumberLabel": "Número de Serie", "netifaceLabel": "Interfaz de red",