-
-
-
+
+
{{ clientData?.property }}
{{ clientData?.value }}
-
-
{{ clientData?.property }}
{{ clientData?.value }}
-
-
-
-
-
-
-
-
-
- {{ column.header }} |
-
-
- {{ column.cell(image) }}
-
-
-
- {{ (image.size / 1024).toFixed(2) }} GB
-
-
- |
-
-
-
-
-
-
-
-
0">
-
-
-
Disco {{ disk.diskNumber }}
-
-
-
-
Usado: {{ disk.used }} GB ({{ disk.percentage }}%)
-
Total: {{ disk.total }} GB
-
-
-
+
+
+
+
-
+
+
+
+ {{ column.header }} |
+
+
+ {{ column.cell(image) }}
+
+
+
+ {{ (image.size / 1024).toFixed(2) }} GB
+
+
+ |
+
+
+
+
+
+
+
+
0">
+
+
+
+
+
+
Disco {{ disk.diskNumber }}
+
Usado: {{ disk.used }} GB ({{ disk.percentage }}%)
+
Total: {{ disk.total }} GB
+
+
+
+
+
+
+
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts
index 3e4c70f..ccf6560 100644
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts
@@ -31,6 +31,24 @@ export class ClientMainViewComponent implements OnInit {
diskUsageData: any[] = [];
partitions: any[] = [];
commands: any[] = [];
+ chartDisk: any[] = [];
+ view: [number, number] = [600, 300];
+ showLegend: boolean = true;
+
+ arrayCommands: any[] = [
+ {name: 'Enceder', slug: 'power-on'},
+ {name: 'Apagar', slug: 'power-off'},
+ {name: 'Reiniciar', slug: 'reboot'},
+ {name: 'Iniciar Sesión', slug: 'login'},
+ {name: 'Crear Image', slug: 'create-image'},
+ {name: 'Deploy Image', slug: 'deploy-image'},
+ {name: 'Eliminar Imagen Cache', slug: 'delete-image-cache'},
+ {name: 'Particionar y Formatear', slug: 'partition'},
+ {name: 'Inventario Software', slug: 'software-inventory'},
+ {name: 'Inventario Hardware', slug: 'hardware-inventory'},
+ {name: 'Ejecutar script', slug: 'run-script'},
+ ];
+
datePipe: DatePipe = new DatePipe('es-ES');
columns = [
{
@@ -58,6 +76,11 @@ export class ClientMainViewComponent implements OnInit {
header: 'Uso',
cell: (partition: any) => `${partition.memoryUsage} %`
},
+ {
+ columnDef: 'operativeSystem',
+ header: 'SO',
+ cell: (partition: any) => `${partition.operativeSystem?.name}`
+ },
];
displayedColumns = [...this.columns.map(column => column.columnDef)];
isDiskUsageEmpty: boolean = true;
@@ -75,6 +98,7 @@ export class ClientMainViewComponent implements OnInit {
ngOnInit() {
this.clientData = history.state.clientData;
+ console.log(this.clientData)
this.loadPartitions()
this.updateGeneralData();
this.updateNetworkData();
@@ -100,11 +124,11 @@ export class ClientMainViewComponent implements OnInit {
this.networkData = [
{ property: 'Remote Pc', value: this.clientData.remotePc || '' },
{ property: 'Subred', value: this.clientData?.subnet || '' },
- { property: 'OGlive', value: '' },
+ { property: 'OGlive', value: this.clientData?.ogLive?.name || '' },
{ property: 'Autoexec', value: '' },
- { property: 'Repositorio', value: '' },
+ { property: 'Repositorio', value: this.clientData?.repository?.name || '' },
{ property: 'Validación', value: this.clientData?.organizationalUnit?.networkSettings?.validation || '' },
- { property: 'Pxe', value: this.clientData?.template.name || '' },
+ { property: 'Pxe', value: this.clientData?.template?.name || '' },
{ property: 'Creado por', value: this.clientData?.createdBy || '' }
];
}
@@ -124,19 +148,39 @@ export class ClientMainViewComponent implements OnInit {
if (partition.partitionNumber === 0) {
diskData!.total = Number((partition.size / 1024).toFixed(2));
} else {
- diskData!.used += Number(((partition.size * (partition.memoryUsage / 100)) / 1024).toFixed(2));
+ diskData!.used += Number((partition.size / 1024).toFixed(2));
diskData!.partitions.push(partition);
}
});
- this.diskUsageData = Array.from(diskUsageMap.entries()).map(([diskNumber, { total, used, partitions }]) => {
- const percentage = total > 0 ? Math.round((used / total) * 100) : 0;
- return { diskNumber, total, used, percentage, partitions };
+ this.chartDisk = Array.from(diskUsageMap.entries()).map(([diskNumber, { total, used, partitions }]) => {
+ const partitionData = partitions.map(partition => ({
+ name: `Partición ${partition.partitionNumber}`,
+ value: Number((partition.size / 1024).toFixed(2))
+ }));
+
+ const freeSpace = total - used;
+ if (freeSpace > 0) {
+ partitionData.push({
+ name: 'Espacio libre',
+ value: Number(freeSpace.toFixed(2))
+ });
+ }
+
+ return {
+ diskNumber,
+ chartData: partitionData,
+ total,
+ used,
+ percentage: total > 0 ? Math.round((used / total) * 100) : 0
+ };
});
+ this.diskUsageData = this.chartDisk;
this.isDiskUsageEmpty = this.diskUsageData.length === 0;
}
+
getStrokeOffset(partitions: any[], index: number): number {
const totalSize = partitions.reduce((acc, part) => acc + (part.size / 1024), 0);
@@ -170,16 +214,35 @@ export class ClientMainViewComponent implements OnInit {
});
}
- onCommandSelect(command: any): void {
- if (command.name === 'Particionar y Formatear') {
+ onCommandSelect(action: any): void {
+ if (action === 'partition') {
this.openPartitionAssistant();
}
+
+ if (action === 'create-image') {
+ this.openCreateImageAssistant();
+ }
+
+ if (action === 'deploy-image') {
+ this.openDeployImageAssistant();
+ }
}
openPartitionAssistant(): void {
- console.log(this.clientData)
this.router.navigate([`/client/${this.clientData.uuid}/partition-assistant`]).then(r => {
console.log('navigated', r);
});
}
+
+ openCreateImageAssistant(): void {
+ this.router.navigate([`/client/${this.clientData.uuid}/create-image`]).then(r => {
+ console.log('navigated', r);
+ });
+ }
+
+ openDeployImageAssistant(): void {
+ this.router.navigate([`/client/${this.clientData.uuid}/deploy-image`]).then(r => {
+ console.log('navigated', r);
+ });
+ }
}
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.css b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.css
new file mode 100644
index 0000000..fc11805
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.css
@@ -0,0 +1,76 @@
+.title {
+ font-size: 24px;
+}
+
+.calendar-button-row {
+ display: flex;
+ justify-content: flex-start;
+ margin-top: 16px;
+}
+
+.divider {
+ margin: 20px 0;
+}
+
+.lists-container {
+ padding: 16px;
+}
+
+.card.unidad-card {
+ height: 100%;
+ box-sizing: border-box;
+}
+
+table {
+ width: 100%;
+ margin-top: 50px;
+}
+
+.search-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ padding: 0 5px;
+ box-sizing: border-box;
+}
+
+.select-container {
+ margin-top: 20px;
+ align-items: center;
+ width: 100%;
+ padding: 0 5px;
+ box-sizing: border-box;
+}
+
+.full-width {
+ width: 100%;
+ margin-bottom: 16px;
+}
+
+.search-string {
+ flex: 2;
+ padding: 5px;
+}
+
+.search-boolean {
+ flex: 1;
+ padding: 5px;
+}
+
+.header-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 10px;
+}
+
+.mat-elevation-z8 {
+ box-shadow: 0px 0px 0px rgba(0,0,0,0.2);
+}
+
+.paginator-container {
+ display: flex;
+ justify-content: end;
+ margin-bottom: 30px;
+}
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.html
new file mode 100644
index 0000000..85216c9
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+ Nombre canónico
+
+
+
+
+ Seleccione imagen
+
+ --
+ {{ image.name }}
+
+
+
+
+
+
+ Seleccionar partición |
+
+
+
+
+
+ |
+
+
+
+ {{ column.header }} |
+
+ {{ column.cell(image) }}
+ |
+
+
+
+
+
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.spec.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.spec.ts
new file mode 100644
index 0000000..3949532
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CreateImageComponent } from './create-image.component';
+
+describe('CreateImageComponent', () => {
+ let component: CreateImageComponent;
+ let fixture: ComponentFixture
;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [CreateImageComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(CreateImageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.ts
new file mode 100644
index 0000000..1c26c50
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/create-image/create-image.component.ts
@@ -0,0 +1,168 @@
+import {Component, EventEmitter, Output} from '@angular/core';
+import {HttpClient} from "@angular/common/http";
+import {ToastrService} from "ngx-toastr";
+import {ActivatedRoute} from "@angular/router";
+import {MatButton} from "@angular/material/button";
+import {MatDivider} from "@angular/material/divider";
+import {NgForOf, NgIf} from "@angular/common";
+import {FormsModule, ReactiveFormsModule} from "@angular/forms";
+import {
+ MatCell, MatCellDef,
+ MatColumnDef,
+ MatHeaderCell,
+ MatHeaderCellDef, MatHeaderRow, MatHeaderRowDef, MatRow, MatRowDef,
+ MatTable,
+ MatTableDataSource
+} from "@angular/material/table";
+import {MatChip} from "@angular/material/chips";
+import {MatCheckbox} from "@angular/material/checkbox";
+import {SelectionModel} from "@angular/cdk/collections";
+import {MatRadioButton, MatRadioGroup} from "@angular/material/radio";
+import {MatFormField, MatLabel} from "@angular/material/form-field";
+import {MatOption} from "@angular/material/autocomplete";
+import {MatSelect} from "@angular/material/select";
+import {MatInput} from "@angular/material/input";
+
+@Component({
+ selector: 'app-create-image',
+ templateUrl: './create-image.component.html',
+ standalone: true,
+ imports: [
+ MatButton,
+ MatDivider,
+ NgForOf,
+ NgIf,
+ ReactiveFormsModule,
+ MatTable,
+ MatColumnDef,
+ MatHeaderCell,
+ MatHeaderCellDef,
+ MatCell,
+ MatCellDef,
+ MatChip,
+ MatHeaderRow,
+ MatRow,
+ MatHeaderRowDef,
+ MatRowDef,
+ MatCheckbox,
+ MatRadioGroup,
+ MatRadioButton,
+ MatFormField,
+ MatLabel,
+ MatOption,
+ MatSelect,
+ MatInput,
+ FormsModule
+ ],
+ styleUrl: './create-image.component.css'
+})
+export class CreateImageComponent {
+ baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
+ @Output() dataChange = new EventEmitter();
+
+ errorMessage = '';
+ clientId: string | null = null;
+ partitions: any[] = [];
+ images: any[] = [];
+ clientName: string = '';
+ selectedImage: string | null = null;
+ selectedPartition: any = null;
+ name: string = '';
+ dataSource = new MatTableDataSource();
+ columns = [
+ {
+ columnDef: 'diskNumber',
+ header: 'Disco',
+ cell: (partition: any) => `${partition.diskNumber}`
+ },
+ {
+ columnDef: 'partitionNumber',
+ header: 'Particion',
+ cell: (partition: any) => `${partition.partitionNumber}`
+ },
+ {
+ columnDef: 'size',
+ header: 'Tamaño',
+ cell: (partition: any) => `${partition.size} MB`
+ },
+ {
+ columnDef: 'filesystem',
+ header: 'Sistema de ficheros',
+ cell: (partition: any) => `${partition.filesystem}`
+ },
+ {
+ columnDef: 'operativeSystem',
+ header: 'SO',
+ cell: (partition: any) => `${partition.operativeSystem?.name}`
+ }
+ ];
+
+ displayedColumns = ['select', ...this.columns.map(column => column.columnDef)];
+ selection = new SelectionModel(true, []);
+
+ constructor(
+ private http: HttpClient,
+ private toastService: ToastrService,
+ private route: ActivatedRoute
+ ) {}
+
+ ngOnInit() {
+ this.clientId = this.route.snapshot.paramMap.get('id');
+
+ this.loadPartitions();
+ this.loadImages();
+ }
+
+ loadPartitions() {
+ const url = `${this.baseUrl}/clients/${this.clientId}`;
+ this.http.get(url).subscribe(
+ (response: any) => {
+ if (response.partitions) {
+ this.clientName = response.name;
+
+ this.dataSource.data = response.partitions.filter((partition: any) => {
+ return partition.partitionNumber !== 0;
+ });
+ }
+ },
+ (error) => {
+ console.error('Error al cargar los datos del cliente:', error);
+ }
+ );
+ }
+
+ loadImages() {
+ const url = `${this.baseUrl}/images?created=true&page=1&itemsPerPage=1000`;
+ this.http.get(url).subscribe(
+ (response: any) => {
+ this.images = response['hydra:member'];
+ },
+ (error) => {
+ console.error('Error al cargar las imágenes:', error);
+ }
+ );
+ }
+
+ save(): void {
+ const payload = {
+ client: `/clients/${this.clientId}`,
+ name: this.name,
+ image: this.selectedImage,
+ partition: this.selectedPartition['@id'],
+ input: 'assistant'
+ };
+
+
+ this.http.post(`${this.baseUrl}/images`, payload)
+ .subscribe({
+ next: (response) => {
+ this.toastService.success('Imagen creada exitosamente');
+ },
+ error: (error) => {
+ console.error('Error:', error);
+ this.toastService.error(error.error['hydra:description']);
+ }
+ }
+ );
+ }
+}
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.css b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.css
new file mode 100644
index 0000000..6f2e1d9
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.css
@@ -0,0 +1,84 @@
+
+.divider {
+ margin: 20px 0;
+}
+
+table {
+ width: 100%;
+ margin-top: 50px;
+}
+
+.search-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ padding: 0 5px;
+ box-sizing: border-box;
+}
+
+.option-container {
+ margin: 20px 0;
+ width: 100%;
+}
+
+.deploy-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ width: 100%;
+ padding: 5px;
+ gap: 10px;
+}
+
+.select-container {
+ margin-top: 20px;
+ align-items: center;
+ width: 100%;
+ padding: 0 5px;
+ box-sizing: border-box;
+}
+
+.input-group {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 16px;
+ margin-top: 20px;
+}
+
+.input-field {
+ flex: 1 1 calc(33.33% - 16px);
+ min-width: 250px;
+}
+
+.full-width {
+ width: 100%;
+ margin-bottom: 16px;
+}
+
+.search-string {
+ flex: 2;
+ padding: 5px;
+}
+
+.search-boolean {
+ flex: 1;
+ padding: 5px;
+}
+
+.header-container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 10px;
+}
+
+.mat-elevation-z8 {
+ box-shadow: 0px 0px 0px rgba(0,0,0,0.2);
+}
+
+.paginator-container {
+ display: flex;
+ justify-content: end;
+ margin-bottom: 30px;
+}
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.html
new file mode 100644
index 0000000..347e2e2
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.html
@@ -0,0 +1,109 @@
+
+
+
+
+
+
+ Actualizar cache
+ Deploy imagen
+
+
+
+
+
+ Seleccione imagen
+
+ {{ image.name }}
+
+
+
+
+ Seleccione método de deploy
+
+ {{ method }}
+
+
+
+
+
+
+
+ Seleccionar partición |
+
+
+
+
+
+ |
+
+
+
+ {{ column.header }} |
+
+ {{ column.cell(image) }}
+ |
+
+
+
+
+
+
+
+
+
+
+
+ Puerto
+
+
+
+
+ Dirección
+
+
+
+
+ Modo Multicast
+
+
+ {{ option.name }}
+
+
+
+
+
+ Velocidad
+
+
+
+
+ Máximo Clientes
+
+
+
+
+ Tiempo Máximo de Espera
+
+
+
+
+
+
+ Modo P2P
+
+
+ {{ option.name }}
+
+
+
+
+
+ Semilla
+
+
+
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.spec.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.spec.ts
new file mode 100644
index 0000000..b6b9991
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { DeployImageComponent } from './deploy-image.component';
+
+describe('DeployImageComponent', () => {
+ let component: DeployImageComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [DeployImageComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(DeployImageComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.ts
new file mode 100644
index 0000000..836df18
--- /dev/null
+++ b/ogWebconsole/src/app/components/groups/components/client-main-view/deploy-image/deploy-image.component.ts
@@ -0,0 +1,161 @@
+import {Component, EventEmitter, Output} from '@angular/core';
+import {MatTableDataSource} from "@angular/material/table";
+import {SelectionModel} from "@angular/cdk/collections";
+import {HttpClient} from "@angular/common/http";
+import {ToastrService} from "ngx-toastr";
+import {ActivatedRoute} from "@angular/router";
+
+@Component({
+ selector: 'app-deploy-image',
+ templateUrl: './deploy-image.component.html',
+ styleUrl: './deploy-image.component.css'
+})
+export class DeployImageComponent {
+ baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
+ @Output() dataChange = new EventEmitter();
+
+ errorMessage = '';
+ clientId: string | null = null;
+ partitions: any[] = [];
+ images: any[] = [];
+ clientName: string = '';
+ selectedImage: string | null = null;
+ selectedOption: string | null = null;
+ selectedMethod: string | null = null;
+ selectedPartition: any = null;
+ mcastIp: string = '';
+ mcastPort: string = '';
+ mcastMode: string = '';
+ mcastSpeed: string = '';
+ mcastMaxClients: string = '';
+ mcastMaxTime: string = '';
+ p2pMode: string = '';
+ p2pTime: string = '';
+ name: string = '';
+
+ protected p2pModeOptions = [
+ { name: 'Leecher', value: 'p2p-mode-leecher' },
+ { name: 'Peer', value: 'p2p-mode-peer' },
+ { name: 'Seeder', value: 'p2p-mode-seeder' },
+ ];
+ protected multicastModeOptions = [
+ {"name": 'Half duplex', "value": "half-duplex"},
+ {"name": 'Full duplex', "value": "full-duplex"},
+ ];
+
+ allMethods = [
+ 'multicast',
+ 'multicast-direct',
+ 'unicast',
+ 'unicast-direct',
+ 'torrent'
+ ];
+
+ updateCacheMethods = [
+ 'multicast',
+ 'unicast',
+ 'torrent'
+ ];
+
+ dataSource = new MatTableDataSource();
+ columns = [
+ {
+ columnDef: 'diskNumber',
+ header: 'Disco',
+ cell: (partition: any) => `${partition.diskNumber}`
+ },
+ {
+ columnDef: 'partitionNumber',
+ header: 'Particion',
+ cell: (partition: any) => `${partition.partitionNumber}`
+ },
+ {
+ columnDef: 'size',
+ header: 'Tamaño',
+ cell: (partition: any) => `${partition.size} MB`
+ },
+ {
+ columnDef: 'filesystem',
+ header: 'Sistema de ficheros',
+ cell: (partition: any) => `${partition.filesystem}`
+ },
+ {
+ columnDef: 'operativeSystem',
+ header: 'SO',
+ cell: (partition: any) => `${partition.operativeSystem?.name}`
+ }
+ ];
+
+ displayedColumns = ['select', ...this.columns.map(column => column.columnDef)];
+ selection = new SelectionModel(true, []);
+
+ constructor(
+ private http: HttpClient,
+ private toastService: ToastrService,
+ private route: ActivatedRoute
+ ) {}
+
+ ngOnInit() {
+ this.clientId = this.route.snapshot.paramMap.get('id');
+
+ this.loadPartitions();
+ this.loadImages();
+ }
+
+ get deployMethods() {
+ return this.selectedOption === 'update-cache' ? this.updateCacheMethods : this.allMethods;
+ }
+
+ isMethod(method: string): boolean {
+ return this.selectedMethod === method;
+ }
+
+ loadPartitions() {
+ const url = `${this.baseUrl}/clients/${this.clientId}`;
+ this.http.get(url).subscribe(
+ (response: any) => {
+ if (response.partitions) {
+ this.clientName = response.name;
+ this.dataSource.data = response?.partitions;
+ }
+ },
+ (error) => {
+ console.error('Error al cargar los datos del cliente:', error);
+ }
+ );
+ }
+
+ loadImages() {
+ const url = `${this.baseUrl}/images?page=1&itemsPerPage=1000`;
+ this.http.get(url).subscribe(
+ (response: any) => {
+ this.images = response['hydra:member'];
+ },
+ (error) => {
+ console.error('Error al cargar las imágenes:', error);
+ }
+ );
+ }
+
+ save(): void {
+ const payload = {
+ client: `/clients/${this.clientId}`,
+ name: this.name,
+ image: this.selectedImage,
+ partition: this.selectedPartition['@id']
+ };
+
+
+ this.http.post(`${this.baseUrl}/images`, payload)
+ .subscribe({
+ next: (response) => {
+ this.toastService.success('Imagen creada exitosamente');
+ },
+ error: (error) => {
+ console.error('Error:', error);
+ this.toastService.error(error.error['hydra:description']);
+ }
+ }
+ );
+ }
+}
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 09e52c4..76c25e2 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
@@ -30,41 +30,42 @@
Partición |
Tipo partición |
Tamaño (MB) |
- Uso (%) |
+ Tamaño (%) |
Formatear |
Eliminar |
-
- {{ partition.partitionNumber }} |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
-
- |
-
+
+ {{ 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 196cc0a..ab0803c 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
@@ -41,7 +41,6 @@ export class PartitionAssistantComponent implements OnInit {
ngOnInit() {
this.clientId = this.route.snapshot.paramMap.get('id');
-
this.loadPartitions();
}
@@ -112,7 +111,6 @@ export class PartitionAssistantComponent implements OnInit {
if (disk) {
const remainingGB = this.getRemainingGB(disk.partitions, disk.totalDiskSize);
- console.log(remainingGB)
if (remainingGB > 0) {
const maxPartitionNumber =
disk.partitions.length > 0 ? Math.max(...disk.partitions.map((p) => p.partitionNumber)) : 0;
@@ -142,20 +140,41 @@ export class PartitionAssistantComponent implements OnInit {
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;
partition.sizeBytes = size;
+
+ partition.percentage = (size / disk.totalDiskSize) * 100;
this.updatePartitionPercentages(disk.partitions, disk.totalDiskSize);
}
}
}
+ updatePartitionPercentage(diskNumber: number, index: number, percentage: number) {
+ const disk = this.disks.find((d) => d.diskNumber === diskNumber);
+ if (disk) {
+ const partition = disk.partitions[index];
+
+ const newSizeMB = (percentage / 100) * disk.totalDiskSize;
+
+ const totalPercentage = disk.partitions.reduce((sum, part) => sum + (part === partition ? percentage : part.percentage), 0);
+
+ if (totalPercentage > 100) {
+ this.errorMessage = 'El tamaño total en porcentaje de las particiones no puede exceder el 100%';
+ partition.percentage = 100 - (totalPercentage - percentage);
+ } else {
+ this.errorMessage = '';
+ partition.percentage = percentage;
+ partition.size = newSizeMB;
+ }
+ }
+ }
+
+
+
getRemainingGB(partitions: Partition[], totalDiskSize: number): number {
- console.log(totalDiskSize)
const totalUsedGB = partitions.reduce((acc, partition) => acc + partition.size, 0);
return Math.max(0, totalDiskSize - totalUsedGB);
}
@@ -228,6 +247,7 @@ export class PartitionAssistantComponent implements OnInit {
this.http.post(this.apiUrl, payload).subscribe(
(response) => {
this.toastService.success('Partición creada exitosamente');
+ window.location.reload();
},
(error) => {
console.error('Error al crear la partición:', error);
@@ -239,6 +259,7 @@ export class PartitionAssistantComponent implements OnInit {
this.http.patch(patchUrl, payload).subscribe(
(response) => {
this.toastService.success('Partición actualizada exitosamente');
+ window.location.reload();
},
(error) => {
console.error('Error al actualizar la partición:', error);
@@ -249,7 +270,6 @@ export class PartitionAssistantComponent implements OnInit {
});
}
-
removePartition(diskNumber: number, partition: Partition) {
const disk = this.disks.find((d) => d.diskNumber === diskNumber);
@@ -264,6 +284,7 @@ export class PartitionAssistantComponent implements OnInit {
this.http.delete(deleteUrl).subscribe(
(response) => {
this.toastService.success('Partición eliminada exitosamente');
+ window.location.reload();
},
(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
deleted file mode 100644
index ad6b310..0000000
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.css
+++ /dev/null
@@ -1,71 +0,0 @@
-.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
deleted file mode 100644
index 4301955..0000000
--- a/ogWebconsole/src/app/components/groups/components/client-main-view/restore-image/restore-image.component.html
+++ /dev/null
@@ -1,39 +0,0 @@
-