diff --git a/ogWebconsole/src/app/app-routing.module.ts b/ogWebconsole/src/app/app-routing.module.ts
index 925f4e6..bca74a7 100644
--- a/ogWebconsole/src/app/app-routing.module.ts
+++ b/ogWebconsole/src/app/app-routing.module.ts
@@ -30,6 +30,7 @@ import {OperativeSystemComponent} from "./components/operative-system/operative-
import {
PartitionAssistantComponent
} from "./components/groups/components/client-main-view/partition-assistant/partition-assistant.component";
+import {RepositoriesComponent} from "./components/repositories/repositories.component";
const routes: Routes = [
{ path: '', redirectTo: 'auth/login', pathMatch: 'full' },
{
@@ -56,6 +57,7 @@ const routes: Routes = [
{ path: 'client/:id', component: ClientMainViewComponent },
{ path: 'client/:id/partition-assistant', component: PartitionAssistantComponent },
{ path: 'images', component: ImagesComponent },
+ { path: 'repositories', component: RepositoriesComponent },
{ path: 'restore-image', component: RestoreImageComponent},
{ path: 'software', component: SoftwareComponent },
{ path: 'software-profiles', component: SoftwareProfileComponent },
diff --git a/ogWebconsole/src/app/app.module.ts b/ogWebconsole/src/app/app.module.ts
index d1f5901..02bb02b 100644
--- a/ogWebconsole/src/app/app.module.ts
+++ b/ogWebconsole/src/app/app.module.ts
@@ -116,6 +116,8 @@ import { CreateOperativeSystemComponent } from './components/operative-system/cr
import { ShowTemplateContentComponent } from './components/ogboot/pxe/show-template-content/show-template-content.component';
import { AddClientsToPxeComponent } from './components/ogboot/pxe/add-clients-to-pxe/add-clients-to-pxe.component';
import { ClientsComponent } from './components/ogboot/pxe/clients/clients.component';
+import { RepositoriesComponent } from './components/repositories/repositories.component';
+import { CreateRepositoryComponent } from './components/repositories/create-repository/create-repository.component';
@NgModule({
declarations: [
AppComponent,
@@ -189,6 +191,8 @@ import { ClientsComponent } from './components/ogboot/pxe/clients/clients.compon
ShowTemplateContentComponent,
AddClientsToPxeComponent,
ClientsComponent,
+ RepositoriesComponent,
+ CreateRepositoryComponent,
],
bootstrap: [AppComponent],
imports: [BrowserModule,
diff --git a/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.css b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.css
new file mode 100644
index 0000000..57c71a9
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.css
@@ -0,0 +1,43 @@
+.dialog-content {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+}
+
+.repository-form {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+}
+
+.form-field {
+ width: 100%;
+ margin-bottom: 16px;
+}
+
+.dialog-actions {
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 24px;
+}
+
+button {
+ margin-left: 8px;
+}
+
+@media (max-width: 600px) {
+ .form-field {
+ width: 100%;
+ }
+
+ .dialog-actions {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ button {
+ width: 100%;
+ margin-left: 0;
+ margin-bottom: 8px;
+ }
+}
diff --git a/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.html b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.html
new file mode 100644
index 0000000..501d1fa
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.html
@@ -0,0 +1,25 @@
+
{{ repositoryId ? 'Editar' : 'Añadir' }} repositorio
+
+
+
+
+
+
+
+
+
diff --git a/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.spec.ts b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.spec.ts
new file mode 100644
index 0000000..fbdb87b
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { CreateRepositoryComponent } from './create-repository.component';
+
+describe('CreateRepositoryComponent', () => {
+ let component: CreateRepositoryComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [CreateRepositoryComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(CreateRepositoryComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.ts b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.ts
new file mode 100644
index 0000000..634dd4f
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/create-repository/create-repository.component.ts
@@ -0,0 +1,91 @@
+import {Component, Inject} from '@angular/core';
+import {FormBuilder, FormGroup, Validators} from "@angular/forms";
+import {HttpClient} from "@angular/common/http";
+import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog";
+import {ToastrService} from "ngx-toastr";
+import {DataService} from "../../images/data.service";
+
+@Component({
+ selector: 'app-create-repository',
+ templateUrl: './create-repository.component.html',
+ styleUrl: './create-repository.component.css'
+})
+export class CreateRepositoryComponent {
+ baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
+ imageForm: FormGroup;
+ repositoryId: string | null = null;
+ softwareProfiles: any[] = [];
+
+ constructor(
+ private fb: FormBuilder,
+ private http: HttpClient,
+ public dialogRef: MatDialogRef,
+ private toastService: ToastrService,
+ private dataService: DataService,
+ @Inject(MAT_DIALOG_DATA) public data: any
+ ) {
+ this.imageForm = this.fb.group({
+ name: ['', Validators.required],
+ ip: [''],
+ comments: [''],
+ });
+ }
+
+ ngOnInit() {
+ if (this.data) {
+ this.load()
+ }
+ }
+
+ load(): void {
+ this.dataService.getImage(this.data).subscribe({
+ next: (response) => {
+ this.imageForm = this.fb.group({
+ name: [response.name, Validators.required],
+ ip: [response.ip],
+ comments: [response.comments],
+ });
+ this.repositoryId = response['@id'];
+ },
+ error: (err) => {
+ console.error('Error fetching remote calendar:', err);
+ }
+ });
+ }
+
+ save(): void {
+ const payload = {
+ name: this.imageForm.value.name,
+ ip: this.imageForm.value.ip,
+ comments: this.imageForm.value.comments,
+ };
+
+ if (this.repositoryId) {
+ this.http.put(`${this.baseUrl}${this.repositoryId}`, payload).subscribe(
+ (response) => {
+ this.toastService.success('Imagen editada 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}/image-repositories`, payload).subscribe(
+ (response) => {
+ this.toastService.success('Imagen añadida correctamente');
+ this.dialogRef.close();
+ },
+ (error) => {
+ this.toastService.error(error['error']['hydra:description']);
+ console.error('Error al añadir la imagen', error);
+ }
+ );
+ }
+ }
+
+ close(): void {
+ this.dialogRef.close();
+ }
+}
diff --git a/ogWebconsole/src/app/components/repositories/repositories.component.css b/ogWebconsole/src/app/components/repositories/repositories.component.css
new file mode 100644
index 0000000..16117cb
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/repositories.component.css
@@ -0,0 +1,102 @@
+.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;
+}
+
+.example-headers-align .mat-expansion-panel-header-description {
+ justify-content: space-between;
+ align-items: center;
+}
+
+.example-headers-align .mat-mdc-form-field + .mat-mdc-form-field {
+ margin-left: 8px;
+}
+
+.example-button-row {
+ display: table-cell;
+ max-width: 600px;
+}
+
+.example-button-row .mat-mdc-button-base {
+ margin: 8px 8px 8px 0;
+}
+
diff --git a/ogWebconsole/src/app/components/repositories/repositories.component.html b/ogWebconsole/src/app/components/repositories/repositories.component.html
new file mode 100644
index 0000000..a2e2a1e
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/repositories.component.html
@@ -0,0 +1,48 @@
+
+
+
+
+
+ Buscar nombre de imagen
+
+ search
+ Pulsar 'enter' para buscar
+
+
+
+
+
+ {{ column.header }} |
+
+
+ {{ column.cell(repository) }}
+
+ |
+
+
+
+ Acciones |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
diff --git a/ogWebconsole/src/app/components/repositories/repositories.component.spec.ts b/ogWebconsole/src/app/components/repositories/repositories.component.spec.ts
new file mode 100644
index 0000000..7169583
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/repositories.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { RepositoriesComponent } from './repositories.component';
+
+describe('RepositoriesComponent', () => {
+ let component: RepositoriesComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [RepositoriesComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(RepositoriesComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/ogWebconsole/src/app/components/repositories/repositories.component.ts b/ogWebconsole/src/app/components/repositories/repositories.component.ts
new file mode 100644
index 0000000..6c0a04b
--- /dev/null
+++ b/ogWebconsole/src/app/components/repositories/repositories.component.ts
@@ -0,0 +1,120 @@
+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 {CreateImageComponent} from "../images/create-image/create-image.component";
+import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component";
+import {CreateRepositoryComponent} from "./create-repository/create-repository.component";
+
+@Component({
+ selector: 'app-repositories',
+ templateUrl: './repositories.component.html',
+ styleUrl: './repositories.component.css'
+})
+export class RepositoriesComponent {
+ 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 repositorio',
+ cell: (repository: any) => `${repository.name}`
+ },
+ {
+ columnDef: 'ip',
+ header: 'Ip',
+ cell: (repository: any) => `${repository.ip}`
+ },
+ {
+ 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}/image-repositories`;
+
+ constructor(
+ public dialog: MatDialog,
+ private http: HttpClient,
+ private toastService: ToastrService
+ ) {}
+
+ ngOnInit(): void {
+ this.search();
+ }
+
+ addImage(): void {
+ const dialogRef = this.dialog.open(CreateRepositoryComponent, {
+ 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;
+ }
+ );
+ }
+
+ editRepository(event: MouseEvent, repository: any): void {
+ event.stopPropagation();
+ this.dialog.open(CreateRepositoryComponent, {
+ width: '600px',
+ data: repository['@id']
+ }).afterClosed().subscribe(() => this.search());
+ }
+
+ deleteRepository(event: MouseEvent,command: any): void {
+ event.stopPropagation();
+ this.dialog.open(DeleteModalComponent, {
+ width: '300px',
+ data: { name: command.name },
+ }).afterClosed().subscribe((result) => {
+ if (result) {
+ this.http.delete(`${this.apiUrl}/${command.uuid}`).subscribe({
+ next: () => {
+ this.toastService.success('Imagen eliminada con éxito');
+ this.search();
+ },
+ error: (error) => {
+ console.error('Error al eliminar la imagen:', error);
+ }
+ });
+ }
+ });
+ }
+
+ onPageChange(event: any): void {
+ this.page = event.pageIndex;
+ this.itemsPerPage = event.pageSize;
+ this.length = event.length;
+ this.search();
+ }
+}