diff --git a/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.ts b/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.ts index 229b4e5..c8e27e5 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.ts +++ b/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.ts @@ -35,7 +35,7 @@ export class CommandsTaskComponent implements OnInit { { columnDef: 'name', header: 'Nombre de tarea', cell: (task: any) => task.name }, { columnDef: 'organizationalUnit', header: 'Ámbito', cell: (task: any) => task.organizationalUnit.name }, { columnDef: 'management', header: 'Gestiones', cell: (task: any) => task.schedules }, - { columnDef: 'nextExecution', header: 'Próxima ejecución', cell: (task: any) => this.datePipe.transform(task.nextExecution, 'dd/MM/yyyy HH:mm:ss') }, + { columnDef: 'nextExecution', header: 'Próxima ejecución', cell: (task: any) => this.datePipe.transform(task.nextExecution, 'dd/MM/yyyy HH:mm:ss', 'UTC') }, { columnDef: 'createdBy', header: 'Creado por', cell: (task: any) => task.createdBy }, ]; diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts b/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts index f47d7ca..9cf584f 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task-schedule/create-task-schedule.component.ts @@ -114,20 +114,26 @@ export class CreateTaskScheduleComponent implements OnInit{ return date.toISOString().substring(11, 16); } + convertDateToLocalISO(date: Date): string { + const adjustedDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())); + return adjustedDate.toISOString(); + } + + onSubmit() { const formData = this.form.value; const payload: any = { commandTask: this.data.task['@id'], - executionDate: formData.recurrenceType === 'none' ? formData.executionDate : null, + executionDate: formData.recurrenceType === 'none' ? this.convertDateToLocalISO(formData.executionDate) : null, executionTime: formData.executionTime, recurrenceType: formData.recurrenceType, recurrenceDetails: { ...formData.recurrenceDetails, - initDate: formData.recurrenceDetails.initDate || null, - endDate: formData.recurrenceDetails.endDate || null, - daysOfWeek: formData.recurrenceDetails.daysOfWeek || [], - months: formData.recurrenceDetails.months || [] + initDate: formData.recurrenceDetails?.initDate || null, + endDate: formData.recurrenceDetails?.endDate || null, + daysOfWeek: formData.recurrenceDetails?.daysOfWeek || [], + months: formData.recurrenceDetails?.months || [] }, enabled: formData.enabled } diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task-script/create-task-script.component.ts b/ogWebconsole/src/app/components/commands/commands-task/create-task-script/create-task-script.component.ts index 4b3497f..f46cc88 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/create-task-script/create-task-script.component.ts +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task-script/create-task-script.component.ts @@ -120,6 +120,7 @@ export class CreateTaskScriptComponent implements OnInit { commandTask: this.data.task['@id'], content: this.commandType === 'existing' ? this.scriptContent : this.newScript, order: this.executionOrder, + type: 'run-script', }).subscribe({ next: () => { this.toastService.success('Tarea creada con éxito'); diff --git a/ogWebconsole/src/app/components/commands/commands-task/show-task-schedule/show-task-schedule.component.ts b/ogWebconsole/src/app/components/commands/commands-task/show-task-schedule/show-task-schedule.component.ts index 108197a..88ea5bf 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/show-task-schedule/show-task-schedule.component.ts +++ b/ogWebconsole/src/app/components/commands/commands-task/show-task-schedule/show-task-schedule.component.ts @@ -28,7 +28,7 @@ export class ShowTaskScheduleComponent implements OnInit{ columns = [ { columnDef: 'id', header: 'ID', cell: (schedule: any) => schedule.id }, { columnDef: 'recurrenceType', header: 'Recurrencia', cell: (schedule: any) => schedule.recurrenceType }, - { columnDef: 'time', header: 'Hora de ejecución', cell: (schedule: any) => this.datePipe.transform(schedule.executionTime, 'HH:mm') }, + { columnDef: 'time', header: 'Hora de ejecución', cell: (schedule: any) => this.datePipe.transform(schedule.executionTime, 'HH:mm', 'UTC') }, { columnDef: 'daysOfWeek', header: 'Dias de la semana', cell: (schedule: any) => schedule.recurrenceDetails.daysOfWeek }, { columnDef: 'months', header: 'Meses', cell: (schedule: any) => schedule.recurrenceDetails.months }, { columnDef: 'enabled', header: 'Activo', cell: (schedule: any) => schedule.enabled } diff --git a/ogWebconsole/src/app/components/commands/commands-task/show-task-script/view-parameters-modal/view-parameters-modal.component.spec.ts b/ogWebconsole/src/app/components/commands/commands-task/show-task-script/view-parameters-modal/view-parameters-modal.component.spec.ts index 6104c77..c814fa3 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/show-task-script/view-parameters-modal/view-parameters-modal.component.spec.ts +++ b/ogWebconsole/src/app/components/commands/commands-task/show-task-script/view-parameters-modal/view-parameters-modal.component.spec.ts @@ -27,7 +27,7 @@ import {TranslateModule} from "@ngx-translate/core"; import {JoyrideModule} from "ngx-joyride"; import {ConfigService} from "@services/config.service"; import {ActivatedRoute} from "@angular/router"; -import {InputDialogComponent} from "../../task-logs/input-dialog/input-dialog.component"; +import {InputDialogComponent} from "../../../../task-logs/input-dialog/input-dialog.component"; import {provideHttpClient} from "@angular/common/http"; describe('ViewParametersModalComponent', () => { diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.css b/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.css deleted file mode 100644 index e69de29..0000000 diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.html b/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.html deleted file mode 100644 index eed69e9..0000000 --- a/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.html +++ /dev/null @@ -1,7 +0,0 @@ -

{{ 'inputDetails' | translate }}

-
-
{{ data.input | json }}
-
-
- -
diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.spec.ts b/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.spec.ts deleted file mode 100644 index 7168136..0000000 --- a/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.spec.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { InputDialogComponent } from './input-dialog.component'; -import {MAT_DIALOG_DATA, MatDialogModule, MatDialogRef} from "@angular/material/dialog"; -import {FormBuilder} from "@angular/forms"; -import {ToastrService} from "ngx-toastr"; -import {provideHttpClient} from "@angular/common/http"; -import {provideHttpClientTesting} from "@angular/common/http/testing"; -import {TranslateModule} from "@ngx-translate/core"; - -describe('InputDialogComponent', () => { - let component: InputDialogComponent; - let fixture: ComponentFixture; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [InputDialogComponent], - imports: [ - MatDialogModule, - TranslateModule.forRoot(), - ], - providers: [ - FormBuilder, - ToastrService, - provideHttpClient(), - provideHttpClientTesting(), - { - provide: MatDialogRef, - useValue: {} - }, - { - provide: MAT_DIALOG_DATA, - useValue: {} - } - ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(InputDialogComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.ts b/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.ts deleted file mode 100644 index 744b415..0000000 --- a/ogWebconsole/src/app/components/commands/commands-task/task-logs/input-dialog/input-dialog.component.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Component, Inject } from '@angular/core'; -import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; - -@Component({ - selector: 'app-input-dialog', - templateUrl: './input-dialog.component.html', - styleUrl: './input-dialog.component.css' -}) -export class InputDialogComponent { - constructor( - public dialogRef: MatDialogRef, - @Inject(MAT_DIALOG_DATA) public data: { input: any } - ) {} - - close(): void { - this.dialogRef.close(); - } -} diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.css b/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.css deleted file mode 100644 index 195127a..0000000 --- a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.css +++ /dev/null @@ -1,118 +0,0 @@ -.header-container { - display: flex; - justify-content: space-between; - align-items: center; - padding: 10px 10px; - border-bottom: 1px solid #ddd; -} - -.header-container-title { - flex-grow: 1; - text-align: left; - margin-left: 1em; -} - -.calendar-button-row { - display: flex; - gap: 15px; -} - -.lists-container { - padding: 16px; -} - -.imagesLists-container { - flex: 1; -} - -.card.unidad-card { - height: 100%; - box-sizing: border-box; -} - -table { - width: 100%; -} - -.search-container { - display: flex; - justify-content: space-between; - align-items: center; - margin: 1.5rem 0rem 1.5rem 0rem; - box-sizing: border-box; -} - -.search-string { - flex: 1; - padding: 5px; -} - -.search-boolean { - flex: 1; - padding: 5px; -} - -.search-select { - flex: 2; - padding: 5px; -} - -.mat-elevation-z8 { - box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.2); -} - -.progress-container { - display: flex; - align-items: center; - gap: 10px; -} - -.paginator-container { - display: flex; - justify-content: end; - margin-bottom: 30px; -} - -.chip-failed { - background-color: #e87979 !important; - color: white; -} - -.chip-success { - background-color: #46c446 !important; - color: white; -} - -.chip-pending { - background-color: #bebdbd !important; - color: black; -} - -.chip-in-progress { - background-color: #f5a623 !important; - color: white; -} - -.status-progress-flex { - display: flex; - align-items: center; - gap: 8px; -} - -button.cancel-button { - display: flex; - align-items: center; - justify-content: center; - padding: 5px; -} - -.cancel-button { - color: red; - background-color: transparent; - border: none; - padding: 0; -} - -.cancel-button mat-icon { - color: red; -} diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.html b/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.html deleted file mode 100644 index f7ceea4..0000000 --- a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.html +++ /dev/null @@ -1,128 +0,0 @@ -
- - -
-

{{ 'adminCommandsTitle' | - translate }}

-
- -
- -
-
- -
- - - - - {{ client.name }} - - - - - - - - - {{ command.name }} - - - - - - Estado - - Todos - Fallido - Pendiente de ejecutar - Ejecutando - Completado con éxito - Cancelado - - -
- - - -
- - - - - - - - - -
{{ column.header }} - - - - -
- - - {{trace.progress}}% -
-
- -
- - {{ - trace.status === 'failed' ? 'Fallido' : - trace.status === 'in-progress' ? 'En ejecución' : - trace.status === 'success' ? 'Finalizado con éxito' : - trace.status === 'pending' ? 'Pendiente de ejecutar' : - trace.status === 'cancelled' ? 'Cancelado' : - trace.status - }} - - -
-
-
- - - - - - - {{ column.cell(trace) }} - -
- -
-
- -
- - -
diff --git a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.ts b/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.ts deleted file mode 100644 index 60a233f..0000000 --- a/ogWebconsole/src/app/components/commands/commands-task/task-logs/task-logs.component.ts +++ /dev/null @@ -1,309 +0,0 @@ -import { ChangeDetectorRef, Component, OnInit } from '@angular/core'; -import { HttpClient } from '@angular/common/http'; -import { Observable, forkJoin } from 'rxjs'; -import { FormControl } from '@angular/forms'; -import { map, startWith } from 'rxjs/operators'; -import { DatePipe } from '@angular/common'; -import { JoyrideService } from 'ngx-joyride'; -import { MatDialog } from "@angular/material/dialog"; -import { InputDialogComponent } from "./input-dialog/input-dialog.component"; -import { ProgressBarMode } from '@angular/material/progress-bar'; -import { DeleteModalComponent } from "../../../../shared/delete_modal/delete-modal/delete-modal.component"; -import { ToastrService } from "ngx-toastr"; -import { ConfigService } from '@services/config.service'; - -@Component({ - selector: 'app-task-logs', - templateUrl: './task-logs.component.html', - styleUrls: ['./task-logs.component.css'] -}) -export class TaskLogsComponent implements OnInit { - baseUrl: string; - mercureUrl: string; - traces: any[] = []; - groupedTraces: any[] = []; - commands: any[] = []; - clients: any[] = []; - length: number = 0; - itemsPerPage: number = 20; - page: number = 0; - loading: boolean = true; - pageSizeOptions: number[] = [10, 20, 30, 50]; - datePipe: DatePipe = new DatePipe('es-ES'); - mode: ProgressBarMode = 'buffer'; - progress = 0; - bufferValue = 0; - - columns = [ - { - columnDef: 'id', - header: 'ID', - cell: (trace: any) => `${trace.id}`, - }, - { - columnDef: 'command', - header: 'Comando', - cell: (trace: any) => `${trace.command}` - }, - { - columnDef: 'client', - header: 'Client', - cell: (trace: any) => `${trace.client?.name}` - }, - { - columnDef: 'status', - header: 'Estado', - cell: (trace: any) => `${trace.status}` - }, - { - columnDef: 'jobId', - header: 'Hilo de trabajo', - cell: (trace: any) => `${trace.jobId}` - }, - { - columnDef: 'input', - header: 'Input', - cell: (trace: any) => `${trace.input}` - }, - { - columnDef: 'output', - header: 'Logs', - cell: (trace: any) => `${trace.output}` - }, - { - columnDef: 'executedAt', - header: 'Programación de ejecución', - cell: (trace: any) => `${this.datePipe.transform(trace.executedAt, 'dd/MM/yyyy hh:mm:ss')}`, - }, - { - columnDef: 'finishedAt', - header: 'Finalización', - cell: (trace: any) => `${this.datePipe.transform(trace.finishedAt, 'dd/MM/yyyy hh:mm:ss')}`, - }, - ]; - displayedColumns = [...this.columns.map(column => column.columnDef)]; - - filters: { [key: string]: string } = {}; - filteredClients!: Observable; - clientControl = new FormControl(); - filteredCommands!: Observable; - commandControl = new FormControl(); - - constructor(private http: HttpClient, - private joyrideService: JoyrideService, - private dialog: MatDialog, - private cdr: ChangeDetectorRef, - private configService: ConfigService, - private toastService: ToastrService - ) { - this.baseUrl = this.configService.apiUrl; - this.mercureUrl = this.configService.mercureUrl; - } - - ngOnInit(): void { - this.loadTraces(); - this.loadCommands(); - //this.loadClients(); - this.filteredCommands = this.commandControl.valueChanges.pipe( - startWith(''), - map(value => (typeof value === 'string' ? value : value?.name)), - map(name => (name ? this._filterCommands(name) : this.commands.slice())) - ); - this.filteredClients = this.clientControl.valueChanges.pipe( - startWith(''), - map(value => (typeof value === 'string' ? value : value?.name)), - map(name => (name ? this._filterClients(name) : this.clients.slice())) - ); - - const eventSource = new EventSource(`${this.mercureUrl}?topic=` - + encodeURIComponent(`traces`)); - - eventSource.onmessage = (event) => { - const data = JSON.parse(event.data); - if (data && data['@id']) { - this.updateTracesStatus(data['@id'], data.status, data.progress); - } - } - } - - private updateTracesStatus(clientUuid: string, newStatus: string, progress: Number): void { - const traceIndex = this.traces.findIndex(trace => trace['@id'] === clientUuid); - if (traceIndex !== -1) { - const updatedTraces = [...this.traces]; - - updatedTraces[traceIndex] = { - ...updatedTraces[traceIndex], - status: newStatus, - progress: progress - }; - - this.traces = updatedTraces; - this.cdr.detectChanges(); - - console.log(`Estado actualizado para la traza ${clientUuid}: ${newStatus}`); - } else { - console.warn(`Traza con UUID ${clientUuid} no encontrado en la lista.`); - } - } - - - private _filterClients(name: string): any[] { - const filterValue = name.toLowerCase(); - return this.clients.filter(client => client.name.toLowerCase().includes(filterValue)); - } - - private _filterCommands(name: string): any[] { - const filterValue = name.toLowerCase(); - return this.commands.filter(command => command.name.toLowerCase().includes(filterValue)); - } - - displayFnClient(client: any): string { - return client && client.name ? client.name : ''; - } - - displayFnCommand(command: any): string { - return command && command.name ? command.name : ''; - } - - onOptionCommandSelected(selectedCommand: any): void { - this.filters['command.id'] = selectedCommand.id; - this.loadTraces(); - } - - onOptionClientSelected(selectedClient: any): void { - this.filters['client.id'] = selectedClient.id; - this.loadTraces(); - } - - openInputModal(inputData: any): void { - this.dialog.open(InputDialogComponent, { - width: '700px', - data: { input: inputData } - }); - } - - cancelTrace(trace: any): void { - this.dialog.open(DeleteModalComponent, { - width: '300px', - data: { name: trace.jobId }, - }).afterClosed().subscribe((result) => { - if (result) { - this.http.post(`${this.baseUrl}/traces/server/${trace.uuid}/cancel`, {}).subscribe({ - next: () => { - this.toastService.success('Transmision de imagen cancelada'); - this.loadTraces(); - }, - error: (error) => { - this.toastService.error(error.error['hydra:description']); - console.error(error.error['hydra:description']); - } - }); - } - }); - } - - loadTraces(): void { - this.loading = true; - const url = `${this.baseUrl}/traces?page=${this.page + 1}&itemsPerPage=${this.itemsPerPage}`; - const params = { ...this.filters }; - if (params['status'] === undefined) { - delete params['status']; - } - this.http.get(url, { params }).subscribe( - (data) => { - this.traces = data['hydra:member']; - this.length = data['hydra:totalItems']; - this.groupedTraces = this.groupByCommandId(this.traces); - this.loading = false; - }, - (error) => { - console.error('Error fetching traces', error); - this.loading = false; - } - ); - } - - loadCommands() { - this.loading = true; - this.http.get(`${this.baseUrl}/commands?&page=1&itemsPerPage=10000`).subscribe( - response => { - this.commands = response['hydra:member']; - this.loading = false; - }, - error => { - console.error('Error fetching commands:', error); - this.loading = false; - } - ); - } - - loadClients() { - this.loading = true; - this.http.get(`${this.baseUrl}/clients?&page=1&itemsPerPage=10000`).subscribe( - response => { - const clientIds = response['hydra:member'].map((client: any) => client['@id']); - const clientDetailsRequests: Observable[] = clientIds.map((id: string) => this.http.get(`${this.baseUrl}${id}`)); - forkJoin(clientDetailsRequests).subscribe( - (clients: any[]) => { - this.clients = clients; - this.loading = false; - }, - (error: any) => { - console.error('Error fetching client details:', error); - this.loading = false; - } - ); - }, - (error: any) => { - console.error('Error fetching clients:', error); - this.loading = false; - } - ); - } - - resetFilters() { - this.loading = true; - this.filters = {}; - this.loadTraces(); - } - - groupByCommandId(traces: any[]): any[] { - const grouped: { [key: string]: any[] } = {}; - - traces.forEach(trace => { - const commandId = trace.command.id; - if (!grouped[commandId]) { - grouped[commandId] = []; - } - grouped[commandId].push(trace); - }); - - return Object.keys(grouped).map(key => ({ - commandId: key, - traces: grouped[key] - })); - } - - onPageChange(event: any): void { - this.page = event.pageIndex; - this.itemsPerPage = event.pageSize; - this.length = event.length; - this.loadTraces(); - } - - iniciarTour(): void { - this.joyrideService.startTour({ - steps: [ - 'titleStep', - 'resetFiltersStep', - 'clientSelectStep', - 'commandSelectStep', - 'tableStep', - 'paginationStep' - ], - showPrevButton: true, - themeColor: '#3f51b5' - }); - } - -}