,
+ private toastService: ToastrService,
+ private dataService: DataService,
+ @Inject(MAT_DIALOG_DATA) public data: any
+ ) {
+ this.menuForm = this.fb.group({
+ name: ['', Validators.required],
+ publicUrl: ['', Validators.required],
+ resolution: ['', Validators.required],
+ comments: [''],
+ });
+ }
+
+ ngOnInit() {
+ if (this.data) {
+ this.load()
+ }
+ }
+
+ load(): void {
+ this.dataService.getImage(this.data).subscribe({
+ next: (response) => {
+ this.menuForm = this.fb.group({
+ name: [response.name, Validators.required],
+ publicUrl: [response.publicUrl, Validators.required],
+ resolution: [response.resolution, Validators.required],
+ comments: [response.comments],
+ });
+ this.menuId = response['@id'];
+ },
+ error: (err) => {
+ console.error('Error fetching remote calendar:', err);
+ }
+ });
+ }
+
+ save(): void {
+ const payload = {
+ name: this.menuForm.value.name,
+ publicUrl: this.menuForm.value.publicUrl,
+ resolution: this.menuForm.value.resolution,
+ comments: this.menuForm.value.comments,
+ };
+
+ if (this.menuId) {
+ this.http.put(`${this.baseUrl}${this.menuId}`, payload).subscribe(
+ (response) => {
+ this.toastService.success('Menu editado correctamente');
+ this.dialogRef.close();
+ },
+ (error) => {
+ this.toastService.error(error['error']['hydra:description']);
+ console.error('Error al editar la imagen', error);
+ }
+ );
+ } else {
+ this.http.post(`${this.baseUrl}/menus`, payload).subscribe(
+ (response) => {
+ this.toastService.success('Menu añadido correctamente');
+ this.dialogRef.close();
+ },
+ (error) => {
+ this.toastService.error(error['error']['hydra:description']);
+ console.error('Error al añadir el menu', error);
+ }
+ );
+ }
+ }
+
+ close(): void {
+ this.dialogRef.close();
+ }
+}
diff --git a/ogWebconsole/src/app/components/menus/menus.component.css b/ogWebconsole/src/app/components/menus/menus.component.css
new file mode 100644
index 0000000..cbdd6d8
--- /dev/null
+++ b/ogWebconsole/src/app/components/menus/menus.component.css
@@ -0,0 +1,83 @@
+.title {
+ font-size: 24px;
+}
+
+.images-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;
+}
+
+.image-container {
+ display: flex;
+ align-items: center;
+ margin-bottom: 16px;
+ border-bottom: 1px solid rgba(122, 122, 122, 0.555);
+}
+
+.image-container h4 {
+ margin: 0;
+ flex: 1;
+}
+
+.image-name{
+ cursor: pointer;
+}
+
+table {
+ width: 100%;
+ margin-top: 50px;
+}
+
+.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;
+}
+
+.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;
+}
diff --git a/ogWebconsole/src/app/components/menus/menus.component.html b/ogWebconsole/src/app/components/menus/menus.component.html
new file mode 100644
index 0000000..031ca6e
--- /dev/null
+++ b/ogWebconsole/src/app/components/menus/menus.component.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+ Buscar nombre de menú
+
+ search
+ Pulsar 'enter' para buscar
+
+
+
+
+
+ {{ column.header }} |
+
+
+ {{ column.cell(menu) }}
+
+ |
+
+
+
+ Acciones |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/ogWebconsole/src/app/components/menus/menus.component.spec.ts b/ogWebconsole/src/app/components/menus/menus.component.spec.ts
new file mode 100644
index 0000000..4f5c591
--- /dev/null
+++ b/ogWebconsole/src/app/components/menus/menus.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { MenusComponent } from './menus.component';
+
+describe('MenusComponent', () => {
+ let component: MenusComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [MenusComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(MenusComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ogWebconsole/src/app/components/menus/menus.component.ts b/ogWebconsole/src/app/components/menus/menus.component.ts
new file mode 100644
index 0000000..4434d07
--- /dev/null
+++ b/ogWebconsole/src/app/components/menus/menus.component.ts
@@ -0,0 +1,141 @@
+import { Component } from '@angular/core';
+import {MatTableDataSource} from "@angular/material/table";
+import {DatePipe} from "@angular/common";
+import {MatDialog} from "@angular/material/dialog";
+import {HttpClient} from "@angular/common/http";
+import {ToastrService} from "ngx-toastr";
+import {JoyrideService} from "ngx-joyride";
+import {Router} from "@angular/router";
+import {CreateRepositoryComponent} from "../repositories/create-repository/create-repository.component";
+import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component";
+import {CreateMenuComponent} from "./create-menu/create-menu.component";
+import {CreateImageComponent} from "../images/create-image/create-image.component";
+
+@Component({
+ selector: 'app-menus',
+ templateUrl: './menus.component.html',
+ styleUrl: './menus.component.css'
+})
+export class MenusComponent {
+ baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
+ dataSource = new MatTableDataSource();
+ length: number = 0;
+ itemsPerPage: number = 10;
+ page: number = 0;
+ loading: boolean = false;
+ filters: { [key: string]: string } = {};
+ datePipe: DatePipe = new DatePipe('es-ES');
+ columns = [
+ {
+ columnDef: 'id',
+ header: 'Id',
+ cell: (repository: any) => `${repository.id}`
+ },
+ {
+ columnDef: 'name',
+ header: 'Nombre de menú',
+ cell: (repository: any) => `${repository.name}`
+ },
+ {
+ columnDef: 'publicUrl',
+ header: 'Url pública',
+ cell: (repository: any) => `${repository.publicUrl}`
+ },
+ {
+ columnDef: 'resolution',
+ header: 'Resolución',
+ cell: (repository: any) => `${repository.resolution}`
+ },
+ {
+ columnDef: 'createdAt',
+ header: 'Fecha de creación',
+ cell: (repository: any) => `${this.datePipe.transform(repository.createdAt, 'dd/MM/yyyy hh:mm:ss')}`
+ }
+ ];
+ displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];
+
+ private apiUrl = `${this.baseUrl}/menus`;
+
+ constructor(
+ public dialog: MatDialog,
+ private http: HttpClient,
+ private toastService: ToastrService,
+ private joyrideService: JoyrideService,
+ private router: Router
+ ) {}
+
+ ngOnInit(): void {
+ this.search();
+ }
+
+ addImage(): void {
+ const dialogRef = this.dialog.open(CreateMenuComponent, {
+ width: '600px'
+ });
+
+ dialogRef.afterClosed().subscribe(() => {
+ this.search();
+ });
+ }
+
+ search(): void {
+ this.loading = true;
+ this.http.get(`${this.apiUrl}?page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
+ data => {
+ this.dataSource.data = data['hydra:member'];
+ this.length = data['hydra:totalItems'];
+ this.loading = false;
+ },
+ error => {
+ console.error('Error fetching images', error);
+ this.loading = false;
+ }
+ );
+ }
+
+ editMenu(event: MouseEvent, menu: any): void {
+ event.stopPropagation();
+ this.dialog.open(CreateMenuComponent, {
+ width: '800px',
+ data: menu['@id']
+ }).afterClosed().subscribe(() => this.search());
+ }
+
+ deleteMenu(event: MouseEvent,menu: any): void {
+ event.stopPropagation();
+ this.dialog.open(DeleteModalComponent, {
+ width: '300px',
+ data: { name: menu.name },
+ }).afterClosed().subscribe((result) => {
+ if (result) {
+ this.http.delete(`${this.apiUrl}/${menu.uuid}`).subscribe({
+ next: () => {
+ this.toastService.success('Menu eliminado con éxito');
+ this.search();
+ },
+ error: (error) => {
+ console.error('Error al eliminar el menú:', error);
+ }
+ });
+ }
+ });
+ }
+
+ onPageChange(event: any): void {
+ this.page = event.pageIndex;
+ this.itemsPerPage = event.pageSize;
+ this.length = event.length;
+ this.search();
+ }
+
+ iniciarTour(): void {
+ this.joyrideService.startTour({
+ steps: [
+ 'titleStep',
+ 'addStep',
+ ],
+ showPrevButton: true,
+ themeColor: '#3f51b5'
+ });
+ }
+}
diff --git a/ogWebconsole/src/app/components/repositories/repositories.component.ts b/ogWebconsole/src/app/components/repositories/repositories.component.ts
index 2845c94..20229db 100644
--- a/ogWebconsole/src/app/components/repositories/repositories.component.ts
+++ b/ogWebconsole/src/app/components/repositories/repositories.component.ts
@@ -128,5 +128,4 @@ export class RepositoriesComponent {
themeColor: '#3f51b5'
});
}
-
}
diff --git a/ogWebconsole/src/app/layout/sidebar/sidebar.component.html b/ogWebconsole/src/app/layout/sidebar/sidebar.component.html
index a343128..e8a12f2 100644
--- a/ogWebconsole/src/app/layout/sidebar/sidebar.component.html
+++ b/ogWebconsole/src/app/layout/sidebar/sidebar.component.html
@@ -151,17 +151,10 @@
-
+
list
{{ 'menus' | translate }}
-
-
-
- search
- {{ 'search' | translate }}
-
-
diff --git a/ogWebconsole/src/locale/en.json b/ogWebconsole/src/locale/en.json
index ea2edaa..311bee0 100644
--- a/ogWebconsole/src/locale/en.json
+++ b/ogWebconsole/src/locale/en.json
@@ -211,6 +211,7 @@
"mcastPortLabel": "Multicast Port",
"mcastModeLabel": "Multicast Mode",
"menuUrlLabel": "Menu URL",
+ "menuLabel": "Menu",
"hardwareProfileLabel": "Hardware Profile",
"urlFormatError": "Invalid URL format.",
"validationToggle": "Validation",
diff --git a/ogWebconsole/src/locale/es.json b/ogWebconsole/src/locale/es.json
index 967e9b4..0033d35 100644
--- a/ogWebconsole/src/locale/es.json
+++ b/ogWebconsole/src/locale/es.json
@@ -363,6 +363,7 @@
"selectOptionPlaceholder": "Selecciona una opción",
"yesOption": "Sí",
"noOption": "No",
+ "menuLabel": "Menu",
"actionsColumn": "Acciones",
"createServerButton": "Crear servidor",
"labelName": "Nombre",