From 8f49e39bd51f33ff06723bb7dd89145643a43d3f Mon Sep 17 00:00:00 2001 From: apuente Date: Wed, 25 Sep 2024 17:14:56 +0200 Subject: [PATCH] Added task and commandGroup components --- ogWebconsole/src/app/app.module.ts | 10 +- .../commands-groups.component.css | 66 ++++++++ .../commands-groups.component.html | 73 ++++++++- .../commands-groups.component.ts | 83 +++++++++- .../create-command-group.component.css | 58 +++++++ .../create-command-group.component.html | 63 +++++++ .../create-command-group.component.spec.ts | 23 +++ .../create-command-group.component.ts | 76 +++++++++ .../detail-command-group.component.css | 155 ++++++++++++++++++ .../detail-command-group.component.html | 37 +++++ .../detail-command-group.component.spec.ts | 23 +++ .../detail-command-group.component.ts | 18 ++ .../commands-task.component.html | 67 +++++++- .../commands-task/commands-task.component.ts | 83 +++++++++- .../create-task/create-task.component.css | 25 +++ .../create-task/create-task.component.html | 44 +++++ .../create-task/create-task.component.spec.ts | 23 +++ .../create-task/create-task.component.ts | 100 +++++++++++ .../detail-task/detail-task.component.css | 0 .../detail-task/detail-task.component.html | 1 + .../detail-task/detail-task.component.spec.ts | 23 +++ .../detail-task/detail-task.component.ts | 10 ++ .../main-commands/commands.component.css | 19 +++ .../main-commands/commands.component.html | 22 ++- .../main-commands/commands.component.ts | 102 +++++------- .../app/layout/sidebar/sidebar.component.css | 4 +- .../app/layout/sidebar/sidebar.component.html | 6 +- 27 files changed, 1141 insertions(+), 73 deletions(-) create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.css create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.html create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.spec.ts create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.ts create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.css create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.html create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.spec.ts create mode 100644 ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.ts create mode 100644 ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.css create mode 100644 ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.html create mode 100644 ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.spec.ts create mode 100644 ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.ts create mode 100644 ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.css create mode 100644 ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.html create mode 100644 ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.spec.ts create mode 100644 ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.ts diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts index 6165226..db3797b 100644 --- a/ogWebconsole/src/app/app.module.ts +++ b/ogWebconsole/src/app/app.module.ts @@ -90,6 +90,10 @@ import { MatDatepickerModule } from '@angular/material/datepicker'; import { MatNativeDateModule } from '@angular/material/core'; import { CommandsGroupsComponent } from './components/commands/commands-groups/commands-groups.component'; import { CommandsTaskComponent } from './components/commands/commands-task/commands-task.component'; +import { CreateCommandGroupComponent } from './components/commands/commands-groups/create-command-group/create-command-group.component'; +import { DetailCommandGroupComponent } from './components/commands/commands-groups/detail-command-group/detail-command-group.component'; +import { CreateTaskComponent } from './components/commands/commands-task/create-task/create-task.component'; +import { DetailTaskComponent } from './components/commands/commands-task/detail-task/detail-task.component'; @NgModule({ declarations: [ AppComponent, @@ -136,7 +140,11 @@ import { CommandsTaskComponent } from './components/commands/commands-task/comma CommandDetailComponent, CreateCommandComponent, CommandsGroupsComponent, - CommandsTaskComponent + CommandsTaskComponent, + CreateCommandGroupComponent, + DetailCommandGroupComponent, + CreateTaskComponent, + DetailTaskComponent ], bootstrap: [AppComponent], imports: [BrowserModule, diff --git a/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.css b/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.css index e69de29..9416d5a 100644 --- a/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.css +++ b/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.css @@ -0,0 +1,66 @@ +.commands-list { + margin-bottom: 20px; + } + + .command-item { + cursor: pointer; + margin-bottom: 10px; + padding: 10px; + border: 1px solid #ccc; + border-radius: 4px; + background-color: #f9f9f9; + } + + .command-item:hover { + background-color: #e9e9e9; + } + + .command-details { + padding: 20px; + border: 1px solid #ddd; + background-color: #f4f4f4; + border-radius: 4px; + } + + .script-display { + margin-top: 20px; + background-color: #000; + color: #fff; + padding: 10px; + border-radius: 4px; + } + + pre { + margin: 0; + font-family: 'Courier New', Courier, monospace; + } + + .mat-elevation-z8{ + margin-top: 20px; + } + tr:hover { + background-color: rgba(219, 219, 219, 0.219); + } + + .detailBtn{ + cursor: pointer; + } + + .search-container { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 0 5px; + box-sizing: border-box; + } + + .search-string { + flex: 2; + padding: 5px; + } + + .search-boolean { + flex: 1; + padding: 5px; + } \ No newline at end of file diff --git a/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.html b/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.html index aba3a48..699c4ea 100644 --- a/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.html +++ b/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.html @@ -1 +1,72 @@ -

commands-groups works!

+
+

Administrar Grupos de Comandos

+
+ +
+
+ +
+ + Buscar nombre de grupo + + search + Pulsar 'enter' para buscar + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Nombre del grupo {{ group.name }} Creado por {{ group.createdBy }} Fecha de creación {{ group.createdAt | date:'short' }} Acciones + + + + + + +
+ +
+ + +
+ \ No newline at end of file diff --git a/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.ts b/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.ts index 8729d11..e5fd3c5 100644 --- a/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.ts +++ b/ogWebconsole/src/app/components/commands/commands-groups/commands-groups.component.ts @@ -1,10 +1,87 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { MatDialog } from '@angular/material/dialog'; +import { ToastrService } from 'ngx-toastr'; +import { CreateCommandGroupComponent } from './create-command-group/create-command-group.component' +import { DetailCommandGroupComponent } from './detail-command-group/detail-command-group.component'; +import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component'; @Component({ selector: 'app-commands-groups', templateUrl: './commands-groups.component.html', - styleUrl: './commands-groups.component.css' + styleUrls: ['./commands-groups.component.css'] }) -export class CommandsGroupsComponent { +export class CommandsGroupsComponent implements OnInit { + baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; + commandGroups: any[] = []; + filters: { [key: string]: string | boolean } = {}; + length: number = 0; + itemsPerPage: number = 10; + page: number = 1; + pageSizeOptions: number[] = [5, 10, 20, 40, 100]; + displayedColumns: string[] = ['name', 'createdBy', 'createdAt', 'actions']; + private apiUrl = `${this.baseUrl}/command-groups`; + constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {} + + ngOnInit(): void { + this.search(); + } + + search(): void { + this.http.get(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe( + (data) => { + this.commandGroups = data['hydra:member']; + this.length = data['hydra:totalItems']; + }, + (error) => { + console.error('Error fetching command groups', error); + } + ); + } + + viewGroupDetails(group: any): void { + this.dialog.open(DetailCommandGroupComponent, { + width: '800px', + data: group, + }).afterClosed().subscribe(() => this.search()); + } + + openCreateCommandGroupModal(): void { + this.dialog.open(CreateCommandGroupComponent, { + width: '600px', + }).afterClosed().subscribe(() => this.search()); + } + + editCommandGroup(group: any): void { + this.dialog.open(CreateCommandGroupComponent, { + width: '600px', + data: { group }, + }).afterClosed().subscribe(() => this.search()); + } + + deleteCommandGroup(group: any): void { + this.dialog.open(DeleteModalComponent, { + width: '300px', + data: { name: group.name }, + }).afterClosed().subscribe((result) => { + if (result) { + this.http.delete(`${this.apiUrl}/${group.uuid}`).subscribe({ + next: () => { + this.toastService.success('Grupo de comandos eliminado con éxito'); + this.search(); + }, + error: (error) => { + console.error('Error al eliminar el grupo de comandos:', error); + } + }); + } + }); + } + + onPageChange(event: any): void { + this.page = event.pageIndex; + this.itemsPerPage = event.pageSize; + this.search(); + } } diff --git a/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.css b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.css new file mode 100644 index 0000000..1b1578d --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.css @@ -0,0 +1,58 @@ +.create-command-group-container { + padding: 20px; + } + + .command-group-form { + display: flex; + flex-direction: column; + } + + .command-selection { + display: flex; + justify-content: space-between; + margin: 20px 0; + } + + .available-commands, .selected-commands { + width: 48%; + } + + .selected-commands-list { + border: 1px solid #ccc; + border-radius: 4px; + padding: 10px; + background-color: #f9f9f9; + } + + .commands-container { + display: flex; + flex-direction: column; + } + + .command-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px; + background-color: #fff; + border-radius: 4px; + margin-bottom: 8px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + } + + .remove-icon { + cursor: pointer; + color: #f44336; /* Rojo para eliminar */ + } + + .chevron-icon { + margin: 0 10px; + color: #666; + } + + .command-group-actions { + margin-top: 20px; + display: flex; + justify-content: space-between; + } + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.html b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.html new file mode 100644 index 0000000..11142fc --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.html @@ -0,0 +1,63 @@ +
+

Crear Grupo de Comandos

+ +
+ + Nombre del Grupo + + + + + Posición + + + + Habilitado + +
+
+

Comandos Disponibles

+ + + + + + + + + + + + + +
Nombre {{ command.name }} Acciones + +
+
+ +
+

Comandos Seleccionados

+
+
+ +
+ {{ command.name }} + close +
+ + chevron_right + +
+
+
+
+
+ +
+ + +
+
+
diff --git a/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.spec.ts b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.spec.ts new file mode 100644 index 0000000..d9f2d35 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateCommandGroupComponent } from './create-command-group.component'; + +describe('CreateCommandGroupComponent', () => { + let component: CreateCommandGroupComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CreateCommandGroupComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CreateCommandGroupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.ts b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.ts new file mode 100644 index 0000000..2d4bd88 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/create-command-group/create-command-group.component.ts @@ -0,0 +1,76 @@ +import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { MatDialogRef } from '@angular/material/dialog'; +import { ToastrService } from 'ngx-toastr'; + +@Component({ + selector: 'app-create-command-group', + templateUrl: './create-command-group.component.html', + styleUrls: ['./create-command-group.component.css'] +}) +export class CreateCommandGroupComponent implements OnInit { + baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; + availableCommands: any[] = []; + selectedCommands: any[] = []; + groupName: string = ''; + position: number = 1; + enabled: boolean = true; + + private apiUrl = 'http://127.0.0.1:8001/commands'; + + constructor( + private http: HttpClient, + private dialogRef: MatDialogRef, + private toastService: ToastrService + ) {} + + ngOnInit(): void { + this.loadAvailableCommands(); + } + + loadAvailableCommands(): void { + this.http.get(this.apiUrl).subscribe( + (data) => { + this.availableCommands = data['hydra:member']; + }, + (error) => { + console.error('Error fetching available commands', error); + } + ); + } + + addCommand(command: any): void { + this.selectedCommands.push(command); + } + + removeCommand(command: any): void { + const index = this.selectedCommands.indexOf(command); + if (index >= 0) { + this.selectedCommands.splice(index, 1); + } + } + + onSubmit(): void { + const payload = { + name: this.groupName, + commands: this.selectedCommands.map(cmd => cmd['@id']), + position: this.position, + enabled: this.enabled + }; + + console.log('Payload', payload); + this.http.post('http://127.0.0.1:8001/command-groups', payload).subscribe({ + next: () => { + this.toastService.success('Grupo de comandos creado con éxito'); + this.dialogRef.close(); + }, + error: (error) => { + console.error('Error creando el grupo de comandos', error); + } + }); + } + + close(): void { + this.dialogRef.close(); + } +} diff --git a/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.css b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.css new file mode 100644 index 0000000..f0fdfb9 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.css @@ -0,0 +1,155 @@ +.detail-command-group-container { + padding: 20px; + } + + .mat-card { + margin: 20px 0; + border-radius: 4px; + border: 1px solid #ccc; + } + + .mat-card-header { + background-color: #f5f5f5; + border-bottom: 1px solid #ddd; + } + + .mat-card-title { + font-size: 20px; + font-weight: bold; + } + + .mat-card-subtitle { + font-size: 14px; + color: #666; + } + + .mat-card-content { + padding: 20px; + } + + h3 { + margin-top: 20px; + font-size: 18px; + } + + table { + width: 100%; + margin-top: 10px; + } + + th.mat-header-cell { + background-color: #f5f5f5; + font-weight: bold; + border-bottom: 2px solid #ccc; + } + + td.mat-cell { + padding: 10px; + border-bottom: 1px solid #ddd; + } + + tr:hover { + background-color: rgba(219, 219, 219, 0.5); + } + + .mat-card-actions { + display: flex; + justify-content: flex-end; + padding: 10px 20px; + } + + button { + background-color: #3f51b5; /* Color primario */ + color: white; + padding: 10px 15px; + border: none; + border-radius: 4px; + cursor: pointer; + } + + button:hover { + background-color: #2c387e; /* Color primario oscuro */ + } + + @media (max-width: 600px) { + .mat-card { + margin: 10px 0; + } + + h3 { + font-size: 16px; + } + + button { + width: 100%; + margin-top: 10px; + } + } + + .cancel-button { + background-color: #dc3545; + color: white; + border-radius: 5px; + } + .cancel-button:hover { + opacity: 0.9; + } + + .create-command-group-container { + padding: 20px; + } + + .command-group-form { + display: flex; + flex-direction: column; + } + + .command-selection { + display: flex; + justify-content: space-between; + margin: 20px 0; + } + + .available-commands, .selected-commands { + width: 48%; + } + + .selected-commands-list { + border: 1px solid #ccc; + border-radius: 4px; + padding: 10px; + background-color: #f9f9f9; + } + + .commands-container { + display: flex; + flex-direction: column; + } + + .command-item { + display: flex; + align-items: center; + justify-content: space-between; + padding: 8px; + background-color: #fff; + border-radius: 4px; + margin-bottom: 8px; + box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); + } + + .remove-icon { + cursor: pointer; + color: #f44336; + } + + .chevron-icon { + margin: 0 10px; + color: #666; + } + + .command-group-actions { + margin-top: 20px; + display: flex; + justify-content: space-between; + } + \ No newline at end of file diff --git a/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.html b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.html new file mode 100644 index 0000000..6054d00 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.html @@ -0,0 +1,37 @@ +
+

Detalles del Grupo de Comandos

+ + + + {{ data.name }} + Creado por: {{ data.createdBy }} + + + +

ID del Grupo: {{ data.uuid }}

+

Posición: {{ data.position }}

+

Fecha de Creación: {{ data.createdAt | date:'short' }}

+ +

Comandos Incluidos:

+ + + + + + + + + + + + + +
Nombre {{ command.name }} UUID {{ command.uuid }}
+
+ +
+
+ +
+
+ \ No newline at end of file diff --git a/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.spec.ts b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.spec.ts new file mode 100644 index 0000000..d13faae --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DetailCommandGroupComponent } from './detail-command-group.component'; + +describe('DetailCommandGroupComponent', () => { + let component: DetailCommandGroupComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DetailCommandGroupComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DetailCommandGroupComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.ts b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.ts new file mode 100644 index 0000000..15f7b02 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-groups/detail-command-group/detail-command-group.component.ts @@ -0,0 +1,18 @@ +import { Component, Inject } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; + +@Component({ + selector: 'app-detail-command-group', + templateUrl: './detail-command-group.component.html', + styleUrls: ['./detail-command-group.component.css'] +}) +export class DetailCommandGroupComponent { + constructor( + @Inject(MAT_DIALOG_DATA) public data: any, + private dialogRef: MatDialogRef + ) {} + + close(): void { + this.dialogRef.close(); + } +} diff --git a/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.html b/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.html index 385462e..7e3770d 100644 --- a/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.html +++ b/ogWebconsole/src/app/components/commands/commands-task/commands-task.component.html @@ -1 +1,66 @@ -

commands-task works!

+
+

Administrar Tareas

+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Nombre {{ task.name }} Grupo de Comandos {{ task.commandGroup.name }} Fecha de Ejecución {{ task.scheduledDate | date:'short' }} Estado {{ task.enabled ? 'Habilitado' : 'Deshabilitado' }} Acciones + + + + + + +
+ + + + \ No newline at end of file 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 15cf5ff..95d6ab7 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 @@ -1,10 +1,87 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { MatDialog } from '@angular/material/dialog'; +import { ToastrService } from 'ngx-toastr'; +import { CreateTaskComponent } from './create-task/create-task.component'; +import { DetailTaskComponent } from './detail-task/detail-task.component'; +import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component'; @Component({ selector: 'app-commands-task', templateUrl: './commands-task.component.html', - styleUrl: './commands-task.component.css' + styleUrls: ['./commands-task.component.css'] }) -export class CommandsTaskComponent { +export class CommandsTaskComponent implements OnInit { + baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; + tasks: any[] = []; + filters: { [key: string]: string | boolean } = {}; + length: number = 0; + itemsPerPage: number = 10; + page: number = 1; + pageSizeOptions: number[] = [5, 10, 20, 40, 100]; + displayedColumns: string[] = ['name', 'commandGroup', 'scheduledDate', 'enabled', 'actions']; + private apiUrl = `${this.baseUrl}/tasks`; + constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {} + + ngOnInit(): void { + this.loadTasks(); + } + + loadTasks(): void { + this.http.get(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe( + (data) => { + this.tasks = data['hydra:member']; + this.length = data['hydra:totalItems']; + }, + (error) => { + console.error('Error fetching tasks', error); + } + ); + } + + viewTaskDetails(task: any): void { + this.dialog.open(DetailTaskComponent, { + width: '800px', + data: task, + }).afterClosed().subscribe(() => this.loadTasks()); + } + + openCreateTaskModal(): void { + this.dialog.open(CreateTaskComponent, { + width: '600px', + }).afterClosed().subscribe(() => this.loadTasks()); + } + + editTask(task: any): void { + this.dialog.open(CreateTaskComponent, { + width: '600px', + data: { task }, + }).afterClosed().subscribe(() => this.loadTasks()); + } + + deleteTask(task: any): void { + this.dialog.open(DeleteModalComponent, { + width: '300px', + data: { name: task.name }, + }).afterClosed().subscribe((result) => { + if (result) { + this.http.delete(`${this.apiUrl}/${task.uuid}`).subscribe({ + next: () => { + this.toastService.success('Tarea eliminada con éxito'); + this.loadTasks(); + }, + error: (error) => { + console.error('Error al eliminar la tarea:', error); + } + }); + } + }); + } + + onPageChange(event: any): void { + this.page = event.pageIndex; + this.itemsPerPage = event.pageSize; + this.loadTasks(); + } } diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.css b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.css new file mode 100644 index 0000000..c1ecdce --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.css @@ -0,0 +1,25 @@ +.full-width { + width: 100%; + } + + .commands-list { + margin-top: 10px; + margin-bottom: 10px; + padding: 10px; + border: 1px solid #ccc; + background-color: #f9f9f9; + border-radius: 4px; + } + + .command-item { + padding: 10px; + background-color: #f4f4f4; + margin-bottom: 10px; + border: 1px solid #ddd; + border-radius: 4px; + } + + .command-item:hover { + background-color: #e9e9e9; + } + \ No newline at end of file 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 new file mode 100644 index 0000000..467f882 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.html @@ -0,0 +1,44 @@ +

Crear Tarea

+ + + + Selecciona un Grupo de Comandos + + + {{ group.name }} + + + Este campo es obligatorio + + +
+

Comandos del Grupo Seleccionado

+
+ {{ command.name }} +
+
+ + + Fecha de Ejecución + + + + Este campo es obligatorio + + + + Hora de Ejecución + + Este campo es obligatorio + + + + Notas + + +
+ + + + + diff --git a/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.spec.ts b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.spec.ts new file mode 100644 index 0000000..a6169eb --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CreateTaskComponent } from './create-task.component'; + +describe('CreateTaskComponent', () => { + let component: CreateTaskComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [CreateTaskComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(CreateTaskComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); 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 new file mode 100644 index 0000000..3bc5220 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-task/create-task/create-task.component.ts @@ -0,0 +1,100 @@ +import { Component, OnInit, Inject } from '@angular/core'; +import { HttpClient } from '@angular/common/http'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; +import { ToastrService } from 'ngx-toastr'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; + +@Component({ + selector: 'app-create-task', + templateUrl: './create-task.component.html', + styleUrls: ['./create-task.component.css'] +}) +export class CreateTaskComponent implements OnInit { + baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; + taskForm: FormGroup; + availableCommandGroups: any[] = []; + selectedGroupCommands: any[] = []; + apiUrl = `${this.baseUrl}/command-tasks`; + + constructor( + private fb: FormBuilder, + private http: HttpClient, + private toastr: ToastrService, + public dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.taskForm = this.fb.group({ + commandGroup: ['', Validators.required], + date: ['', Validators.required], + time: ['', Validators.required], + notes: [''] + }); + } + + ngOnInit(): void { + this.loadCommandGroups(); + } + + loadCommandGroups(): void { + this.http.get(`${this.baseUrl}/command-groups`).subscribe( + (data) => { + this.availableCommandGroups = data['hydra:member']; + }, + (error) => { + this.toastr.error('Error al cargar los grupos de comandos'); + } + ); + } + + onCommandGroupChange(): void { + const selectedGroupId = this.taskForm.get('commandGroup')?.value; + this.http.get(`${this.baseUrl}/command-groups/${selectedGroupId}`).subscribe( + (data) => { + this.selectedGroupCommands = data.commands; + }, + (error) => { + this.toastr.error('Error al cargar los comandos del grupo seleccionado'); + } + ); + } + + saveTask(): void { + if (this.taskForm.invalid) { + this.toastr.error('Por favor, rellene todos los campos obligatorios'); + return; + } + + const formData = this.taskForm.value; + const dateTime = this.combineDateAndTime(formData.date, formData.time); + + const payload = { + commandGroups: '/command-groups/'+formData.commandGroup, + commands: this.selectedGroupCommands.map(cmd => cmd['@id']), + dateTime: dateTime, + notes: formData.notes || '' + }; + console.log(payload); + stop; + this.http.post(this.apiUrl, payload).subscribe({ + next: () => { + this.toastr.success('Tarea creada con éxito'); + this.dialogRef.close(true); + }, + error: () => { + this.toastr.error('Error al crear la tarea'); + } + }); + } + + combineDateAndTime(date: string, time: string): string { + const dateObj = new Date(date); + const [hours, minutes] = time.split(':').map(Number); + + dateObj.setHours(hours, minutes, 0); + return dateObj.toISOString(); // Return in ISO format (e.g., 2021-10-01T00:00:00+00:00) + } + + close(): void { + this.dialogRef.close(); + } +} diff --git a/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.css b/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.css new file mode 100644 index 0000000..e69de29 diff --git a/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.html b/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.html new file mode 100644 index 0000000..015f118 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.html @@ -0,0 +1 @@ +

detail-task works!

diff --git a/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.spec.ts b/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.spec.ts new file mode 100644 index 0000000..7fa5c15 --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.spec.ts @@ -0,0 +1,23 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { DetailTaskComponent } from './detail-task.component'; + +describe('DetailTaskComponent', () => { + let component: DetailTaskComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [DetailTaskComponent] + }) + .compileComponents(); + + fixture = TestBed.createComponent(DetailTaskComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.ts b/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.ts new file mode 100644 index 0000000..ca6401d --- /dev/null +++ b/ogWebconsole/src/app/components/commands/commands-task/detail-task/detail-task.component.ts @@ -0,0 +1,10 @@ +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-detail-task', + templateUrl: './detail-task.component.html', + styleUrl: './detail-task.component.css' +}) +export class DetailTaskComponent { + +} diff --git a/ogWebconsole/src/app/components/commands/main-commands/commands.component.css b/ogWebconsole/src/app/components/commands/main-commands/commands.component.css index c98fd38..fffd686 100644 --- a/ogWebconsole/src/app/components/commands/main-commands/commands.component.css +++ b/ogWebconsole/src/app/components/commands/main-commands/commands.component.css @@ -44,4 +44,23 @@ tr:hover { .detailBtn{ cursor: pointer; +} + +.search-container { + display: flex; + justify-content: space-between; + align-items: center; + width: 100%; + padding: 0 5px; + box-sizing: border-box; +} + +.search-string { + flex: 2; + padding: 5px; +} + +.search-boolean { + flex: 1; + padding: 5px; } \ No newline at end of file diff --git a/ogWebconsole/src/app/components/commands/main-commands/commands.component.html b/ogWebconsole/src/app/components/commands/main-commands/commands.component.html index f974425..b99a3b0 100644 --- a/ogWebconsole/src/app/components/commands/main-commands/commands.component.html +++ b/ogWebconsole/src/app/components/commands/main-commands/commands.component.html @@ -1,9 +1,18 @@
-

Administrar comandos

-
+

Administrar comandos

+
+ +
+ + Buscar nombre de comando + + search + Pulsar 'enter' para buscar + +
@@ -51,3 +60,12 @@
+ +
+ + +
diff --git a/ogWebconsole/src/app/components/commands/main-commands/commands.component.ts b/ogWebconsole/src/app/components/commands/main-commands/commands.component.ts index 81460c5..2eec6ff 100644 --- a/ogWebconsole/src/app/components/commands/main-commands/commands.component.ts +++ b/ogWebconsole/src/app/components/commands/main-commands/commands.component.ts @@ -1,10 +1,10 @@ import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { MatDialog } from '@angular/material/dialog'; +import { ToastrService } from 'ngx-toastr'; import { CommandDetailComponent } from './detail-command/command-detail.component'; import { CreateCommandComponent } from './create-command/create-command.component'; import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component'; -import { ToastrService } from 'ngx-toastr'; @Component({ selector: 'app-commands', @@ -14,19 +14,25 @@ import { ToastrService } from 'ngx-toastr'; export class CommandsComponent implements OnInit { baseUrl: string = import.meta.env.NG_APP_BASE_API_URL; commands: any[] = []; - displayedColumns: string[] = ['name', 'createdBy', 'createdAt', 'actions']; - private apiUrl = 'http://127.0.0.1:8001/commands?page=1&itemsPerPage=30'; + filters: { [key: string]: string | boolean } = {}; + length: number = 0; + itemsPerPage: number = 10; + page: number = 1; + pageSizeOptions: number[] = [5, 10, 20, 40, 100]; + displayedColumns: string[] = ['name', 'createdBy', 'createdAt', 'actions']; + private apiUrl = `${this.baseUrl}/commands`; - constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) { } + constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {} ngOnInit(): void { - this.loadCommands(); + this.search(); } - loadCommands(): void { - this.http.get(this.apiUrl).subscribe( + search(): void { + this.http.get(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe( (data) => { this.commands = data['hydra:member']; + this.length = data['hydra:totalItems']; }, (error) => { console.error('Error fetching commands', error); @@ -34,66 +40,48 @@ export class CommandsComponent implements OnInit { ); } - openCreateCommandModal(): void { - const dialogRef = this.dialog.open(CreateCommandComponent, { - width: '600px' - }); + viewDetails(command: any): void { + this.dialog.open(CommandDetailComponent, { + width: '800px', + data: command, + }).afterClosed().subscribe(() => this.search()); + } - dialogRef.afterClosed().subscribe(result => { - this.loadCommands(); - }); + openCreateCommandModal(): void { + this.dialog.open(CreateCommandComponent, { + width: '600px', + }).afterClosed().subscribe(() => this.search()); } editCommand(command: any): void { - const dialogRef = this.dialog.open(CreateCommandComponent, { + this.dialog.open(CreateCommandComponent, { width: '600px', - data: { command: command } - }); + data: { command }, + }).afterClosed().subscribe(() => this.search()); + } - dialogRef.afterClosed().subscribe(result => { + deleteCommand(command: any): void { + this.dialog.open(DeleteModalComponent, { + width: '300px', + data: { name: command.name }, + }).afterClosed().subscribe((result) => { if (result) { - console.log('Comando editado:', result); - this.loadCommands(); + this.http.delete(`${this.apiUrl}/${command.uuid}`).subscribe({ + next: () => { + this.toastService.success('Comando eliminado con éxito'); + this.search(); + }, + error: (error) => { + console.error('Error al eliminar el comando:', error); + } + }); } }); } - viewDetails(command: any): void { - const dialogRef = this.dialog.open(CommandDetailComponent, { - width: '800px', - data: command - }); - - dialogRef.afterClosed().subscribe(result => { - this.loadCommands(); - }); + onPageChange(event: any): void { + this.page = event.pageIndex; + this.itemsPerPage = event.pageSize; + this.search(); } - - deleteCommand(command: any): void { - const dialogRef = this.dialog.open(DeleteModalComponent, - { - width: '300px', - data: { name: command.name } - }); - - dialogRef.afterClosed().subscribe(result => { - if (result) { - const apiUrl = `${this.baseUrl}/commands/${command.uuid}`; - - this.http.delete(apiUrl).subscribe({ - next: () => { - console.log('Role deleted successfully'); - this.loadCommands(); - this.toastService.success('Role deleted successfully'); - }, - error: (error) => { - console.error('Error deleting role:', error); - } - }); - } else { - console.log('Role deletion cancelled'); - } - }); - } - } diff --git a/ogWebconsole/src/app/layout/sidebar/sidebar.component.css b/ogWebconsole/src/app/layout/sidebar/sidebar.component.css index 8267199..a74eca6 100644 --- a/ogWebconsole/src/app/layout/sidebar/sidebar.component.css +++ b/ogWebconsole/src/app/layout/sidebar/sidebar.component.css @@ -1,6 +1,6 @@ mat-nav-list { width: auto; - margin-right: 3px; + margin-right: 5px; overflow-x: hidden; } @@ -18,7 +18,7 @@ mat-list-item { } mat-icon { - margin-right: 8px; + margin-right: 5px; } .user-logged { diff --git a/ogWebconsole/src/app/layout/sidebar/sidebar.component.html b/ogWebconsole/src/app/layout/sidebar/sidebar.component.html index ee7546b..bb4e55d 100644 --- a/ogWebconsole/src/app/layout/sidebar/sidebar.component.html +++ b/ogWebconsole/src/app/layout/sidebar/sidebar.component.html @@ -31,13 +31,13 @@ - splitscreen_add - Grupo de comandos + chevron_right + Grupos - task + chevron_right Tareas