refs #918 New images components and update sidebar links
parent
df67445b53
commit
0276c92680
|
@ -9,7 +9,7 @@ import { AdminComponent } from './components/admin/admin.component';
|
|||
import { UsersComponent } from './components/admin/users/users/users.component';
|
||||
import { RolesComponent } from './components/admin/roles/roles/roles.component';
|
||||
import { GroupsComponent } from './components/groups/groups.component';
|
||||
import { ImagesComponent } from './components/ogboot/images/images.component';
|
||||
import { PXEimagesComponent } from './components/ogboot/pxe-images/pxe-images.component';
|
||||
import { PxeComponent } from './components/ogboot/pxe/pxe.component';
|
||||
import { PxeBootFilesComponent } from './components/ogboot/pxe-boot-files/pxe-boot-files.component';
|
||||
import {OgbootStatusComponent} from "./components/ogboot/ogboot-status/ogboot-status.component";
|
||||
|
@ -21,6 +21,8 @@ import { CommandsGroupsComponent } from './components/commands/commands-groups/c
|
|||
import { CommandsTaskComponent } from './components/commands/commands-task/commands-task.component';
|
||||
import { TaskLogsComponent } from './components/commands/commands-task/task-logs/task-logs.component';
|
||||
import { StatusComponent } from "./components/ogdhcp/og-dhcp-subnets/status/status.component";
|
||||
import { ClientMainViewComponent } from './components/groups/components/client-main-view/client-main-view.component';
|
||||
import { ImagesComponent } from './components/images/images.component';
|
||||
const routes: Routes = [
|
||||
{ path: '', redirectTo: 'auth/login', pathMatch: 'full' },
|
||||
{
|
||||
|
@ -32,7 +34,7 @@ const routes: Routes = [
|
|||
{ path: 'users', component: UsersComponent },
|
||||
{ path: 'user-groups', component: RolesComponent },
|
||||
{ path: 'groups', component: GroupsComponent },
|
||||
{ path: 'images', component: ImagesComponent },
|
||||
{ path: 'pxe-images', component: PXEimagesComponent },
|
||||
{ path: 'pxe', component: PxeComponent },
|
||||
{ path: 'pxe-boot-file', component: PxeBootFilesComponent },
|
||||
{ path: 'ogboot-status', component: OgbootStatusComponent },
|
||||
|
@ -44,6 +46,8 @@ const routes: Routes = [
|
|||
{ path: 'commands-task', component: CommandsTaskComponent },
|
||||
{ path: 'commands-logs', component: TaskLogsComponent },
|
||||
{ path: 'calendars', component: CalendarComponent },
|
||||
{ path: 'client/:id', component: ClientMainViewComponent },
|
||||
{ path: 'images', component: ImagesComponent },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
@ -66,9 +66,9 @@ import { ClassroomViewDialogComponent } from './components/groups/shared/classro
|
|||
import { MatPaginator } from "@angular/material/paginator";
|
||||
import { SaveFiltersDialogComponent } from './components/groups/shared/save-filters-dialog/save-filters-dialog.component';
|
||||
import { AcctionsModalComponent } from './components/groups/shared/acctions-modal/acctions-modal.component';
|
||||
import { ImagesComponent } from './components/ogboot/images/images.component';
|
||||
import { CreateImageComponent } from './components/ogboot/images/create-image/create-image/create-image.component';
|
||||
import { InfoImageComponent } from './components/ogboot/images/info-image/info-image/info-image.component';
|
||||
import { PXEimagesComponent } from './components/ogboot/pxe-images/pxe-images.component';
|
||||
import { CreatePXEImageComponent } from './components/ogboot/pxe-images/create-image/create-image/create-image.component';
|
||||
import { InfoImageComponent } from './components/ogboot/pxe-images/info-image/info-image/info-image.component';
|
||||
import { PxeComponent } from './components/ogboot/pxe/pxe.component';
|
||||
import { CreatePxeTemplateComponent } from './components/ogboot/pxe/create-pxeTemplate/create-pxe-template.component';
|
||||
import { PxeBootFilesComponent } from './components/ogboot/pxe-boot-files/pxe-boot-files.component';
|
||||
|
@ -103,6 +103,9 @@ import { OrganizationalUnitTabViewComponent } from './components/groups/componen
|
|||
import { ServerInfoDialogComponent } from './components/ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component';
|
||||
import { StatusComponent } from './components/ogdhcp/og-dhcp-subnets/status/status.component';
|
||||
import {MatSliderModule} from '@angular/material/slider';
|
||||
import { ClientMainViewComponent } from './components/groups/components/client-main-view/client-main-view.component';
|
||||
import { ImagesComponent } from './components/images/images.component';
|
||||
import { CreateImageComponent } from './components/images/create-image/create-image.component';
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
|
@ -132,8 +135,8 @@ import {MatSliderModule} from '@angular/material/slider';
|
|||
ClassroomViewDialogComponent,
|
||||
SaveFiltersDialogComponent,
|
||||
AcctionsModalComponent,
|
||||
ImagesComponent,
|
||||
CreateImageComponent,
|
||||
PXEimagesComponent,
|
||||
CreatePXEImageComponent,
|
||||
InfoImageComponent,
|
||||
PxeComponent,
|
||||
CreatePxeTemplateComponent,
|
||||
|
@ -161,7 +164,10 @@ import {MatSliderModule} from '@angular/material/slider';
|
|||
TaskLogsComponent,
|
||||
OrganizationalUnitTabViewComponent,
|
||||
ServerInfoDialogComponent,
|
||||
StatusComponent
|
||||
StatusComponent,
|
||||
ClientMainViewComponent,
|
||||
ImagesComponent,
|
||||
CreateImageComponent
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
imports: [BrowserModule,
|
||||
|
|
|
@ -5,7 +5,7 @@ import {MatDialog} from "@angular/material/dialog";
|
|||
import {HttpClient} from "@angular/common/http";
|
||||
import {DataService} from "./data.service";
|
||||
import {ToastrService} from "ngx-toastr";
|
||||
import {InfoImageComponent} from "../ogboot/images/info-image/info-image/info-image.component";
|
||||
import {InfoImageComponent} from "../ogboot/pxe-images/info-image/info-image/info-image.component";
|
||||
import {PageEvent} from "@angular/material/paginator";
|
||||
import {CreateCalendarComponent} from "./create-calendar/create-calendar.component";
|
||||
import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component";
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
.partition-assistant {
|
||||
font-family: Arial, sans-serif;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.partition-bar {
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
height: 30px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.partition-segment {
|
||||
text-align: center;
|
||||
color: white;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.partition-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.partition-table th, .partition-table td {
|
||||
border: 1px solid #ccc;
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.remove-btn {
|
||||
background-color: red;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title">Asistente de Particionado de Disco</h2>
|
||||
</div>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<!-- Lista de particiones añadidas -->
|
||||
<h3>Particiones actuales</h3>
|
||||
<mat-list>
|
||||
<mat-list-item *ngFor="let partition of partitions">
|
||||
{{ partition.name }} - {{ partition.size }} GB - {{ partition.type }}
|
||||
<button mat-icon-button color="warn" (click)="removePartition(partition)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</mat-list-item>
|
||||
</mat-list>
|
||||
|
||||
<!-- Añadir nueva partición -->
|
||||
<h3>Añadir Partición</h3>
|
||||
<div class="partition-form">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Nombre</mat-label>
|
||||
<input matInput placeholder="Nombre de la partición" [(ngModel)]="newPartition.name">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Tamaño (GB)</mat-label>
|
||||
<input matInput type="number" placeholder="Tamaño" [(ngModel)]="newPartition.size">
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Tipo</mat-label>
|
||||
<mat-select [(ngModel)]="newPartition.type">
|
||||
<mat-option *ngFor="let type of partitionTypes" [value]="type">{{ type }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Nuevo campo para seleccionar imagen -->
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Imagen</mat-label>
|
||||
<mat-select [(ngModel)]="selectedImageUuid">
|
||||
<mat-option *ngFor="let image of images" [value]="image.uuid">
|
||||
{{ image.name }} - {{ image.description }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<!-- Botón para añadir partición -->
|
||||
<button mat-raised-button color="primary" (click)="addPartition()">Añadir Partición</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
import { Component, Input, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
|
||||
interface ClientInfo {
|
||||
name: string;
|
||||
type: string;
|
||||
ip: string;
|
||||
mac: string;
|
||||
serialNumber: string;
|
||||
netiface: string;
|
||||
netDriver: string;
|
||||
}
|
||||
|
||||
interface Partition {
|
||||
name: string;
|
||||
size: number;
|
||||
type: string;
|
||||
}
|
||||
|
||||
interface Disk {
|
||||
name: string;
|
||||
size: number;
|
||||
}
|
||||
|
||||
interface ImageData {
|
||||
name: string;
|
||||
uuid: string; // Usaremos el UUID como valor
|
||||
description: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'app-partition-assistant',
|
||||
templateUrl: './partition-assistant.component.html',
|
||||
styleUrls: ['./partition-assistant.component.css']
|
||||
})
|
||||
export class PartitionAssistantComponent implements OnInit {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
|
||||
@Input() clientUuid!: string;
|
||||
clientInfo: ClientInfo | undefined;
|
||||
availableDisks: Disk[] = [];
|
||||
selectedDisk: Disk | undefined;
|
||||
partitions: Partition[] = [];
|
||||
images: ImageData[] = []; // Lista para almacenar las imágenes cargadas
|
||||
selectedImageUuid: string = ''; // Variable para almacenar la imagen seleccionada
|
||||
|
||||
newPartition: Partition = { name: '', size: 0, type: '' };
|
||||
partitionTypes: string[] = ['NTFS', 'FAT32', 'EXT4'];
|
||||
|
||||
constructor(
|
||||
private http: HttpClient,
|
||||
private toastService: ToastrService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
if (this.clientUuid) {
|
||||
this.getClientInfo(this.clientUuid);
|
||||
} else {
|
||||
console.error('No client UUID provided!');
|
||||
}
|
||||
|
||||
// Llamada a la API para obtener las imágenes
|
||||
this.getImages();
|
||||
}
|
||||
|
||||
getClientInfo(uuid: string): void {
|
||||
this.http.get<ClientInfo>(`${this.baseUrl}/clients/${uuid}`)
|
||||
.subscribe(
|
||||
(response: ClientInfo) => {
|
||||
this.clientInfo = response;
|
||||
console.log('Client info:', this.clientInfo);
|
||||
},
|
||||
error => {
|
||||
console.error('Error fetching client info:', error);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// Método para obtener las imágenes desde la API
|
||||
getImages(): void {
|
||||
this.http.get<any>('http://127.0.0.1:8001/images?page=1&itemsPerPage=30')
|
||||
.subscribe(
|
||||
(response) => {
|
||||
this.images = response['hydra:member'];
|
||||
console.log('Images loaded:', this.images);
|
||||
},
|
||||
error => {
|
||||
console.error('Error fetching images:', error);
|
||||
this.toastService.error('Error al cargar las imágenes.');
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
addPartition(): void {
|
||||
if (this.newPartition.name && this.newPartition.size > 0 && this.newPartition.type) {
|
||||
// Añadir la partición solo si todos los campos son válidos
|
||||
this.partitions.push({ ...this.newPartition });
|
||||
this.newPartition = { name: '', size: 0, type: '' };
|
||||
} else {
|
||||
this.toastService.error('Por favor, complete todos los campos correctamente.');
|
||||
}
|
||||
}
|
||||
|
||||
removePartition(partition: Partition): void {
|
||||
this.partitions = this.partitions.filter(p => p !== partition);
|
||||
}
|
||||
}
|
|
@ -1,13 +1,4 @@
|
|||
/* Global Container */
|
||||
.container {
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 40px;
|
||||
background-color: #f4f6f9;
|
||||
font-family: 'Arial', sans-serif;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
|
||||
/* Header - Title and Icon */
|
||||
.client-header {
|
||||
|
@ -31,7 +22,7 @@
|
|||
}
|
||||
|
||||
.icon-pc {
|
||||
font-size: 100px;
|
||||
font-size: 25px;
|
||||
color: #3b82f6;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<div class="container">
|
||||
<div class="client-header">
|
||||
<div class="client-icon">
|
||||
<mat-icon class="icon-pc">computer</mat-icon>
|
||||
|
@ -17,6 +16,9 @@
|
|||
<p><strong>Type:</strong> {{ clientData?.type }}</p>
|
||||
<p><strong>MAC Address:</strong> {{ clientData?.mac }}</p>
|
||||
<p><strong>Serial Number:</strong> {{ clientData?.serialNumber }}</p>
|
||||
<h2>Organizational Unit</h2>
|
||||
<p><strong>Name:</strong> {{ clientData?.organizationalUnit?.name }}</p>
|
||||
<p><strong>Type:</strong> {{ clientData?.organizationalUnit?.type }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Disk Space Usage -->
|
||||
|
@ -42,26 +44,4 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Organizational Unit -->
|
||||
<div class="info-section">
|
||||
<h2>Organizational Unit</h2>
|
||||
<p><strong>Name:</strong> {{ clientData?.organizationalUnit?.name }}</p>
|
||||
<p><strong>Type:</strong> {{ clientData?.organizationalUnit?.type }}</p>
|
||||
</div>
|
||||
|
||||
<!-- Network Settings -->
|
||||
<div class="info-section">
|
||||
<h2>Network Settings</h2>
|
||||
<p><strong>Next Server:</strong> {{ clientData?.organizationalUnit?.networkSettings?.nextServer }}</p>
|
||||
<p><strong>Boot File Name:</strong> {{ clientData?.organizationalUnit?.networkSettings?.bootFileName }}</p>
|
||||
<p><strong>DNS:</strong> {{ clientData?.organizationalUnit?.networkSettings?.dns }}</p>
|
||||
<p><strong>Router:</strong> {{ clientData?.organizationalUnit?.networkSettings?.router }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="client-footer">
|
||||
<p><strong>Created At:</strong> {{ clientData?.createdAt | date }}</p>
|
||||
<p><strong>Created By:</strong> {{ clientData?.createdBy }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<h2 mat-dialog-title>Añadir nueva imagen</h2>
|
||||
<mat-dialog-content>
|
||||
<form>
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Nombre de la imagen</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.name" name="name" required>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Descripción</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.description" name="description">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Comentarios</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.comments" name="comments">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Tipo</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.type" name="type">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Ruta de la imagen</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.path" name="path" required>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Revisión</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.revision" name="revision">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Información</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.info" name="info">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Tamaño (en MB)</mat-label>
|
||||
<input matInput type="number" [(ngModel)]="imagePayload.size" name="size">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Cliente</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.client" name="client">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-label>Perfil de software</mat-label>
|
||||
<input matInput [(ngModel)]="imagePayload.softwareProfile" name="softwareProfile">
|
||||
</mat-form-field>
|
||||
</form>
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
<button mat-button (click)="close()">Cancelar</button>
|
||||
<button mat-button color="primary" (click)="saveImage()">Guardar</button>
|
||||
</mat-dialog-actions>
|
|
@ -0,0 +1,52 @@
|
|||
import { Component } from '@angular/core';
|
||||
import { MatDialogRef } from '@angular/material/dialog';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
|
||||
@Component({
|
||||
selector: 'app-create-image',
|
||||
templateUrl: './create-image.component.html',
|
||||
styleUrls: ['./create-image.component.css']
|
||||
})
|
||||
export class CreateImageComponent {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
imagePayload = {
|
||||
name: null,
|
||||
description: null,
|
||||
comments: null,
|
||||
type: null,
|
||||
path: null,
|
||||
revision: null,
|
||||
info: null,
|
||||
size: null,
|
||||
client: null,
|
||||
softwareProfile: null
|
||||
};
|
||||
|
||||
constructor(
|
||||
public dialogRef: MatDialogRef<CreateImageComponent>,
|
||||
private http: HttpClient,
|
||||
private toastService: ToastrService
|
||||
) {}
|
||||
|
||||
saveImage(): void {
|
||||
// Remover propiedades que son null antes de enviar la solicitud
|
||||
const payload = { ...this.imagePayload };
|
||||
|
||||
// Enviar la solicitud POST al servidor
|
||||
this.http.post(`${this.baseUrl}/images`, payload).subscribe({
|
||||
next: () => {
|
||||
this.toastService.success('Imagen creada con éxito');
|
||||
this.dialogRef.close(true); // Cierra el diálogo y retorna true
|
||||
},
|
||||
error: (error) => {
|
||||
console.error('Error al crear la imagen:', error);
|
||||
this.toastService.error('Error al crear la imagen');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
close(): void {
|
||||
this.dialogRef.close(); // Cierra el diálogo sin retorno
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title">Administrar imágenes</h2>
|
||||
<div class="images-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addImage()">Añadir imagen</button>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label>Buscar nombre de imagen</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint>Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let image"> {{ column.cell(image) }} </td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
|
||||
<div class="paginator-container">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
[pageSizeOptions]="[5, 10, 20, 40, 100]"
|
||||
(page)="onPageChange($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { CreateImageComponent } from './create-image/create-image.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-images',
|
||||
templateUrl: './images.component.html',
|
||||
styleUrls: ['./images.component.css']
|
||||
})
|
||||
export class ImagesComponent implements OnInit {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
dataSource = new MatTableDataSource<any>();
|
||||
length: number = 0;
|
||||
itemsPerPage: number = 10;
|
||||
page: number = 1;
|
||||
loading: boolean = false;
|
||||
filters: { [key: string]: string } = {};
|
||||
datePipe: DatePipe = new DatePipe('es-ES');
|
||||
columns = [
|
||||
{
|
||||
columnDef: 'uuid',
|
||||
header: 'UUID',
|
||||
cell: (image: any) => `${image.uuid}`
|
||||
},
|
||||
{
|
||||
columnDef: 'name',
|
||||
header: 'Nombre de imagen',
|
||||
cell: (image: any) => `${image.name}`
|
||||
},
|
||||
{
|
||||
columnDef: 'downloadUrl',
|
||||
header: 'Url descarga',
|
||||
cell: (image: any) => `${image.downloadUrl}`
|
||||
},
|
||||
{
|
||||
columnDef: 'createdAt',
|
||||
header: 'Fecha de creación',
|
||||
cell: (image: any) => `${this.datePipe.transform(image.createdAt, 'dd/MM/yyyy hh:mm:ss')}`
|
||||
}
|
||||
];
|
||||
displayedColumns = [...this.columns.map(column => column.columnDef)];
|
||||
|
||||
private apiUrl = `${this.baseUrl}/images`;
|
||||
|
||||
constructor(
|
||||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private toastService: ToastrService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.search();
|
||||
}
|
||||
|
||||
addImage(): void {
|
||||
const dialogRef = this.dialog.open(CreateImageComponent, {
|
||||
width: '400px'
|
||||
});
|
||||
|
||||
dialogRef.afterClosed().subscribe(() => {
|
||||
this.search();
|
||||
});
|
||||
}
|
||||
|
||||
search(): void {
|
||||
this.loading = true;
|
||||
this.http.get<any>(`${this.apiUrl}?page=${this.page}&itemsPerPage=${this.itemsPerPage}&filters=${JSON.stringify(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;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
onPageChange(event: any): void {
|
||||
this.page = event.pageIndex;
|
||||
this.itemsPerPage = event.pageSize;
|
||||
this.search();
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ import { ToastrService } from 'ngx-toastr';
|
|||
templateUrl: './create-image.component.html',
|
||||
styleUrls: ['./create-image.component.css']
|
||||
})
|
||||
export class CreateImageComponent implements OnInit {
|
||||
export class CreatePXEImageComponent implements OnInit {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
name: string = '';
|
||||
downloads: any[] = [];
|
||||
|
@ -19,7 +19,7 @@ export class CreateImageComponent implements OnInit {
|
|||
constructor(
|
||||
private toastService: ToastrService,
|
||||
private http: HttpClient,
|
||||
public dialogRef: MatDialogRef<CreateImageComponent>,
|
||||
public dialogRef: MatDialogRef<CreatePXEImageComponent>,
|
||||
@Inject(MAT_DIALOG_DATA) public data: any
|
||||
) { }
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
.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;
|
||||
height: 100px;
|
||||
padding: 10px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { ImagesComponent } from './images.component';
|
||||
import { PXEimagesComponent } from './pxe-images.component';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { of } from 'rxjs';
|
||||
import { MatAccordion, MatExpansionPanel, MatExpansionPanelHeader, MatExpansionPanelTitle, MatExpansionPanelDescription } from '@angular/material/expansion';
|
||||
|
@ -14,9 +14,9 @@ import { FormsModule } from '@angular/forms';
|
|||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatTableModule } from '@angular/material/table';
|
||||
|
||||
describe('ImagesComponent', () => {
|
||||
let component: ImagesComponent;
|
||||
let fixture: ComponentFixture<ImagesComponent>;
|
||||
describe('PXEimagesComponent', () => {
|
||||
let component: PXEimagesComponent;
|
||||
let fixture: ComponentFixture<PXEimagesComponent>;
|
||||
|
||||
let mockToastrService: jasmine.SpyObj<ToastrService>;
|
||||
|
||||
|
@ -24,7 +24,7 @@ describe('ImagesComponent', () => {
|
|||
|
||||
mockToastrService = jasmine.createSpyObj('ToastrService', ['success', 'error']);
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ImagesComponent],
|
||||
declarations: [PXEimagesComponent],
|
||||
imports: [HttpClientModule,
|
||||
MatAccordion,
|
||||
MatExpansionPanel,
|
||||
|
@ -47,7 +47,7 @@ describe('ImagesComponent', () => {
|
|||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(ImagesComponent);
|
||||
fixture = TestBed.createComponent(PXEimagesComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
|
@ -1,7 +1,7 @@
|
|||
import {Component, OnInit, signal} from '@angular/core';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { CreateImageComponent } from './create-image/create-image/create-image.component';
|
||||
import { CreatePXEImageComponent } from './create-image/create-image/create-image.component';
|
||||
import { InfoImageComponent } from './info-image/info-image/info-image.component';
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import {PageEvent} from "@angular/material/paginator";
|
||||
|
@ -11,11 +11,11 @@ import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/
|
|||
import {DataService} from "./data.service";
|
||||
|
||||
@Component({
|
||||
selector: 'app-images',
|
||||
templateUrl: './images.component.html',
|
||||
styleUrls: ['./images.component.css']
|
||||
selector: 'app-pxe-images',
|
||||
templateUrl: './pxe-images.component.html',
|
||||
styleUrls: ['./pxe-images.component.css']
|
||||
})
|
||||
export class ImagesComponent implements OnInit {
|
||||
export class PXEimagesComponent implements OnInit {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
images: { downloadUrl: string; name: string; uuid: string }[] = [];
|
||||
dataSource = new MatTableDataSource<any>();
|
||||
|
@ -78,7 +78,7 @@ export class ImagesComponent implements OnInit {
|
|||
}
|
||||
|
||||
addImage(): void {
|
||||
const dialogRef = this.dialog.open(CreateImageComponent, {
|
||||
const dialogRef = this.dialog.open(CreatePXEImageComponent, {
|
||||
width: '400px'
|
||||
});
|
||||
|
||||
|
@ -158,7 +158,7 @@ export class ImagesComponent implements OnInit {
|
|||
}
|
||||
|
||||
editImage(image: any): void {
|
||||
const dialogRef = this.dialog.open(CreateImageComponent, {
|
||||
const dialogRef = this.dialog.open(CreatePXEImageComponent, {
|
||||
width: '700px',
|
||||
data: image
|
||||
});
|
|
@ -91,7 +91,7 @@
|
|||
<span i18n="@@gallery">Estado</span>
|
||||
</span>
|
||||
</mat-list-item>
|
||||
<mat-list-item routerLink="/images">
|
||||
<mat-list-item routerLink="/pxe-images">
|
||||
<span class="entry">
|
||||
<mat-icon class="icon">album</mat-icon>
|
||||
<span i18n="@@gallery">ogLive</span>
|
||||
|
@ -133,6 +133,13 @@
|
|||
</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item class="disabled" routerLink="/images">
|
||||
<span class="entry">
|
||||
<mat-icon class="icon">photo</mat-icon>
|
||||
<span i18n="@@repositories">imágenes</span>
|
||||
</span>
|
||||
</mat-list-item>
|
||||
|
||||
<mat-list-item class="disabled">
|
||||
<span class="entry">
|
||||
<mat-icon class="icon">list</mat-icon>
|
||||
|
|
Loading…
Reference in New Issue