refs #1604. Backup image UX
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
parent
0350e0110c
commit
09f83f6af7
|
@ -1,3 +1,5 @@
|
||||||
|
<app-loading [isLoading]="loading"></app-loading>
|
||||||
|
|
||||||
<h2 mat-dialog-title>{{ imageId ? 'Editar' : 'Crear' }} imagen</h2>
|
<h2 mat-dialog-title>{{ imageId ? 'Editar' : 'Crear' }} imagen</h2>
|
||||||
|
|
||||||
<mat-dialog-content class="dialog-content">
|
<mat-dialog-content class="dialog-content">
|
||||||
|
@ -14,11 +16,10 @@
|
||||||
<input matInput formControlName="name" required>
|
<input matInput formControlName="name" required>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<mat-form-field appearance="fill" class="form-field">
|
<mat-form-field appearance="fill" class="form-field" *ngIf="!imageId">
|
||||||
<mat-label>{{ 'repositoryLabel' | translate }}</mat-label>
|
<mat-label>{{ 'repositoryLabel' | translate }}</mat-label>
|
||||||
<mat-select formControlName="imageRepositories" required multiple>
|
<mat-select formControlName="imageRepositories" required multiple>
|
||||||
<mat-option *ngFor="let imageRepository of repositories" [value]="imageRepository['@id']"
|
<mat-option *ngFor="let imageRepository of repositories" [value]="imageRepository['@id']">
|
||||||
[disabled]="imageId !== null">
|
|
||||||
{{ imageRepository.name }}
|
{{ imageRepository.name }}
|
||||||
</mat-option>
|
</mat-option>
|
||||||
</mat-select>
|
</mat-select>
|
||||||
|
|
|
@ -16,8 +16,9 @@ export class CreateImageComponent implements OnInit {
|
||||||
imageId: string | null = null;
|
imageId: string | null = null;
|
||||||
softwareProfiles: any[] = [];
|
softwareProfiles: any[] = [];
|
||||||
repositories: any[] = [];
|
repositories: any[] = [];
|
||||||
|
loading: boolean = false;
|
||||||
partitionInfo: { [key: string]: string } = {};
|
partitionInfo: { [key: string]: string } = {};
|
||||||
showWarning: boolean = false; // Nueva variable para mostrar la advertencia
|
showWarning: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private fb: FormBuilder,
|
private fb: FormBuilder,
|
||||||
|
@ -39,12 +40,13 @@ export class CreateImageComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
|
this.loading = true;
|
||||||
if (this.data) {
|
if (this.data) {
|
||||||
this.load()
|
this.load()
|
||||||
}
|
}
|
||||||
this.fetchSoftwareProfiles();
|
this.fetchSoftwareProfiles();
|
||||||
this.fetchRepositories();
|
this.fetchRepositories();
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
load(): void {
|
load(): void {
|
||||||
|
@ -79,7 +81,6 @@ export class CreateImageComponent implements OnInit {
|
||||||
this.softwareProfiles = response['hydra:member'];
|
this.softwareProfiles = response['hydra:member'];
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Error al obtener los perfiles de software:', error);
|
|
||||||
this.toastService.error('Error al obtener los perfiles de software');
|
this.toastService.error('Error al obtener los perfiles de software');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -92,7 +93,6 @@ export class CreateImageComponent implements OnInit {
|
||||||
this.repositories = response['hydra:member'];
|
this.repositories = response['hydra:member'];
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
console.error('Error al obtener los repositorios de imágenes:', error);
|
|
||||||
this.toastService.error('Error al obtener los repositorios de imágenes');
|
this.toastService.error('Error al obtener los repositorios de imágenes');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -117,7 +117,6 @@ export class CreateImageComponent implements OnInit {
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
this.toastService.error(error['error']['hydra:description']);
|
this.toastService.error(error['error']['hydra:description']);
|
||||||
console.error('Error al editar la imagen', error);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
@ -128,7 +127,6 @@ export class CreateImageComponent implements OnInit {
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
this.toastService.error(error['error']['hydra:description']);
|
this.toastService.error(error['error']['hydra:description']);
|
||||||
console.error('Error al añadir la imagen', error);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
.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; /* Alinea texto a la izquierda y botón a la derecha */
|
||||||
|
align-items: center; /* Centra verticalmente */
|
||||||
|
padding: 8px;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selected-item button {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-container {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 1em;
|
||||||
|
padding: 1.5em;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
<app-loading [isLoading]="loading"></app-loading>
|
||||||
|
|
||||||
|
<h2 mat-dialog-title>Realizar backup a repositorio remoto</h2>
|
||||||
|
|
||||||
|
<mat-dialog-content>
|
||||||
|
<form [formGroup]="form">
|
||||||
|
<mat-form-field appearance="fill" class="form-field">
|
||||||
|
<mat-label>Ip servidor</mat-label>
|
||||||
|
<input matInput formControlName="repoIp" name="description">
|
||||||
|
</mat-form-field>
|
||||||
|
<mat-form-field appearance="fill" class="form-field">
|
||||||
|
<mat-label>Remote path remoto</mat-label>
|
||||||
|
<input matInput formControlName="remotePath" name="description">
|
||||||
|
</mat-form-field>
|
||||||
|
</form>
|
||||||
|
</mat-dialog-content>
|
||||||
|
|
||||||
|
<div mat-dialog-actions class="action-container">
|
||||||
|
<button class="ordinary-button" (click)="close()">Cancelar</button>
|
||||||
|
<button class="submit-button" [disabled]="!form.valid" (click)="save()">Continuar</button>
|
||||||
|
</div>
|
|
@ -0,0 +1,23 @@
|
||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { BackupImageComponent } from './backup-image.component';
|
||||||
|
|
||||||
|
describe('BackupImageComponent', () => {
|
||||||
|
let component: BackupImageComponent;
|
||||||
|
let fixture: ComponentFixture<BackupImageComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
declarations: [BackupImageComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(BackupImageComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,58 @@
|
||||||
|
import {Component, Inject, OnInit} 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";
|
||||||
|
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-backup-image',
|
||||||
|
templateUrl: './backup-image.component.html',
|
||||||
|
styleUrl: './backup-image.component.css'
|
||||||
|
})
|
||||||
|
export class BackupImageComponent implements OnInit {
|
||||||
|
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||||
|
loading: boolean = false;
|
||||||
|
form!: FormGroup;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
private fb: FormBuilder,
|
||||||
|
private http: HttpClient,
|
||||||
|
public dialogRef: MatDialogRef<BackupImageComponent>,
|
||||||
|
private toastService: ToastrService,
|
||||||
|
private router: Router,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: { imageImageRepository: any }
|
||||||
|
) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.form = this.fb.group({
|
||||||
|
remotePath: ['', Validators.required],
|
||||||
|
repoIp: ['', Validators.required]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.loading = true
|
||||||
|
this.http.post<any>(`${this.baseUrl}${this.data.imageImageRepository['@id']}/backup-image`, {
|
||||||
|
remotePath: this.form.value.remotePath,
|
||||||
|
repoIp: this.form.value.repoIp
|
||||||
|
}).subscribe({
|
||||||
|
next: (response) => {
|
||||||
|
this.toastService.success('Peticion de backup de imagen enviada correctamente');
|
||||||
|
this.dialogRef.close();
|
||||||
|
this.loading = false;
|
||||||
|
this.router.navigate(['/commands-logs']);
|
||||||
|
},
|
||||||
|
error: error => {
|
||||||
|
this.loading = false;
|
||||||
|
this.toastService.error('Error al realizar la petición de backup de imagen');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.dialogRef.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
<mat-tab-group dynamicHeight>
|
<mat-tab-group dynamicHeight>
|
||||||
<mat-tab label="Estado servidor">
|
<mat-tab label="Estado servidor">
|
||||||
|
<app-loading [isLoading]="loading"></app-loading>
|
||||||
<div class="server-status">
|
<div class="server-status">
|
||||||
<h2>OgRepository Server Status</h2>
|
<h2>OgRepository Server Status</h2>
|
||||||
|
|
||||||
|
@ -108,7 +109,7 @@
|
||||||
<input matInput formControlName="comments" name="comments">
|
<input matInput formControlName="comments" name="comments">
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
<button class="submit-button" class="save-button" (click)="save()">Guardar</button>
|
<button class="submit-button" (click)="save()">Guardar</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class MainRepositoryViewComponent implements OnInit {
|
||||||
repositoryForm: FormGroup<any>;
|
repositoryForm: FormGroup<any>;
|
||||||
repositoryId: string | null = null;
|
repositoryId: string | null = null;
|
||||||
dataSource = new MatTableDataSource<any>();
|
dataSource = new MatTableDataSource<any>();
|
||||||
loading: boolean = true;
|
loading: boolean = false;
|
||||||
diskUsage: any = {};
|
diskUsage: any = {};
|
||||||
servicesStatus: any = {};
|
servicesStatus: any = {};
|
||||||
processesStatus: any = {};
|
processesStatus: any = {};
|
||||||
|
@ -103,9 +103,8 @@ export class MainRepositoryViewComponent implements OnInit {
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.repositoryId = this.route.snapshot.paramMap.get('id');
|
this.repositoryId = this.route.snapshot.paramMap.get('id');
|
||||||
this.loading = true
|
|
||||||
this.load()
|
|
||||||
this.loadStatus()
|
this.loadStatus()
|
||||||
|
this.load()
|
||||||
}
|
}
|
||||||
|
|
||||||
load(): void {
|
load(): void {
|
||||||
|
@ -118,11 +117,9 @@ export class MainRepositoryViewComponent implements OnInit {
|
||||||
ip: [response.ip],
|
ip: [response.ip],
|
||||||
comments: [response.comments],
|
comments: [response.comments],
|
||||||
});
|
});
|
||||||
this.loading = false;
|
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
console.error('Error al cargar los datos del cliente:', error);
|
console.error('Error al cargar los datos del cliente:', error);
|
||||||
this.loading = false;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -158,9 +155,11 @@ export class MainRepositoryViewComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
loadStatus(): void {
|
loadStatus(): void {
|
||||||
|
this.loading = true;
|
||||||
this.http.get<any>(`${this.baseUrl}/image-repositories/server/${this.repositoryId}/status`).subscribe(data => {
|
this.http.get<any>(`${this.baseUrl}/image-repositories/server/${this.repositoryId}/status`).subscribe(data => {
|
||||||
if (!data.success) {
|
if (!data.success) {
|
||||||
console.error('Error: No se pudo obtener los datos del servidor');
|
this.toastService.error('Error al obtener el estado del servidor');
|
||||||
|
this.loading = false;
|
||||||
this.status = false;
|
this.status = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -182,13 +181,11 @@ export class MainRepositoryViewComponent implements OnInit {
|
||||||
];
|
];
|
||||||
|
|
||||||
this.cpuUsage = { percentage: cpu.used_percentage };
|
this.cpuUsage = { percentage: cpu.used_percentage };
|
||||||
|
|
||||||
this.servicesStatus = Object.entries(services).map(([name, status]) => ({ name, status }));
|
this.servicesStatus = Object.entries(services).map(([name, status]) => ({ name, status }));
|
||||||
|
|
||||||
this.processesStatus = Object.entries(processes).map(([name, status]) => ({ name, status }));
|
this.processesStatus = Object.entries(processes).map(([name, status]) => ({ name, status }));
|
||||||
|
this.loading = false;
|
||||||
}, error => {
|
}, error => {
|
||||||
console.error('Error fetching status', error);
|
this.loading = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue