diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html
index 273c99e..2a01f5c 100644
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html
@@ -63,8 +63,8 @@
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html
index bc674a1..b38b624 100644
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/partition-assistant/partition-assistant.component.html
@@ -28,7 +28,7 @@
- {{ j + 1 }} |
+ {{ partition.partitionNumber }} |
|
-
+
|
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 2ef9ded..f020f81 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
@@ -2,6 +2,8 @@ import { Component, Input, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
interface Partition {
+ uuid?: string; // Agregamos uuid opcional
+ partitionNumber: number;
size: number;
type: string;
sizeBytes: number;
@@ -17,11 +19,11 @@ interface Partition {
})
export class PartitionAssistantComponent implements OnInit {
@Input() data: any;
- @Input() clientUuid: string | undefined; // El clientUuid que necesitas
+ @Input() clientUuid: string | undefined;
errorMessage = '';
originalPartitions: any[] = [];
- disks: { diskNumber: number, totalDiskSize: number, partitions: Partition[] }[] = [];
+ disks: { diskNumber: number; totalDiskSize: number; partitions: Partition[] }[] = [];
private apiUrl = 'http://127.0.0.1:8001/partitions';
@@ -33,9 +35,9 @@ export class PartitionAssistantComponent implements OnInit {
initializeDisks() {
const partitionsFromData = this.data.partitions;
- this.originalPartitions = JSON.parse(JSON.stringify(partitionsFromData)); // Guardar una copia de las particiones originales
+ this.originalPartitions = JSON.parse(JSON.stringify(partitionsFromData));
- const disksMap = new Map();
+ const disksMap = new Map();
partitionsFromData.forEach((partition: any) => {
if (!disksMap.has(partition.diskNumber)) {
@@ -47,8 +49,10 @@ export class PartitionAssistantComponent implements OnInit {
disk!.totalDiskSize = this.convertBytesToGB(partition.size);
} else {
disk!.partitions.push({
+ uuid: partition.uuid, // Incluimos el uuid
+ partitionNumber: partition.partitionNumber,
size: this.convertBytesToGB(partition.size),
- type: 'NTFS', // Puedes cambiar el tipo según sea necesario
+ type: partition.type,
sizeBytes: partition.size,
format: false,
color: '#' + Math.floor(Math.random() * 16777215).toString(16),
@@ -72,24 +76,28 @@ export class PartitionAssistantComponent implements OnInit {
}
updatePartitionPercentages(partitions: Partition[], totalDiskSize: number) {
- partitions.forEach(partition => {
+ partitions.forEach((partition) => {
partition.percentage = (partition.size / totalDiskSize) * 100;
});
}
- // Añadir una nueva partición
addPartition(diskNumber: number) {
- const disk = this.disks.find(d => d.diskNumber === diskNumber);
+ const disk = this.disks.find((d) => d.diskNumber === diskNumber);
if (disk) {
const remainingGB = this.getRemainingGB(disk.partitions, disk.totalDiskSize);
if (remainingGB > 0) {
+ const maxPartitionNumber =
+ disk.partitions.length > 0 ? Math.max(...disk.partitions.map((p) => p.partitionNumber)) : 0;
+ const newPartitionNumber = maxPartitionNumber + 1;
+
disk.partitions.push({
+ partitionNumber: newPartitionNumber,
size: 0,
- type: 'NTFS', // Tipo por defecto, puede ser cambiado por el usuario
+ type: 'NTFS',
sizeBytes: 0,
format: false,
- color: '#' + Math.floor(Math.random() * 16777215).toString(16), // Color aleatorio
+ color: '#' + Math.floor(Math.random() * 16777215).toString(16),
percentage: 0
});
this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize);
@@ -99,15 +107,16 @@ export class PartitionAssistantComponent implements OnInit {
}
}
- // Actualizar el tamaño de una partición
updatePartitionSize(diskNumber: number, index: number, size: number) {
- const disk = this.disks.find(d => d.diskNumber === diskNumber);
+ const disk = this.disks.find((d) => d.diskNumber === diskNumber);
if (disk) {
const partition = disk.partitions[index];
const remainingGB = this.getRemainingGB(disk.partitions, disk.totalDiskSize) + partition.size;
if (size > remainingGB) {
- this.errorMessage = `El tamaño de la partición no puede superar el espacio libre (${remainingGB.toFixed(2)} GB).`;
+ this.errorMessage = `El tamaño de la partición no puede superar el espacio libre (${remainingGB.toFixed(
+ 2
+ )} GB).`;
} else {
this.errorMessage = '';
partition.size = size;
@@ -132,17 +141,28 @@ export class PartitionAssistantComponent implements OnInit {
getModifiedOrNewPartitions() {
const modifiedPartitions: any[] = [];
- this.disks.forEach(disk => {
- disk.partitions.forEach((partition, index) => {
+ this.disks.forEach((disk) => {
+ disk.partitions.forEach((partition) => {
const originalPartition = this.originalPartitions.find(
- p => p.diskNumber === disk.diskNumber && p.partitionNumber === index + 1
+ (p) => p.diskNumber === disk.diskNumber && p.partitionNumber === partition.partitionNumber
);
- // Si no existe en las originales, es nueva
if (!originalPartition) {
- modifiedPartitions.push({ partition, diskNumber: disk.diskNumber, partitionNumber: index + 1 });
+ // Es una nueva partición
+ modifiedPartitions.push({
+ partition,
+ diskNumber: disk.diskNumber,
+ partitionNumber: partition.partitionNumber,
+ isNew: true
+ });
} else if (this.isPartitionModified(originalPartition, partition)) {
- modifiedPartitions.push({ partition, diskNumber: disk.diskNumber, partitionNumber: index + 1 });
+ // La partición ha sido modificada
+ modifiedPartitions.push({
+ partition,
+ diskNumber: disk.diskNumber,
+ partitionNumber: partition.partitionNumber,
+ isNew: false
+ });
}
});
});
@@ -158,33 +178,62 @@ export class PartitionAssistantComponent implements OnInit {
return;
}
- modifiedPartitions.forEach(({ partition, diskNumber, partitionNumber }) => {
+ modifiedPartitions.forEach(({ partition, diskNumber, partitionNumber, isNew }) => {
const payload = {
diskNumber: diskNumber,
partitionNumber: partitionNumber,
size: partition.size,
filesystem: partition.type,
- client: `https://example.com/${this.clientUuid}`
+ client: `/clients/${this.clientUuid}`
};
- this.http.post(this.apiUrl, payload).subscribe(
- response => {
- console.log('Partición guardada exitosamente:', response);
- },
- error => {
- console.error('Error al guardar la partición:', error);
- }
- );
+ if (isNew) {
+ // Es una nueva partición, usamos POST
+ this.http.post(this.apiUrl, payload).subscribe(
+ (response) => {
+ console.log('Partición creada exitosamente:', response);
+ },
+ (error) => {
+ console.error('Error al crear la partición:', error);
+ }
+ );
+ } else if (partition.uuid) {
+ // Es una partición existente modificada, usamos PATCH
+ const patchUrl = `${this.apiUrl}/${partition.uuid}`;
+ this.http.patch(patchUrl, payload).subscribe(
+ (response) => {
+ console.log('Partición actualizada exitosamente:', response);
+ },
+ (error) => {
+ console.error('Error al actualizar la partición:', error);
+ }
+ );
+ }
});
}
- // Eliminar partición de un disco
- removePartition(diskNumber: number, index: number) {
- const disk = this.disks.find(d => d.diskNumber === diskNumber);
+ removePartition(diskNumber: number, partition: Partition) {
+ const disk = this.disks.find((d) => d.diskNumber === diskNumber);
if (disk) {
- disk.partitions.splice(index, 1);
- this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize);
+ const index = disk.partitions.indexOf(partition);
+ if (index !== -1) {
+ disk.partitions.splice(index, 1);
+ this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize);
+
+ if (partition.uuid) {
+ // La partición existía originalmente, enviamos DELETE
+ const deleteUrl = `${this.apiUrl}/${partition.uuid}`;
+ this.http.delete(deleteUrl).subscribe(
+ (response) => {
+ console.log('Partición eliminada exitosamente:', response);
+ },
+ (error) => {
+ console.error('Error al eliminar la partición:', error);
+ }
+ );
+ }
+ }
}
}
}
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.css b/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.css
index e69de29..ad6b310 100644
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.css
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.css
@@ -0,0 +1,71 @@
+.partition-assistant {
+ font-family: 'Roboto', sans-serif;
+ background-color: #f9f9f9;
+ padding: 20px;
+ border-radius: 10px;
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
+ margin: 20px auto;
+ }
+
+ .header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-bottom: 15px;
+ padding: 10px;
+ background-color: #fff;
+ border-radius: 8px;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
+ }
+
+ .partition-table {
+ width: 100%;
+ border-collapse: collapse;
+ background-color: #fff;
+ border-radius: 8px;
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
+ overflow: hidden;
+ margin-bottom: 20px;
+ }
+
+ .partition-table th {
+ background-color: #f5f5f5;
+ color: #333;
+ padding: 12px;
+ font-weight: 600;
+ }
+
+ .partition-table td {
+ padding: 10px;
+ text-align: center;
+ border-bottom: 1px solid #eee;
+ }
+
+ .partition-table select {
+ padding: 5px;
+ border-radius: 4px;
+ border: 1px solid #ccc;
+ width: 100%;
+ }
+
+ .actions {
+ display: flex;
+ justify-content: flex-end;
+ padding-top: 10px;
+ }
+
+ button.mat-flat-button {
+ background-color: #28a745;
+ color: white;
+ padding: 10px 20px;
+ border-radius: 4px;
+ font-size: 1rem;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background-color 0.3s ease;
+ }
+
+ button.mat-flat-button:hover {
+ background-color: #218838;
+ }
+
\ No newline at end of file
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.html
index 8351543..f8f105a 100644
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.html
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.html
@@ -1 +1,38 @@
-restore-image works!
+
+
+
+
+
+
+ Partición |
+ Imagen ISO |
+ OgLive |
+
+
+
+
+ {{ partition.partitionNumber }} |
+
+
+ |
+
+
+ |
+
+
+
+
+
+
+
+
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.ts
index 46f1874..65d424d 100644
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.ts
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.ts
@@ -1,10 +1,95 @@
-import { Component } from '@angular/core';
+import { Component, Input, OnInit } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+
+interface Image {
+ '@id': string;
+ '@type': string;
+ name: string;
+ description: string;
+ comments: string;
+ uuid: string;
+ id: number;
+}
+
+interface Partition {
+ diskNumber: number;
+ partitionNumber: number;
+ associatedImageId?: string;
+ associatedOgLive?: string;
+}
@Component({
selector: 'app-restore-image',
templateUrl: './restore-image.component.html',
- styleUrl: './restore-image.component.css'
+ styleUrls: ['./restore-image.component.css']
})
-export class RestoreImageComponent {
+export class RestoreImageComponent implements OnInit {
+ @Input() data: any;
+ disks: { diskNumber: number; partitions: Partition[] }[] = [];
+ availableImages: Image[] = [];
+ availableOgLives: string[] = [];
+
+ constructor(private http: HttpClient) {}
+
+ ngOnInit(): void {
+ this.initializeDisks();
+ this.fetchAvailableImages();
+ this.availableOgLives = ['LiveCD1', 'LiveCD2', 'LiveCD3'];
+ }
+
+ initializeDisks() {
+ const partitionsFromData = this.data.partitions;
+ const disksMap = new Map();
+
+ partitionsFromData.forEach((partition: any) => {
+ if (!disksMap.has(partition.diskNumber)) {
+ disksMap.set(partition.diskNumber, []);
+ }
+
+ disksMap.get(partition.diskNumber)!.push({
+ diskNumber: partition.diskNumber,
+ partitionNumber: partition.partitionNumber
+ });
+ });
+
+ disksMap.forEach((partitions, diskNumber) => {
+ this.disks.push({ diskNumber, partitions });
+ });
+ }
+
+ fetchAvailableImages() {
+ const url = 'http://127.0.0.1:8001/images?page=1&itemsPerPage=30';
+ this.http.get(url).subscribe(
+ (response: any) => {
+ this.availableImages = response['hydra:member'];
+ },
+ (error) => {
+ console.error('Error al obtener las imágenes:', error);
+ }
+ );
+ }
+
+ onImageSelected(partition: Partition, event: Event) {
+ const selectElement = event.target as HTMLSelectElement;
+ partition.associatedImageId = selectElement.value;
+ }
+
+ onOgLiveSelected(partition: Partition, event: Event) {
+ const selectElement = event.target as HTMLSelectElement;
+ partition.associatedOgLive = selectElement.value;
+ }
+
+ saveAssociations() {
+ this.disks.forEach(disk => {
+ disk.partitions.forEach(partition => {
+ if (partition.associatedImageId || partition.associatedOgLive) {
+ console.log(
+ `Guardando para disco ${partition.diskNumber}, partición ${partition.partitionNumber}, ` +
+ `Imagen ID: ${partition.associatedImageId}, OgLive: ${partition.associatedOgLive}`
+ );
+ }
+ });
+ });
+ }
}
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 e54bd91..8c13383 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
@@ -19,7 +19,11 @@
Perfil de software
-
+
+
+ {{ profile.description }}
+
+
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 f68a14a..9939531 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,16 +1,30 @@
-import { Component } from '@angular/core';
+import { Component, OnInit } from '@angular/core';
import { 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;
+}
+
@Component({
selector: 'app-create-image',
templateUrl: './create-image.component.html',
styleUrls: ['./create-image.component.css']
})
-export class CreateImageComponent {
+export class CreateImageComponent implements OnInit {
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
- imagePayload = {
+ imagePayload: ImagePayload = {
name: null,
description: null,
comments: null,
@@ -23,21 +37,44 @@ export class CreateImageComponent {
softwareProfile: null
};
+ softwareProfiles: any[] = [];
+
constructor(
public dialogRef: MatDialogRef,
private http: HttpClient,
private toastService: ToastrService
) {}
- saveImage(): void {
- // Remover propiedades que son null antes de enviar la solicitud
- const payload = { ...this.imagePayload };
+ ngOnInit() {
+ this.fetchSoftwareProfiles();
+ }
- // Enviar la solicitud POST al servidor
+ fetchSoftwareProfiles() {
+ const url = 'http://127.0.0.1:8001/software-profiles?page=1&itemsPerPage=30';
+ this.http.get(url).subscribe({
+ next: (response: any) => {
+ this.softwareProfiles = response['hydra:member'];
+ },
+ error: (error) => {
+ console.error('Error al obtener los perfiles de software:', error);
+ this.toastService.error('Error al obtener los perfiles de software');
+ }
+ });
+ }
+
+ saveImage(): void {
+ const payload = { ...this.imagePayload };
+ Object.keys(payload).forEach(key => {
+ if (payload[key] == null) {
+ delete payload[key];
+ }
+ });
+
+ console.log('Payload:', payload);
this.http.post(`${this.baseUrl}/images`, payload).subscribe({
next: () => {
this.toastService.success('Imagen creada con éxito');
- this.dialogRef.close(true); // Cierra el diálogo y retorna true
+ this.dialogRef.close(true);
},
error: (error) => {
console.error('Error al crear la imagen:', error);
@@ -47,6 +84,6 @@ export class CreateImageComponent {
}
close(): void {
- this.dialogRef.close(); // Cierra el diálogo sin retorno
+ this.dialogRef.close();
}
}