Merge pull request 'develop' (#7) from develop into main
Reviewed-on: #7pull/10/head opengnsys_devel-0.0.15
commit
ad0d4c1a40
|
@ -113,8 +113,6 @@ import { CreateSoftwareProfileComponent } from './components/software-profile/cr
|
||||||
import { OperativeSystemComponent } from './components/operative-system/operative-system.component';
|
import { OperativeSystemComponent } from './components/operative-system/operative-system.component';
|
||||||
import { CreateOperativeSystemComponent } from './components/operative-system/create-operative-system/create-operative-system.component';
|
import { CreateOperativeSystemComponent } from './components/operative-system/create-operative-system/create-operative-system.component';
|
||||||
import { ShowTemplateContentComponent } from './components/ogboot/pxe/show-template-content/show-template-content.component';
|
import { ShowTemplateContentComponent } from './components/ogboot/pxe/show-template-content/show-template-content.component';
|
||||||
import { AddClientsToPxeComponent } from './components/ogboot/pxe/add-clients-to-pxe/add-clients-to-pxe.component';
|
|
||||||
import { ClientsComponent } from './components/ogboot/pxe/clients/clients.component';
|
|
||||||
import { RepositoriesComponent } from './components/repositories/repositories.component';
|
import { RepositoriesComponent } from './components/repositories/repositories.component';
|
||||||
import { CreateRepositoryComponent } from './components/repositories/create-repository/create-repository.component';
|
import { CreateRepositoryComponent } from './components/repositories/create-repository/create-repository.component';
|
||||||
import { ExecuteCommandComponent } from './components/commands/main-commands/execute-command/execute-command.component';
|
import { ExecuteCommandComponent } from './components/commands/main-commands/execute-command/execute-command.component';
|
||||||
|
@ -200,8 +198,6 @@ export function HttpLoaderFactory(http: HttpClient) {
|
||||||
OperativeSystemComponent,
|
OperativeSystemComponent,
|
||||||
CreateOperativeSystemComponent,
|
CreateOperativeSystemComponent,
|
||||||
ShowTemplateContentComponent,
|
ShowTemplateContentComponent,
|
||||||
AddClientsToPxeComponent,
|
|
||||||
ClientsComponent,
|
|
||||||
RepositoriesComponent,
|
RepositoriesComponent,
|
||||||
CreateRepositoryComponent,
|
CreateRepositoryComponent,
|
||||||
ExecuteCommandComponent,
|
ExecuteCommandComponent,
|
||||||
|
|
|
@ -42,7 +42,6 @@ table {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100px;
|
height: 100px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin-top: 16px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.mat-elevation-z8 {
|
.mat-elevation-z8 {
|
||||||
|
@ -55,21 +54,15 @@ table {
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.example-headers-align .mat-expansion-panel-header-description {
|
.images-button-row {
|
||||||
justify-content: space-between;
|
display: flex;
|
||||||
align-items: center;
|
justify-content: flex-start;
|
||||||
|
margin-top: 16px;
|
||||||
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.example-headers-align .mat-mdc-form-field + .mat-mdc-form-field {
|
mat-spinner {
|
||||||
margin-left: 8px;
|
margin: 0 auto;
|
||||||
}
|
align-self: center;
|
||||||
|
|
||||||
.button-row {
|
|
||||||
display: table-cell;
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-row .mat-mdc-button-base {
|
|
||||||
margin: 8px 8px 8px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
<mat-accordion class="example-headers-align">
|
|
||||||
<mat-expansion-panel hideToggle>
|
|
||||||
<mat-expansion-panel-header joyrideStep="serverInfoStep" [text]="'serverInfoDescription' | translate">
|
|
||||||
<mat-panel-title>{{ 'serverInfoTitle' | translate }}</mat-panel-title>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
<div class="button-row">
|
|
||||||
<button mat-flat-button color="primary" (click)="syncOgBoot()">{{ 'syncDatabaseButton' | translate }}</button>
|
|
||||||
</div>
|
|
||||||
<div class="button-row">
|
|
||||||
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()">{{ 'viewInfoButton' | translate }}</button>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
</mat-accordion>
|
|
||||||
|
|
||||||
<div class="header-container">
|
<div class="header-container">
|
||||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||||
<mat-icon>help</mat-icon>
|
<mat-icon>help</mat-icon>
|
||||||
|
@ -20,6 +6,7 @@
|
||||||
{{ 'adminImagesTitle' | translate }}
|
{{ 'adminImagesTitle' | translate }}
|
||||||
</h2>
|
</h2>
|
||||||
<div class="images-button-row">
|
<div class="images-button-row">
|
||||||
|
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()">{{ 'viewInfoButton' | translate }}</button>
|
||||||
<button mat-flat-button color="primary" (click)="addImage()" joyrideStep="addImageStep" [text]="'addImageButtonDescription' | translate">
|
<button mat-flat-button color="primary" (click)="addImage()" joyrideStep="addImageStep" [text]="'addImageButtonDescription' | translate">
|
||||||
{{ 'addImageButton' | translate }}
|
{{ 'addImageButton' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
@ -55,7 +42,8 @@
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" [text]="'tableDescription' | translate">
|
<mat-spinner *ngIf="loading"></mat-spinner>
|
||||||
|
<table *ngIf="!loading" mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" [text]="'tableDescription' | translate">
|
||||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ column.header }}</th>
|
<th mat-header-cell *matHeaderCellDef>{{ column.header }}</th>
|
||||||
<td mat-cell *matCellDef="let image">
|
<td mat-cell *matCellDef="let image">
|
||||||
|
@ -78,7 +66,7 @@
|
||||||
|
|
||||||
<ng-container *ngIf="column.columnDef === 'name'">
|
<ng-container *ngIf="column.columnDef === 'name'">
|
||||||
<span matTooltip="{{ image.name }}">
|
<span matTooltip="{{ image.name }}">
|
||||||
{{ image.name ? image.name.substring(0, 20) + '...' : '' }}
|
{{ image.name }}
|
||||||
</span>
|
</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@ -95,8 +83,8 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'actionsColumnHeader' | translate }}</th>
|
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'actionsColumnHeader' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let image" joyrideStep="actionsStep" [text]="'actionsDescription' | translate">
|
<td mat-cell *matCellDef="let image" style="text-align: center;" joyrideStep="actionsStep" [text]="'actionsDescription' | translate">
|
||||||
<button mat-icon-button color="info" (click)="showOgLive($event, image)">
|
<button mat-icon-button color="info" (click)="showOgLive($event, image)">
|
||||||
<mat-icon>{{ 'viewIcon' | translate }}</mat-icon>
|
<mat-icon>{{ 'viewIcon' | translate }}</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
|
@ -110,7 +98,7 @@
|
||||||
<mat-icon>menu</mat-icon>
|
<mat-icon>menu</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #menu="matMenu">
|
<mat-menu #menu="matMenu">
|
||||||
<button mat-menu-item (click)="toggleAction(image, 'install')">{{ 'installOption' | translate }}</button>
|
<button mat-menu-item [disabled]="image.installed" (click)="toggleAction(image, 'install')">{{ 'installOption' | translate }}</button>
|
||||||
<button mat-menu-item [disabled]="!image.installed" (click)="toggleAction(image, 'uninstall')">
|
<button mat-menu-item [disabled]="!image.installed" (click)="toggleAction(image, 'uninstall')">
|
||||||
{{ 'uninstallOption' | translate }}
|
{{ 'uninstallOption' | translate }}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -44,11 +44,6 @@ export class PXEimagesComponent implements OnInit {
|
||||||
header: 'Nombre de imagen',
|
header: 'Nombre de imagen',
|
||||||
cell: (user: any) => `${user.name}`
|
cell: (user: any) => `${user.name}`
|
||||||
},
|
},
|
||||||
{
|
|
||||||
columnDef: 'downloadUrl',
|
|
||||||
header: 'Url descarga',
|
|
||||||
cell: (user: any) => `${user.downloadUrl}`
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
columnDef: 'isDefault',
|
columnDef: 'isDefault',
|
||||||
header: 'Imagen por defecto',
|
header: 'Imagen por defecto',
|
||||||
|
@ -56,7 +51,7 @@ export class PXEimagesComponent implements OnInit {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
columnDef: 'installed',
|
columnDef: 'installed',
|
||||||
header: 'Imagen instalada en ogBoot',
|
header: 'Imagen instalada',
|
||||||
cell: (user: any) => `${user.installed}`
|
cell: (user: any) => `${user.installed}`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -83,8 +78,11 @@ export class PXEimagesComponent implements OnInit {
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.loading = true;
|
||||||
this.search();
|
this.search();
|
||||||
this.loadAlert();
|
this.loadAlert();
|
||||||
|
this.syncOgBoot()
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
addImage(): void {
|
addImage(): void {
|
||||||
|
@ -99,15 +97,12 @@ export class PXEimagesComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
search(): void {
|
search(): void {
|
||||||
this.loading = true;
|
|
||||||
this.dataService.getImages(this.filters).subscribe(
|
this.dataService.getImages(this.filters).subscribe(
|
||||||
data => {
|
data => {
|
||||||
this.dataSource.data = data;
|
this.dataSource.data = data;
|
||||||
this.loading = false;
|
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
console.error('Error fetching og lives', error);
|
console.error('Error fetching og lives', error);
|
||||||
this.loading = false;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -250,7 +245,7 @@ export class PXEimagesComponent implements OnInit {
|
||||||
syncOgBoot(): void {
|
syncOgBoot(): void {
|
||||||
this.http.post(`${this.apiUrl}/sync`, {})
|
this.http.post(`${this.apiUrl}/sync`, {})
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
this.toastService.success('Sincronización completada');
|
this.toastService.success('Sincronización con oGBoot exitosa');
|
||||||
this.search()
|
this.search()
|
||||||
}, error => {
|
}, error => {
|
||||||
console.error('Error al sincronizar', error);
|
console.error('Error al sincronizar', error);
|
||||||
|
@ -261,7 +256,6 @@ export class PXEimagesComponent implements OnInit {
|
||||||
iniciarTour(): void {
|
iniciarTour(): void {
|
||||||
this.joyrideService.startTour({
|
this.joyrideService.startTour({
|
||||||
steps: [
|
steps: [
|
||||||
'serverInfoStep',
|
|
||||||
'titleStep',
|
'titleStep',
|
||||||
'addImageStep',
|
'addImageStep',
|
||||||
'searchNameStep',
|
'searchNameStep',
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
.loading-container {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat-form-field {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
mat-dialog-actions {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
<h2 mat-dialog-title>{{ 'addClientsTitle' | translate: { subnetName: data.subnetName } }}</h2>
|
|
||||||
|
|
||||||
<mat-dialog-content>
|
|
||||||
<mat-form-field appearance="fill" class="search-select">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
matInput
|
|
||||||
[formControl]="clientControl"
|
|
||||||
[matAutocomplete]="clientAuto"
|
|
||||||
[placeholder]="'selectClientPlaceholder' | translate">
|
|
||||||
<mat-autocomplete
|
|
||||||
#clientAuto="matAutocomplete"
|
|
||||||
[displayWith]="displayFnClient"
|
|
||||||
(optionSelected)="onOptionClientSelected($event.option.value)">
|
|
||||||
<mat-option
|
|
||||||
*ngFor="let client of filteredClients | async"
|
|
||||||
[value]="client">
|
|
||||||
{{ client.name }}
|
|
||||||
</mat-option>
|
|
||||||
</mat-autocomplete>
|
|
||||||
</mat-form-field>
|
|
||||||
|
|
||||||
<div *ngIf="selectedClients.length > 0">
|
|
||||||
<h3>{{ 'selectedClientsTitle' | translate }}</h3>
|
|
||||||
<ul>
|
|
||||||
<li *ngFor="let client of selectedClients">
|
|
||||||
{{ client.name }}
|
|
||||||
<button mat-icon-button color="warn" (click)="removeClient(client)">
|
|
||||||
<mat-icon>{{ 'deleteIcon' | translate }}</mat-icon>
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</mat-dialog-content>
|
|
||||||
|
|
||||||
<mat-dialog-actions>
|
|
||||||
<button mat-button (click)="close()">{{ 'cancelButton' | translate }}</button>
|
|
||||||
<button mat-button (click)="save()">{{ 'addButton' | translate }}</button>
|
|
||||||
</mat-dialog-actions>
|
|
|
@ -1,69 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { AddClientsToPxeComponent } from './add-clients-to-pxe.component';
|
|
||||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
|
||||||
import { MatOptionModule } from '@angular/material/core';
|
|
||||||
import { MatDividerModule } from '@angular/material/divider';
|
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
||||||
import { MatProgressSpinner, MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
|
||||||
import { MatTableModule } from '@angular/material/table';
|
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { ToastrModule } from 'ngx-toastr';
|
|
||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
||||||
import { MatDialogModule, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
|
||||||
import { MatListModule } from '@angular/material/list';
|
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
describe('AddClientsToPxeComponent', () => {
|
|
||||||
let component: AddClientsToPxeComponent;
|
|
||||||
let fixture: ComponentFixture<AddClientsToPxeComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [AddClientsToPxeComponent],
|
|
||||||
imports: [
|
|
||||||
HttpClientTestingModule,
|
|
||||||
ToastrModule.forRoot(),
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
MatDividerModule,
|
|
||||||
MatFormFieldModule,
|
|
||||||
MatInputModule,
|
|
||||||
MatIconModule,
|
|
||||||
MatButtonModule,
|
|
||||||
MatTableModule,
|
|
||||||
MatPaginatorModule,
|
|
||||||
MatTooltipModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MatProgressSpinnerModule,
|
|
||||||
MatDialogModule,
|
|
||||||
MatSelectModule,
|
|
||||||
MatTabsModule,
|
|
||||||
MatAutocompleteModule,
|
|
||||||
MatListModule,
|
|
||||||
TranslateModule.forRoot()
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
{ provide: MatDialogRef, useValue: {} },
|
|
||||||
{ provide: MAT_DIALOG_DATA, useValue: {} }
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(AddClientsToPxeComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,98 +0,0 @@
|
||||||
import {Component, Inject} from '@angular/core';
|
|
||||||
import {Observable, startWith} from "rxjs";
|
|
||||||
import {FormControl} from "@angular/forms";
|
|
||||||
import {HttpClient} from "@angular/common/http";
|
|
||||||
import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
import {ToastrService} from "ngx-toastr";
|
|
||||||
import {map} from "rxjs/operators";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-add-clients-to-pxe',
|
|
||||||
templateUrl: './add-clients-to-pxe.component.html',
|
|
||||||
styleUrl: './add-clients-to-pxe.component.css'
|
|
||||||
})
|
|
||||||
export class AddClientsToPxeComponent {
|
|
||||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
|
||||||
clients: any[] = [];
|
|
||||||
selectedClients: any[] = [];
|
|
||||||
loading: boolean = true;
|
|
||||||
filters: { [key: string]: string } = {};
|
|
||||||
filteredClients!: Observable<any[]>;
|
|
||||||
clientControl = new FormControl();
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private http: HttpClient,
|
|
||||||
public dialogRef: MatDialogRef<AddClientsToPxeComponent>,
|
|
||||||
private toastService: ToastrService,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data: { subnetUuid: string, subnetName: string }
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit(): void {
|
|
||||||
this.loading = true;
|
|
||||||
|
|
||||||
this.loadClients();
|
|
||||||
|
|
||||||
this.filteredClients = this.clientControl.valueChanges.pipe(
|
|
||||||
startWith(''),
|
|
||||||
map(value => (typeof value === 'string' ? value : value?.name)),
|
|
||||||
map(name => (name ? this._filterClients(name) : this.clients.slice()))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadClients() {
|
|
||||||
this.http.get<any>( `${this.baseUrl}/clients?&page=1&itemsPerPage=10000&exists[template]=false`).subscribe(
|
|
||||||
response => {
|
|
||||||
this.clients = response['hydra:member'];
|
|
||||||
this.loading = false;
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
console.error('Error fetching parent units:', error);
|
|
||||||
this.loading = false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
save() {
|
|
||||||
const postData = {
|
|
||||||
clients: this.selectedClients.map(client => client['@id'])
|
|
||||||
};
|
|
||||||
|
|
||||||
this.http.post(`${this.baseUrl}/pxe-templates/${this.data.subnetUuid}/add-clients`, postData).subscribe(
|
|
||||||
response => {
|
|
||||||
this.toastService.success('Clientes asignados correctamente');
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
this.toastService.error(error.error['hydra:description']);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.dialogRef.close(this.selectedClients);
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
this.dialogRef.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
removeClient(client: any) {
|
|
||||||
const index = this.selectedClients.indexOf(client);
|
|
||||||
if (index >= 0) {
|
|
||||||
this.selectedClients.splice(index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private _filterClients(name: string): any[] {
|
|
||||||
const filterValue = name.toLowerCase();
|
|
||||||
return this.clients.filter(client => client.name.toLowerCase().includes(filterValue));
|
|
||||||
}
|
|
||||||
|
|
||||||
displayFnClient(client: any): string {
|
|
||||||
return client && client.name ? client.name : '';
|
|
||||||
}
|
|
||||||
|
|
||||||
onOptionClientSelected(client: any) {
|
|
||||||
if (!this.selectedClients.includes(client)) {
|
|
||||||
this.selectedClients.push(client);
|
|
||||||
}
|
|
||||||
this.clientControl.setValue('');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
|
|
||||||
mat-dialog-actions {
|
|
||||||
margin-top: 20px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.green-icon {
|
|
||||||
color: green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.red-icon {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.spacing-container {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list-item-content {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start; /* Alinea el contenido al inicio */
|
|
||||||
justify-content: space-between; /* Espacio entre los textos y los íconos */
|
|
||||||
width: 100%; /* Asegúrate de que el contenido ocupe todo el ancho */
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-content {
|
|
||||||
flex-grow: 1;
|
|
||||||
margin-right: 16px;
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-icon {
|
|
||||||
margin-left: 8px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
<h2 mat-dialog-title>{{ 'manageClientsTitle' | translate }}</h2>
|
|
||||||
<mat-dialog-content>
|
|
||||||
<mat-list>
|
|
||||||
<ng-container *ngFor="let client of clients">
|
|
||||||
<mat-list-item>
|
|
||||||
<div class="list-item-content">
|
|
||||||
<mat-icon matListItemIcon [ngClass]="{'red-icon': client.pxeSync === false || !client.pxeSync, 'green-icon': client.pxeSync === true}">
|
|
||||||
computer
|
|
||||||
</mat-icon>
|
|
||||||
<div class="text-content">
|
|
||||||
<div matListItemTitle>{{ client.name }}</div>
|
|
||||||
<div matListItemLine>{{ client.mac }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="icon-container">
|
|
||||||
<button mat-icon-button color="info" (click)="showInfo(client)">
|
|
||||||
<mat-icon>{{ 'viewIcon' | translate }}</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button mat-icon-button color="primary" (click)="addClientToTemplate(client)">
|
|
||||||
<mat-icon>{{ 'syncIcon' | translate }}</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button mat-icon-button color="warn" class="right-icon" (click)="deleteClient(client)">
|
|
||||||
<mat-icon>{{ 'deleteIcon' | translate }}</mat-icon>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</mat-list-item>
|
|
||||||
</ng-container>
|
|
||||||
</mat-list>
|
|
||||||
</mat-dialog-content>
|
|
||||||
<mat-dialog-actions align="end">
|
|
||||||
<button mat-button type="button" (click)="onCancel()">{{ 'cancelButton' | translate }}</button>
|
|
||||||
</mat-dialog-actions>
|
|
|
@ -1,70 +0,0 @@
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { ClientsComponent } from './clients.component';
|
|
||||||
import { MatInputModule } from '@angular/material/input';
|
|
||||||
import { HttpClientTestingModule } from '@angular/common/http/testing';
|
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
|
||||||
import { MatOptionModule } from '@angular/material/core';
|
|
||||||
import { MatDividerModule } from '@angular/material/divider';
|
|
||||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
|
||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
|
||||||
import { MatProgressSpinner, MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|
||||||
import { MatSelectModule } from '@angular/material/select';
|
|
||||||
import { MatTableModule } from '@angular/material/table';
|
|
||||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { ToastrModule } from 'ngx-toastr';
|
|
||||||
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
|
|
||||||
import { MatAutocompleteModule } from '@angular/material/autocomplete';
|
|
||||||
import { MatListModule } from '@angular/material/list';
|
|
||||||
import { MatTabsModule } from '@angular/material/tabs';
|
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
|
|
||||||
describe('ClientsComponent', () => {
|
|
||||||
let component: ClientsComponent;
|
|
||||||
let fixture: ComponentFixture<ClientsComponent>;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
|
||||||
await TestBed.configureTestingModule({
|
|
||||||
declarations: [ClientsComponent],
|
|
||||||
imports: [
|
|
||||||
HttpClientTestingModule,
|
|
||||||
ToastrModule.forRoot(),
|
|
||||||
BrowserAnimationsModule,
|
|
||||||
MatDividerModule,
|
|
||||||
MatFormFieldModule,
|
|
||||||
MatInputModule,
|
|
||||||
MatIconModule,
|
|
||||||
MatButtonModule,
|
|
||||||
MatTableModule,
|
|
||||||
MatPaginatorModule,
|
|
||||||
MatTooltipModule,
|
|
||||||
FormsModule,
|
|
||||||
ReactiveFormsModule,
|
|
||||||
MatProgressSpinnerModule,
|
|
||||||
MatDialogModule,
|
|
||||||
MatSelectModule,
|
|
||||||
MatTabsModule,
|
|
||||||
MatAutocompleteModule,
|
|
||||||
MatListModule,
|
|
||||||
TranslateModule.forRoot()
|
|
||||||
],
|
|
||||||
providers: [
|
|
||||||
{ provide: MatDialogRef, useValue: {} },
|
|
||||||
{ provide: MAT_DIALOG_DATA, useValue: {data: {id: 123}} }
|
|
||||||
|
|
||||||
]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
|
|
||||||
fixture = TestBed.createComponent(ClientsComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,107 +0,0 @@
|
||||||
import {Component, Inject} from '@angular/core';
|
|
||||||
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
|
|
||||||
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
|
|
||||||
import {HttpClient} from "@angular/common/http";
|
|
||||||
import {ToastrService} from "ngx-toastr";
|
|
||||||
import {DeleteModalComponent} from "../../../../shared/delete_modal/delete-modal/delete-modal.component";
|
|
||||||
import {Observable} from "rxjs";
|
|
||||||
import {
|
|
||||||
ServerInfoDialogComponent
|
|
||||||
} from "../../../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'app-clients',
|
|
||||||
templateUrl: './clients.component.html',
|
|
||||||
styleUrl: './clients.component.css'
|
|
||||||
})
|
|
||||||
export class ClientsComponent {
|
|
||||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
|
||||||
templateForm!: FormGroup;
|
|
||||||
clients: any[] = [];
|
|
||||||
alertMessage: string | null = null;
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
public dialogRef: MatDialogRef<ClientsComponent>,
|
|
||||||
public dialog: MatDialog,
|
|
||||||
private http: HttpClient,
|
|
||||||
private toastService: ToastrService,
|
|
||||||
@Inject(MAT_DIALOG_DATA) public data: any
|
|
||||||
) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.getPxeClients()
|
|
||||||
}
|
|
||||||
|
|
||||||
getPxeClients(): void {
|
|
||||||
this.http.get<any>(`${this.baseUrl}/clients?template.id=${this.data.data.id}`).subscribe({
|
|
||||||
next: data => {
|
|
||||||
this.clients = data['hydra:member']
|
|
||||||
},
|
|
||||||
error: error => {
|
|
||||||
console.error('Error al obtener los clientes PXE:', error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
addClientToTemplate(client: any): void {
|
|
||||||
const postData = {
|
|
||||||
client: client['@id']
|
|
||||||
};
|
|
||||||
|
|
||||||
this.http.post(`${this.baseUrl}/pxe-templates/${this.data.data.uuid}/sync-client`, postData).subscribe(
|
|
||||||
response => {
|
|
||||||
this.toastService.success('Clientes asignados correctamente');
|
|
||||||
this.getPxeClients()
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
this.toastService.error(error.error['hydra:description']);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
loadAlert(client: any): Observable<any> {
|
|
||||||
return this.http.post<any>(`${this.baseUrl}/clients/server/${client.uuid}/get-pxe`, {});
|
|
||||||
}
|
|
||||||
|
|
||||||
showInfo(client:any) {
|
|
||||||
this.loadAlert(client).subscribe(
|
|
||||||
response => {
|
|
||||||
this.alertMessage = response.message;
|
|
||||||
|
|
||||||
this.dialog.open(ServerInfoDialogComponent, {
|
|
||||||
width: '600px',
|
|
||||||
data: {
|
|
||||||
message: this.alertMessage
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
error => {
|
|
||||||
console.error('Error al cargar la información del alert', error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteClient(client: any): void {
|
|
||||||
const dialogRef = this.dialog.open(DeleteModalComponent, {
|
|
||||||
width: '300px',
|
|
||||||
data: { name: client.name }
|
|
||||||
});
|
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
|
||||||
if (result) {
|
|
||||||
this.http.post(`${this.baseUrl}/pxe-templates/${this.data.data.uuid}/delete-client`, { client: client['@id'] }).subscribe({
|
|
||||||
next: () => {
|
|
||||||
this.toastService.success('Cliente eliminado exitosamente');
|
|
||||||
this.dialogRef.close();
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
this.toastService.error(error.error['hydra:description']);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}})
|
|
||||||
}
|
|
||||||
|
|
||||||
onCancel(): void {
|
|
||||||
this.dialogRef.close(false);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -104,8 +104,7 @@ exit`
|
||||||
this.dialogRef.close(true);
|
this.dialogRef.close(true);
|
||||||
},
|
},
|
||||||
error: error => {
|
error: error => {
|
||||||
this.toastService.error('Error al crear la plantilla PXE');
|
this.toastService.error(error.error['hydra:description']);
|
||||||
this.dialogRef.close(false);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ table {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
height: 100px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,27 +42,21 @@ table {
|
||||||
box-shadow: 0px 0px 0px rgba(0,0,0,0.2);
|
box-shadow: 0px 0px 0px rgba(0,0,0,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.template-button-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-top: 16px;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat-spinner {
|
||||||
|
margin: 0 auto;
|
||||||
|
align-self: center;
|
||||||
|
}
|
||||||
|
|
||||||
.paginator-container {
|
.paginator-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: end;
|
justify-content: end;
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.example-headers-align .mat-expansion-panel-header-description {
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example-headers-align .mat-mdc-form-field + .mat-mdc-form-field {
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example-button-row {
|
|
||||||
display: table-cell;
|
|
||||||
max-width: 600px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example-button-row .mat-mdc-button-base {
|
|
||||||
margin: 8px 8px 8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,10 @@
|
||||||
<mat-accordion class="example-headers-align">
|
|
||||||
<mat-expansion-panel hideToggle>
|
|
||||||
<mat-expansion-panel-header joyrideStep="serverInfoStep" text="{{ 'serverInfoDescription' | translate }}">
|
|
||||||
<mat-panel-title>{{ 'serverInfoTitle' | translate }}</mat-panel-title>
|
|
||||||
</mat-expansion-panel-header>
|
|
||||||
<div class="example-button-row">
|
|
||||||
<button mat-flat-button color="primary" (click)="syncTemplates()">{{ 'syncDatabaseButton' | translate }}</button>
|
|
||||||
</div>
|
|
||||||
<div class="example-button-row">
|
|
||||||
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()">{{ 'viewInfoButton' | translate }}</button>
|
|
||||||
</div>
|
|
||||||
</mat-expansion-panel>
|
|
||||||
</mat-accordion>
|
|
||||||
|
|
||||||
<div class="header-container">
|
<div class="header-container">
|
||||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||||
<mat-icon>help</mat-icon>
|
<mat-icon>help</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<h2 class="title" joyrideStep="titleStep" text="{{ 'adminPxeDescription' | translate }}">{{ 'adminPxeTitle' | translate }}</h2>
|
<h2 class="title" joyrideStep="titleStep" text="{{ 'adminPxeDescription' | translate }}">{{ 'adminPxeTitle' | translate }}</h2>
|
||||||
<div class="pxe-button-row">
|
<div class="template-button-row">
|
||||||
|
<button mat-flat-button color="accent" (click)="openInfoDialog()">{{ 'viewInfoButton' | translate }}</button>
|
||||||
<button mat-flat-button color="primary" (click)="addPxeTemplate()" joyrideStep="addTemplateStep" text="{{ 'addTemplateButtonDescription' | translate }}">{{ 'addTemplateButton' | translate }}</button>
|
<button mat-flat-button color="primary" (click)="addPxeTemplate()" joyrideStep="addTemplateStep" text="{{ 'addTemplateButtonDescription' | translate }}">{{ 'addTemplateButton' | translate }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -41,7 +28,8 @@
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="{{ 'tableDescription' | translate }}">
|
<mat-spinner *ngIf="loading"></mat-spinner>
|
||||||
|
<table *ngIf="!loading" mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="{{ 'tableDescription' | translate }}">
|
||||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ column.header }}</th>
|
<th mat-header-cell *matHeaderCellDef>{{ column.header }}</th>
|
||||||
<td mat-cell *matCellDef="let image">
|
<td mat-cell *matCellDef="let image">
|
||||||
|
@ -57,26 +45,17 @@
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-container matColumnDef="actions">
|
<ng-container matColumnDef="actions">
|
||||||
<th mat-header-cell *matHeaderCellDef>{{ 'actionsColumn' | translate }}</th>
|
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'actionsColumn' | translate }}</th>
|
||||||
<td mat-cell *matCellDef="let template">
|
<td mat-cell *matCellDef="let template" style="text-align: center;">
|
||||||
<button mat-icon-button color="info" (click)="showTemplate($event, template)">
|
<button mat-icon-button color="info" (click)="showTemplate($event, template)">
|
||||||
<mat-icon>visibility</mat-icon>
|
<mat-icon>visibility</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button color="info" [disabled]="template.clientsLength === 0" (click)="editClients($event, template)">
|
|
||||||
<mat-icon>computer</mat-icon>
|
|
||||||
</button>
|
|
||||||
<button mat-icon-button color="primary" (click)="editPxeTemplate(template)">
|
<button mat-icon-button color="primary" (click)="editPxeTemplate(template)">
|
||||||
<mat-icon>edit</mat-icon>
|
<mat-icon>edit</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
<button mat-icon-button color="warn" (click)="toggleAction(template, 'delete')">
|
||||||
<mat-icon>menu</mat-icon>
|
<mat-icon>{{ 'deleteIcon' | translate }}</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<mat-menu #menu="matMenu">
|
|
||||||
<button mat-menu-item (click)="toggleAction(template, 'create')">{{ 'createServerButton' | translate }}</button>
|
|
||||||
<button mat-menu-item (click)="addClientsToPxe(template)">{{ 'addClientButton' | translate }}</button>
|
|
||||||
<button mat-menu-item (click)="toggleAction(template, 'sync')">{{ 'syncDatabaseButton' | translate }}</button>
|
|
||||||
<button mat-menu-item (click)="toggleAction(template, 'delete')">{{ 'deleteButton' | translate }}</button>
|
|
||||||
</mat-menu>
|
|
||||||
</td>
|
</td>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
|
|
@ -6,21 +6,12 @@ import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { PageEvent } from '@angular/material/paginator';
|
import { PageEvent } from '@angular/material/paginator';
|
||||||
import { ToastrService } from 'ngx-toastr';
|
import { ToastrService } from 'ngx-toastr';
|
||||||
import { DatePipe } from '@angular/common';
|
import { DatePipe } from '@angular/common';
|
||||||
import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component';
|
|
||||||
import { DataService } from './data.service';
|
import { DataService } from './data.service';
|
||||||
import {
|
|
||||||
ShowOrganizationalUnitComponent
|
|
||||||
} from "../../groups/shared/organizational-units/show-organizational-unit/show-organizational-unit.component";
|
|
||||||
import {ShowTemplateContentComponent} from "./show-template-content/show-template-content.component";
|
import {ShowTemplateContentComponent} from "./show-template-content/show-template-content.component";
|
||||||
import {ServerInfoDialogComponent} from "../../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
|
import {ServerInfoDialogComponent} from "../../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
|
||||||
import {
|
|
||||||
AddClientsToSubnetComponent
|
|
||||||
} from "../../ogdhcp/og-dhcp-subnets/add-clients-to-subnet/add-clients-to-subnet.component";
|
|
||||||
import {Subnet} from "../../ogdhcp/og-dhcp-subnets/og-dhcp-subnets.component";
|
|
||||||
import {AddClientsToPxeComponent} from "./add-clients-to-pxe/add-clients-to-pxe.component";
|
|
||||||
import {Observable} from "rxjs";
|
import {Observable} from "rxjs";
|
||||||
import {ClientsComponent} from "./clients/clients.component";
|
|
||||||
import { JoyrideService } from 'ngx-joyride';
|
import { JoyrideService } from 'ngx-joyride';
|
||||||
|
import {DeleteModalComponent} from "../../../shared/delete_modal/delete-modal/delete-modal.component";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-pxe',
|
selector: 'app-pxe',
|
||||||
|
@ -78,19 +69,20 @@ export class PxeComponent {
|
||||||
) { }
|
) { }
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.loading = true;
|
||||||
this.search();
|
this.search();
|
||||||
|
this.loadAlert()
|
||||||
|
this.syncTemplates()
|
||||||
|
this.loading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
search(): void {
|
search(): void {
|
||||||
this.loading = true;
|
|
||||||
this.dataService.getPxeTemplates(this.filters).subscribe(
|
this.dataService.getPxeTemplates(this.filters).subscribe(
|
||||||
data => {
|
data => {
|
||||||
this.dataSource.data = data;
|
this.dataSource.data = data;
|
||||||
this.loading = false;
|
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
console.error('Error fetching pxe templates', error);
|
console.error('Error fetching pxe templates', error);
|
||||||
this.loading = false;
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -105,6 +97,7 @@ export class PxeComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
editPxeTemplate(template: any) {
|
editPxeTemplate(template: any) {
|
||||||
const dialogRef = this.dialog.open(CreatePxeTemplateComponent, {
|
const dialogRef = this.dialog.open(CreatePxeTemplateComponent, {
|
||||||
data: template, // Pasa los datos del template para edición
|
data: template, // Pasa los datos del template para edición
|
||||||
|
@ -118,40 +111,26 @@ export class PxeComponent {
|
||||||
|
|
||||||
toggleAction(image: any, action: string): void {
|
toggleAction(image: any, action: string): void {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case 'create':
|
|
||||||
this.http.post(`${this.apiUrl}/server/${image.uuid}/post`, {}).subscribe({
|
|
||||||
next: (response) => {
|
|
||||||
this.search();
|
|
||||||
// @ts-ignore
|
|
||||||
this.toastService.success(response.success);
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
this.toastService.error(error.error.error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'sync':
|
|
||||||
this.http.get(`${this.apiUrl}/server/${image.uuid}/get`, {}).subscribe({
|
|
||||||
next: (response) => {
|
|
||||||
this.search();
|
|
||||||
// @ts-ignore
|
|
||||||
this.toastService.success(response.success);
|
|
||||||
},
|
|
||||||
error: (error) => {
|
|
||||||
this.toastService.error(error.error.error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
case 'delete':
|
case 'delete':
|
||||||
|
const dialogRef = this.dialog.open(DeleteModalComponent, {
|
||||||
|
width: '300px',
|
||||||
|
data: { name: image.name }
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogRef.afterClosed().subscribe(result => {
|
||||||
|
if (result) {
|
||||||
this.http.post(`${this.apiUrl}/server/${image.uuid}/delete`, {}).subscribe({
|
this.http.post(`${this.apiUrl}/server/${image.uuid}/delete`, {}).subscribe({
|
||||||
next: () => {
|
next: () => {
|
||||||
this.toastService.success('Plantilla eliminada correctamente');
|
this.toastService.success('Plantilla eliminada exitosamente');
|
||||||
this.search();
|
this.search();
|
||||||
},
|
},
|
||||||
error: (error) => {
|
error: (error) => {
|
||||||
this.toastService.error(error.error.error);
|
console.error('Error al eliminar la subred', error);
|
||||||
|
this.toastService.error(error.error['hydra:description']);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
console.error('Acción no soportada:', action);
|
console.error('Acción no soportada:', action);
|
||||||
|
@ -164,11 +143,6 @@ export class PxeComponent {
|
||||||
const dialogRef = this.dialog.open(ShowTemplateContentComponent, { data: { data }, width: '700px'});
|
const dialogRef = this.dialog.open(ShowTemplateContentComponent, { data: { data }, width: '700px'});
|
||||||
}
|
}
|
||||||
|
|
||||||
editClients(event: MouseEvent, data: any): void {
|
|
||||||
event.stopPropagation();
|
|
||||||
const dialogRef = this.dialog.open(ClientsComponent, { data: { data }, width: '700px'});
|
|
||||||
}
|
|
||||||
|
|
||||||
syncTemplates() {
|
syncTemplates() {
|
||||||
this.http.post(`${this.apiUrl}/sync`, {})
|
this.http.post(`${this.apiUrl}/sync`, {})
|
||||||
.subscribe(response => {
|
.subscribe(response => {
|
||||||
|
@ -180,17 +154,6 @@ export class PxeComponent {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addClientsToPxe(template: Subnet) {
|
|
||||||
const dialogRef = this.dialog.open(AddClientsToPxeComponent, {
|
|
||||||
width: '600px',
|
|
||||||
data: { subnetUuid: template.uuid, subnetName: template.name }
|
|
||||||
});
|
|
||||||
|
|
||||||
dialogRef.afterClosed().subscribe(result => {
|
|
||||||
this.search();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
applyFilter() {
|
applyFilter() {
|
||||||
this.http.get<any>(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}`).subscribe({
|
this.http.get<any>(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}`).subscribe({
|
||||||
next: (response) => {
|
next: (response) => {
|
||||||
|
@ -207,7 +170,7 @@ export class PxeComponent {
|
||||||
return this.http.get<any>(`${this.apiUrl}/server/get-collection`);
|
return this.http.get<any>(`${this.apiUrl}/server/get-collection`);
|
||||||
}
|
}
|
||||||
|
|
||||||
openSubnetInfoDialog() {
|
openInfoDialog() {
|
||||||
this.loadAlert().subscribe(
|
this.loadAlert().subscribe(
|
||||||
response => {
|
response => {
|
||||||
this.alertMessage = response.message;
|
this.alertMessage = response.message;
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<mat-divider class="divider"></mat-divider>
|
|
||||||
<mat-spinner *ngIf="loading"></mat-spinner>
|
<mat-spinner *ngIf="loading"></mat-spinner>
|
||||||
<table *ngIf="!loading" mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Visualiza y administra las subredes listadas según los filtros aplicados.">
|
<table *ngIf="!loading" mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Visualiza y administra las subredes listadas según los filtros aplicados.">
|
||||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"loginError": "Login error: {{error}}",
|
"loginError": "Login error: {{error}}",
|
||||||
"labelUsers": "Users",
|
"labelUsers": "Users",
|
||||||
"labelRoles": "Roles",
|
"labelRoles": "Roles",
|
||||||
"adminImagesTitle": "Manage clients",
|
"adminImagesTitle": "Manage images",
|
||||||
"addUser": "Add users",
|
"addUser": "Add users",
|
||||||
"searchLabel": "Search image name",
|
"searchLabel": "Search image name",
|
||||||
"searchPlaceholder": "Search",
|
"searchPlaceholder": "Search",
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
"loginError": "Login error: {{error}}",
|
"loginError": "Login error: {{error}}",
|
||||||
"labelUsers": "Usuarios",
|
"labelUsers": "Usuarios",
|
||||||
"labelRoles": "Roles",
|
"labelRoles": "Roles",
|
||||||
"adminImagesTitle": "Administrar clientes",
|
"adminImagesTitle": "Administrar OgLives",
|
||||||
"addUser": "Añadir usuarios",
|
"addUser": "Añadir usuarios",
|
||||||
"searchLabel": "Buscar nombre de imagen",
|
"searchLabel": "Buscar nombre de imagen",
|
||||||
"searchPlaceholder": "Búsqueda",
|
"searchPlaceholder": "Búsqueda",
|
||||||
|
|
Loading…
Reference in New Issue