diff --git a/ogWebconsole/.env b/ogWebconsole/.env index 454cc0f..3e0dde5 100644 --- a/ogWebconsole/.env +++ b/ogWebconsole/.env @@ -1,2 +1 @@ -#NG_APP_BASE_API_URL=http://127.0.0.1:8090 -NG_APP_BASE_API_URL=http://127.0.0.1:8080 +NG_APP_BASE_API_URL=http://127.0.0.1:8001 diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 4353e27..85be9c5 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -102,6 +102,7 @@ import { TaskLogsComponent } from './components/commands/commands-task/task-logs import { OrganizationalUnitTabViewComponent } from './components/groups/components/organizational-unit-tab-view/organizational-unit-tab-view.component'; import { ServerInfoDialogComponent } from './components/ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component'; import { StatusComponent } from './components/ogdhcp/og-dhcp-subnets/status/status.component'; +import {MatSliderModule} from '@angular/material/slider'; @NgModule({ declarations: [ AppComponent, @@ -188,6 +189,7 @@ import { StatusComponent } from './components/ogdhcp/og-dhcp-subnets/status/stat NgxChartsModule, MatDatepickerModule, MatNativeDateModule, + MatSliderModule, ToastrModule.forRoot( { timeOut: 5000, diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.html b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.html index fc2838a..8b88d6b 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.html +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.html @@ -64,41 +64,45 @@ - - - - Selecciona Unidad Organizacional - - - {{ unit.name }} - - - Este campo es obligatorio - + + + + Selecciona Unidad Organizacional + + + {{ unit.name }} + + + Este campo es obligatorio + - - Selecciona aula - - - {{ child.name }} - - - + + Selecciona aula + + + {{ child.name }} + + + - - Selecciona Clientes - - - {{ client.name }} ({{ client.ip }}) - - - + + Selecciona Clientes + + + Seleccionar todos + + + {{ client.name }} ({{ client.ip }}) + + + + +
+ + +
+
-
- - -
-
diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.ts b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.ts index d4b0307..4b06e85 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.ts +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.ts @@ -20,6 +20,7 @@ export class CreateTaskComponent implements OnInit { availableOrganizationalUnits: any[] = []; selectedUnitChildren: any[] = []; selectedClients: any[] = []; + selectedClientIds: Set = new Set(); constructor( private fb: FormBuilder, @@ -124,6 +125,7 @@ export class CreateTaskComponent implements OnInit { (data) => { this.selectedClients = data.clients; this.taskForm.patchValue({ selectedClients: [] }); + this.selectedClientIds.clear(); }, (error) => { this.toastr.error('Error al cargar los detalles del aula seleccionada'); @@ -131,6 +133,20 @@ export class CreateTaskComponent implements OnInit { ); } + toggleSelectAll() { + const allSelected = this.areAllSelected(); + if (allSelected) { + this.selectedClientIds.clear(); + } else { + this.selectedClients.forEach(client => this.selectedClientIds.add(client.uuid)); + } + this.taskForm.get('selectedClients')!.setValue(Array.from(this.selectedClientIds)); + } + + areAllSelected(): boolean { + return this.selectedClients.length > 0 && this.selectedClients.every(client => this.selectedClientIds.has(client.uuid)); + } + saveTask(): void { if (this.taskForm.invalid) { this.toastr.error('Por favor, rellene todos los campos obligatorios'); @@ -143,16 +159,16 @@ export class CreateTaskComponent implements OnInit { ? formData.extraCommands.map((id: any) => `/commands/${id}`) : null; - const payload: any = { - commandGroups: formData.commandGroup ? [`/command-groups/${formData.commandGroup}`] : null, - dateTime: dateTime, - notes: formData.notes || '', - clients: this.selectedClients.map((client: any) => client['@id']), - }; + const payload: any = { + commandGroups: formData.commandGroup ? [`/command-groups/${formData.commandGroup}`] : null, + dateTime: dateTime, + notes: formData.notes || '', + clients: Array.from(this.selectedClientIds).map((uuid: string) => `/clients/${uuid}`), + }; - if (selectedCommands) { - payload.commands = selectedCommands; - } + if (selectedCommands) { + payload.commands = selectedCommands; + } if (this.editing) { const taskId = this.data.task.uuid; diff --git a/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.html b/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.html index 944582c..b192713 100644 --- a/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.html +++ b/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.html @@ -99,7 +99,7 @@ - + diff --git a/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.ts b/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.ts index 469f9f0..1a5a00a 100644 --- a/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.ts +++ b/ogWebconsole/src/app/components/groups/components/advanced-search/advanced-search.component.ts @@ -19,6 +19,7 @@ import { SaveFiltersDialogComponent } from '../../shared/save-filters-dialog/sav import { AcctionsModalComponent } from '../../shared/acctions-modal/acctions-modal.component'; import {MatTableDataSource} from "@angular/material/table"; import {DatePipe} from "@angular/common"; +import { Router } from '@angular/router'; @Component({ @@ -62,7 +63,8 @@ export class AdvancedSearchComponent { public dialog: MatDialog, private toastService: ToastrService, private _bottomSheet: MatBottomSheet, - private http: HttpClient + private http: HttpClient, + private router: Router ) {} ngOnInit(): void { @@ -406,9 +408,21 @@ export class AdvancedSearchComponent { } - sendActions() { const dialogRef = this.dialog.open(AcctionsModalComponent, { data: { selectedElements: this.selectedElements }, width: '700px'}); } + + + onDobleClick(event: MouseEvent, data: any, type: string): void { + console.log('Doble click en:', data); + + if (type === 'client') { + this.router.navigate(['client', data]); + } + else { + console.error('ADD VIEW FOR OU'); + } + } + } diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.css b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.css new file mode 100644 index 0000000..6cd9cae --- /dev/null +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.css @@ -0,0 +1,128 @@ +/* Global Container */ +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 40px; + background-color: #f4f6f9; + font-family: 'Arial', sans-serif; + color: #333; + } + + /* Header - Title and Icon */ + .client-header { + display: flex; + align-items: center; + margin-bottom: 40px; + background-color: #fff; + padding: 20px; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + } + + .client-icon { + flex-shrink: 0; /* Prevent shrinking of the icon */ + margin-right: 20px; + display: flex; + align-items: center; + justify-content: center; + min-width: 120px; /* Ensure the icon has enough space */ + min-height: 120px; + } + + .icon-pc { + font-size: 100px; + color: #3b82f6; + } + + .client-title h1 { + font-size: 2rem; + margin-bottom: 10px; + } + + .client-title p { + margin: 2px 0; + font-size: 1rem; + color: #666; + } + + /* Information Section */ + .client-info { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 40px; + } + + .info-section { + background-color: #fff; + padding: 20px; + border-radius: 12px; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + } + + .info-section h2 { + font-size: 1.4rem; + margin-bottom: 10px; + color: #0056b3; + } + + .info-section p { + font-size: 1rem; + margin: 5px 0; + } + + /* Disk Usage Section */ + .disk-usage { + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + } + + .chart-container { + width: 150px; + height: 150px; + margin-bottom: 10px; + } + + .circular-chart { + display: block; + margin: 0 auto; + max-width: 100%; + max-height: 150px; + } + + .circle-bg { + fill: none; + stroke: #eee; + stroke-width: 3.8; + } + + .circle { + fill: none; + stroke-width: 3.8; + stroke: #00bfa5; + stroke-linecap: round; + animation: progress 1s ease-out forwards; + } + + .percentage { + fill: #333; + font-size: 0.5rem; + text-anchor: middle; + } + + /* Footer */ + .client-footer { + margin-top: 40px; + text-align: center; + font-size: 1rem; + color: #555; + } + + @keyframes progress { + 0% { + stroke-dasharray: 0, 100; + } + } + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html new file mode 100644 index 0000000..b3ef2de --- /dev/null +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.html @@ -0,0 +1,67 @@ +
+
+
+ computer +
+
+

{{ clientData?.name }}

+

UUID: {{ clientData?.uuid }}

+

IP Address: {{ clientData?.ip }}

+
+
+ +
+ +
+

General Information

+

Type: {{ clientData?.type }}

+

MAC Address: {{ clientData?.mac }}

+

Serial Number: {{ clientData?.serialNumber }}

+
+ + +
+

Disk Space

+
+
+ + + + 75% + +
+

Used: 75% (375GB)

+

Total: 500GB

+
+
+ + +
+

Organizational Unit

+

Name: {{ clientData?.organizationalUnit?.name }}

+

Type: {{ clientData?.organizationalUnit?.type }}

+
+ + +
+

Network Settings

+

Next Server: {{ clientData?.organizationalUnit?.networkSettings?.nextServer }}

+

Boot File Name: {{ clientData?.organizationalUnit?.networkSettings?.bootFileName }}

+

DNS: {{ clientData?.organizationalUnit?.networkSettings?.dns }}

+

Router: {{ clientData?.organizationalUnit?.networkSettings?.router }}

+
+
+ + +
+ \ No newline at end of file diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.spec.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.spec.ts new file mode 100644 index 0000000..9b91bce --- /dev/null +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ClientMainViewComponent } from './client-main-view.component'; + +describe('ClientMainViewComponent', () => { + let component: ClientMainViewComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ClientMainViewComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ClientMainViewComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts new file mode 100644 index 0000000..e779de1 --- /dev/null +++ b/ogWebconsole/src/app/components/groups/components/client-main-view/client-main-view.component.ts @@ -0,0 +1,36 @@ +import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; + +@Component({ + selector: 'app-client-main-view', + templateUrl: './client-main-view.component.html', + styleUrl: './client-main-view.component.css' +}) +export class ClientMainViewComponent implements OnInit { + baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; + clientUuid: string; + clientData: any; + + constructor(private http: HttpClient) { + const url = window.location.href; + const segments = url.split('/'); + this.clientUuid = segments[segments.length - 1]; + } + + ngOnInit() { + this.loadClientData(); + } + + loadClientData() { + this.http.get(`${this.baseUrl}/clients/${this.clientUuid}`).subscribe( + data => { + this.clientData = data; + }, + error => { + console.error('Error loading client data:', error); + } + ); + } + + +} diff --git a/ogWebconsole/src/app/components/groups/shared/acctions-modal/acctions-modal.component.ts b/ogWebconsole/src/app/components/groups/shared/acctions-modal/acctions-modal.component.ts index 0c865bb..6143cff 100644 --- a/ogWebconsole/src/app/components/groups/shared/acctions-modal/acctions-modal.component.ts +++ b/ogWebconsole/src/app/components/groups/shared/acctions-modal/acctions-modal.component.ts @@ -5,6 +5,7 @@ import { ToastrService } from 'ngx-toastr'; import { CreatePxeBootFileComponent } from '../../../ogboot/pxe-boot-files/create-pxeBootFile/create-pxe-boot-file/create-pxe-boot-file.component'; import { HttpClient } from '@angular/common/http'; import { CommandDetailComponent } from '../../../commands/main-commands/detail-command/command-detail.component'; +import { RouterLink } from '@angular/router'; @Component({ selector: 'app-acctions-modal', templateUrl: './acctions-modal.component.html', @@ -38,7 +39,7 @@ export class AcctionsModalComponent { private http: HttpClient, @Inject(MAT_DIALOG_DATA) public data: any ) { - this.selectedElements = data?.selectedElements || []; + this.selectedElements = data?.selectedElements || []; } onSend(): void { @@ -52,24 +53,9 @@ export class AcctionsModalComponent { }); } -onCommandClick(command: any): void { -const payload = { - clients: this.selectedElements.map((uuid: any) => `/clients/${uuid}`) -}; + onCommandClick(command: any): void { -const apiUrl = `${this.baseUrl}/commands/${command.uuid}/execute`; - -this.http.post(apiUrl, payload).subscribe({ - next: () => { - console.log('Command executed successfully'); - this.loadCommands(); - this.toastService.success('Command executed successfully'); - }, - error: (error) => { - console.error('Error executing command:', error); } -}); -} chunkArray(arr: any[], chunkSize: number): any[] { const chunks = []; diff --git a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/create-pxeBootFile/create-pxe-boot-file/create-pxe-boot-file.component.ts b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/create-pxeBootFile/create-pxe-boot-file/create-pxe-boot-file.component.ts index be0efe0..89e90e6 100644 --- a/ogWebconsole/src/app/components/ogboot/pxe-boot-files/create-pxeBootFile/create-pxe-boot-file/create-pxe-boot-file.component.ts +++ b/ogWebconsole/src/app/components/ogboot/pxe-boot-files/create-pxeBootFile/create-pxe-boot-file/create-pxe-boot-file.component.ts @@ -27,8 +27,6 @@ export class CreatePxeBootFileComponent implements OnInit { this.selectedElements = this.data.clients; this.clientes = this.selectedElements.map((client: { uuid: any }) => `/clients/${client.uuid}`); this.loadPxeTemplates(); - - // Configura el modo de edición si se proporciona bootFile if (this.data.bootFile) { this.isEditMode = true; this.selectedPxeTemplate = this.data.bootFile.template.uuid; @@ -60,7 +58,6 @@ export class CreatePxeBootFileComponent implements OnInit { }; if (this.isEditMode && this.data.bootFile) { - // Edit mode: Actualizar boot file existente this.http.put(`${this.baseUrl}/pxe-boot-files/${this.data.bootFile.uuid}`, payload) .subscribe({ next: response => { @@ -72,7 +69,6 @@ export class CreatePxeBootFileComponent implements OnInit { } }); } else { - // Create mode: Crear nuevo boot file this.http.post(`${this.baseUrl}/pxe-boot-files`, payload) .subscribe({ next: response => {