From 4c9757a7c26ec01e54cd201a0695849349978a00 Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Thu, 9 Oct 2025 10:57:31 +0200 Subject: [PATCH] Updated partition assistant --- CHANGELOG.md | 14 ++++ .../global-status/global-status.component.ts | 83 +++++++++++++------ .../partition-assistant.component.ts | 11 +-- .../manage-client.component.html | 18 ---- .../manage-client/manage-client.component.ts | 30 +------ .../show-git-images.component.html | 5 +- .../show-git-images.component.ts | 35 ++++++++ 7 files changed, 117 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c95c05..8555928 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,18 @@ # Changelog +## [0.26.0] - 2025-10-09 +### Improved +- Se han eliminado campos redudantes en la creacion/edicion de cliente +- En el particionador, ahora el despleagble del disco se autocompleta en caso de ser 1. + +--- +## [0.25.0] - 2025-10-08 +### Added +- Se ha añadido una logica en el particionador, el cual filtra las opciones del sistema de ficheros, segun el tipo de particion seleccionado. + +### Fixed +- Se ha corregido el componente "estado global" ya que no funcionaba correctamente para el repositorio- + +--- ## [0.24.1] - 2025-10-06 ### Fixed - Se ha corregido un error en los casos de 2 discos o mas en el asistente de particionado. diff --git a/ogWebconsole/src/app/components/global-status/global-status.component.ts b/ogWebconsole/src/app/components/global-status/global-status.component.ts index 2d09a25..32f84c7 100644 --- a/ogWebconsole/src/app/components/global-status/global-status.component.ts +++ b/ogWebconsole/src/app/components/global-status/global-status.component.ts @@ -210,21 +210,32 @@ export class GlobalStatusComponent implements OnInit { this.loading = true; } this.errorRepositories = {}; - const timeoutId = setTimeout(() => { - if (showLoading) { - this.loading = false; - } - this.repositories.forEach(repository => { - if (!(repository.uuid in this.errorRepositories)) { - this.errorRepositories[repository.uuid] = true; - } - }); - }, 5000); - + this.http.get(`${this.repositoriesUrl}?page=1&itemsPerPage=10`).subscribe( data => { - this.repositories = data['hydra:member']; + console.log('Respuesta de repositorios:', data); // Debug log + this.repositories = data['hydra:member'] || []; + console.log('Repositorios cargados:', this.repositories); // Debug log + + if (this.repositories.length === 0) { + if (showLoading) { + this.loading = false; + } + return; + } + let remainingRepositories = this.repositories.length; + const timeoutId = setTimeout(() => { + if (showLoading) { + this.loading = false; + } + // Marcar como error los repositorios que no han respondido + this.repositories.forEach(repository => { + if (!(repository.uuid in this.errorRepositories)) { + this.errorRepositories[repository.uuid] = true; + } + }); + }, 5000); this.repositories.forEach(repository => { this.loadRepositoryStatus(repository.uuid, (errorOccurred: boolean) => { @@ -242,39 +253,61 @@ export class GlobalStatusComponent implements OnInit { }); }, error => { + console.error('Error al cargar repositorios:', error); // Debug log this.loading = false; - this.repositories.forEach(repository => { - this.errorRepositories[repository.uuid] = true; - }); - clearTimeout(timeoutId); + this.repositories = []; + this.toastService.error('Error al cargar la lista de repositorios'); } ); } loadRepositoryStatus(repositoryUuid: string, callback: (errorOccurred: boolean) => void): void { + console.log(`Cargando estado del repositorio: ${repositoryUuid}`); // Debug log const timeoutId = setTimeout(() => { + console.log(`Timeout al cargar estado del repositorio: ${repositoryUuid}`); // Debug log callback(true); }, 5000); + this.http.get(`${this.baseUrl}/image-repositories/server/${repositoryUuid}/status`).subscribe( data => { - const output = data.output; + console.log(`Estado del repositorio ${repositoryUuid}:`, data); // Debug log + + if (!data.success) { + console.error(`Error en la respuesta del repositorio ${repositoryUuid}:`, data); + clearTimeout(timeoutId); + callback(true); + return; + } + + const details = data.details; + const { disk, services, ram, cpu, processes } = details; + this.repositoryStatuses[repositoryUuid] = { - ...output, disk: { - ...output.disk, - used: parseFloat(output.disk.used), - available: parseFloat(output.disk.available) + ...disk, + used: parseFloat(disk.used.replace('GB', '')), + available: parseFloat(disk.available.replace('GB', '')), + total: parseFloat(disk.total.replace('GB', '')), + percentage: disk.used_percentage }, ram: { - ...output.ram, - used: parseFloat(output.ram.used), - available: parseFloat(output.ram.available) - } + ...ram, + used: parseFloat(ram.used.replace('GB', '')), + available: parseFloat(ram.available.replace('GB', '')), + total: parseFloat(ram.total.replace('GB', '')), + percentage: ram.used_percentage + }, + cpu: { + used_percentage: cpu.used_percentage + }, + services: services, + processes: processes }; clearTimeout(timeoutId); callback(false); }, error => { + console.error(`Error al cargar estado del repositorio ${repositoryUuid}:`, error); // Debug log this.toastService.error(error.error['hydra:description'] || 'Error al cargar el estado del repositorio'); clearTimeout(timeoutId); callback(true); diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts index 0613468..71438db 100644 --- a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.ts @@ -63,16 +63,13 @@ export class PartitionAssistantComponent implements OnInit, AfterViewInit, OnDes partitionCode: string = ''; generatedInstructions: string = ''; - // Propiedades para validación de particiones partitionValidationStatus: 'idle' | 'loading' | 'success' | 'error' = 'idle'; partitionValidationMessage: string = ''; - private validationDebounceTime = 500; // ms + private validationDebounceTime = 500; private validationSubject = new Subject(); - // Columnas para mat-table displayedColumns: string[] = ['partitionNumber', 'partitionCode', 'filesystem', 'size', 'percentage', 'format', 'actions']; - // Paleta de colores para las particiones private partitionColors = [ '#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E9', @@ -304,6 +301,11 @@ export class PartitionAssistantComponent implements OnInit, AfterViewInit, OnDes this.disks.forEach((disk) => { this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize); }); + + if (this.disks.length === 1) { + this.selectedDiskNumber = this.disks[0].diskNumber; + this.onDiskSelectionChange(); + } } convertBytesToGB(bytes: number): number { @@ -855,7 +857,6 @@ export class PartitionAssistantComponent implements OnInit, AfterViewInit, OnDes return this.partitionColors[(partitionNumber - 1) % this.partitionColors.length]; } - private validatePartitionCode(partitionCode: string | undefined | null): string { if (!partitionCode || partitionCode.trim() === '') { return 'EMPTY'; diff --git a/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.html b/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.html index ba16f19..3e37862 100644 --- a/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.html +++ b/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.html @@ -44,15 +44,6 @@ - - {{ 'netDriverLabel' | translate }} - - - {{ type.name }} - - - - {{ 'macLabel' | translate }} @@ -74,15 +65,6 @@ - - {{ 'hardwareProfileLabel' | translate }} - - - {{ profile.description }} - - - - {{ 'repositoryLabel' | translate }} diff --git a/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.ts b/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.ts index d38075c..9861be3 100644 --- a/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.ts +++ b/ogWebconsole/src/app/components/groups/shared/clients/manage-client/manage-client.component.ts @@ -16,7 +16,6 @@ export class ManageClientComponent implements OnInit { clientForm!: FormGroup; parentUnits: any[] = []; parentUnitsWithPaths: { id: string, name: string, path: string }[] = []; - hardwareProfiles: any[] = []; ogLives: any[] = []; menus: any[] = []; templates: any[] = []; @@ -29,9 +28,6 @@ export class ManageClientComponent implements OnInit { { name: 'Eth1', value: 'eth1' }, { name: 'Eth2', value: 'eth2' } ]; - protected netDriverTypes = [ - { name: 'Generic', value: 'generic' } - ]; isEditMode: boolean; constructor( @@ -53,7 +49,6 @@ export class ManageClientComponent implements OnInit { this.initForm(); const observables = [ this.loadParentUnits(), - this.loadHardwareProfiles(), this.loadOgLives(), this.loadPxeTemplates(), this.loadRepositories(), @@ -83,11 +78,10 @@ export class ManageClientComponent implements OnInit { name: ['', Validators.required], serialNumber: [''], netiface: null, - netDriver: null, + netDriver: 'generic', mac: ['', Validators.pattern(/^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/)], ip: ['', Validators.required], pxeTemplate: [null], - hardwareProfile: [null], ogLive: [null], repository: [null], menu: [null], @@ -108,7 +102,6 @@ export class ManageClientComponent implements OnInit { netiface: unit.networkSettings?.netiface, path: this.dataService.getOrganizationalUnitPath(unit, this.parentUnits), repository: unit.networkSettings?.repository?.['@id'], - hardwareProfile: unit.networkSettings?.hardwareProfile?.['@id'], ogLive: unit.networkSettings?.ogLive?.['@id'], menu: unit.networkSettings?.menu?.['@id'], pxeTemplate: unit.networkSettings?.pxeTemplate?.['@id'], @@ -134,21 +127,6 @@ export class ManageClientComponent implements OnInit { return this.parentUnitsWithPaths.find(unit => unit.id === parentId)?.name; } - loadHardwareProfiles(): Promise { - return new Promise((resolve, reject) => { - this.dataService.getHardwareProfiles().subscribe( - (data: any[]) => { - this.hardwareProfiles = data; - resolve(); - }, - error => { - console.error('Error fetching hardware profiles:', error); - reject(error); - } - ); - }); - } - loadOgLives(): Promise { return new Promise((resolve, reject) => { const url = `${this.baseUrl}/og-lives?page=1&itemsPerPage=30`; @@ -210,7 +188,7 @@ export class ManageClientComponent implements OnInit { resolve(); }, error => { - console.error('Error fetching ogLives:', error); + console.error('Error fetching repositories:', error); reject(error); } ); @@ -226,7 +204,6 @@ export class ManageClientComponent implements OnInit { if (selectedUnit) { this.clientForm.patchValue({ repository: selectedUnit.repository || null, - hardwareProfile: selectedUnit.hardwareProfile || null, ogLive: selectedUnit.ogLive || null, menu: selectedUnit.menu || null, netiface: selectedUnit.netiface || null, @@ -246,9 +223,8 @@ export class ManageClientComponent implements OnInit { ip: data.ip, mac: data.mac, netiface: data.netiface, - netDriver: data.netDriver, + netDriver: 'generic', serialNumber: data.serialNumber, - hardwareProfile: data.hardwareProfile ? data.hardwareProfile['@id'] : null, organizationalUnit: data.organizationalUnit ? data.organizationalUnit['@id'] : null, repository: data.repository ? data.repository['@id'] : null, ogLive: data.ogLive ? data.ogLive['@id'] : null, diff --git a/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.html b/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.html index 0510216..242b781 100644 --- a/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.html +++ b/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.html @@ -11,6 +11,7 @@
+
@@ -100,10 +101,6 @@ - - diff --git a/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.ts b/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.ts index 77268a1..d640fb6 100644 --- a/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.ts +++ b/ogWebconsole/src/app/components/repositories/show-git-images/show-git-images.component.ts @@ -11,6 +11,7 @@ import {ServerInfoDialogComponent} from "../../ogdhcp/server-info-dialog/server- import {CreateTagModalComponent} from "./create-tag-modal/create-tag-modal.component"; import {CreateBranchModalComponent} from "./create-branch-modal/create-branch-modal.component"; import { BackupRepositoryModalComponent } from './backup-repository-modal/backup-repository-modal.component'; +import {DeleteModalComponent} from "../../../shared/delete_modal/delete-modal/delete-modal.component"; @Component({ selector: 'app-show-git-commits', @@ -317,6 +318,40 @@ export class ShowGitCommitsComponent implements OnInit{ window.open(`http://localhost:3100/oggit/${this.selectedRepository}/commit/${commit.hexsha}`, '_blank'); } + deleteRepository(): void { + if (!this.selectedRepository) { + this.toastService.warning('Por favor, selecciona un repositorio primero'); + return; + } + + const dialogRef = this.dialog.open(DeleteModalComponent, { + width: '400px', + data: { + name: this.selectedRepository, + title: 'Eliminar Repositorio', + message: '¿Estás seguro que deseas eliminar este repositorio? Esta acción no se puede deshacer.', + confirmText: 'Eliminar', + cancelText: 'Cancelar' + } + }); + + dialogRef.afterClosed().subscribe(result => { + if (result) { + const payload = { repositoryName: this.selectedRepository }; + this.http.post(`${this.baseUrl}/image-repositories/server/git/${this.data.repositoryUuid}/delete`, payload).subscribe({ + next: () => { + this.toastService.success('Repositorio eliminado con éxito'); + this.dialogRef.close(true); + }, + error: (error) => { + console.error('Error al eliminar el repositorio:', error); + this.toastService.error('Error al eliminar el repositorio'); + } + }); + } + }); + } + onNoClick(): void { this.dialogRef.close(); }