From cf3785d863a940ebb58d1f9f97a96a02e7223c3e Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Mon, 2 Sep 2024 10:07:35 +0200 Subject: [PATCH] Some improvements. Added filter search and refactor --- ogWebconsole/src/app/app-routing.module.ts | 2 +- ogWebconsole/src/app/app.module.ts | 6 +- .../app/components/groups/groups.component.ts | 33 ++++--- .../components/ogboot/images/data.service.ts | 34 ++++++++ .../ogboot/images/images.component.css | 38 ++------ .../ogboot/images/images.component.html | 12 ++- .../ogboot/images/images.component.ts | 69 ++++++--------- .../pxe-boot-files.component.css | 22 +---- .../pxe-boot-files.component.html | 53 +++++++++--- .../pxe-boot-files.component.ts | 68 ++++++++++++--- .../create-pxe-template.component.css | 0 .../create-pxe-template.component.html | 0 .../create-pxe-template.component.spec.ts | 0 .../create-pxe-template.component.ts | 0 .../app/components/ogboot/pxe/data.service.ts | 35 ++++++++ .../edit-pxe-template.component.css | 52 +++++++++++ .../edit-pxe-template.component.html | 0 .../edit-pxe-template.component.spec.ts | 0 .../edit-pxe-template.component.ts | 0 .../ogboot/pxe/{pxe => }/pxe.component.css | 66 ++++++-------- .../ogboot/pxe/{pxe => }/pxe.component.html | 13 ++- .../pxe/{pxe => }/pxe.component.spec.ts | 0 .../ogboot/pxe/{pxe => }/pxe.component.ts | 81 ++++++++--------- .../edit-pxe-template.component.css | 86 ------------------- 24 files changed, 359 insertions(+), 311 deletions(-) create mode 100644 ogWebconsole/src/app/components/ogboot/images/data.service.ts rename ogWebconsole/src/app/components/ogboot/pxe/{pxe/create-pxeTemplate/create-pxe-template => create-pxeTemplate}/create-pxe-template.component.css (100%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe/create-pxeTemplate/create-pxe-template => create-pxeTemplate}/create-pxe-template.component.html (100%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe/create-pxeTemplate/create-pxe-template => create-pxeTemplate}/create-pxe-template.component.spec.ts (100%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe/create-pxeTemplate/create-pxe-template => create-pxeTemplate}/create-pxe-template.component.ts (100%) create mode 100644 ogWebconsole/src/app/components/ogboot/pxe/data.service.ts create mode 100644 ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.css rename ogWebconsole/src/app/components/ogboot/pxe/{pxe => }/edit-pxe-template/edit-pxe-template.component.html (100%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe => }/edit-pxe-template/edit-pxe-template.component.spec.ts (100%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe => }/edit-pxe-template/edit-pxe-template.component.ts (100%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe => }/pxe.component.css (67%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe => }/pxe.component.html (83%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe => }/pxe.component.spec.ts (100%) rename ogWebconsole/src/app/components/ogboot/pxe/{pxe => }/pxe.component.ts (72%) delete mode 100644 ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.css diff --git a/ogWebconsole/src/app/app-routing.module.ts b/ogWebconsole/src/app/app-routing.module.ts index 8c9c96c..432180e 100644 --- a/ogWebconsole/src/app/app-routing.module.ts +++ b/ogWebconsole/src/app/app-routing.module.ts @@ -10,7 +10,7 @@ import { UsersComponent } from './components/admin/users/users/users.component'; import { RolesComponent } from './components/admin/roles/roles/roles.component'; import { GroupsComponent } from './components/groups/groups.component'; import { ImagesComponent } from './components/ogboot/images/images.component'; -import { PxeComponent } from './components/ogboot/pxe/pxe/pxe.component'; +import { PxeComponent } from './components/ogboot/pxe/pxe.component'; import { PxeBootFilesComponent } from './components/ogboot/pxe-boot-files/pxe-boot-files.component'; import {OgbootStatusComponent} from "./components/ogboot/ogboot-status/ogboot-status.component"; import { OgdhcpComponent } from './components/ogdhcp/ogdhcp.component'; diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 2408854..9d6c5ea 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -73,9 +73,9 @@ import { ImagesComponent } from './components/ogboot/images/images.component'; import { CreateImageComponent } from './components/ogboot/images/create-image/create-image/create-image.component'; import { EditImageComponent } from './components/ogboot/images/edit-image/edit-image/edit-image.component'; import { InfoImageComponent } from './components/ogboot/images/info-image/info-image/info-image.component'; -import { PxeComponent } from './components/ogboot/pxe/pxe/pxe.component'; -import { CreatePxeTemplateComponent } from './components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component'; -import { EditPxeTemplateComponent } from './components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component'; +import { PxeComponent } from './components/ogboot/pxe/pxe.component'; +import { CreatePxeTemplateComponent } from './components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component'; +import { EditPxeTemplateComponent } from './components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component'; import { PxeBootFilesComponent } from './components/ogboot/pxe-boot-files/pxe-boot-files.component'; import {MatExpansionPanel, MatExpansionPanelDescription, MatExpansionPanelTitle} from "@angular/material/expansion"; import { OgbootStatusComponent } from './components/ogboot/ogboot-status/ogboot-status.component'; diff --git a/ogWebconsole/src/app/components/groups/groups.component.ts b/ogWebconsole/src/app/components/groups/groups.component.ts index 17f95f7..547b3c2 100644 --- a/ogWebconsole/src/app/components/groups/groups.component.ts +++ b/ogWebconsole/src/app/components/groups/groups.component.ts @@ -26,11 +26,11 @@ import { AcctionsModalComponent } from './acctions-modal/acctions-modal.componen export class GroupsComponent implements OnInit { organizationalUnits: UnidadOrganizativa[] = []; selectedUnidad: UnidadOrganizativa | null = null; - selectedDetail: any | null = null; + selectedDetail: any | null = null; children: any[] = []; breadcrumb: string[] = []; - clientsData: any[] = []; - breadcrumbData: any[] = []; + clientsData: any[] = []; + breadcrumbData: any[] = []; loading:boolean = false; loadingChildren:boolean = false; searchTerm: string = ''; @@ -50,7 +50,7 @@ export class GroupsComponent implements OnInit { page: number = 1; pageSizeOptions: number[] = [5, 10, 25, 100]; selectedElements: any[] = []; - isAllSelected: boolean = false; + isAllSelected: boolean = false; constructor( @@ -82,26 +82,25 @@ export class GroupsComponent implements OnInit { this.dataService.getOrganizationalUnits(this.searchTerm).subscribe( data => { this.organizationalUnits = data; - this.loading = false; + this.loading = false; }, error => { console.error('Error fetching unidades organizativas', error); - this.loading = false; + this.loading = false; } ); } - onSelectUnidad(unidad: UnidadOrganizativa): void { this.selectedUnidad = unidad; - this.selectedDetail = unidad; + this.selectedDetail = unidad; this.breadcrumb = [unidad.name]; this.breadcrumbData = [unidad]; this.loadChildrenAndClients(unidad.id); } onSelectChild(child: any): void { - this.selectedDetail = child; + this.selectedDetail = child; if (child.type !== 'client' && child.uuid && child.id) { this.breadcrumb.push(child.name || child.name); this.breadcrumbData.push(child); @@ -127,27 +126,27 @@ export class GroupsComponent implements OnInit { console.log('Children data:', childrenData); this.dataService.getClients(id).subscribe( clientsData => { - this.clientsData = clientsData; + this.clientsData = clientsData; const newChildren = [...childrenData, ...clientsData]; if (newChildren.length > 0) { this.children = newChildren; } else { - this.children = []; + this.children = []; } this.loadingChildren = false }, error => { console.error('Error fetching clients', error); - this.clientsData = []; - this.children = []; + this.clientsData = []; + this.children = []; this.loadingChildren = false } ); }, error => { console.error('Error fetching children', error); - this.children = []; + this.children = []; this.loadingChildren = false } ); @@ -369,7 +368,7 @@ export class GroupsComponent implements OnInit { this.selectedFilterStatus = response.filters.filter4 || []; this.filterIP = response.filters.filter5 || ''; this.filterMAC = response.filters.filter6 || ''; - + this.applyFilter(); } }, error => { @@ -378,7 +377,7 @@ export class GroupsComponent implements OnInit { } - + onCheckboxChange(event: any, name: string, uuid: string) { if (event.checked) { this.selectedElements.push({ name, uuid }); @@ -412,5 +411,5 @@ export class GroupsComponent implements OnInit { sendActions() { const dialogRef = this.dialog.open(AcctionsModalComponent, { data: { selectedElements: this.selectedElements }, width: '700px'}); } - + } diff --git a/ogWebconsole/src/app/components/ogboot/images/data.service.ts b/ogWebconsole/src/app/components/ogboot/images/data.service.ts new file mode 100644 index 0000000..871d266 --- /dev/null +++ b/ogWebconsole/src/app/components/ogboot/images/data.service.ts @@ -0,0 +1,34 @@ +import { Injectable } from '@angular/core'; +import {HttpClient, HttpParams} from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class DataService { + private apiUrl = 'http://127.0.0.1:8080/og-lives?page=1&itemsPerPage=1000'; + + constructor(private http: HttpClient) {} + + getImages(search: string = ''): Observable { + let url = `${this.apiUrl}`; + if (search) { + url += `&name=${encodeURIComponent(search)}`; + } + + return this.http.get(url).pipe( + map(response => { + if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { + return response['hydra:member']; + } else { + throw new Error('Unexpected response format'); + } + }), + catchError(error => { + console.error('Error fetching images', error); + return throwError(error); + }) + ); + } +} diff --git a/ogWebconsole/src/app/components/ogboot/images/images.component.css b/ogWebconsole/src/app/components/ogboot/images/images.component.css index 1ae51cc..b1c07c2 100644 --- a/ogWebconsole/src/app/components/ogboot/images/images.component.css +++ b/ogWebconsole/src/app/components/ogboot/images/images.component.css @@ -1,11 +1,3 @@ -.header-container { - display: flex; - justify-content: space-between; - align-items: center; - height: 100px; - padding: 10px; -} - .title { font-size: 24px; } @@ -16,11 +8,6 @@ margin-top: 16px; } -button { - margin-left: 10px; - margin-bottom: 20px; -} - .divider { margin: 20px 0; } @@ -50,33 +37,26 @@ button { flex: 1; } -.mat-icon-button { - margin-left: 16px; - align-self: center; +.image-name{ + cursor: pointer; } -.mat-menu { - min-width: 160px; -} - - .image-name{ - cursor: pointer; - } - table { width: 100%; margin-top: 50px; } +.search-container mat-form-field { + width: 100%; +} + .header-container { - margin-top: 16px; display: flex; justify-content: space-between; align-items: center; -} - -.header-container h1 { - margin: 0; + height: 100px; + padding: 10px; + margin-top: 16px; } .mat-elevation-z8 { diff --git a/ogWebconsole/src/app/components/ogboot/images/images.component.html b/ogWebconsole/src/app/components/ogboot/images/images.component.html index 2bd1513..ae2d6d8 100644 --- a/ogWebconsole/src/app/components/ogboot/images/images.component.html +++ b/ogWebconsole/src/app/components/ogboot/images/images.component.html @@ -22,27 +22,32 @@ +
+ + Buscar nombre de imagen + + search + Pulsar 'enter' para buscar + +
-
{{ column.header }} - {{ image[column.columnDef] ? 'check_circle' : 'cancel' }} - {{ image.downloadUrl ? image.downloadUrl.substring(0, 20) + '...' : '' }} - {{ column.cell(image) }} @@ -50,7 +55,6 @@ Acciones diff --git a/ogWebconsole/src/app/components/ogboot/images/images.component.ts b/ogWebconsole/src/app/components/ogboot/images/images.component.ts index 7ccfc76..1ce2ab0 100644 --- a/ogWebconsole/src/app/components/ogboot/images/images.component.ts +++ b/ogWebconsole/src/app/components/ogboot/images/images.component.ts @@ -9,6 +9,7 @@ import {PageEvent} from "@angular/material/paginator"; import {ToastrService} from "ngx-toastr"; import { DatePipe } from "@angular/common"; import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component'; +import {DataService} from "./data.service"; @Component({ selector: 'app-images', @@ -23,6 +24,8 @@ export class ImagesComponent implements OnInit { page: number = 1; pageSizeOptions: number[] = [5, 10, 20, 40, 100]; selectedElements: string[] = []; + loading:boolean = false; + searchTerm: string = ''; alertMessage: string | null = null; readonly panelOpenState = signal(false); datePipe: DatePipe = new DatePipe('es-ES'); @@ -65,26 +68,15 @@ export class ImagesComponent implements OnInit { constructor( public dialog: MatDialog, private http: HttpClient, + private dataService: DataService, private toastService: ToastrService - ) {} + ) {} ngOnInit(): void { - this.loadImages(); + this.search(); this.loadAlert(); } - loadImages(): void { - this.http.get(`${this.apiUrl}?page=1&itemsPerPage=${this.itemsPerPage}`).subscribe({ - next: (response) => { - this.dataSource.data = response['hydra:member']; - this.length = response['hydra:totalItems']; - }, - error: (error) => { - console.error('Error al cargar las imágenes:', error); - } - }); - } - addImage(): void { const dialogRef = this.dialog.open(CreateImageComponent, { width: '400px' @@ -92,10 +84,24 @@ export class ImagesComponent implements OnInit { dialogRef.afterClosed().subscribe(result => { console.log('The dialog was closed'); - this.loadImages(); // Opcional: recargar imágenes después de añadir una nueva + this.search(); }); } + search(): void { + this.loading = true; + this.dataService.getImages(this.searchTerm).subscribe( + data => { + this.dataSource.data = data; + this.loading = false; + }, + error => { + console.error('Error fetching og lives', error); + this.loading = false; + } + ); + } + showInfo(image: any): void { const dialogRef = this.dialog.open(InfoImageComponent, { width: '700px', @@ -110,7 +116,7 @@ export class ImagesComponent implements OnInit { next: () => { console.log('Imagen cambiada'); this.toastService.success('Petición de cambio de imagen enviada'); - this.loadImages(); + this.search(); }, error: (error) => { console.error('Error al cambiar la imagen:', error); @@ -123,7 +129,7 @@ export class ImagesComponent implements OnInit { next: () => { console.log('Imagen cambiada'); this.toastService.success('Petición de instalación enviada'); - this.loadImages(); + this.search(); }, error: (error) => { console.error('Error al instalar la imagen:', error); @@ -137,7 +143,7 @@ export class ImagesComponent implements OnInit { console.log('Imagen cambiada'); this.toastService.success('Petición de desinstalación enviada'); /* this.deleteImage(image); */ - this.loadImages(); + this.search(); }, error: (error) => { console.error('Error al desinstalar la imagen:', error); @@ -151,29 +157,6 @@ export class ImagesComponent implements OnInit { } } - deleteImage(image: any): void { - const dialogRef = this.dialog.open(DeleteModalComponent, { - width: '300px', - data: { name: image.name } - }); - - dialogRef.afterClosed().subscribe(result => { - if (result) { - this.http.delete(`${this.apiUrl}/${image.uuid}`).subscribe({ - next: () => { - console.log('Imagen eliminada'); - this.toastService.success('Image deleted successfully'); - this.loadImages(); - }, - error: (error) => { - console.error('Error al eliminar la imagen:', error); - } - }); - } else { - console.log('Eliminación de imagen cancelada'); - } - }); } - editImage(image: any): void { const dialogRef = this.dialog.open(EditImageComponent, { width: '700px', @@ -182,7 +165,7 @@ export class ImagesComponent implements OnInit { dialogRef.afterClosed().subscribe(result => { if (result) { - this.loadImages(); + this.search(); } }); } @@ -227,7 +210,7 @@ export class ImagesComponent implements OnInit { this.http.post(`${this.apiUrl}/sync`, {}) .subscribe(response => { this.toastService.success('Sincronización completada'); - this.loadImages() + this.search() }, error => { console.error('Error al sincronizar', error); this.toastService.error('Error al sincronizar'); diff --git a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.css b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.css index c26379f..2bdc07b 100644 --- a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.css +++ b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.css @@ -2,7 +2,9 @@ display: flex; justify-content: space-between; align-items: center; + height: 100px; padding: 10px; + margin-top: 16px; } .title { @@ -15,11 +17,6 @@ margin-top: 16px; } -button { - margin-left: 10px; - margin-bottom: 20px; -} - .divider { margin: 20px 0; } @@ -54,26 +51,13 @@ button { align-self: center; } -.mat-menu { - min-width: 160px; -} - .template-name{ cursor: pointer; } table { width: 100%; -} - -.header-container { - display: flex; - justify-content: space-between; - align-items: center; -} - -.header-container h1 { - margin: 0; + margin-top: 50px; } .mat-elevation-z8 { diff --git a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.html b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.html index 7ed0c5f..c2c4c84 100644 --- a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.html +++ b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.html @@ -1,27 +1,60 @@ + + + + Sincronización ogBoot + + {{ getIcon().name }} + + +

Oglives creados en servidor ogBoot: {{ alertMessage }}

+

Oglives creados en servidor ogCore (base de datos): {{ length }}

+ +
+ +
+
+
+

Administrar ficheros de arranque PXE

+ - - + - diff --git a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.ts b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.ts index 573dca2..b4350b1 100644 --- a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.ts +++ b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/pxe-boot-files.component.ts @@ -2,9 +2,11 @@ import { Component } from '@angular/core'; import {MatTableDataSource} from "@angular/material/table"; import {MatDialog} from "@angular/material/dialog"; import {HttpClient} from "@angular/common/http"; -import { CreatePxeTemplateComponent } from '../pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component'; -import { EditPxeTemplateComponent } from '../pxe/pxe/edit-pxe-template/edit-pxe-template.component'; +import { CreatePxeTemplateComponent } from '../pxe/create-pxeTemplate/create-pxe-template.component'; +import { EditPxeTemplateComponent } from '../pxe/edit-pxe-template/edit-pxe-template.component'; import {PageEvent} from "@angular/material/paginator"; +import {ToastrService} from "ngx-toastr"; +import {DatePipe} from "@angular/common"; @Component({ selector: 'app-pxe-boot-files', @@ -16,9 +18,11 @@ export class PxeBootFilesComponent { currentPage: number = 1; dataSource = new MatTableDataSource(); length: number = 0; + alertMessage: string | null = null; itemsPerPage: number = 10; page: number = 1; pageSizeOptions: number[] = [5, 10, 20, 40, 100]; + datePipe: DatePipe = new DatePipe('es-ES'); selectedElements: string[] = []; columns = [ { @@ -27,27 +31,38 @@ export class PxeBootFilesComponent { cell: (user: any) => `${user.id}` }, { - columnDef: 'name', + columnDef: 'templateName', header: 'Nombre de la plantilla', - cell: (user: any) => `${user.name}` + cell: (user: any) => `${user.template.name}` + }, + { + columnDef: 'clients', + header: 'Clientes', + cell: (user: any) => user.clients }, { columnDef: 'createdAt', header: 'Fecha de creación', - cell: (user: any) => `${user.createdAt}` + cell: (user: any) => `${this.datePipe.transform(user.createdAt, 'dd/MM/yyyy hh:mm:ss')}` } ]; displayedColumns = [...this.columns.map(column => column.columnDef), 'actions']; private apiUrl = 'http://127.0.0.1:8080/pxe-boot-files'; - constructor(public dialog: MatDialog, private http: HttpClient) { } + constructor( + public dialog: MatDialog, + private http: HttpClient, + private toastService: ToastrService + ) + { } ngOnInit(): void { - this.loadPxeTemplates(); + this.loadPxeBootFiles(); + this.loadAlert(); } - loadPxeTemplates(): void { + loadPxeBootFiles(): void { this.http.get(`${this.apiUrl}?page=1&itemsPerPage=${this.itemsPerPage}`).subscribe({ next: (response) => { this.dataSource.data = response['hydra:member']; @@ -65,7 +80,7 @@ export class PxeBootFilesComponent { }); dialogRef.afterClosed().subscribe(() => { - this.loadPxeTemplates(); + this.loadPxeBootFiles(); }); } @@ -79,7 +94,7 @@ export class PxeBootFilesComponent { this.http.post(`${this.apiUrl}/server/${image.uuid}/post`, {}).subscribe({ next: () => { console.log('Plantilla cambiada'); - this.loadPxeTemplates(); + this.loadPxeBootFiles(); }, error: (error) => { console.error('Error al cambiar la imagen:', error); @@ -90,7 +105,7 @@ export class PxeBootFilesComponent { this.http.post(`${this.apiUrl}/server/${image.uuid}/delete`, {}).subscribe({ next: () => { console.log('Plantilla cambiada'); - this.loadPxeTemplates(); + this.loadPxeBootFiles(); }, error: (error) => { console.error('Error al cambiar la imagen:', error); @@ -113,7 +128,7 @@ export class PxeBootFilesComponent { }); dialogRef.afterClosed().subscribe(() => { - this.loadPxeTemplates(); + this.loadPxeBootFiles(); }); } @@ -135,4 +150,33 @@ export class PxeBootFilesComponent { this.applyFilter(); } + loadAlert() { + this.http.get(`${this.apiUrl}/server/get-collection`) + .subscribe(response => { + // @ts-ignore + this.alertMessage = response.templates.length + }, error => { + console.error('Error al cargar la información del alert', error); + }); + } + + getIcon(): { name: string, color: string } { + if (Number(this.alertMessage) === this.length) { + return { name: 'check_circle', color: 'green' }; // Icono de check verde + } else { + return { name: 'cancel', color: 'red' }; // Icono de cruz roja + } + } + + syncOgCore(): void { + this.http.post(`${this.apiUrl}/sync`, {}) + .subscribe(response => { + this.toastService.success('Sincronización completada'); + this.loadPxeBootFiles() + }, error => { + console.error('Error al sincronizar', error); + this.toastService.error('Error al sincronizar'); + }); + } + } diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.css b/ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.css similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.css rename to ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.css diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.html b/ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.html similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.html rename to ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.html diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.spec.ts b/ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.spec.ts similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.spec.ts rename to ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.spec.ts diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.ts b/ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.ts similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/create-pxeTemplate/create-pxe-template/create-pxe-template.component.ts rename to ogWebconsole/src/app/components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component.ts diff --git a/ogWebconsole/src/app/components/ogboot/pxe/data.service.ts b/ogWebconsole/src/app/components/ogboot/pxe/data.service.ts new file mode 100644 index 0000000..10b7621 --- /dev/null +++ b/ogWebconsole/src/app/components/ogboot/pxe/data.service.ts @@ -0,0 +1,35 @@ + +import { Injectable } from '@angular/core'; +import {HttpClient, HttpParams} from '@angular/common/http'; +import { Observable, throwError } from 'rxjs'; +import { catchError, map } from 'rxjs/operators'; + +@Injectable({ + providedIn: 'root' +}) +export class DataService { + private apiUrl = 'http://127.0.0.1:8080/pxe-templates?page=1&itemsPerPage=1000'; + + constructor(private http: HttpClient) {} + + getPxeTemplates(search: string = ''): Observable { + let url = `${this.apiUrl}`; + if (search) { + url += `&name=${encodeURIComponent(search)}`; + } + + return this.http.get(url).pipe( + map(response => { + if (response['hydra:member'] && Array.isArray(response['hydra:member'])) { + return response['hydra:member']; + } else { + throw new Error('Unexpected response format'); + } + }), + catchError(error => { + console.error('Error fetching pxe templates', error); + return throwError(error); + }) + ); + } +} diff --git a/ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.css b/ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.css new file mode 100644 index 0000000..d56d90c --- /dev/null +++ b/ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.css @@ -0,0 +1,52 @@ +form { + max-width: 600px; + margin: 20px auto; + padding: 20px; +} + +mat-form-field { + width: 100%; + margin-bottom: 20px; +} + +pre { + background-color: #eceff1; + padding: 15px; + border-radius: 4px; + white-space: pre-wrap; + word-wrap: break-word; + font-size: 0.9rem; + color: #333; +} + +mat-dialog-actions { + margin-top: 20px; + display: flex; + justify-content: flex-end; +} + +button { + margin-left: 10px; +} + +button[type="submit"] { + background-color: #3f51b5; + color: #fff; +} + +button[type="submit"]:disabled { + background-color: #c5cae9; +} + +h2 { + margin-bottom: 20px; + font-size: 1.5rem; + color: #000000; + text-align: center; +} + +h3 { + margin-top: 30px; + font-size: 1.2rem; + color: #000000; +} diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.html b/ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.html similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.html rename to ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.html diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.spec.ts b/ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.spec.ts similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.spec.ts rename to ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.spec.ts diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.ts b/ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.ts similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.ts rename to ogWebconsole/src/app/components/ogboot/pxe/edit-pxe-template/edit-pxe-template.component.ts diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.css b/ogWebconsole/src/app/components/ogboot/pxe/pxe.component.css similarity index 67% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.css rename to ogWebconsole/src/app/components/ogboot/pxe/pxe.component.css index f567f1c..26df947 100644 --- a/ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.css +++ b/ogWebconsole/src/app/components/ogboot/pxe/pxe.component.css @@ -1,26 +1,16 @@ .header-container { - display: flex; - justify-content: space-between; - align-items: center; - height: 100px; - padding: 10px; + display: flex; + justify-content: space-between; + align-items: center; + height: 100px; + padding: 10px; + margin-top: 16px; } .title { font-size: 24px; } -.templates-button-row { - display: flex; - justify-content: flex-start; - margin-top: 16px; -} - -button { - margin-left: 10px; - margin-bottom: 20px; -} - .divider { margin: 20px 0; } @@ -55,10 +45,6 @@ button { align-self: center; } -.mat-menu { - min-width: 160px; -} - .template-name{ cursor: pointer; } @@ -68,6 +54,10 @@ table { margin-top: 50px; } +.search-container mat-form-field { + width: 100%; +} + .header-container { margin-top: 16px; display: flex; @@ -75,10 +65,6 @@ table { align-items: center; } -.header-container h1 { - margin: 0; -} - .mat-elevation-z8 { box-shadow: 0px 0px 0px rgba(0,0,0,0.2); } @@ -90,28 +76,28 @@ table { } .info-container { - background-color: #e8eaf6; - padding: 16px; - border-radius: 4px; - font-size: 14px; - overflow-x: auto; - margin-top: 16px; - border: 1px solid #c5cae9; + background-color: #e8eaf6; + padding: 16px; + border-radius: 4px; + font-size: 14px; + overflow-x: auto; + margin-top: 16px; + border: 1px solid #c5cae9; } .info-container h3 { margin-top: 0; - font-size: 16px; - color: #000000; + font-size: 16px; + color: #000000; } .info-container p { - margin: 8px 0; - line-height: 1.5; + margin: 8px 0; + line-height: 1.5; } .info-container strong { - color: #0d47a1; + color: #0d47a1; } .info-container { @@ -140,12 +126,12 @@ table { } .info-container pre { - background-color: #f5f5f5; + background-color: #f5f5f5; padding: 16px; border-radius: 4px; - font-size: 12px; - overflow-x: auto; - white-space: pre; + font-size: 12px; + overflow-x: auto; + white-space: pre; border: 1px solid #dcdcdc; } diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.html b/ogWebconsole/src/app/components/ogboot/pxe/pxe.component.html similarity index 83% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.html rename to ogWebconsole/src/app/components/ogboot/pxe/pxe.component.html index eb2425f..f2be751 100644 --- a/ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.html +++ b/ogWebconsole/src/app/components/ogboot/pxe/pxe.component.html @@ -8,6 +8,9 @@

Plantillas creadsa en servidor ogBoot: {{ alertMessage }}

Plantillas creadsa en servidor ogCore (base de datos): {{ length }}

+
+ +
@@ -18,6 +21,14 @@ +
+ + Buscar nombre de plantilla + + search + Pulsar 'enter' para buscar + +
{{ column.header }} - {{ column.cell(image) }} + {{column.header}} + + + + + + + + + + {{column.cell(element)}} + {{ column.cell(user) }} Acciones - - - -
@@ -66,4 +77,4 @@

Detalles de {{ selectedItem.name }}

{{ previewContent }}
-
\ No newline at end of file + diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.spec.ts b/ogWebconsole/src/app/components/ogboot/pxe/pxe.component.spec.ts similarity index 100% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.spec.ts rename to ogWebconsole/src/app/components/ogboot/pxe/pxe.component.spec.ts diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.ts b/ogWebconsole/src/app/components/ogboot/pxe/pxe.component.ts similarity index 72% rename from ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.ts rename to ogWebconsole/src/app/components/ogboot/pxe/pxe.component.ts index 3a0ae77..ee6e2ec 100644 --- a/ogWebconsole/src/app/components/ogboot/pxe/pxe/pxe.component.ts +++ b/ogWebconsole/src/app/components/ogboot/pxe/pxe.component.ts @@ -1,13 +1,14 @@ import { HttpClient } from '@angular/common/http'; import { Component } from '@angular/core'; -import { CreatePxeTemplateComponent } from './create-pxeTemplate/create-pxe-template/create-pxe-template.component'; +import { CreatePxeTemplateComponent } from './create-pxeTemplate/create-pxe-template.component'; import { MatDialog } from '@angular/material/dialog'; import { EditPxeTemplateComponent } from './edit-pxe-template/edit-pxe-template.component'; import {MatTableDataSource} from "@angular/material/table"; import {PageEvent} from "@angular/material/paginator"; import {ToastrService} from "ngx-toastr"; import {DatePipe} from "@angular/common"; -import { DeleteModalComponent } from '../../../../shared/delete_modal/delete-modal/delete-modal.component'; +import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component'; +import {DataService} from "./data.service"; @Component({ selector: 'app-pxe', @@ -15,7 +16,7 @@ import { DeleteModalComponent } from '../../../../shared/delete_modal/delete-mod styleUrl: './pxe.component.css' }) export class PxeComponent { - pxeTemplates: any[] = []; + pxeTemplates: any[] = []; currentPage: number = 1; dataSource = new MatTableDataSource(); length: number = 0; @@ -23,6 +24,8 @@ export class PxeComponent { page: number = 1; pageSizeOptions: number[] = [5, 10, 20, 40, 100]; selectedElements: string[] = []; + loading:boolean = false; + searchTerm: string = '' alertMessage: string | null = null; datePipe: DatePipe = new DatePipe('es-ES'); selectedItem: any = null; @@ -57,24 +60,26 @@ export class PxeComponent { public dialog: MatDialog, private http: HttpClient, private toastService: ToastrService, + private dataService: DataService ) { } ngOnInit(): void { - this.loadPxeTemplates(); - this.loadAlert() + this.search() + this.loadAlert(); } - loadPxeTemplates(): void { - this.http.get(`${this.apiUrl}?page=1&itemsPerPage=${this.itemsPerPage}`).subscribe({ - next: (response) => { - this.dataSource.data = response['hydra:member']; - this.length = response['hydra:totalItems']; - console.log('Plantillas PXE cargadas:', this.pxeTemplates); + search(): void { + this.loading = true; + this.dataService.getPxeTemplates(this.searchTerm).subscribe( + data => { + this.dataSource.data = data; + this.loading = false; }, - error: error => { - console.error('Error al cargar plantillas PXE:', error); + error => { + console.error('Error fetching pxe templates', error); + this.loading = false; } - }); + ); } addPxeTemplate() { @@ -83,7 +88,7 @@ export class PxeComponent { }); dialogRef.afterClosed().subscribe(() => { - this.loadPxeTemplates(); + this.search(); }); } @@ -98,7 +103,7 @@ export class PxeComponent { case 'create': this.http.post(`${this.apiUrl}/server/${image.uuid}/post`, {}).subscribe({ next: (response) => { - this.loadPxeTemplates(); + this.search(); // @ts-ignore this.toastService.success(response.message); }, @@ -111,7 +116,7 @@ export class PxeComponent { this.http.post(`${this.apiUrl}/server/${image.uuid}/delete`, {}).subscribe({ next: () => { console.log('Plantilla cambiada'); - this.loadPxeTemplates(); + this.search(); }, error: (error) => { console.error('Error al cambiar la imagen:', error); @@ -124,40 +129,14 @@ export class PxeComponent { } } - deletePxeTemplate(template: any) { - // Lógica para eliminar una plantilla - const dialogRef = this.dialog.open(DeleteModalComponent, { - width: '300px' - }); - - console.log('Eliminando pxe:', template.uuid); - - dialogRef.afterClosed().subscribe(result => { - if (result) { - this.http.delete(`http://127.0.0.1:8080/pxe-templates/${template.uuid}`).subscribe({ - next: () => { - console.log('pxe eliminado'); - this.toastService.success('PXE deleted successfully'); - this.loadPxeTemplates(); - }, - error: (error) => { - console.error('Error al eliminar la pxe:', error); - } - }); - } else { - console.log('Eliminación de pxe cancelada'); - } - }); - - } - editPxeTemplate(template: any) { const dialogRef = this.dialog.open(EditPxeTemplateComponent, { - data: template + data: template, + width: '600px' }); dialogRef.afterClosed().subscribe(() => { - this.loadPxeTemplates(); + this.search(); }); } @@ -197,4 +176,14 @@ export class PxeComponent { } } + syncOgCore(): void { + this.http.post(`${this.apiUrl}/sync`, {}) + .subscribe(response => { + this.toastService.success('Sincronización completada'); + this.search() + }, error => { + console.error('Error al sincronizar', error); + this.toastService.error('Error al sincronizar'); + }); + } } diff --git a/ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.css b/ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.css deleted file mode 100644 index e991549..0000000 --- a/ogWebconsole/src/app/components/ogboot/pxe/pxe/edit-pxe-template/edit-pxe-template.component.css +++ /dev/null @@ -1,86 +0,0 @@ -mat-form-field { - width: 100%; - margin-bottom: 16px; - padding: 5px; - } - - .button-group { - display: flex; - justify-content: space-between; - } - - button { - width: 48%; - } - - :host { - display: block; - padding: 20px; - background-color: #f5f5f5; - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); -} - -.mat-form-field { - width: 100%; - margin-bottom: 16px; -} - -.mat-step-label { - font-weight: bold; - font-size: 1.1em; -} - -button { - margin: 8px 0; -} - -.mat-stepper-header { - background-color: #fff; - padding: 16px; - border-bottom: 1px solid #e0e0e0; - border-radius: 8px 8px 0 0; -} - -.mat-stepper-horizontal-line { - border-color: #3f51b5; -} - -.mat-stepper-horizontal { - background-color: #fff; - padding: 0; - border-radius: 8px; - overflow: hidden; -} - -.mat-step-header { - background-color: #e8eaf6; - color: #3f51b5; -} - -.mat-step-header .mat-step-icon { - background-color: #3f51b5; - color: #fff; -} - -.mat-stepper-content { - padding: 16px; - background-color: #fff; - border-radius: 0 0 8px 8px; -} - -pre { - background-color: #e8eaf6; - padding: 16px; - border-radius: 4px; - font-size: 12px; - overflow-x: auto; -} - -.mat-raised-button { - margin-right: 8px; -} - -.mat-button { - margin-right: 8px; -}
{{ column.header }}