refs #1472. Changes in images and imageRepo
testing/ogGui-multibranch/pipeline/head This commit looks good Details

pull/16/head
Manuel Aranda Rosales 2025-02-10 13:59:14 +01:00
parent 3e64ae03ba
commit 75357b82c8
10 changed files with 84 additions and 42 deletions

View File

@ -1,9 +1,11 @@
<app-loading [isLoading]="loading"></app-loading>
<h2 mat-dialog-title>Transferir imagen {{data.image?.name}}</h2> <h2 mat-dialog-title>Transferir imagen {{data.image?.name}}</h2>
<mat-dialog-content> <mat-dialog-content>
<mat-form-field appearance="fill" class="full-width"> <mat-form-field appearance="fill" class="full-width">
<mat-label>Seleccione nuevo repositorio destino</mat-label> <mat-label>Seleccione nuevo repositorio destino</mat-label>
<mat-select [(value)]="selectedRepository"> <mat-select [(value)]="selectedRepositories" multiple>
<mat-option *ngFor="let repository of repositories" [value]="repository['@id']">{{ repository.name }}</mat-option> <mat-option *ngFor="let repository of repositories" [value]="repository['@id']">{{ repository.name }}</mat-option>
</mat-select> </mat-select>
</mat-form-field> </mat-form-field>

View File

@ -12,6 +12,8 @@ import {MatButtonModule} from "@angular/material/button";
import {MatSelectModule} from "@angular/material/select"; import {MatSelectModule} from "@angular/material/select";
import {BrowserAnimationsModule} from "@angular/platform-browser/animations"; import {BrowserAnimationsModule} from "@angular/platform-browser/animations";
import {TranslateModule} from "@ngx-translate/core"; import {TranslateModule} from "@ngx-translate/core";
import {LoadingComponent} from "../../../shared/loading/loading.component";
import {MatProgressSpinner} from "@angular/material/progress-spinner";
describe('ExportImageComponent', () => { describe('ExportImageComponent', () => {
let component: ExportImageComponent; let component: ExportImageComponent;
@ -19,7 +21,7 @@ describe('ExportImageComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [ExportImageComponent], declarations: [ExportImageComponent, LoadingComponent],
imports: [ imports: [
ReactiveFormsModule, ReactiveFormsModule,
MatDialogModule, MatDialogModule,
@ -27,6 +29,7 @@ describe('ExportImageComponent', () => {
MatInputModule, MatInputModule,
MatButtonModule, MatButtonModule,
MatSelectModule, MatSelectModule,
MatProgressSpinner,
BrowserAnimationsModule, BrowserAnimationsModule,
ToastrModule.forRoot(), ToastrModule.forRoot(),
TranslateModule.forRoot() TranslateModule.forRoot()

View File

@ -13,7 +13,7 @@ export class ExportImageComponent implements OnInit {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
loading: boolean = true; loading: boolean = true;
repositories: any[] = []; repositories: any[] = [];
selectedRepository: string = ''; selectedRepositories: any[] = [];
constructor( constructor(
private http: HttpClient, private http: HttpClient,
@ -31,27 +31,42 @@ export class ExportImageComponent implements OnInit {
} }
loadRepositories() { loadRepositories() {
this.http.get<any>(`${this.baseUrl}/image-repositories?id[neq]=1&page=1&itemsPerPage=50`).subscribe( const excludedIds = this.data?.image?.imageRepositories?.map((repository: any) => repository.id) || null;
response => {
this.repositories = response['hydra:member']; let url = `${this.baseUrl}/image-repositories?page=1&itemsPerPage=50`;
this.loading = false;
}, if (excludedIds) {
error => console.error('Error fetching organizational units:', error) url += `&id[neq]=${excludedIds.join(',')}`;
); }
this.http.get<any>(url)
.subscribe(
response => {
this.repositories = response['hydra:member'];
this.loading = false;
},
error => {
console.error('Error fetching repositories:', error);
this.loading = false;
}
);
} }
save() { save() {
this.http.post<any>(`${this.baseUrl}${this.selectedRepository}/transfer-image`, { this.loading = true;
images: [this.data.image['@id']] this.http.post<any>(`${this.baseUrl}${this.data.image['@id']}/transfer-image`, {
repositories: this.selectedRepositories
}).subscribe({ }).subscribe({
next: (response) => { next: (response) => {
this.toastService.success('Imagen exportada correctamente'); this.toastService.success('Petición de exportación de imagen realizada correctamente');
this.dialogRef.close(); this.dialogRef.close();
this.loading = false;
this.router.navigate(['/commands-logs']); this.router.navigate(['/commands-logs']);
}, },
error: error => { error: error => {
console.error('Error al exportar imagen:', error); this.loading = false;
this.toastService.error('Error al exportar imagen'); this.toastService.error('Error en la petición de exportación de imagen');
} }
}); });
} }

View File

@ -129,7 +129,7 @@ export class ImagesComponent implements OnInit {
search(): void { search(): void {
this.loading = true; this.loading = true;
this.http.get<any>(`${this.apiUrl}?page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}&repository.id=${this.repositoryId}`, { params: this.filters }).subscribe( this.http.get<any>(`${this.apiUrl}?page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}&repositoryId=${this.repositoryId}`, { params: this.filters }).subscribe(
data => { data => {
this.dataSource.data = data['hydra:member']; this.dataSource.data = data['hydra:member'];
this.length = data['hydra:totalItems']; this.length = data['hydra:totalItems'];
@ -197,15 +197,35 @@ export class ImagesComponent implements OnInit {
}); });
break; break;
case 'delete-trash': case 'delete-trash':
this.http.post(`${this.baseUrl}/images/server/${image.uuid}/delete-trash`, {}).subscribe({ if (!image.imageFullsum) {
next: () => { const dialogRef = this.dialog.open(DeleteModalComponent, {
this.toastService.success('Petición de eliminación de la papelera temporal enviada'); width: '400px',
this.search() data: { name: image.name },
}, });
error: (error) => {
this.toastService.error(error.error['hydra:description']); dialogRef.afterClosed().subscribe((result) => {
} this.http.delete(`${this.baseUrl}${image['@id']}`).subscribe({
}); next: () => {
this.toastService.success('Image deleted successfully');
this.search()
},
error: (error) => {
this.toastService.error('Error deleting image');
}
});
});
} else {
this.http.post(`${this.baseUrl}/images/server/${image.uuid}/delete-trash`, {}).subscribe({
next: () => {
this.toastService.success('Petición de eliminación de la papelera temporal enviada');
this.search()
},
error: (error) => {
this.toastService.error(error.error['hydra:description']);
}
});
}
break; break;
case 'delete-permanent': case 'delete-permanent':
this.http.post(`${this.baseUrl}/images/server/${image.uuid}/delete-permanent`, {}).subscribe({ this.http.post(`${this.baseUrl}/images/server/${image.uuid}/delete-permanent`, {}).subscribe({

View File

@ -1,6 +1,7 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { JoyrideService } from 'ngx-joyride'; import { JoyrideService } from 'ngx-joyride';
import {ToastrService} from "ngx-toastr";
@Component({ @Component({
selector: 'app-ogboot-status', selector: 'app-ogboot-status',
@ -25,7 +26,11 @@ export class OgbootStatusComponent implements OnInit {
domain: ['#FF6384', '#3f51b5'] domain: ['#FF6384', '#3f51b5']
}; };
constructor(private http: HttpClient, private joyrideService: JoyrideService) {} constructor(
private http: HttpClient,
private joyrideService: JoyrideService,
private toastService: ToastrService,
) {}
ngOnInit(): void { ngOnInit(): void {
this.loadStatus(); this.loadStatus();
@ -48,10 +53,12 @@ export class OgbootStatusComponent implements OnInit {
value: parseFloat(this.diskUsage.available) value: parseFloat(this.diskUsage.available)
} }
]; ];
this.loading = false;
}, error => { }, error => {
console.error('Error fetching status', error); this.toastService.error('Error al sincronizar con el el servicio de og-boot');
this.loading = false;
}); });
this.loading = false;
} }
getServices(): { name: string, status: string }[] { getServices(): { name: string, status: string }[] {

View File

@ -48,10 +48,11 @@ export class StatusComponent {
value: parseFloat(this.diskUsage.available) value: parseFloat(this.diskUsage.available)
} }
]; ];
this.loading = false;
}, error => { }, error => {
this.loading = false;
console.error('Error fetching status', error); console.error('Error fetching status', error);
}); });
this.loading = false;
} }
getServices(): { name: string, status: string }[] { getServices(): { name: string, status: string }[] {

View File

@ -209,7 +209,7 @@ export class MainRepositoryViewComponent implements OnInit {
searchImages(): void { searchImages(): void {
this.loading = true; this.loading = true;
this.http.get<any>(`${this.apiUrl}?repository.id=${this.repositoryData.id}&page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe( this.http.get<any>(`${this.apiUrl}?repositoryId=${this.repositoryData.id}&page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
data => { data => {
this.dataSource.data = data['hydra:member']; this.dataSource.data = data['hydra:member'];
this.length = data['hydra:totalItems']; this.length = data['hydra:totalItems'];

View File

@ -1,3 +1,5 @@
<app-loading [isLoading]="loading"></app-loading>
<div class="header-container"> <div class="header-container">
<button mat-icon-button color="primary" (click)="iniciarTour()"> <button mat-icon-button color="primary" (click)="iniciarTour()">
<mat-icon>help</mat-icon> <mat-icon>help</mat-icon>
@ -41,7 +43,6 @@
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th> <th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
<td mat-cell *matCellDef="let repository" style="text-align: center;"> <td mat-cell *matCellDef="let repository" style="text-align: center;">
<button mat-icon-button color="primary" (click)="importImage($event, repository)" i18n="@@editImage"> <mat-icon>move_to_inbox</mat-icon></button>
<button mat-icon-button color="primary" (click)="editRepository($event, repository)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button> <button mat-icon-button color="primary" (click)="editRepository($event, repository)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
<button mat-icon-button color="warn" (click)="deleteRepository($event, repository)"> <button mat-icon-button color="warn" (click)="deleteRepository($event, repository)">
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon> <mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>

View File

@ -19,6 +19,8 @@ import { ToastrModule, ToastrService } from 'ngx-toastr';
import { DataService } from '../calendar/data.service'; import { DataService } from '../calendar/data.service';
import { JoyrideModule } from 'ngx-joyride'; import { JoyrideModule } from 'ngx-joyride';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import {LoadingComponent} from "../../shared/loading/loading.component";
import {MatProgressSpinner} from "@angular/material/progress-spinner";
describe('RepositoriesComponent', () => { describe('RepositoriesComponent', () => {
let component: RepositoriesComponent; let component: RepositoriesComponent;
@ -26,7 +28,7 @@ describe('RepositoriesComponent', () => {
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
declarations: [RepositoriesComponent], declarations: [RepositoriesComponent, LoadingComponent],
imports: [ imports: [
ReactiveFormsModule, ReactiveFormsModule,
FormsModule, FormsModule,
@ -40,6 +42,7 @@ describe('RepositoriesComponent', () => {
MatDividerModule, MatDividerModule,
MatIconModule, MatIconModule,
BrowserAnimationsModule, BrowserAnimationsModule,
MatProgressSpinner,
ToastrModule.forRoot(), ToastrModule.forRoot(),
TranslateModule.forRoot(), TranslateModule.forRoot(),
JoyrideModule.forRoot(), JoyrideModule.forRoot(),

View File

@ -92,16 +92,6 @@ export class RepositoriesComponent {
this.router.navigate(['repository', repository.uuid]); this.router.navigate(['repository', repository.uuid]);
} }
importImage(event: MouseEvent, repository: any): void {
event.stopPropagation();
this.dialog.open(ImportImageComponent, {
width: '600px',
data: { repository }
}).afterClosed().subscribe(() => {
this.search();
});
}
deleteRepository(event: MouseEvent,command: any): void { deleteRepository(event: MouseEvent,command: any): void {
event.stopPropagation(); event.stopPropagation();
this.dialog.open(DeleteModalComponent, { this.dialog.open(DeleteModalComponent, {