diff options
author | Juan Manuel Bardallo juanmanuel.bardallo@sic.uhu.es <juanmanuel.bardallo@sic.uhu.es> | 2019-06-07 10:14:09 +0200 |
---|---|---|
committer | Juan Manuel Bardallo juanmanuel.bardallo@sic.uhu.es <juanmanuel.bardallo@sic.uhu.es> | 2019-06-07 10:14:09 +0200 |
commit | 4ba1d5aefc6c437334fa031c58ecddca0f926a13 (patch) | |
tree | 09f41596574157e7c0288aac813bd71804e9cd84 | |
parent | 09120935ac33f613c2f733d41af8213048e3bd27 (diff) |
Creado gestion de plantillas netboot
Mejoras de estabilidad en componentes:
- Asistente de particionado
- Vista de un cliente
- Vista unidad organizativa
26 files changed, 1142 insertions, 828 deletions
diff --git a/admin/WebConsole3/frontend/src/app/api/netboot.service.ts b/admin/WebConsole3/frontend/src/app/api/netboot.service.ts index d4ad0c94..ab469ae1 100644 --- a/admin/WebConsole3/frontend/src/app/api/netboot.service.ts +++ b/admin/WebConsole3/frontend/src/app/api/netboot.service.ts @@ -1,20 +1,24 @@ -import { Injectable } from '@angular/core';
-import { HttpClient} from '@angular/common/http';
-
-import { environment } from '../../environments/environment';
-import { Netboot } from "../model/netboot";
-import { NetbootSerializer } from "../serializer/netboot.serializer";
-
-import {ResourceService} from "globunet-angular/core/providers/api/resource.service";
-
-
-@Injectable({
- providedIn: 'root'
-})
-export class NetbootService extends ResourceService<Netboot> {
-
- constructor(http: HttpClient){
- super(http, environment.API_URL,"netboots", new NetbootSerializer());
- }
-
-}
+import {Injectable} from '@angular/core'; +import {HttpClient} from '@angular/common/http'; + +import {environment} from '../../environments/environment'; +import {Netboot} from '../model/netboot'; +import {NetbootSerializer} from '../serializer/netboot.serializer'; + +import {ResourceService} from 'globunet-angular/core/providers/api/resource.service'; +import {Observable} from 'rxjs'; + + +@Injectable({ + providedIn: 'root' +}) +export class NetbootService extends ResourceService<Netboot> { + + constructor(http: HttpClient) { + super(http, environment.API_URL, 'netboots', new NetbootSerializer()); + } + + updateFiles(assignedNetboots: {}): Observable<any> { + return this.httpClient.post(this.url + '/clients', JSON.stringify(assignedNetboots)); + } +} diff --git a/admin/WebConsole3/frontend/src/app/app-routing.module.ts b/admin/WebConsole3/frontend/src/app/app-routing.module.ts index f91738a4..00db6a26 100644 --- a/admin/WebConsole3/frontend/src/app/app-routing.module.ts +++ b/admin/WebConsole3/frontend/src/app/app-routing.module.ts @@ -30,6 +30,7 @@ import {CreateImageCommandComponent} from './pages/command/create-image-command/ import {DeleteCacheImageCommandComponent} from './pages/command/delete-cache-image-command/delete-cache-image-command.component'; import {FormatCommandComponent} from './pages/command/format-command/format-command.component'; import {PartitionFormatCommandComponent} from './pages/command/partition-format-command/partition-format-command.component'; +import {NetbootClientsComponent} from './pages/netboot/clients/netboot-clients.component'; const routes: Routes = [ @@ -195,6 +196,10 @@ const routes: Routes = [ component: NetbootEditComponent }, { + path: 'netboots/clients', + component: NetbootClientsComponent + }, + { path: 'user/profile', component: ProfileComponent } diff --git a/admin/WebConsole3/frontend/src/app/app.module.ts b/admin/WebConsole3/frontend/src/app/app.module.ts index 57a5b737..36690d68 100644 --- a/admin/WebConsole3/frontend/src/app/app.module.ts +++ b/admin/WebConsole3/frontend/src/app/app.module.ts @@ -80,6 +80,7 @@ import {FormatCommandComponent} from './pages/command/format-command/format-comm import {PartitionFormatCommandComponent} from './pages/command/partition-format-command/partition-format-command.component'; import {ColResizableDirective} from './pages/common/directive/col-resizable.directive'; import { NgxDaterangepickerMd } from 'ngx-daterangepicker-material'; +import {NetbootClientsComponent} from './pages/netboot/clients/netboot-clients.component'; @NgModule({ @@ -144,6 +145,7 @@ import { NgxDaterangepickerMd } from 'ngx-daterangepicker-material'; TraceComponent, NetbootComponent, NetbootEditComponent, + NetbootClientsComponent, ProfileComponent, OgCommandsPipe ], @@ -182,6 +184,7 @@ import { NgxDaterangepickerMd } from 'ngx-daterangepicker-material'; TraceComponent, NetbootComponent, NetbootEditComponent, + NetbootClientsComponent, ProfileComponent ], imports: [ diff --git a/admin/WebConsole3/frontend/src/app/form-type/netboot.form-type.ts b/admin/WebConsole3/frontend/src/app/form-type/netboot.form-type.ts index 8ffea78e..7d27dcd4 100644 --- a/admin/WebConsole3/frontend/src/app/form-type/netboot.form-type.ts +++ b/admin/WebConsole3/frontend/src/app/form-type/netboot.form-type.ts @@ -1,12 +1,16 @@ -import {GlobunetFormType} from './globunet.form-type';
-import {Netboot} from '../model/netboot';
-
-
-export class NetbootFormType extends GlobunetFormType {
- getForm() {
- const form: any[] = GlobunetFormType.getForm(new Netboot());
- this.setFieldType(form, 'template', 'textarea');
-
- return form;
- }
-}
+import {GlobunetFormType} from './globunet.form-type'; +import {Netboot} from '../model/netboot'; + + +export class NetbootFormType extends GlobunetFormType { + getForm() { + const form: any[] = GlobunetFormType.getForm(new Netboot()); + this.setFieldType(form, 'type', 'select'); + this.getField(form, 'type').options = { + items: ['bios', 'uefi'] + }; + this.setFieldType(form, 'template', 'textarea'); + + return form; + } +} diff --git a/admin/WebConsole3/frontend/src/app/model/netboot.ts b/admin/WebConsole3/frontend/src/app/model/netboot.ts index 9c223846..1c292929 100644 --- a/admin/WebConsole3/frontend/src/app/model/netboot.ts +++ b/admin/WebConsole3/frontend/src/app/model/netboot.ts @@ -1,7 +1,8 @@ -import { Resource } from 'globunet-angular/core/models/api/resource';
-
-export class Netboot extends Resource {
- public name = '';
- public filename = '';
- public template = '';
-}
+import { Resource } from 'globunet-angular/core/models/api/resource'; + +export class Netboot extends Resource { + public name = ''; + public type = 'bios'; + public filename = ''; + public template = ''; +} diff --git a/admin/WebConsole3/frontend/src/app/pages/client/client.component.html b/admin/WebConsole3/frontend/src/app/pages/client/client.component.html index 81c0a3ac..240258e3 100644 --- a/admin/WebConsole3/frontend/src/app/pages/client/client.component.html +++ b/admin/WebConsole3/frontend/src/app/pages/client/client.component.html @@ -69,7 +69,7 @@ <tbody *ngIf="partition.size > 0"> <tr ng-class="{'odd': $index%2 == 0, 'even': $index%2 != 0}"> <td>{{partition.numPartition}}</td> - <td>{{partition.parttype}}</td> + <td>{{partition.type}}</td> <td>{{partition.filesystem}}</td> <td>{{getSizeInGB(partition.size)}} GB</td> <td><span class="badge" diff --git a/admin/WebConsole3/frontend/src/app/pages/client/client.component.ts b/admin/WebConsole3/frontend/src/app/pages/client/client.component.ts index 0611d6dc..39585cc1 100644 --- a/admin/WebConsole3/frontend/src/app/pages/client/client.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/client/client.component.ts @@ -60,6 +60,9 @@ export class ClientComponent implements OnInit { this.clientService.read(id).subscribe( client => { this.client = client; + this.ogCommonService.selectedClients = {}; + this.ogCommonService.selectedClients[client.id] = client; + this.client.disksConfig = this.ogCommonService.getDisksConfigFromPartitions(this.client.partitions); const self = this; @@ -151,7 +154,7 @@ export class ClientComponent implements OnInit { (partition.os || partition.filesystem), partition.percentOfDisk + '%' ]); - diskPieChartColors[0].backgroundColor.push(self.getPartitionColor(partition)); + diskPieChartColors[0].backgroundColor.push(self.ogCommonService.getPartitionColor(partition)); } }); const diskChartOptions: ChartOptions = { @@ -187,23 +190,6 @@ export class ClientComponent implements OnInit { + series.percentOfDisk + '%</div>'; } - getPartitionColor(partition) { - let color = 'rgb(252, 90, 90)'; - - // Para la partición de datos se usa un color específico - if (partition.osName === 'DATA') { - color = 'rgb(237,194,64)'; - } else if (partition.filesystem === 'NTFS') { - color = 'rgb(0,192, 239)'; - } else if (partition.filesystem.match('EXT')) { - color = 'rgb(96, 92, 168)'; - } else if (partition.filesystem.match('LINUX-SWAP')) { - color = 'rgb(84, 84, 84)'; - } else if (partition.filesystem.match('CACHE')) { - color = 'rgb(252, 90, 90)'; - } - return color; - } save() { let request: Observable<Client>; diff --git a/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html index c21f5c8d..597cf82a 100644 --- a/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html +++ b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.html @@ -11,7 +11,7 @@ <div> <div class="col-md-12"> <div class="box-tools pull-right"> - <button class="btn btn-primary" translate="save" (click)="save()"></button> + <button class="btn btn-primary" translate="save" [disabled]="clients.length == 0" (click)="save()"></button> </div> </div> </div> @@ -81,23 +81,25 @@ <input type="text" name="netdriver" class="form-control" [(ngModel)]="commonProperties.netdriver" /> </div> </div> - <div class="form-group col-md-3"> - <label for="oglive" translate="oglive"> - <span class="symbol required ng-scope"></span> - </label> - <select class="form-control" required="true" [(ngModel)]="commonProperties.oglive" name="oglive"> - <option *ngFor="let item of constants.ogliveinfo" [value]="item.directory"> - {{item.directory}} - </option> - </select> + <div class="col-xs-3"> + <div class="form-group"> + <label for="oglive" class="control-label" translate="oglive"> + </label> + <select class="form-control" required="true" [(ngModel)]="commonProperties.oglive" name="oglive"> + <option *ngFor="let item of constants.ogliveinfo" [value]="item.directory"> + {{item.directory}} + </option> + </select> + </div> </div> - <div class="form-group col-md-2"> - <label for="netboot" translate="netboot"> - <span class="symbol required ng-scope"></span> - </label> - <select class="form-control" required="true" [(ngModel)]="commonProperties.netboot" name="netboot"> - <option *ngFor="let item of netboots" [value]="item.id">{{item.name}}</option> - </select> + <div class="col-md-2"> + <div class="form-group"> + <label for="netboot" class="control-label" translate="netboot"> + </label> + <select class="form-control" required="true" [(ngModel)]="commonProperties.netboot" name="netboot"> + <option *ngFor="let item of netboots" [value]="item.id">{{item.name}}</option> + </select> + </div> </div> </div> </div> diff --git a/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts index 70394ba4..0bdb1a0e 100644 --- a/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/client/dhcp/client-dhcp.component.ts @@ -62,7 +62,7 @@ export class ClientDhcpComponent implements OnInit { (repositories) => { this.repositories = repositories; this.commonProperties.repository = this.repositories[0].id; - if (!this.hardwareProfiles) { + if (this.hardwareProfiles.length === 0) { this.hardwareProfileService.list().subscribe( (response) => { this.hardwareProfiles = response; @@ -201,8 +201,12 @@ export class ClientDhcpComponent implements OnInit { // Si se indicó un padre en la url, se añade dicha propiedad client.organizationalUnit = ou; client.idproautoexec = 0; + client.repository = this.commonProperties.repository; + client.hardwareProfile = this.commonProperties.hardwareProfile; client.netdriver = this.commonProperties.netdriver; client.netiface = this.commonProperties.netiface; + client.netboot = this.commonProperties.netboot; + client.oglive = this.commonProperties.oglive; // Propiedades comunes // client.repository = this.commonProperties.repository; // client.hardwareProfile = this.commonProperties.hardwareProfile; diff --git a/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts index e0aeb988..77acb399 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/command/delete-cache-image-command/delete-cache-image-command.component.ts @@ -102,7 +102,7 @@ export class DeleteCacheImageCommandComponent implements OnInit { this.execution.script += '\n'; } } - //this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$'); + // this.execution.script = this.execution.script.replace(/\"/g, '\\"').replace(/\$/g, '\\\$'); this.execution.type = 'RUN_SCRIPT'; this.execution.sendConfig = true; diff --git a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.html b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.html index fab8b8d7..b24acb24 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.html +++ b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.html @@ -19,8 +19,8 @@ </div> <div class="col-md-4"> <span translate="part_table"></span>: <b> - <select name="partTableType" [(ngModel)]="diskConfig.parttable.type" (change)="checkPartitionTableType()"> - <option *ngFor="let partitionTableTypes of partitionTableTypes">{{partitionTableTypes.type}}</option> + <select name="partTableType" [(ngModel)]="diskConfig.parttable" (change)="checkPartitionTableType()"> + <option *ngFor="let partitionTableType of partitionTableTypes" [ngValue]="partitionTableType">{{partitionTableType.type}}</option> </select></b> </div> <div class="col-md-4"> @@ -39,11 +39,11 @@ <div class="col-md-12"> <table col-resizable class="disk-partitions" [elements]="diskConfig.partitions" cr-update-property="usage" (onResize)="updatePartitionUsage($event)"> <tr> - <td *ngFor="let partition of diskConfig.partitions" [style]="sanitizer.bypassSecurityTrustStyle('width: '+ partition.usage + '%; background-color:' + getPartitionColor(partition))"> + <td *ngFor="let partition of diskConfig.partitions" [style]="sanitizer.bypassSecurityTrustStyle('width: '+ partition.usage + '%; background-color:' + ogCommonService.getPartitionColor(partition))"> <span><span translate="{{partition.type}}"></span> ({{partition.usage}}%)</span> - <table *ngIf="partition.partitions && partition.partitions.length > 0" [elements]="partition.partitions" col-resizable class="disk-partitions" cr-update-property="usage" (onResize)="updateExtendedPartitions($event)" cr-force-refresh="refresh-extended-partitions"> + <table *ngIf="partition.partitions && partition.partitions.length > 0" col-resizable class="disk-partitions" [elements]="partition.partitions" cr-update-property="usage" (onResize)="updateExtendedPartitionsUsage($event)"> <tr> - <td *ngFor="let extendedPartition of partition.partitions" [style]="sanitizer.bypassSecurityTrustStyle('width: '+extendedPartition.usage+'%; background-color: '+ getPartitionColor(extendedPartition))"> + <td *ngFor="let extendedPartition of partition.partitions" [style]="sanitizer.bypassSecurityTrustStyle('width: '+extendedPartition.usage+'%; background-color: '+ ogCommonService.getPartitionColor(extendedPartition))"> <span>{{extendedPartition.type}} ({{extendedPartition.usage}}%)</span> </td> </tr> @@ -72,39 +72,51 @@ <tr [ngClass]="index%2 == 0 ? 'odd' : 'even'" *ngIf="partition.partition != 0"> <td>{{partition.partition}} ({{getSizeInGB(partition.size)}}GB)</td> <td> - <select name="partitionType" [disabled]="partTableTypeIsGPT() && index == 0 && isEFI(partition)" [(ngModel)]="partition.type" (change)="checkPartitionType(partition)"> + <select name="partitionType" [disabled]="partTableTypeIsGPT() && index == 0 && ogCommonService.isEFI(partition)" [(ngModel)]="partition.type" (change)="checkPartitionType(partition)"> <option *ngFor="let partitionType of diskConfig.parttable.partitions">{{partitionType.type}}</option> </select> </td> - <td>{{partition.filesystem}}</td> + <td> + <select name="partitionType" [disabled]="partTableTypeIsGPT() && index == 0 && ogCommonService.isEFI(partition)" [(ngModel)]="partition.filesystem" > + <option *ngFor="let partitionFilesystem of constants.filesystems">{{partitionFilesystem}}</option> + </select> + </td> <td> <input step=".01" name="partitionSize" type="number" [(ngModel)]="partition.size" (change)="setPartitionUsage(diskConfig, partition)"/> + ({{getSizeInGB(partition.size)}} GB) </td> <td> <input step=".01" name="partitionUsage" type="number" [(ngModel)]="partition.usage" (change)="updatePartitionUsage(partition)"> <span>%</span> </td> <td> - <div *ngIf="isEXTENDED(partition) != true" class="checkbox clip-check check-primary checkbox-inline" style="margin-top: 0"> + <div *ngIf="ogCommonService.isEXTENDED(partition) != true" class="checkbox clip-check check-primary checkbox-inline" style="margin-top: 0"> <input name="format" icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" value="true" [(ngModel)]="partition.format" /> </div> </td> <td> - <button *ngIf="!(partTableTypeIsGPT() && $index == 0 && isEFI(partition))" class="btn btn-danger btn-xs"><i class="fa fa-times" (click)="removePartition(partition)"></i></button> + <button *ngIf="!(partTableTypeIsGPT() && $index == 0 && ogCommonService.isEFI(partition))" class="btn btn-danger btn-xs"><i class="fa fa-times" (click)="removePartition(partition)"></i></button> </td> - <td *ngIf="isEXTENDED(partition) == true"> + <td *ngIf="ogCommonService.isEXTENDED(partition) == true"> <button class="btn btn-primary btn-xs"><i class="fa fa-plus" (click)="addExtendedPartition(partition)"></i></button> </td> </tr> <tr *ngFor="let extendedPartition of partition.partitions" class="extended" ng-class="{'odd': $index%2 == 0, 'even': $index%2 != 0}"> <td>{{extendedPartition.partition}}</td> <td> - <select name="extendedPartitionType" [(ngModel)]="extendedPartition.type" (change)="checkPartitionType(extendedPartition)"> + <select name="extendedPartitionType" [(ngModel)]="extendedPartition.type" (change)="checkPartitionType(extendedPartition, partition)"> <option *ngFor="let partitionType of diskConfig.parttable.partitions">{{partitionType.type}}</option> </select> </td> - <td>{{extendedPartition.filesystem}}</td> - <td><input step=".01" name="extendedPartitonSize" type="number"[(ngModel)]="extendedPartition.size" (change)="updateExtendedPartitions(extendedPartition)"/></td> + <td> + <select name="extendedPartitionType" [(ngModel)]="extendedPartition.filesystem" > + <option *ngFor="let partitionFilesystem of constants.filesystems">{{partitionFilesystem}}</option> + </select> + </td> + <td> + <input step=".01" name="extendedPartitonSize" type="number"[(ngModel)]="extendedPartition.size" (change)="updateExtendedPartitions(extendedPartition)"/> + ({{getSizeInGB(extendedPartition.size)}} GB) + </td> <td> <input step=".01" name="extendedPartitionUsage" type="number"[(ngModel)]="extendedPartition.usage" (change)="updateExtendedPartitionsUsage(extendedPartition)"> <span>%</span> diff --git a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts index eb36930a..6f291452 100644 --- a/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/command/partition-format-command/partition-format-command.component.ts @@ -15,605 +15,555 @@ import {Client} from '../../../model/client'; import {Execution} from '../../../model/command'; @Component({ - selector: 'app-partition-format-command', - templateUrl: './partition-format-command.component.html', - styleUrls: [ './partition-format-command.component.scss' ] + selector: 'app-partition-format-command', + templateUrl: './partition-format-command.component.html', + styleUrls: ['./partition-format-command.component.scss'] }) export class PartitionFormatCommandComponent implements OnInit { - execution = new Execution(); - command = {}; - user: User; - constants: any; - diskConfig: any; - partitionTableTypes = ['MSDOS', 'GPT']; - partitionTypes = []; - editInstructions = false; - - // this tells the tabs component which Pages - // should be each tab's root Page - constructor(public ogCommandsService: OGCommandsService, - public sanitizer: DomSanitizer, - private authModule: AuthModule, - private router: Router, - private activatedRoute: ActivatedRoute, - public ogCommonService: OgCommonService, - private commandService: CommandService, - private ogSweetAlert: OgSweetAlertService, - private toaster: ToasterService, - private translate: TranslateService) { - this.user = this.authModule.getLoggedUser(); - this.diskConfig = {}; - this.ogCommonService.saveSelection(); - } - - ngOnInit() { - if (this.user) { - this.ogCommonService.loadEngineConfig().subscribe( - data => { - this.constants = data.constants; - // Comprobar la selección de clientes - if (this.ogCommonService.selectedClients) { - - // Recorrer todos los clientes seleccionados y usar el tamaño del disco de menor tamaño - const clientsId = Object.keys(this.ogCommonService.selectedClients); - let minSize = 0; - // por defecto la tabla de particiones msdos - let parttable = this.ogCommonService.getPartitionTable({partitionCode: 1}); - if (this.ogCommonService.selectedClients[clientsId[0]].partitions[0]) { - minSize = this.ogCommonService.selectedClients[clientsId[0]].partitions[0].size; - parttable = this.ogCommonService.getPartitionTable(this.ogCommonService.selectedClients[clientsId[0]].partitions[0]); - } - - for (let c = 1; c < clientsId.length; c++) { - if (this.ogCommonService.selectedClients[clientsId[0]].partitions[0].size < minSize) { - minSize = this.ogCommonService.selectedClients[clientsId[0]].partitions[0].size; + execution = new Execution(); + command = {}; + user: User; + constants: any; + diskConfig: any; + partitionTableTypes = ['MSDOS', 'GPT']; + partitionTypes = []; + editInstructions = false; + + // this tells the tabs component which Pages + // should be each tab's root Page + constructor(public ogCommandsService: OGCommandsService, + public sanitizer: DomSanitizer, + private authModule: AuthModule, + private router: Router, + private activatedRoute: ActivatedRoute, + public ogCommonService: OgCommonService, + private commandService: CommandService, + private ogSweetAlert: OgSweetAlertService, + private toaster: ToasterService, + private translate: TranslateService) { + this.user = this.authModule.getLoggedUser(); + this.diskConfig = {}; + this.ogCommonService.saveSelection(); + } + + ngOnInit() { + if (this.user) { + this.ogCommonService.loadEngineConfig().subscribe( + data => { + this.constants = data.constants; + // Comprobar la selección de clientes + if (this.ogCommonService.selectedClients) { + + // Recorrer todos los clientes seleccionados y usar el tamaño del disco de menor tamaño + const clientsId = Object.keys(this.ogCommonService.selectedClients); + let minSize = 0; + // por defecto la tabla de particiones msdos + let parttable = this.ogCommonService.getPartitionTable({partitionCode: 1}); + if (this.ogCommonService.selectedClients[clientsId[0]].partitions[0]) { + minSize = this.ogCommonService.selectedClients[clientsId[0]].partitions[0].size; + parttable = this.ogCommonService.getPartitionTable(this.ogCommonService.selectedClients[clientsId[0]].partitions[0]); + } + + for (let c = 1; c < clientsId.length; c++) { + if (this.ogCommonService.selectedClients[clientsId[0]].partitions[0].size < minSize) { + minSize = this.ogCommonService.selectedClients[clientsId[0]].partitions[0].size; + + } + } + + this.diskConfig = { + disk: 1, + parttable: parttable, + size: minSize, + partitions: [ + { + partition: 0, + type: 'free_space', + filesystem: '', + size: minSize, + usage: 100, + } + ] + }; + // TODO - Revisar Usamos la tabla de particiones del cliente seleccionado + const client: Client = this.ogCommonService.selectedClients[clientsId[0]]; + const clientPartitions = []; + client.partitions.forEach((partition) => { + // si es la partición 0 o una partición Vacía no EFI + if (partition.numPartition !== 0) { + + // Obtener el tipo de partición según su code + if (partition.partitionCode.length === 1) { + partition.partitionCode = '0' + partition.partitionCode; + } + const partTypes = this.diskConfig.parttable.partitions.filter(p => p.id === partition.partitionCode.toUpperCase()); + if (partTypes.length > 0) { + partition.type = partTypes[0].type; + } + clientPartitions.push(partition); + } + }); + this.diskConfig.partitions = clientPartitions.concat((this.diskConfig.partitions)); + this.reorderPartitions(); + + this.setChartData(this.diskConfig); + this.partitionTableTypes = this.constants.partitiontable; + } else { + // TODO - dar error? + this.ogSweetAlert.error(this.translate.instant('opengnsys_error'), this.translate.instant('not_clients_selected')); + this.router.navigate(['app/ous']); + } } - } - - this.diskConfig = { - disk: 1, - parttable: parttable, - size: minSize, - partitions: [ - { - partition: 0, - type: 'free_space', - filesystem: '', - size: minSize, - usage: 100, - } - ] - }; - // TODO - Revisar Usamos la tabla de particiones del cliente seleccionado - const client: Client = this.ogCommonService.selectedClients[clientsId[0]]; - const clientPartitions = []; - client.partitions.forEach((partition) => { - if (partition.numPartition !== 0 && partition.filesystem !== 'EMPTY') { - - // Obtener el tipo de partición según su code - if (partition.partitionCode.length === 1) { - partition.partitionCode = '0' + partition.partitionCode; - } - const partTypes = this.diskConfig.parttable.partitions.filter(p => p.id === partition.partitionCode.toUpperCase()); - if (partTypes.length > 0) { - partition.type = partTypes[0].type; - } - clientPartitions.push(partition); - } - }); - this.diskConfig.partitions = clientPartitions.concat((this.diskConfig.partitions)); - this.reorderPartitions(); + ); + } + } - this.setChartData(this.diskConfig); - this.partitionTableTypes = this.constants.partitiontable; - } else { - // TODO - dar error? - this.ogSweetAlert.error(this.translate.instant('opengnsys_error'), this.translate.instant('not_clients_selected')); - this.router.navigate(['app/ous']); - } - } - ); + partTableTypeIsGPT() { + return this.diskConfig.parttable.type === 'GPT'; } - } - - - partTableTypeIsGPT() { - return this.diskConfig.parttable.type === 'GPT'; - } - - partTableTypeIsMSDOS() { - return this.diskConfig.parttable.type === 'MSDOS'; - } - - partTableTypeIsLVM() { - return this.diskConfig.parttable.type === 'LVM'; - } - partTableTypeIsZPOOL() { - return this.diskConfig.parttable.type === 'ZPOOL'; - } - - isEFI(partition) { - return partition.type === 'EFI'; - } - - isCACHE(partition) { - return partition.type === 'CACHE'; - } - - isEXTENDED(partition) { - return partition.type === 'EXTENDED'; - } - - isWINDOWS(partition) { - return partition.type === 'NTFS' || partition.type === 'WINDOWS'; - } - - isLINUX(partition) { - return typeof partition.type === 'string' && partition.type.includes('LINUX'); - } - - isLINUXSWAP(partition) { - return partition.type === 'LINUX-SWAP'; - } - - isDATA(partition) { - return partition.type === 'DATA'; - } - - isUNKNOWN(partition) { - return partition.type === 'UNKNOWN'; - } - - isFreeSpace(partition) { - return partition.type === 'free_space'; - } - - - convertPartitionType(partition) { - if (this.partTableTypeIsMSDOS()) { - if (this.isWINDOWS(partition)) { - partition.type = 'NTFS'; - } else if (this.isUNKNOWN(partition)) { - partition.type = 'NTFS'; - } - } else if (this.partTableTypeIsGPT()) { - if (this.isWINDOWS(partition)) { - partition.type = 'WINDOWS'; - } else if (this.isDATA(partition)) { - partition.type = 'UNKNOWN'; - } - } else if (this.partTableTypeIsLVM()) { - partition.type = 'LVM-LV'; - } else if (this.partTableTypeIsZPOOL()) { - partition.type = 'ZFS-VOL'; + + partTableTypeIsMSDOS() { + return this.diskConfig.parttable.type === 'MSDOS'; } - } - checkPartitionTableType() { - const self = this; - if (this.partTableTypeIsMSDOS()) { - if (this.diskConfig.partitions.length > 5) { - this.ogSweetAlert.info('opengnsys_info', 'En MS-DOS sólo puede haber 4 particiones primarias, se creará una extendida con el resto de particiones'); - const tmpPartitions = []; - const extendedPartition = { - type: 'EXTENDED', - partitions: [], - size: 0, - usage: 0 - }; - const hasCache = (this.diskConfig.partitions.filter((partition) => partition.type === 'CACHE').length > 0); - // Si tiene cache se añaden 2 particiones, más la cache y el espacio libre - const numParts = hasCache ? 2 : 3; - this.diskConfig.partitions.forEach(function(partition, index) { - self.convertPartitionType(partition); - if (index < numParts || self.isFreeSpace(partition) || self.isCACHE(partition)) { - tmpPartitions.push(partition); - } else { - extendedPartition.partitions.push(partition); - extendedPartition.size += partition.size; - } - }); - // Actualizar porcentajes de las particiones extendidas - for (let p = 0; p < extendedPartition.partitions.length; p++) { - self.setPartitionUsage(extendedPartition, extendedPartition.partitions[p]); - } - tmpPartitions.push(extendedPartition); - self.diskConfig.partitions = tmpPartitions; - self.updatePartitionUsage(this.diskConfig.partitions[0]); - } else { - self.diskConfig.partitions.forEach(function(partition, index) { - self.convertPartitionType(partition); - }); - } - - } else { - const tmpPartitions = []; - // Para particiones GPT se crea una particion EFI en primer lugar de 512M - if (this.partTableTypeIsGPT()) { - // Comprobar si existe ya una partición EFI al principio del disco, sino, crearla - if (!this.isEFI(this.diskConfig.partitions[0])) { - tmpPartitions.push({ - type: 'EFI', - size: 512000, - usage: (512000 / this.diskConfig.size) * 100 - }); + partTableTypeIsLVM() { + return this.diskConfig.parttable.type === 'LVM'; + } + + partTableTypeIsZPOOL() { + return this.diskConfig.parttable.type === 'ZPOOL'; + } + + + convertPartitionType(partition) { + if (this.partTableTypeIsMSDOS()) { + if (this.ogCommonService.isWINDOWS(partition)) { + partition.type = 'NTFS'; + } else if (this.ogCommonService.isUNKNOWN(partition)) { + partition.type = 'NTFS'; + } + } else if (this.partTableTypeIsGPT()) { + if (this.ogCommonService.isWINDOWS(partition)) { + partition.type = 'WINDOWS'; + } else if (this.ogCommonService.isDATA(partition)) { + partition.type = 'UNKNOWN'; + } + } else if (this.partTableTypeIsLVM()) { + partition.type = 'LVM-LV'; + } else if (this.partTableTypeIsZPOOL()) { + partition.type = 'ZFS-VOL'; } - } + } + + checkPartitionTableType() { + const self = this; + if (this.partTableTypeIsMSDOS()) { + if (this.diskConfig.partitions.length > 5) { + this.ogSweetAlert.info('opengnsys_info', 'En MS-DOS sólo puede haber 4 particiones primarias, se creará una extendida con el resto de particiones'); + const tmpPartitions = []; + const extendedPartition = { + type: 'EXTENDED', + partitions: [], + size: 0, + usage: 0 + }; + const hasCache = (this.diskConfig.partitions.filter((partition) => partition.type === 'CACHE').length > 0); + // Si tiene cache se añaden 2 particiones, más la cache y el espacio libre + const numParts = hasCache ? 2 : 3; + this.diskConfig.partitions.forEach(function (partition, index) { + self.convertPartitionType(partition); + if (index < numParts || self.ogCommonService.isFreeSpace(partition) || self.ogCommonService.isCACHE(partition)) { + tmpPartitions.push(partition); + } else { + extendedPartition.partitions.push(partition); + extendedPartition.size += partition.size; + } + }); + // Actualizar porcentajes de las particiones extendidas + for (let p = 0; p < extendedPartition.partitions.length; p++) { + self.setPartitionUsage(extendedPartition, extendedPartition.partitions[p]); + } + tmpPartitions.push(extendedPartition); + self.diskConfig.partitions = tmpPartitions; + self.updatePartitionUsage(this.diskConfig.partitions[0]); + } else { + self.diskConfig.partitions.forEach(function (partition, index) { + self.convertPartitionType(partition); + }); + } - this.diskConfig.partitions.forEach(function(partition) { - self.convertPartitionType(partition); - if (!self.isEXTENDED(partition)) { - tmpPartitions.push(partition); } else { - partition.partitions.forEach(function(extPart) { - self.convertPartitionType(extPart); - tmpPartitions.push(extPart); - self.setPartitionUsage(this.diskConfig, extPart); - }); + const tmpPartitions = []; + // Para particiones GPT se crea una particion EFI en primer lugar de 512M + if (this.partTableTypeIsGPT()) { + // Comprobar si existe ya una partición EFI al principio del disco, sino, crearla + if (!this.ogCommonService.isEFI(this.diskConfig.partitions[0])) { + tmpPartitions.push({ + type: 'EFI', + size: 512000, + usage: (512000 / this.diskConfig.size) * 100 + }); + } + } + + this.diskConfig.partitions.forEach(function (partition) { + self.convertPartitionType(partition); + if (!self.ogCommonService.isEXTENDED(partition)) { + tmpPartitions.push(partition); + } else { + partition.partitions.forEach(function (extPart) { + self.convertPartitionType(extPart); + tmpPartitions.push(extPart); + self.setPartitionUsage(self.diskConfig, extPart); + }); + } + }); + this.diskConfig.partitions = tmpPartitions; + this.updatePartitionUsage(this.diskConfig.partitions[0]); } - }); - this.diskConfig.partitions = tmpPartitions; - this.updatePartitionUsage(this.diskConfig.partitions[0]); - } - } - - addPartition() { - // Si el tipo de tabla de particiones es MSDOS, sólo se admiten 4 particiones - if (this.partTableTypeIsGPT() || (this.partTableTypeIsMSDOS() && this.diskConfig.partitions.length < 5)) { - this.diskConfig.partitions.push({ - partition: (this.diskConfig.partitions.length), - type: this.partTableTypeIsGPT() ? 'WINDOWS' : 'NTFS', - filesystem: '', - size: 0, - usage: 5 - - }); - this.updatePartitionUsage(this.diskConfig.partitions[this.diskConfig.partitions.length - 1]); - } else if (this.partTableTypeIsMSDOS()) { - this.ogSweetAlert.warning('opengnsys_warning', 'En MS-DOS sólo puede haber 4 particiones primarias, utilice alguna como extendida si necesita más particiones'); } - // Actualizar información - // setChartData(this.diskConfig); - } - - addExtendedPartition(partition) { - partition.partitions.push({ - partition: (partition.partitions.length + 1), - type: 'NTFS', - filesystem: '', - size: 0, - usage: 0 - - }); - const extendedPartUsage = Math.round(100 / partition.partitions.length); - partition.partitions.forEach(function(extPart) { - extPart.usage = extendedPartUsage; - }); - // Actualiza tamaños en funcion del porcentaje de uso - this.updateExtendedPartitions(partition); - } - - updateExtendedPartitions(extPartition) { - const parentPartition = this.diskConfig.partitions.filter((partition) => partition.type === 'EXTENDED')[0]; - const totalSize = parentPartition.size; - parentPartition.partitions.forEach( function(extPart, index) { - extPart.partition = (index + 1); - extPart.size = Math.round((extPart.usage || 0) * totalSize / 100); - }); - } - - updateExtendedPartitionsUsage(extPartition) { - const parentPartition = this.diskConfig.partitions.filter((partition) => partition.type === 'EXTENDED')[0]; - const index = parentPartition.partitions.indexOf(extPartition); - let nextPart = null; - // si solo hay una partición el uso es siempre el 100% - if (parentPartition.partitions.length === 1) { - extPartition.usage = 100; - } else { - nextPart = null; - // el porcentaje que crezca la particion, se le resta a la siguiente o a la anterior si es la ultima - if (index === parentPartition.partitions.length - 1) { - nextPart = parentPartition.partitions[index - 1]; - } else { - nextPart = parentPartition.partitions[index + 1]; - } - let restPercent = 100; - parentPartition.partitions.forEach(function(extPart) { - restPercent -= (extPart.usage || 0); // Hay casos en los que se obtiene NaN - }); - // Le quitamos el porcentaje a la particion contigua hasta que quede con un mínimo de 1 - if (nextPart.usage > (restPercent * -1)) { - nextPart.usage += restPercent; - } else { - // restamos 1 al resto del porcentaje que será lo que ocupe la particion contigua - restPercent = Math.abs(restPercent) - (nextPart.usage - 1); - nextPart.usage = 1; - - extPartition.usage -= restPercent; - } + + addPartition() { + // Si el tipo de tabla de particiones es MSDOS, sólo se admiten 4 particiones + if (this.partTableTypeIsGPT() || (this.partTableTypeIsMSDOS() && this.diskConfig.partitions.length < 5)) { + this.diskConfig.partitions.push({ + partition: (this.diskConfig.partitions.length), + type: this.partTableTypeIsGPT() ? 'WINDOWS' : 'NTFS', + filesystem: '', + size: 0, + usage: 5 + + }); + this.updatePartitionUsage(this.diskConfig.partitions[this.diskConfig.partitions.length - 1]); + } else if (this.partTableTypeIsMSDOS()) { + this.ogSweetAlert.warning('opengnsys_warning', 'En MS-DOS sólo puede haber 4 particiones primarias, utilice alguna como extendida si necesita más particiones'); + } + // Actualizar información + // setChartData(this.diskConfig); } - this.updateExtendedPartitions(extPartition); - } - - removeExtendedPartition(extPartition) { - const parentPartition = this.diskConfig.partitions.filter((partition) => partition.type === 'EXTENDED')[0]; - const index = parentPartition.partitions.indexOf(extPartition); - if (index !== -1) { - parentPartition.partitions.splice(index, 1); + + addExtendedPartition(partition) { + partition.partitions.push({ + partition: (partition.partitions.length + 1), + type: 'NTFS', + filesystem: '', + size: 0, + usage: 0 + + }); + const extendedPartUsage = Math.round(100 / partition.partitions.length); + partition.partitions.forEach(function (extPart) { + extPart.usage = extendedPartUsage; + }); + // Actualiza tamaños en funcion del porcentaje de uso + this.updateExtendedPartitions(partition); } - // Comprobamos el % que queda libre ahora - const freePercent = Math.round(extPartition.usage / parentPartition.partitions.length); - parentPartition.partitions.forEach(function(extPart) { - extPart.usage += freePercent; - extPart.size = Math.round(extPart.usage * parentPartition.size / 100); - }); - } - - - reorderPartitions() { - const self = this; - const tmpPartitions = []; - let indexFreeSpace = -1; - let indexCache = -1; - this.diskConfig.partitions.forEach(function(partition, index) { - if (partition.type !== 'free_space' && !self.isCACHE(partition)) { - partition.partition = (tmpPartitions.length + 1); - tmpPartitions.push(partition); - } else if (self.isCACHE(partition)) { - indexCache = index; - } else if (partition.type === 'free_space') { - indexFreeSpace = index; - } - }); - // Añadir el espacio libre y la cache - if (indexFreeSpace !== -1) { - this.diskConfig.partitions[indexFreeSpace].usage = this.calculateFreeSpace(this.diskConfig.partitions[indexFreeSpace]); - tmpPartitions.push(this.diskConfig.partitions[indexFreeSpace]); + + updateExtendedPartitions(extPartition) { + const parentPartition = this.diskConfig.partitions.filter((partition) => partition.type === 'EXTENDED')[0]; + const totalSize = parentPartition.size; + parentPartition.partitions.forEach(function (extPart, index) { + extPart.partition = (index + 1); + extPart.size = Math.round((extPart.usage || 0) * totalSize / 100); + }); } - if (indexCache !== -1) { - tmpPartitions.push(this.diskConfig.partitions[indexCache]); + + updateExtendedPartitionsUsage(extPartition) { + const parentPartition = this.diskConfig.partitions.filter((partition) => partition.type === 'EXTENDED')[0]; + const index = parentPartition.partitions.indexOf(extPartition); + let nextPart = null; + // si solo hay una partición el uso es siempre el 100% + if (parentPartition.partitions.length === 1) { + extPartition.usage = 100; + } else { + nextPart = null; + // el porcentaje que crezca la particion, se le resta a la siguiente o a la anterior si es la ultima + if (index === parentPartition.partitions.length - 1) { + nextPart = parentPartition.partitions[index - 1]; + } else { + nextPart = parentPartition.partitions[index + 1]; + } + let restPercent = 100; + parentPartition.partitions.forEach(function (extPart) { + restPercent -= (extPart.usage || 0); // Hay casos en los que se obtiene NaN + }); + // Le quitamos el porcentaje a la particion contigua hasta que quede con un mínimo de 1 + if (nextPart.usage > (restPercent * -1)) { + nextPart.usage += restPercent; + } else { + // restamos 1 al resto del porcentaje que será lo que ocupe la particion contigua + restPercent = Math.abs(restPercent) - (nextPart.usage - 1); + nextPart.usage = 1; + + extPartition.usage -= restPercent; + } + } + this.updateExtendedPartitions(extPartition); } - this.diskConfig.partitions = tmpPartitions; - } - - setChartData(diskConfig) { - const self = this; - const diskChartData = []; - const diskChartLabels = []; - const diskPieChartColors = [{ - backgroundColor: [] - }]; - let usedSpace = 0; - - diskConfig.partitions.forEach( function(partition) { - if (partition.size > 0) { - self.setPartitionUsage(diskConfig, partition); - if (partition.type === 'free_space') { - partition.usage = self.calculateFreeSpace(partition); + + removeExtendedPartition(extPartition) { + const parentPartition = this.diskConfig.partitions.filter((partition) => partition.type === 'EXTENDED')[0]; + const index = parentPartition.partitions.indexOf(extPartition); + if (index !== -1) { + parentPartition.partitions.splice(index, 1); } - // El espacio libre solo se añade si es 0 - if (partition.type !== 'free_space' || (partition.type === 'free_space' && partition.usage > 0)) { - diskChartData.push(partition.usage); - diskChartLabels.push([ - self.translate.instant(partition.os || partition.filesystem || partition.type), - (partition.usage + '%') - ]); - diskPieChartColors[0].backgroundColor.push(self.getPartitionColor(partition)); + // Comprobamos el % que queda libre ahora + const freePercent = Math.round(extPartition.usage / parentPartition.partitions.length); + parentPartition.partitions.forEach(function (extPart) { + extPart.usage += freePercent; + extPart.size = Math.round(extPart.usage * parentPartition.size / 100); + }); + } + + + reorderPartitions() { + const self = this; + const tmpPartitions = []; + let indexFreeSpace = -1; + let indexCache = -1; + this.diskConfig.partitions.forEach(function (partition, index) { + if (partition.type !== 'free_space' && !self.ogCommonService.isCACHE(partition)) { + partition.partition = (tmpPartitions.length + 1); + tmpPartitions.push(partition); + } else if (self.ogCommonService.isCACHE(partition)) { + indexCache = index; + } else if (partition.type === 'free_space') { + indexFreeSpace = index; + } + }); + // Añadir el espacio libre y la cache + if (indexFreeSpace !== -1) { + this.diskConfig.partitions[indexFreeSpace].usage = this.calculateFreeSpace(this.diskConfig.partitions[indexFreeSpace]); + tmpPartitions.push(this.diskConfig.partitions[indexFreeSpace]); } - if (partition.type !== 'free_space') { - usedSpace += partition.usage; + if (indexCache !== -1) { + tmpPartitions.push(this.diskConfig.partitions[indexCache]); } - } - }); - - this.diskConfig.remaining = Math.round(100 * (100 - usedSpace)) / 100; - - const diskChartOptions: ChartOptions = { - responsive: true, - legend: { - position: 'bottom' - }, - plugins: { - datalabels: { - formatter: (value, ctx) => { - const label = ctx.chart.data.labels[ctx.dataIndex]; - return label; - }, - }, - } - }; - - diskConfig.diskChartData = diskChartData; - diskConfig.diskChartOptions = diskChartOptions; - diskConfig.diskChartLabels = diskChartLabels; - diskConfig.diskPieChartColors = diskPieChartColors; - } - - getPartitionColor(partition) { - let color = '#c5e72b'; - // Para la partición de datos se usa un color específico - if (this.isDATA(partition)) { - color = 'rgb(237,194,64)'; - } else if (this.isEFI(partition)) { - color = '#bfe4e5'; - } else if (this.isWINDOWS(partition)) { - color = '#00c0ef'; - } else if (this.isLINUXSWAP(partition)) { - color = '#545454'; - } else if (this.isLINUX(partition)) { - color = '#605ca8'; - } else if (this.isCACHE(partition)) { - color = '#FC5A5A'; - } else if (this.isFreeSpace(partition)) { - color = '#bcbcbc'; + this.diskConfig.partitions = tmpPartitions; } - return color; - } - - /* - * Custom Label formatter - * ---------------------- - */ - labelFormatter(label, series) { - return '<div style="font-size:13px; text-align:center; padding:2px; color: #000; font-weight: 600;">' - + '<br>' - + series.usage + '%</div>'; - } - - getSizeInGB(size) { - size = size / (1024 * 1024); - return Math.round(size * 100) / 100; - } - - setPartitionUsage(diskConfig, partition) { - partition.usage = Math.round(((partition.size * 100) / diskConfig.size) * 100) / 100; - } - - checkPartitionType(partition) { - let ok = true; - if (this.isCACHE(partition)) { - // Comprobar si ya hay alguna partición como CACHE - if (this.diskConfig.partitions.filter((p) => p.type === 'CACHE').length > 1) { - this.ogSweetAlert.error('opengnsys_error', 'Solo debe haber una CACHE'); - partition.type = 'NTFS'; - ok = false; - } - } else if (this.isEXTENDED(partition)) { - // Comprobar si ya hay alguna partición como EXTENDIDA - if (this.diskConfig.partitions.filter((p) => p.type === 'EXTENDED').length > 1) { - this.ogSweetAlert.error('opengnsys_error', 'Solo debe haber una EXTENDIDA'); - partition.type = 'NTFS'; - ok = false; - } else { - partition.partitions = [ - { - partition: 1, - type: 'NTFS', - filesystem: '', - size: partition.size, - usage: 100 - - } - ]; - } - } else if (typeof partition.partitions !== 'undefined' && partition.partitions.length > 0) { - ok = false; - const self = this; - this.ogSweetAlert.question('opengnsys_question', 'Esta particion contiene otras partitiones!, si continua, dichas particiones serán eliminadas....', - function(yes) { - partition.partitions = []; - self.updatePartitionUsage(partition); - }, - function(cancel) { - // Si contesta no se deja el tipo extendido - partition.type = 'EXTENDED'; - } - ); + + setChartData(diskConfig) { + const self = this; + const diskChartData = []; + const diskChartLabels = []; + const diskPieChartColors = [{ + backgroundColor: [] + }]; + let usedSpace = 0; + + diskConfig.partitions.forEach(function (partition) { + if (partition.size > 0) { + self.setPartitionUsage(diskConfig, partition); + if (partition.type === 'free_space') { + partition.usage = self.calculateFreeSpace(partition); + } + // El espacio libre solo se añade si es 0 + if (partition.type !== 'free_space' || (partition.type === 'free_space' && partition.usage > 0)) { + diskChartData.push(partition.usage); + diskChartLabels.push([ + self.translate.instant(partition.os || partition.filesystem || partition.type), + (partition.usage + '%') + ]); + diskPieChartColors[0].backgroundColor.push(self.ogCommonService.getPartitionColor(partition)); + } + if (partition.type !== 'free_space') { + usedSpace += partition.usage; + } + } + }); + + this.diskConfig.remaining = Math.round(100 * (100 - usedSpace)) / 100; + + const diskChartOptions: ChartOptions = { + responsive: true, + legend: { + position: 'bottom' + }, + plugins: { + datalabels: { + formatter: (value, ctx) => { + const label = ctx.chart.data.labels[ctx.dataIndex]; + return label; + }, + }, + } + }; + + diskConfig.diskChartData = diskChartData; + diskConfig.diskChartOptions = diskChartOptions; + diskConfig.diskChartLabels = diskChartLabels; + diskConfig.diskPieChartColors = diskPieChartColors; + } + + /* + * Custom Label formatter + * ---------------------- + */ + labelFormatter(label, series) { + return '<div style="font-size:13px; text-align:center; padding:2px; color: #000; font-weight: 600;">' + + '<br>' + + series.usage + '%</div>'; + } + + getSizeInGB(size) { + size = size / (1024 * 1024); + return Math.round(size * 100) / 100; } - if (ok) { - this.updatePartitionUsage(partition); + setPartitionUsage(diskConfig, partition) { + partition.usage = Math.round(((partition.size * 100) / diskConfig.size) * 100) / 100; } - } - updatePartitionUsage(partition) { - const remaining = this.calculateFreeSpace(partition); - if (partition.usage > remaining) { - partition.usage = remaining; + checkPartitionType(partition, parentPartition) { + let ok = true; + if (this.ogCommonService.isCACHE(partition)) { + // Comprobar si ya hay alguna partición como CACHE + if (this.diskConfig.partitions.filter((p) => p.type === 'CACHE').length > 1) { + this.ogSweetAlert.error('opengnsys_error', 'Solo debe haber una CACHE'); + partition.type = 'NTFS'; + ok = false; + } + } else if (this.ogCommonService.isEXTENDED(partition)) { + // Comprobar si ya hay alguna partición como EXTENDIDA + if (this.diskConfig.partitions.filter((p) => p.type === 'EXTENDED').length > 1) { + this.ogSweetAlert.error('opengnsys_error', 'Solo debe haber una EXTENDIDA'); + partition.type = 'NTFS'; + ok = false; + } else { + partition.partitions = [ + { + partition: 1, + type: 'NTFS', + filesystem: '', + size: partition.size, + usage: 100 + + } + ]; + } + } else if (typeof partition.partitions !== 'undefined' && partition.partitions.length > 0) { + ok = false; + const self = this; + this.ogSweetAlert.question('opengnsys_question', 'Esta particion contiene otras partitiones!, si continua, dichas particiones serán eliminadas....', + function (yes) { + partition.partitions = []; + self.updatePartitionUsage(partition); + }, + function (cancel) { + // Si contesta no se deja el tipo extendido + partition.type = 'EXTENDED'; + } + ); + } + + if (ok) { + if (parentPartition) { + this.updateExtendedPartitionsUsage(parentPartition); + } else { + this.updatePartitionUsage(partition); + } + } } - partition.size = Math.round(this.diskConfig.size * partition.usage / 100); - this.setChartData(this.diskConfig); - this.reorderPartitions(); - // Si es una partición extendida - if (typeof partition.partitions !== 'undefined' && partition.partitions.length > 0) { - this.updateExtendedPartitions(partition.partitions[0]); + + updatePartitionUsage(partition) { + const remaining = this.calculateFreeSpace(partition); + if (partition.usage > remaining) { + partition.usage = remaining; + } + partition.size = Math.round(this.diskConfig.size * partition.usage / 100); + this.setChartData(this.diskConfig); + this.reorderPartitions(); + // Si es una partición extendida + if (typeof partition.partitions !== 'undefined' && partition.partitions.length > 0) { + this.updateExtendedPartitions(partition.partitions[0]); + } } - } - - calculateFreeSpace(asignedPartition) { - let usedSpace = 0; - this.diskConfig.partitions.forEach(function(partition, index) { - if (partition !== asignedPartition && partition.type !== 'free_space') { - usedSpace += partition.usage || 0; - } - }); - return Math.round(100 * (100 - usedSpace)) / 100; - } - - removePartition(partition) { - const index = this.diskConfig.partitions.indexOf(partition); - if (index !== -1) { - this.diskConfig.partitions.splice(index, 1); + + calculateFreeSpace(asignedPartition) { + let usedSpace = 0; + this.diskConfig.partitions.forEach(function (partition, index) { + if (partition !== asignedPartition && partition.type !== 'free_space') { + usedSpace += partition.usage || 0; + } + }); + return Math.round(100 * (100 - usedSpace)) / 100; } - this.setChartData(this.diskConfig); + removePartition(partition) { + const index = this.diskConfig.partitions.indexOf(partition); + if (index !== -1) { + this.diskConfig.partitions.splice(index, 1); + } + + this.setChartData(this.diskConfig); - } + } // var RC='@'; // document.fdatosejecucion.atributos.value="scp="+escape(document.fdatos.codigo.value)+RC; - /**/ - generateOgInstruction() { - const self = this; - let initPartitionTable = 'ogCreatePartitionTable ' + this.diskConfig.disk + ' ' + this.diskConfig.parttable.type + '\n'; - initPartitionTable += 'ogEcho log session "[0] $MSG_HELP_ogCreatePartitions"\n'; - initPartitionTable += 'ogEcho session "[10] $MSG_HELP_ogUnmountAll ' + this.diskConfig.disk + '"\n'; - initPartitionTable += 'ogUnmountAll ' + this.diskConfig.disk + ' 2>/dev/null\n'; - initPartitionTable += 'ogUnmountCache\n'; - initPartitionTable += 'ogEcho session "[30] $MSG_HELP_ogUpdatePartitionTable ' + this.diskConfig.disk + '"\n'; - initPartitionTable += 'ogDeletePartitionTable ' + this.diskConfig.disk + '\n'; - initPartitionTable += 'ogUpdatePartitionTable ' + this.diskConfig.disk + '\n'; - - let createPartitions = 'ogEcho session "[60] $MSG_HELP_ogListPartitions ' + this.diskConfig.disk + '"\n'; - createPartitions += 'ogExecAndLog command session ogListPartitions ' + this.diskConfig.disk + '\n'; - - let cacheInstruction = ''; - let partitionList = ''; - let formatInstructions = ''; - this.diskConfig.partitions.forEach(function(partition, index) { - if (partition.type !== 'free_space') { - // La unica particion especial es la 4 que es cache, para el resto - if (!self.isCACHE(partition)) { - partitionList += ' ' + partition.type + ':' + partition.size; - if (self.isEXTENDED(partition)) { - for (let p = 0; p < partition.partitions.length; p++) { - partitionList += ' ' + partition.partitions[p].type + ':' + partition.partitions[p].size; - if (partition.partitions[p].format === true) { - formatInstructions += 'ogUnmount ' + self.diskConfig.disk + ' ' + (partition.partition + (partition.partitions[p].partition - 1)) + '\n'; - formatInstructions += 'ogFormat ' + self.diskConfig.disk + ' ' + (partition.partition + (partition.partitions[p].partition - 1)) + '\n'; - } + /**/ + generateOgInstruction() { + const self = this; + this.ogCommandsService.execution.sendConfig = true; + let initPartitionTable = 'ogCreatePartitionTable ' + this.diskConfig.disk + ' ' + this.diskConfig.parttable.type + '\n'; + initPartitionTable += 'ogEcho log session "[0] $MSG_HELP_ogCreatePartitions"\n'; + initPartitionTable += 'ogEcho session "[10] $MSG_HELP_ogUnmountAll ' + this.diskConfig.disk + '"\n'; + initPartitionTable += 'ogUnmountAll ' + this.diskConfig.disk + ' 2>/dev/null\n'; + initPartitionTable += 'ogUnmountCache\n'; + initPartitionTable += 'ogEcho session "[30] $MSG_HELP_ogUpdatePartitionTable ' + this.diskConfig.disk + '"\n'; + initPartitionTable += 'ogDeletePartitionTable ' + this.diskConfig.disk + '\n'; + initPartitionTable += 'ogUpdatePartitionTable ' + this.diskConfig.disk + '\n'; + + let createPartitions = 'ogEcho session "[60] $MSG_HELP_ogListPartitions ' + this.diskConfig.disk + '"\n'; + createPartitions += 'ogExecAndLog command session ogListPartitions ' + this.diskConfig.disk + '\n'; + + let cacheInstruction = ''; + let partitionList = ''; + let formatInstructions = ''; + this.diskConfig.partitions.forEach(function (partition, index) { + if (partition.type !== 'free_space') { + // La unica particion especial es la 4 que es cache, para el resto + if (!self.ogCommonService.isCACHE(partition)) { + partitionList += ' ' + partition.type + ':' + partition.size; + if (self.ogCommonService.isEXTENDED(partition)) { + for (let p = 0; p < partition.partitions.length; p++) { + partitionList += ' ' + partition.partitions[p].type + ':' + partition.partitions[p].size; + if (partition.partitions[p].format === true) { + formatInstructions += 'ogUnmount ' + self.diskConfig.disk + ' ' + (partition.partition + (partition.partitions[p].partition - 1)) + '\n'; + formatInstructions += 'ogFormat ' + self.diskConfig.disk + ' ' + (partition.partition + (partition.partitions[p].partition - 1)) + ' ' + ((partition.partitions[p].partition.filesystem) ? partition.partitions[p].partition.filesystem : '') + '\n'; + } + } + } + if (partition.format === true) { + formatInstructions += 'ogUnmount ' + self.diskConfig.disk + ' ' + partition.partition + '\n'; + formatInstructions += 'ogFormat ' + self.diskConfig.disk + ' ' + partition.partition + ' ' + (partition.filesystem ? partition.filesystem : '') + '\n'; + } + } else { + cacheInstruction = 'ogEcho session "[50] $MSG_HELP_ogCreateCache"\n'; + cacheInstruction += 'initCache ' + self.diskConfig.disk + ' ' + partition.size + ' NOMOUNT &>/dev/null\n'; + + if (partition.format === true) { + formatInstructions += 'ogUnmountCache\n'; + formatInstructions += 'ogFormatCache\n'; + } + } } - } - if (partition.format === true) { - formatInstructions += 'ogUnmount ' + self.diskConfig.disk + ' ' + partition.partition + '\n'; - formatInstructions += 'ogFormat ' + self.diskConfig.disk + ' ' + partition.partition + '\n'; - } - } else { - cacheInstruction = 'ogEcho session "[50] $MSG_HELP_ogCreateCache"\n'; - cacheInstruction += 'initCache ' + self.diskConfig.disk + ' ' + partition.size + ' NOMOUNT &>/dev/null\n'; + }); - if (partition.format === true) { - formatInstructions += 'ogUnmountCache\n'; - formatInstructions += 'ogFormatCache\n'; - } - } - } - }); - - createPartitions += 'ogEcho session "[70] $MSG_HELP_ogCreatePartitions ' + partitionList + '"\n'; - createPartitions += 'ogExecAndLog command ogCreatePartitions ' + this.diskConfig.disk + partitionList + '\n'; - createPartitions += 'ogEcho session "[80] $MSG_HELP_ogSetPartitionActive ' + this.diskConfig.disk + ' 1"\n'; - createPartitions += 'ogSetPartitionActive ' + this.diskConfig.disk + ' 1\n'; - createPartitions += 'ogEcho log session "[100] $MSG_HELP_ogListPartitions ' + this.diskConfig.disk + '"\n'; - createPartitions += 'ogUpdatePartitionTable ' + this.diskConfig.disk + '\n'; - createPartitions += 'ms-sys /dev/sda | grep unknow && ms-sys /dev/sda\n'; - createPartitions += 'ogExecAndLog command session log ogListPartitions ' + this.diskConfig.disk + '\n'; - - this.ogCommandsService.ogInstructions = initPartitionTable + cacheInstruction + createPartitions + formatInstructions; - } + createPartitions += 'ogEcho session "[70] $MSG_HELP_ogCreatePartitions ' + partitionList + '"\n'; + createPartitions += 'ogExecAndLog command ogCreatePartitions ' + this.diskConfig.disk + partitionList + '\n'; + createPartitions += 'ogEcho session "[80] $MSG_HELP_ogSetPartitionActive ' + this.diskConfig.disk + ' 1"\n'; + createPartitions += 'ogSetPartitionActive ' + this.diskConfig.disk + ' 1\n'; + createPartitions += 'ogEcho log session "[100] $MSG_HELP_ogListPartitions ' + this.diskConfig.disk + '"\n'; + createPartitions += 'ogUpdatePartitionTable ' + this.diskConfig.disk + '\n'; + createPartitions += 'ms-sys /dev/sda | grep unknow && ms-sys /dev/sda\n'; + createPartitions += 'ogExecAndLog command session log ogListPartitions ' + this.diskConfig.disk + '\n'; + + this.ogCommandsService.ogInstructions = initPartitionTable + cacheInstruction + createPartitions + formatInstructions; + } } diff --git a/admin/WebConsole3/frontend/src/app/pages/common/directive/col-resizable.directive.ts b/admin/WebConsole3/frontend/src/app/pages/common/directive/col-resizable.directive.ts index 7c32f406..937605a3 100644 --- a/admin/WebConsole3/frontend/src/app/pages/common/directive/col-resizable.directive.ts +++ b/admin/WebConsole3/frontend/src/app/pages/common/directive/col-resizable.directive.ts @@ -2,80 +2,89 @@ import {Directive, DoCheck, ElementRef, EventEmitter, Input, OnDestroy, OnInit, class ResizeInfo { - width: number; - percent: number; + width: number; + percent: number; } @Directive({ - selector: '[col-resizable]' + selector: '[col-resizable]' }) -export class ColResizableDirective implements OnInit, DoCheck { - private el: ElementRef; - private start: any; - private pressed: boolean; - private startX: number; - private startWidth: any; +export class ColResizableDirective implements OnInit, DoCheck { + private el: ElementRef; + private start: any; + private pressed: boolean; + private startX: number; + private startWidth: any; - @Input() - elements: any[]; + @Input() + elements: any[]; - @Output() - onResize = new EventEmitter<ResizeInfo>(); - private elementProperty: string; + @Output() + onResize = new EventEmitter<ResizeInfo>(); + private elementProperty: string; - constructor(el: ElementRef, private renderer: Renderer2) { - this.el = el; + constructor(el: ElementRef, private renderer: Renderer2) { + this.el = el; - } + } - ngOnInit() { - this.elementProperty = this.el.nativeElement.getAttribute('cr-update-property') || ''; - } - ngDoCheck(): void { - const table = this.el.nativeElement; - const trs = table.getElementsByTagName('tr'); - let tds = null; + ngOnInit() { + this.elementProperty = this.el.nativeElement.getAttribute('cr-update-property') || ''; + } - for (let i = 0; i < trs.length; i++) { - tds = trs[i].getElementsByTagName('td'); - if (tds.length > 0) { - for (let n = 0; n < tds.length; n++) { + ngDoCheck(): void { + const table = this.el.nativeElement; + const trs = table.rows; + let tds = null; - if (tds[n].getElementsByClassName('resizer').length === 0) { - const span = document.createElement('span'); - span.classList.add('resizer'); - tds[n].appendChild(span); - span.addEventListener('mousedown', (event) => { - this.start = event.target; - this.pressed = true; - this.startX = event.x; - this.startWidth = this.start.parentElement.offsetWidth; - this.initResizableColumns(); - }); - } + for (let i = 0; i < trs.length; i++) { + tds = trs[i].cells; + if (tds.length > 0) { + for (let n = 0; n < tds.length; n++) { + // Buscar un elemento resizer si existe + let found = false; + let c = 0; + while (c < tds[n].children.length && !found) { + if (tds[n].children[c].classList.contains('resizer') === true) { + found = true; + } + c++; + } + if (!found) { + const span = document.createElement('span'); + span.classList.add('resizer'); + tds[n].appendChild(span); + span.addEventListener('mousedown', (event) => { + this.start = event.target; + this.pressed = true; + this.startX = event.x; + this.startWidth = this.start.parentElement.offsetWidth; + this.initResizableColumns(); + }); + } + } + } } - } } - } - private initResizableColumns() { - this.renderer.listen('body', 'mousemove', (event) => { - if (this.pressed) { - const width = this.startWidth + (event.x - this.startX); - this.start.parentElement.style.width = width + 'px'; - const element = this.elements[this.start.parentElement.cellIndex]; - if (typeof element !== 'undefined' && this.elementProperty !== ''){ - element[this.elementProperty] = ((width / this.el.nativeElement.offsetWidth) * 100); - } - this.onResize.emit(element); - } - }) - this.renderer.listen('body', 'mouseup', (event) => { - if (this.pressed) { - this.pressed = false; - } - }); - } + private initResizableColumns() { + this.renderer.listen('body', 'mousemove', (event) => { + if (this.pressed) { + const width = this.startWidth + (event.x - this.startX); + this.start.parentElement.style.width = width + 'px'; + const element = this.elements[this.start.parentElement.cellIndex]; + if (typeof element !== 'undefined' && this.elementProperty !== '') { + element[this.elementProperty] = Math.round(((width / this.el.nativeElement.offsetWidth) * 100) * 100) / 100; + } + this.onResize.emit(element); + } + }); + this.renderer.listen('body', 'mouseup', (event) => { + if (this.pressed) { + this.pressed = false; + } + }); + } } diff --git a/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.html b/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.html index 7e010811..5b25a74f 100644 --- a/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.html +++ b/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.html @@ -8,7 +8,7 @@ <textarea class="form-control" *ngIf="field.type == 'textarea'" [name]="field.name" [(ngModel)]="model[field.field]"></textarea> <input *ngIf="field.type == 'checkbox'" [name]="field.name" icheck checkbox-class="icheckbox_square-blue" radio-class="iradio_square-blue" type="checkbox" class="selection-checkbox" [(ngModel)]="model[field.field]" /> <select *ngIf="field.type == 'select'" [compareWith]="compareFn" [name]="field.name" [(ngModel)]="model[field.field]"> - <option *ngFor="let option of field.options.items" [ngValue]="getValue(field, option)">{{option[field.options.label]|translate}}</option> + <option *ngFor="let option of field.options.items" [ngValue]="getValue(field, option)">{{getLabel(field, option)|translate}}</option> </select> </div> </div> diff --git a/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.ts b/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.ts index 2cb113be..9d7b0da4 100644 --- a/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/common/forms/form-input.component.ts @@ -9,7 +9,7 @@ export class FormInputComponent { private _cols: number; @Input() model; - + @Input() set cols(cols) { this._cols = (typeof cols !== 'undefined') ? (12 / cols) : 6; @@ -44,14 +44,23 @@ export class FormInputComponent { return result; } + getLabel(field: any, option: any) { + let result = option; + if (field.options.label) { + result = option[field.options.label]; + } + return result; + } + compareFn = (a, b) => { let result = false; if (a !== null && b !== null && typeof a === 'object' && typeof b === 'object') { result = (a.id === b.id); - } else{ + } else { result = (a === b); } return result; } + } diff --git a/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.html b/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.html new file mode 100644 index 00000000..0cdd1093 --- /dev/null +++ b/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.html @@ -0,0 +1,47 @@ +<section class="content-header"> + <h1 translate="netboot_templates"> + </h1> + <ol class="breadcrumb"> + <li><a [routerLink]="'/app/ous'"><i class="fa fa-th"></i> {{'ous'|translate}}</a></li> + <li class="active" translate="netboot_templates"></li> + </ol> +</section> +<section fixed-toolboxbar class="toolboxbar"> + <div> + <div class="col-md-12"> + <div class="box-tools pull-right"> + <button class="btn btn-primary" translate="save" (click)="save()"></button> + </div> + </div> + </div> +</section> +<section class="content"> + <div class="row table netboot" *ngFor="let netboots of netbootTypes"> + <div class="col-md-12"> + <h2><span translate="type"></span>: {{netboots[0].type}}</h2> + </div> + <div class="col-md-2" *ngFor="let netboot of netboots"> + <div class="box box-primary"> + <div class="box-header with-border"> + <h3 class="box-title">{{netboot.name}}</h3> + <div class="box-tools pull-right"> + <button type="button" class="btn btn-xs btn-flat hidden-md hidden-lg" ng-class="{'btn-default': multiSelection == false, 'btn-primary': multiSelection == true}" (click)="multiSelection = !multiSelection"><i class="fa fa-list-ul"></i></button> + <button [disabled]="selectionForMove.length == 0" type="button" class="btn btn-xs btn-default btn-flat" (click)="moveSelectionToNetboot(netboot.id)"> + <i class="fa fa-download"></i> + </button> + </div> + </div> + <!-- /.box-header --> + <div class="box-body"> + <select name="selection" [(ngModel)]="selectionForMove" multiple> + <option (click)="checkSelection(netboot.id, clientId)" *ngFor="let clientId of assignedNetboots[netboot.id]" value="{{netboot.id}}_{{clientId}}">{{ogCommonService.selectedClients[clientId].name}}</option> + </select> + </div> + <!-- /.box-body --> + <div class="box-footer"> + </div> + <!-- /.box-footer--> + </div> + </div> + </div> +</section> diff --git a/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.scss b/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.scss new file mode 100644 index 00000000..1471a307 --- /dev/null +++ b/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.scss @@ -0,0 +1,10 @@ +app-netboot { + + .input-group { + width: 100%; + } + + .input-group textarea { + min-height: 500px; + } +} diff --git a/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.ts b/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.ts new file mode 100644 index 00000000..a4e9b95d --- /dev/null +++ b/admin/WebConsole3/frontend/src/app/pages/netboot/clients/netboot-clients.component.ts @@ -0,0 +1,139 @@ +import {Component, OnInit} from '@angular/core'; + +import { NetbootService } from 'src/app/api/netboot.service'; +import {OgSweetAlertService} from '../../../service/og-sweet-alert.service'; +import {ToasterService} from '../../../service/toaster.service'; +import {TranslateService} from '@ngx-translate/core'; +import {ActivatedRoute, Router} from '@angular/router'; +import {OgCommonService} from '../../../service/og-common.service'; +import {User} from '../../../model/user'; +import {AuthModule} from 'globunet-angular/core'; + +@Component({ + selector: 'app-netboot', + templateUrl: './netboot-clients.component.html', + styleUrls: [ './netboot-clients.component.scss' ] +}) +export class NetbootClientsComponent implements OnInit { + multiSelection = false; + netboots = []; + uefiNetboots = []; + biosNetboots = []; + assignedNetboots = {}; + selectionForMove = []; + rangeSelection = { + start: -1, + end: -1 + }; + user: User; + netbootTypes = []; + // this tells the tabs component which Pages + // should be each tab's root Page + constructor(public netbootService: NetbootService, private authModule: AuthModule, public ogCommonService: OgCommonService, private router: Router, private activatedRoute: ActivatedRoute, private ogSweetAlert: OgSweetAlertService, private toaster: ToasterService, private translate: TranslateService) { + this.user = this.authModule.getLoggedUser(); + } + + + + ngOnInit() { + if (this.user && this.ogCommonService.selectedClients) { + this.netbootService.list().subscribe( + (result) => { + this.netboots = result; + const self = this; + this.netboots.forEach((netboot) => { + if (netboot.type && netboot.type === 'uefi') { + self.uefiNetboots.push(netboot); + } else { + self.biosNetboots.push(netboot); + } + }); + this.netbootTypes.push(this.biosNetboots); + this.netbootTypes.push(this.uefiNetboots); + const clientIds = Object.keys(this.ogCommonService.selectedClients); + // Recorrer todos los clientes y formar los grupos según el partitionCode de sus particiones, deben coincidir todos + for (let index = 0; index < clientIds.length; index++) { + // Generamos una clave usando disco-particion-code para comparar + const client = this.ogCommonService.selectedClients[clientIds[index]]; + if (!client.netboot) { + client.netboot = this.netboots[0]; + } + if (!this.assignedNetboots[client.netboot.id]) { + this.assignedNetboots[client.netboot.id] = []; + } + this.assignedNetboots[client.netboot.id].push(client.id); + } + }, + (error) => { + this.toaster.pop({type: 'error', title: 'error', body: error}); + } + ); + } else { + // TODO - dar error? + this.ogSweetAlert.error(this.translate.instant('opengnsys_error'), this.translate.instant('not_clients_selected')); + this.router.navigate(['app.ous']); + } + } + + moveSelectionToNetboot(id) { + // La selección está formada por dos parametros separados por "_", netbootId y clientId + for (let i = 0; i < this.selectionForMove.length; i++) { + const ids = this.selectionForMove[i].split('_'); + const netbootId = parseInt(ids[0]); + const clientId = parseInt(ids[1]); + // Eliminar el id del cliente del netboot origen + const index = this.assignedNetboots[netbootId].indexOf(clientId); + this.assignedNetboots[netbootId].splice(index, 1); + // Se introduce en el netboot seleccionado + if (!this.assignedNetboots[id]) { + this.assignedNetboots[id] = []; + } + this.assignedNetboots[id].push(clientId); + } + // Reiniciar los rangos seleccionados por si los hubiese + this.rangeSelection.start = -1; + this.rangeSelection.end = -1; + + } + + checkSelection(netbootId, clientId) { + if (this.multiSelection === true) { + if (this.rangeSelection.start === -1) { + this.rangeSelection.start = clientId; + } else if (this.rangeSelection.end === -1) { + this.rangeSelection.end = clientId; + // Realizar la seleccion + let start = this.assignedNetboots[netbootId].indexOf(this.rangeSelection.start); + let end = this.assignedNetboots[netbootId].indexOf(this.rangeSelection.end); + if (end < start) { + const tmp = start; + start = end; + end = tmp; + } + this.selectionForMove = []; + for (let index = start; index <= end; index++) { + this.selectionForMove.push(netbootId + '_' + this.assignedNetboots[netbootId][index]); + } + } else { + this.rangeSelection.start = clientId; + this.rangeSelection.end = -1; + } + } else { + this.rangeSelection.start = -1; + this.rangeSelection.end = -1; + } + + } + + save(Form) { + this.netbootService.updateFiles(this.assignedNetboots).subscribe( + (response) => { + this.toaster.pop({type: 'success', title: this.translate.instant('success'), body: this.translate.instant('successfully_updated')}); + this.router.navigate(['app.ous']); + }, + (error) => { + this.toaster.pop({type: 'error', title: 'error', body: error}); + } + ); + } +} diff --git a/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.html b/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.html index 55912dfa..883a13ca 100644 --- a/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.html +++ b/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.html @@ -1,53 +1,91 @@ -<div ui-view>
- <section class="content-header">
- <h1 translate="netboot">
- </h1>
- <ol class="breadcrumb">
- <li><a [routerLink]="'app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li>
- <li class="active" translate="netboot_templates"></li>
- </ol>
- </section>
- <section fixed-toolboxbar class="toolboxbar">
- <div >
- <div class="col-md-12">
- <div class="input-group">
- <input type="text" name="q" class="form-control" placeholder="Search..." [(ngModel)]="searchText">
- <span class="input-group-btn">
- <button type="button" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i>
- </button>
- </span>
- </div>
- </div>
- <div class="col-md-12" style="margin-top: 5px;margin-bottom: 5px;">
- <div class="box-tools pull-right">
- <button class="btn btn-default" [routerLink]="'/app/netboots/create'" translate="new_netboot"></button>
- </div>
- </div>
- </div>
- </section>
- <section class="content">
- <div class="row">
- <div class="col-md-12">
- <table class="table table-hover">
- <tbody><tr>
- <th translate="name"></th>
- <th translate="filename"></th>
- <th translate="options"></th>
- </tr>
- <tr *ngFor="let netboot of netboots; let index = index" class="{{index%2 == 0?'odd':'even'}}">
- <td>
- <span >{{netboot.name}}</span>
- </td>
- <td>
- <span >{{netboot.filename}}</span>
- </td>
- <td class="right">
- <app-table-action [rowData]="netboot" [options]="tableOptions" (edit)="goToNetbootEdit($event.id)" (delete)="deleteNetboot($event.id)"></app-table-action>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </section>
-</div>
+<div ui-view> + <section class="content-header"> + <h1 translate="netboot"> + </h1> + <ol class="breadcrumb"> + <li><a [routerLink]="'app/dashboard'"><i class="fa fa-dashboard"></i> {{'dashboard'|translate}}</a></li> + <li class="active" translate="netboot_templates"></li> + </ol> + </section> + <section fixed-toolboxbar class="toolboxbar"> + <div > + <div class="col-md-12"> + <div class="input-group"> + <input type="text" name="q" class="form-control" placeholder="Search..." [(ngModel)]="searchText"> + <span class="input-group-btn"> + <button type="button" name="search" id="search-btn" class="btn btn-flat"><i class="fa fa-search"></i> + </button> + </span> + </div> + </div> + <div class="col-md-12" style="margin-top: 5px;margin-bottom: 5px;"> + <div class="box-tools pull-right"> + <button class="btn btn-default" [routerLink]="'/app/netboots/create'" translate="new_netboot"></button> + </div> + </div> + </div> + </section> + <section class="content"> + + <mk-tabs> + <mk-tab> + <mk-tab-header><span translate="BIOS"></span></mk-tab-header> + <mk-tab-content> + <div class="row"> + <div class="col-md-12"> + <table class="table table-hover"> + <tbody><tr> + <th translate="name"></th> + <th translate="filename"></th> + <th translate="options"></th> + </tr> + <tr *ngFor="let netboot of biosNetboots; let index = index" class="{{index%2 == 0?'odd':'even'}}"> + <td> + <span >{{netboot.name}}</span> + </td> + <td> + <span >{{netboot.filename}}</span> + </td> + <td class="right"> + <app-table-action [rowData]="netboot" [options]="tableOptions" (edit)="goToNetbootEdit($event.id)" (delete)="deleteNetboot($event.id)"></app-table-action> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </mk-tab-content> + </mk-tab> + <mk-tab> + <mk-tab-header><span translate="UEFI"></span></mk-tab-header> + <mk-tab-content> + <div class="row"> + <div class="col-md-12"> + <table class="table table-hover"> + <tbody><tr> + <th translate="name"></th> + <th translate="filename"></th> + <th translate="options"></th> + </tr> + <tr *ngFor="let netboot of uefiNetboots; let index = index" class="{{index%2 == 0?'odd':'even'}}"> + <td> + <span >{{netboot.name}}</span> + </td> + <td> + <span >{{netboot.filename}}</span> + </td> + <td class="right"> + <app-table-action [rowData]="netboot" [options]="tableOptions" (edit)="goToNetbootEdit($event.id)" (delete)="deleteNetboot($event.id)"></app-table-action> + </td> + </tr> + </tbody> + </table> + </div> + </div> + </mk-tab-content> + </mk-tab> + </mk-tabs> + + + </section> +</div> diff --git a/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.ts b/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.ts index a275e0be..9090710f 100644 --- a/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/netboot/netboot.component.ts @@ -14,7 +14,9 @@ import {Router} from '@angular/router'; }) export class NetbootComponent implements OnInit { searchText: any; - netboots: any[]; + netboots: any[] = []; + biosNetboots: any[] = []; + uefiNetboots: any[] = []; tableOptions: any; // this tells the tabs component which Pages @@ -43,6 +45,14 @@ export class NetbootComponent implements OnInit { this.netbootService.list().subscribe( response => { this.netboots = response; + const self = this; + this.netboots.forEach((netboot) => { + if (netboot.type && netboot.type === 'uefi') { + self.uefiNetboots.push(netboot); + } else { + self.biosNetboots.push(netboot); + } + }); }, error => { this.toaster.pop({type: 'error', title: 'error', body: error}); diff --git a/admin/WebConsole3/frontend/src/app/pages/organizational-unit/edit/organizational-unit-edit.component.ts b/admin/WebConsole3/frontend/src/app/pages/organizational-unit/edit/organizational-unit-edit.component.ts index b65f60b0..dad2a23b 100644 --- a/admin/WebConsole3/frontend/src/app/pages/organizational-unit/edit/organizational-unit-edit.component.ts +++ b/admin/WebConsole3/frontend/src/app/pages/organizational-unit/edit/organizational-unit-edit.component.ts @@ -41,6 +41,7 @@ export class OrganizationalUnitEditComponent implements OnInit { data => { this.constants = data.constants; this.formType = new OrganizationalUnitFormType().getForm(); + this.activatedRoute.paramMap.subscribe( (route: any) => { if (route.params.id) { @@ -54,9 +55,29 @@ export class OrganizationalUnitEditComponent implements OnInit { ); } else { this.ou = new OrganizationalUnit(); - this.ou.networkSettings = new NetworkSettings(); - this.ou.networkSettings.p2pMode = this.constants.ou.options.p2p.modes[0]; - this.ou.networkSettings.mcastMode = this.constants.ou.options.multicast.modes[0]; + this.activatedRoute.queryParams.subscribe( + query => { + if (query.parent) { + // Si viene de un padre, copiamos sus propiedades + this.ou.parent = query.parent; + // @ts-ignore + this.organizationalUnitService.read(this.ou.parent).subscribe( + parent => { + this.ou.networkSettings = parent.networkSettings; + }, + error => { + this.ou.networkSettings = new NetworkSettings(); + this.ou.networkSettings.p2pMode = this.constants.ou.options.p2p.modes[0]; + this.ou.networkSettings.mcastMode = this.constants.ou.options.multicast.modes[0]; + } + ); + } else { + this.ou.networkSettings = new NetworkSettings(); + this.ou.networkSettings.p2pMode = this.constants.ou.options.p2p.modes[0]; + this.ou.networkSettings.mcastMode = this.constants.ou.options.multicast.modes[0]; + } + } + ); } } ); diff --git a/admin/WebConsole3/frontend/src/app/serializer/client.serializer.ts b/admin/WebConsole3/frontend/src/app/serializer/client.serializer.ts index 3b893ada..efce4380 100644 --- a/admin/WebConsole3/frontend/src/app/serializer/client.serializer.ts +++ b/admin/WebConsole3/frontend/src/app/serializer/client.serializer.ts @@ -7,7 +7,7 @@ export class ClientSerializer extends Serializer { // @ts-ignore client.repository = (client.repository && typeof client.repository === 'object') ? client.repository.id : client.repository; // @ts-ignore - client.hardwareProfile = (client.hardwareProfile) ? client.hardwareProfile.id : null; + client.hardwareProfile = (client.hardwareProfile && typeof client.hardwareProfile === 'object') ? client.hardwareProfile.id : client.hardwareProfile; // @ts-ignore client.netboot = (client.netboot && typeof client.netboot === 'object') ? client.netboot.id : client.netboot; return super.toJson(client); diff --git a/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts b/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts index 6b54a896..6194f123 100644 --- a/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts +++ b/admin/WebConsole3/frontend/src/app/service/og-commands.service.ts @@ -7,17 +7,18 @@ import {Router} from '@angular/router'; import {Injectable} from '@angular/core'; import * as _ from 'lodash'; import {environment} from '../../environments/environment'; +import {Execution} from '../model/command'; @Injectable({ providedIn: 'root' }) export class OGCommandsService { public ogInstructions = ''; - public execution: any; + public execution: Execution; private commands: any; constructor(private router: Router, private ogCommonService: OgCommonService, private toaster: ToasterService, private ogSweetAlert: OgSweetAlertService, private commandService: CommandService, private translate: TranslateService) { - this.execution = {}; + this.execution = new Execution(); this.commands = environment.commands; } diff --git a/admin/WebConsole3/frontend/src/app/service/og-common.service.ts b/admin/WebConsole3/frontend/src/app/service/og-common.service.ts index 88c87b08..b04c1def 100644 --- a/admin/WebConsole3/frontend/src/app/service/og-common.service.ts +++ b/admin/WebConsole3/frontend/src/app/service/og-common.service.ts @@ -282,7 +282,7 @@ export class OgCommonService { } else { // Comprobar el tipo de partición dependiendo del código const elements = partitionTable.partitions.filter((element) => (element.id === partition.partitionCode)); - partition.parttype = (elements.length > 0) ? elements[0].type : ''; + partition.type = (elements.length > 0) ? elements[0].type : ''; // Si es cache, actualizar su contenido if (partition.partitionCode === 'ca') { // actualizar el contenido de la cache @@ -351,4 +351,61 @@ export class OgCommonService { array.push(component.id); } } + + getPartitionColor(partition) { + let color = '#c5e72b'; + // Para la partición de datos se usa un color específico + if (this.isDATA(partition)) { + color = 'rgb(237,194,64)'; + } else if (this.isEFI(partition)) { + color = '#bfe4e5'; + } else if (this.isWINDOWS(partition)) { + color = '#00c0ef'; + } else if (this.isLINUXSWAP(partition)) { + color = '#545454'; + } else if (this.isLINUX(partition)) { + color = '#605ca8'; + } else if (this.isCACHE(partition)) { + color = '#FC5A5A'; + } else if (this.isFreeSpace(partition)) { + color = '#bcbcbc'; + } + return color; + } + + isEFI(partition) { + return partition.type === 'EFI'; + } + + isCACHE(partition) { + return partition.type === 'CACHE'; + } + + isEXTENDED(partition) { + return partition.type === 'EXTENDED'; + } + + isWINDOWS(partition) { + return partition.type === 'NTFS' || partition.type === 'WINDOWS'; + } + + isLINUX(partition) { + return typeof partition.type === 'string' && partition.type.includes('LINUX'); + } + + isLINUXSWAP(partition) { + return partition.type === 'LINUX-SWAP'; + } + + isDATA(partition) { + return partition.type === 'DATA'; + } + + isUNKNOWN(partition) { + return partition.type === 'UNKNOWN'; + } + + isFreeSpace(partition) { + return partition.type === 'free_space'; + } } diff --git a/admin/WebConsole3/frontend/src/app/service/og-sweet-alert.service.ts b/admin/WebConsole3/frontend/src/app/service/og-sweet-alert.service.ts index ad63ee1c..ce502a63 100644 --- a/admin/WebConsole3/frontend/src/app/service/og-sweet-alert.service.ts +++ b/admin/WebConsole3/frontend/src/app/service/og-sweet-alert.service.ts @@ -1,51 +1,53 @@ -import {Injectable} from '@angular/core';
-import Swal from 'sweetalert2';
-import {TranslateService} from '@ngx-translate/core';
-
-@Injectable({
- providedIn: 'root'
-})
-export class OgSweetAlertService {
- constructor(private translate: TranslateService) {}
-
- swal(options): Promise<any> {
- return Swal.fire(options);
- }
-
-
- success(title, message) {
- Swal.fire( title, message, 'success' );
- }
-
- error(title, message) {
- Swal.fire( title, message, 'error' );
- }
-
- warning(title, message) {
- Swal.fire( title, message, 'warning' );
- }
-
- info(title, message) {
- Swal.fire( title, message, 'info' );
- }
-
- question(title, message, okcallback?, cancelcallback?) {
- Swal.fire({
- title: title,
- text: message,
- type: 'info',
- showCancelButton: true,
- cancelButtonText: this.translate.instant('no'),
- cancelButtonClass: 'default',
- confirmButtonClass: 'primary',
- confirmButtonText: this.translate.instant('yes')
-
- }).then((response) => {
- if (response.dismiss) {
- cancelcallback(response);
- } else {
- okcallback(response);
- }
- });
- }
-}
+import {Injectable} from '@angular/core'; +import Swal from 'sweetalert2'; +import {TranslateService} from '@ngx-translate/core'; + +@Injectable({ + providedIn: 'root' +}) +export class OgSweetAlertService { + constructor(private translate: TranslateService) {} + + swal(options): Promise<any> { + return Swal.fire(options); + } + + + success(title, message) { + Swal.fire( title, message, 'success' ); + } + + error(title, message) { + Swal.fire( title, message, 'error' ); + } + + warning(title, message) { + Swal.fire( title, message, 'warning' ); + } + + info(title, message) { + Swal.fire( title, message, 'info' ); + } + + question(title, message, okcallback?, cancelcallback?) { + Swal.fire({ + title: title, + text: message, + type: 'info', + showCancelButton: true, + cancelButtonText: this.translate.instant('no'), + cancelButtonClass: 'default', + confirmButtonClass: 'primary', + confirmButtonText: this.translate.instant('yes') + + }).then((response) => { + if (response.dismiss) { + if (typeof cancelcallback === 'function') { + cancelcallback(response); + } + } else { + okcallback(response); + } + }); + } +} diff --git a/admin/WebConsole3/frontend/tslint.json b/admin/WebConsole3/frontend/tslint.json index 7c5f0d65..4ab8d4c2 100644 --- a/admin/WebConsole3/frontend/tslint.json +++ b/admin/WebConsole3/frontend/tslint.json @@ -29,7 +29,7 @@ "label-position": true, "max-line-length": [ true, - 240 + 300 ], "member-access": false, "member-ordering": [ |