Updated repo/images UX
testing/ogGui-multibranch/pipeline/head This commit looks good
Details
testing/ogGui-multibranch/pipeline/head This commit looks good
Details
parent
b81db79237
commit
45bf13e63a
|
@ -50,7 +50,6 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
ngOnChanges(changes: SimpleChanges): void {
|
||||
if (changes['clientData']) {
|
||||
console.log(this.clientData.length)
|
||||
console.log('clientData ha cambiado:', changes['clientData'].currentValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,13 +93,11 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
}
|
||||
|
||||
powerOnClient(): void {
|
||||
const payload = {
|
||||
client: ''
|
||||
}
|
||||
|
||||
this.http.post('', payload).subscribe(
|
||||
this.http.post(`${this.baseUrl}/image-repositories/wol`, {
|
||||
clients: this.clientData.map((client: any) => client['@id'])
|
||||
}).subscribe(
|
||||
response => {
|
||||
this.toastService.success('Cliente actualizado correctamente');
|
||||
this.toastService.success('Petición de encendido enviada correctamente');
|
||||
},
|
||||
error => {
|
||||
this.toastService.error('Error de conexión con el cliente');
|
||||
|
@ -113,7 +110,7 @@ export class ExecuteCommandComponent implements OnInit {
|
|||
clients: this.clientData.map((client: any) => client['@id'])
|
||||
}).subscribe(
|
||||
response => {
|
||||
this.toastService.success('Cliente actualizado correctamente');
|
||||
this.toastService.success('Petición de apagado enviada correctamente');
|
||||
},
|
||||
error => {
|
||||
this.toastService.error('Error de conexión con el cliente');
|
||||
|
|
|
@ -39,4 +39,4 @@ button {
|
|||
|
||||
mat-slide-toggle{
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,9 @@ export class CreateOrganizationalUnitComponent implements OnInit {
|
|||
|
||||
loadOgLives() {
|
||||
this.dataService.getOgLives().subscribe(
|
||||
(data: any[]) => this.ogLives = data,
|
||||
(data: any[]) => {
|
||||
this.ogLives = data
|
||||
},
|
||||
error => console.error('Error fetching ogLives', error)
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,35 +5,34 @@ h1 {
|
|||
color: #3f51b5;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
|
||||
.network-form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
|
||||
.form-field {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
.mat-dialog-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
|
||||
.mat-dialog-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
|
||||
button {
|
||||
text-transform: none;
|
||||
font-size: 16px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.mat-slide-toggle {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
</form>
|
||||
|
||||
<!-- Paso 2: Información del Aula -->
|
||||
<form *ngIf="generalFormGroup.value.type === 'classroom'" [formGroup]="classroomInfoFormGroup">
|
||||
<form *ngIf="generalFormGroup.value.type === 'classroom'" [formGroup]="classroomInfoFormGroup">
|
||||
<mat-form-field class="form-field">
|
||||
<mat-label>{{ 'locationLabel' | translate }}</mat-label>
|
||||
<input matInput formControlName="location">
|
||||
|
|
|
@ -90,11 +90,6 @@ export class CreateImageComponent implements OnInit {
|
|||
}
|
||||
|
||||
saveImage(): void {
|
||||
if (this.imageForm.invalid) {
|
||||
this.toastService.error('Por favor, rellena los campos obligatorios');
|
||||
return;
|
||||
}
|
||||
|
||||
const payload: any = {
|
||||
name: this.imageForm.value.name,
|
||||
description: this.imageForm.value.description,
|
||||
|
|
|
@ -91,6 +91,11 @@ table {
|
|||
color: white;
|
||||
}
|
||||
|
||||
.chip-transferring {
|
||||
background-color: #f5a623 !important;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.header-container-title {
|
||||
flex-grow: 1;
|
||||
text-align: left;
|
||||
|
|
|
@ -40,7 +40,8 @@
|
|||
'chip-failed': image.status === 'failed',
|
||||
'chip-success': image.status === 'success',
|
||||
'chip-pending': image.status === 'pending',
|
||||
'chip-in-progress': image.status === 'in-progress'
|
||||
'chip-in-progress': image.status === 'in-progress',
|
||||
'chip-transferring': image.status === 'transferring',
|
||||
}">
|
||||
{{ getStatusLabel(image[column.columnDef]) }}
|
||||
</mat-chip>
|
||||
|
@ -65,8 +66,9 @@
|
|||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item (click)="toggleAction(image, 'get-aux')">Obtener ficheros auxiliares</button>
|
||||
<button mat-menu-item [disabled]="!image.imageFullsum || image.status !== 'success'" (click)="toggleAction(image, 'delete-trash')">Eliminar imagen temporalmente</button>
|
||||
<button mat-menu-item [disabled]="!image.imageFullsum || image.status !== 'success'" (click)="toggleAction(image, 'delete-permanent')">Eliminar imagen</button>
|
||||
<button mat-menu-item [disabled]="!image.imageFullsum || image.status !== 'trash'" (click)="toggleAction(image, 'recover')">Recuperar imagen de la papelera</button>
|
||||
<button mat-menu-item (click)="toggleAction(image, 'export')">Exportar imagen</button>
|
||||
<button mat-menu-item [disabled]="!image.imageFullsum || image.status !== 'success'" (click)="toggleAction(image, 'export')">Exportar imagen</button>
|
||||
</mat-menu>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import {Component, Input, 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';
|
||||
import {CreateCommandComponent} from "../commands/main-commands/create-command/create-command.component";
|
||||
import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component";
|
||||
import {ServerInfoDialogComponent} from "../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
|
||||
import {Observable} from "rxjs";
|
||||
import {InfoImageComponent} from "../ogboot/pxe-images/info-image/info-image/info-image.component";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
import {ExportImageComponent} from "./export-image/export-image.component";
|
||||
|
||||
|
@ -68,16 +66,34 @@ export class ImagesComponent implements OnInit {
|
|||
displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];
|
||||
|
||||
private apiUrl = `${this.baseUrl}/images`;
|
||||
@Input() repositoryUuid: any
|
||||
private repositoryId: any;
|
||||
|
||||
constructor(
|
||||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService
|
||||
private joyrideService: JoyrideService,
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.search();
|
||||
if (this.repositoryUuid) {
|
||||
this.loadRepository()
|
||||
} else {
|
||||
this.search();
|
||||
}
|
||||
}
|
||||
|
||||
loadRepository(): void {
|
||||
this.http.get<any>(`${this.baseUrl}/image-repositories/${this.repositoryUuid}`, {}).subscribe(
|
||||
data => {
|
||||
this.repositoryId = data.id;
|
||||
this.search();
|
||||
},
|
||||
error => {
|
||||
console.error('Error fetching image repositories', error);
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
getStatusLabel(status: string): string {
|
||||
|
@ -111,7 +127,7 @@ export class ImagesComponent implements OnInit {
|
|||
|
||||
search(): void {
|
||||
this.loading = true;
|
||||
this.http.get<any>(`${this.apiUrl}?page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}`, { params: this.filters }).subscribe(
|
||||
this.http.get<any>(`${this.apiUrl}?page=${this.page +1 }&itemsPerPage=${this.itemsPerPage}&repository.id=${this.repositoryId}`, { params: this.filters }).subscribe(
|
||||
data => {
|
||||
this.dataSource.data = data['hydra:member'];
|
||||
this.length = data['hydra:totalItems'];
|
||||
|
@ -206,6 +222,17 @@ export class ImagesComponent implements OnInit {
|
|||
}
|
||||
});
|
||||
break;
|
||||
case 'delete-permanent':
|
||||
this.http.post(`${this.baseUrl}/images/server/${image.uuid}/delete-permanent`, {}).subscribe({
|
||||
next: () => {
|
||||
this.toastService.success('Petición de eliminación de la papelera temporal enviada');
|
||||
this.search()
|
||||
},
|
||||
error: (error) => {
|
||||
this.toastService.error(error.error['hydra:description']);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'recover':
|
||||
this.http.post(`${this.baseUrl}/images/server/${image.uuid}/recover`, {}).subscribe({
|
||||
next: () => {
|
||||
|
|
|
@ -20,3 +20,20 @@ mat-dialog-actions {
|
|||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.selected-list ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.selected-item {
|
||||
display: flex;
|
||||
justify-content: space-between; /* Alinea texto a la izquierda y botón a la derecha */
|
||||
align-items: center; /* Centra verticalmente */
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.selected-item button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
|
|
@ -7,6 +7,19 @@
|
|||
<mat-option *ngFor="let image of images" [value]="image['@id']">{{ image.name }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div *ngIf="selectedClients.length > 0" class="selected-list">
|
||||
<h3>Imágenes seleccionadas:</h3>
|
||||
<ul>
|
||||
<li *ngFor="let imageId of selectedClients" class="selected-item">
|
||||
<span>{{ getImageName(imageId) }}</span>
|
||||
<button mat-icon-button color="warn" (click)="removeImage(imageId)">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</mat-dialog-content>
|
||||
|
||||
<mat-dialog-actions>
|
||||
|
|
|
@ -38,6 +38,15 @@ export class ImportImageComponent implements OnInit{
|
|||
);
|
||||
}
|
||||
|
||||
getImageName(imageId: string): string {
|
||||
const image = this.images.find(img => img['@id'] === imageId);
|
||||
return image ? image.name : 'Desconocido';
|
||||
}
|
||||
|
||||
removeImage(imageId: string) {
|
||||
this.selectedClients = this.selectedClients.filter(id => id !== imageId);
|
||||
}
|
||||
|
||||
save() {
|
||||
this.http.post<any>(`${this.baseUrl}${this.data.repository['@id']}/import-image`, {
|
||||
images: this.selectedClients
|
||||
|
|
|
@ -123,6 +123,6 @@
|
|||
</mat-tab>
|
||||
|
||||
<mat-tab label="Listado de imágenes">
|
||||
<app-images />
|
||||
<app-images [repositoryUuid]="repositoryId"></app-images>
|
||||
</mat-tab>
|
||||
</mat-tab-group>
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let repository" style="text-align: center;">
|
||||
<button mat-icon-button color="primary" (click)="importImage($event, repository)" i18n="@@editImage"> <mat-icon>download</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="importImage($event, repository)" i18n="@@editImage"> <mat-icon>move_to_inbox</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editRepository($event, repository)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="deleteRepository($event, repository)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
|
|
|
@ -283,6 +283,7 @@
|
|||
"partitionSizeColumn": "Size (MB)",
|
||||
"usageColumn": "Usage (%)",
|
||||
"formatColumn": "Format",
|
||||
"remotePcLabel": "Remote PC",
|
||||
"ntfsOption": "NTFS",
|
||||
"linuxOption": "LINUX",
|
||||
"cacheOption": "CACHE",
|
||||
|
|
|
@ -301,6 +301,7 @@
|
|||
"noResultsMessage": "No hay resultados para mostrar.",
|
||||
"imagesTitle": "Administrar imágenes",
|
||||
"repositoryTitle": "Administrar repositorios",
|
||||
"remotePcLabel": "Remote PC",
|
||||
"addImageButton": "Añadir imagen",
|
||||
"searchNameDescription": "Busca imágenes por nombre para encontrar rápidamente una imagen específica.",
|
||||
"searchDefaultDescription": "Filtra las imágenes para mostrar solo las imágenes por defecto o no por defecto.",
|
||||
|
|
Loading…
Reference in New Issue