From 0bbe428739e8bdc1216c46fcb1bf7a26083a7baf Mon Sep 17 00:00:00 2001 From: Manuel Aranda Date: Thu, 3 Oct 2024 19:04:16 +0200 Subject: [PATCH] Refactor trace --- ogWebconsole/src/app/app.module.ts | 74 ++++----- .../task-logs/task-logs.component.css | 85 +++++++++- .../task-logs/task-logs.component.html | 132 +++++---------- .../task-logs/task-logs.component.ts | 150 ++++++++++++++---- 4 files changed, 283 insertions(+), 158 deletions(-) diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 8773ebc..9b60f72 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -42,7 +42,7 @@ import { EditClientComponent } from './components/groups/shared/clients/edit-cli import { ClassroomViewComponent } from './components/groups/shared/classroom-view/classroom-view.component'; import { MatProgressSpinner } from "@angular/material/progress-spinner"; import { MatMenu, MatMenuItem, MatMenuTrigger } from "@angular/material/menu"; -import { MatAutocomplete } from "@angular/material/autocomplete"; +import {MatAutocomplete, MatAutocompleteTrigger} from "@angular/material/autocomplete"; import { MatChip, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule } from "@angular/material/chips"; import { ClientViewComponent } from './components/groups/shared/client-view/client-view.component'; import { MatTab, MatTabGroup } from "@angular/material/tabs"; @@ -159,42 +159,42 @@ import { OrganizationalUnitTabViewComponent } from './components/groups/componen OrganizationalUnitTabViewComponent ], bootstrap: [AppComponent], - imports: [BrowserModule, - AppRoutingModule, - FormsModule, - ReactiveFormsModule, - MatToolbarModule, - MatIconModule, - MatButtonModule, - MatSidenavModule, - NoopAnimationsModule, - MatCardModule, - MatCheckboxModule, - MatFormFieldModule, - MatInputModule, - MatListModule, - MatTableModule, - MatDialogModule, - MatSelectModule, - MatDividerModule, - MatStepperModule, - DragDropModule, - MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem, MatAutocomplete, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule, MatChip, MatProgressSpinner, MatTabGroup, MatTab, MatTooltip, - MatExpansionModule, - NgxChartsModule, - MatDatepickerModule, - MatNativeDateModule, - ToastrModule.forRoot( - { - timeOut: 5000, - positionClass: 'toast-bottom-right', - preventDuplicates: true, - progressBar: true, - progressAnimation: 'increasing', - closeButton: true - } - ), MatGridList, MatTree, MatTreeNode, MatNestedTreeNode, MatTreeNodeToggle, MatTreeNodeDef, MatTreeNodePadding, MatTreeNodeOutlet, MatPaginator, MatGridTile, MatExpansionPanel, MatExpansionPanelTitle, MatExpansionPanelDescription, MatRadioGroup, MatRadioButton - ], + imports: [BrowserModule, + AppRoutingModule, + FormsModule, + ReactiveFormsModule, + MatToolbarModule, + MatIconModule, + MatButtonModule, + MatSidenavModule, + NoopAnimationsModule, + MatCardModule, + MatCheckboxModule, + MatFormFieldModule, + MatInputModule, + MatListModule, + MatTableModule, + MatDialogModule, + MatSelectModule, + MatDividerModule, + MatStepperModule, + DragDropModule, + MatSlideToggleModule, MatMenu, MatMenuTrigger, MatMenuItem, MatAutocomplete, MatChipListbox, MatChipOption, MatChipSet, MatChipsModule, MatChip, MatProgressSpinner, MatTabGroup, MatTab, MatTooltip, + MatExpansionModule, + NgxChartsModule, + MatDatepickerModule, + MatNativeDateModule, + ToastrModule.forRoot( + { + timeOut: 5000, + positionClass: 'toast-bottom-right', + preventDuplicates: true, + progressBar: true, + progressAnimation: 'increasing', + closeButton: true + } + ), MatGridList, MatTree, MatTreeNode, MatNestedTreeNode, MatTreeNodeToggle, MatTreeNodeDef, MatTreeNodePadding, MatTreeNodeOutlet, MatPaginator, MatGridTile, MatExpansionPanel, MatExpansionPanelTitle, MatExpansionPanelDescription, MatRadioGroup, MatRadioButton, MatAutocompleteTrigger + ], schemas: [ CUSTOM_ELEMENTS_SCHEMA, ], 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 index 482cf8c..0a5a10b 100644 --- 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 @@ -1,3 +1,82 @@ -mat-form-field{ - margin: 10px; -} \ No newline at end of file +.title { + font-size: 24px; +} + +.calendar-button-row { + display: flex; + justify-content: flex-start; + margin-top: 16px; +} + +.divider { + margin: 20px 0; +} + +.lists-container { + padding: 16px; +} + +.imagesLists-container { + flex: 1; +} + +.card.unidad-card { + height: 100%; + box-sizing: border-box; +} + +table { + width: 100%; + margin-top: 50px; +} + +.search-container { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 5px; + box-sizing: border-box; +} + +.search-string { + flex: 1; + padding: 5px; +} + +.search-boolean { + flex: 1; + padding: 5px; +} + +.search-select { + flex: 2; + padding: 5px; +} + +.header-container { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px; +} + +.mat-elevation-z8 { + box-shadow: 0px 0px 0px rgba(0,0,0,0.2); +} + +.paginator-container { + display: flex; + justify-content: end; + margin-bottom: 30px; +} + +.mat-chip-readonly-true { + background-color: #4CAF50 !important; + color: white !important; +} + +.mat-chip-readonly-false { + background-color: #F44336 !important; + color: white !important; +} + 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 index ccee5f3..e841376 100644 --- 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 @@ -1,91 +1,47 @@
-

Trazas de ejecuciones

- - - Buscar por comando - - - - - Buscar por cliente - - - - - Buscar por estado - - - - - Buscar por usuario - - - - - Buscar por fecha - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Ejecución {{ group.commandId }} Comando - -
{{ trace.command.name }}
-
-
Cliente - -
{{ trace.client.name }}
-
-
Estado - -
{{ trace.status }}
-
-
Ejecutado En - -
{{ trace.executedAt | date:'short' }}
-
-
Creado Por - -
{{ trace.createdBy }}
-
-
- +

Trazas de comandos y procedimientos

+ + +
+ + + + + {{ client.name }} + + + + + + + + + + {{ command.name }} + + + +
+ + + + + + + + + +
{{ column.header }} + + {{ column.cell(trace) }} + +
+ +
+ [pageSize]="itemsPerPage" + [pageIndex]="page" + [pageSizeOptions]="pageSizeOptions" + (page)="onPageChange($event)"> - \ No newline at end of file +
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 index 44a3992..96f46f5 100644 --- 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 @@ -1,5 +1,9 @@ import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; +import {Observable, startWith} from 'rxjs'; +import {FormControl} from "@angular/forms"; +import {map} from "rxjs/operators"; +import {DatePipe} from "@angular/common"; @Component({ selector: 'app-task-logs', @@ -7,36 +11,111 @@ import { HttpClient } from '@angular/common/http'; styleUrls: ['./task-logs.component.css'] }) export class TaskLogsComponent implements OnInit { - baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; traces: any[] = []; groupedTraces: any[] = []; + commands: any[] = []; + clients: any[] = []; length: number = 0; itemsPerPage: number = 20; - page: number = 1; + page: number = 0; + loading: boolean = true; pageSizeOptions: number[] = [10, 20, 30, 50]; - displayedColumns: string[] = ['commandId','commandName', 'clientName', 'status', 'executedAt', 'createdBy']; + datePipe: DatePipe = new DatePipe('es-ES'); - searchCommand: string = ''; - searchClient: string = ''; - searchStatus: string = ''; - searchCreatedBy: string = ''; - searchExecutedAt: string = ''; + columns = [ + { + columnDef: 'id', + header: 'ID', + cell: (trace: any) => `${trace.id}`, + }, + { + columnDef: 'command', + header: 'Comando', + cell: (trace: any) => `${trace.command?.name}` + }, + { + columnDef: 'client', + header: 'Client', + cell: (trace: any) => `${trace.client?.name}` + }, + { + columnDef: 'status', + header: 'Estado', + cell: (trace: any) => `${trace.status}` + }, + { + columnDef: 'executedAt', + header: 'Programacion de ejecución', + cell: (trace: any) => `${this.datePipe.transform(trace.executedAt, 'dd/MM/yyyy hh:mm:ss')}`, + }, + { + columnDef: 'createdAt', + header: 'Fecha de creación', + cell: (trace: any) => `${this.datePipe.transform(trace.createdAt, '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) {} 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())) + ); + } + + 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(); } loadTraces(): void { - const url = `${this.baseUrl}/traces?page=${this.page}&itemsPerPage=${this.itemsPerPage}`; - - this.http.get(url).subscribe( + const url = `${this.baseUrl}/traces?page=${this.page + 1}&itemsPerPage=${this.itemsPerPage}`; + this.http.get(url, { params: this.filters }).subscribe( (data) => { this.traces = data['hydra:member']; this.length = data['hydra:totalItems']; - this.groupedTraces = this.groupByCommandId(this.traces); + this.groupedTraces = this.groupByCommandId(this.traces); }, (error) => { console.error('Error fetching traces', error); @@ -44,6 +123,32 @@ export class TaskLogsComponent implements OnInit { ); } + loadCommands() { + 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 parent units:', error); + this.loading = false; + } + ); + } + + loadClients() { + this.http.get( `${this.baseUrl}/clients?&page=1&itemsPerPage=10000`).subscribe( + response => { + this.clients = response['hydra:member']; + this.loading = false; + }, + error => { + console.error('Error fetching parent units:', error); + this.loading = false; + } + ); + } + groupByCommandId(traces: any[]): any[] { const grouped: { [key: string]: any[] } = {}; @@ -62,23 +167,8 @@ export class TaskLogsComponent implements OnInit { } onPageChange(event: any): void { - this.page = event.pageIndex + 1; - this.itemsPerPage = event.pageSize; - this.loadTraces(); - } - - filterTraces(): void { - const filtered = this.traces.filter(trace => { - const commandMatch = trace.command.name.toLowerCase().includes(this.searchCommand.toLowerCase()); - const clientMatch = trace.client.name.toLowerCase().includes(this.searchClient.toLowerCase()); - const statusMatch = trace.status.toLowerCase().includes(this.searchStatus.toLowerCase()); - const createdByMatch = trace.createdBy.toLowerCase().includes(this.searchCreatedBy.toLowerCase()); - const executedAtMatch = trace.executedAt.toLowerCase().includes(this.searchExecutedAt.toLowerCase()); - - return commandMatch && clientMatch && statusMatch && createdByMatch && executedAtMatch; - }); - - this.length = filtered.length; - this.groupedTraces = this.groupByCommandId(filtered); + this.page = event.pageIndex + 1; + this.itemsPerPage = event.pageSize; + this.loadTraces(); } }