develop #23

Merged
maranda merged 12 commits from develop into main 2025-05-19 16:58:24 +02:00
18 changed files with 208 additions and 188 deletions

View File

@ -1,4 +1,13 @@
# Changelog
## [0.13.0] - 2025-05-20
### Added
- Se ha añadido nuevo campo "SSL_ENABLED" en el apartado configuracion.
### Improved
- Mejoras en el asistente de particionado.
- Se han añadido mejoras en los filtros de las trazas.
---
## [0.12.0] - 2025-5-13
### Added
- Se ha añadido un nuevo modal del detalle de las acciones ejecutadas por cada cliente.

View File

@ -16,12 +16,20 @@
<ng-container matColumnDef="value">
<mat-header-cell *matHeaderCellDef> Valor </mat-header-cell>
<mat-cell *matCellDef="let variable">
<mat-form-field class="value-input">
<!-- Si es booleano, usamos checkbox -->
<mat-checkbox *ngIf="isBoolean(variable.value)"
[checked]="variable.value === 'true'"
(change)="variable.value = $event.checked ? 'true' : 'false'">
</mat-checkbox>
<!-- Si no es booleano, usamos input -->
<mat-form-field *ngIf="!isBoolean(variable.value)" class="value-input">
<input matInput [(ngModel)]="variable.value" />
</mat-form-field>
</mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
@ -30,4 +38,4 @@
<button class="action-button" (click)="loadEnvVars()">Recargar</button>
<button class="submit-button" (click)="saveEnvVars()">Guardar Cambios</button>
</div>
</div>
</div>

View File

@ -31,12 +31,15 @@ export class EnvVarsComponent {
this.envVars = Object.entries(response.vars).map(([name, value]) => ({ name, value }));
},
error: (err) => {
console.error('Error al cargar las variables de entorno:', err);
this.toastService.error('No se pudieron cargar las variables de entorno.');
}
});
}
isBoolean(value: string): boolean {
return value === 'true' || value === 'false';
}
saveEnvVars(): void {
const vars = this.envVars.reduce((acc, variable) => {
acc[variable.name] = variable.value;

View File

@ -115,6 +115,7 @@ export class CreateTaskScheduleComponent implements OnInit{
}
convertDateToLocalISO(date: Date): string {
date = new Date(date);
const adjustedDate = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
return adjustedDate.toISOString();
}

View File

@ -75,6 +75,7 @@ export class CreateCommandComponent implements OnInit{
readOnly: this.createCommandForm.value.readOnly,
enabled: this.createCommandForm.value.enabled,
comments: this.createCommandForm.value.comments,
parameters: this.createCommandForm.value.parameters,
};
if (this.commandId) {

View File

@ -10,11 +10,11 @@
</h4>
</div>
<div class="button-row">
<button class="action-button" [disabled]="data.status === 'busy' || !selectedModelClient || !allSelected || !selectedDisk" (click)="save()">Ejecutar</button>
<button class="action-button" [disabled]="data.status === 'busy' || !selectedModelClient || !allSelected || !selectedDisk || (selectedDisk.totalDiskSize - selectedDisk.used) <= 0" (click)="save()">Ejecutar</button>
</div>
<div>
<button mat-stroked-button color="accent" [disabled]="data.status === 'busy' || !selectedModelClient || !allSelected || !selectedDisk" (click)="openScheduleModal()">
<button mat-stroked-button color="accent" [disabled]="data.status === 'busy' || !selectedModelClient || !allSelected || !selectedDisk || (selectedDisk.totalDiskSize - selectedDisk.used) <= 0" (click)="openScheduleModal()">
<mat-icon>schedule</mat-icon> Opciones de programación
</button>
</div>
@ -101,15 +101,15 @@
<div class="disk-space-info-container">
<div class="disk-space-info" [ngClass]="selectedDisk.used < selectedDisk.totalDiskSize ? 'chip-free' : 'chip-full'">
Espacio usado: {{ selectedDisk.used }} MB
Espacio usado: {{ selectedDisk.used | number:'1.2-2' }} MB
</div>
<div class="disk-space-info" [ngClass]="selectedDisk.used < selectedDisk.totalDiskSize ? 'chip-free' : 'chip-full'">
Espacio libre: {{ selectedDisk.totalDiskSize - selectedDisk.used}} MB
Espacio libre: {{ (selectedDisk.totalDiskSize - selectedDisk.used) | number:'1.2-2' }} MB
</div>
<div class="disk-space-info">
Espacio total: {{ selectedDisk.totalDiskSize }} MB
Espacio total: {{ selectedDisk.totalDiskSize | number:'1.2-2' }} MB
</div>
</div>

View File

@ -109,8 +109,8 @@ export class PartitionAssistantComponent implements OnInit{
this.http.get(url).subscribe(
(response) => {
this.data = response;
this.initializeDisks();
this.partitionCode = this.data.partitions[0].partitionCode;
this.initializeDisks();
},
(error) => {
console.error('Error al cargar los datos del cliente:', error);
@ -160,11 +160,11 @@ export class PartitionAssistantComponent implements OnInit{
disk!.partitions.push({
uuid: partition.uuid,
partitionNumber: partition.partitionNumber,
size: this.convertBytesToGB(partition.size),
size: this.convertBytesToGB(partition.partitionNumber === 1 && this.partitionCode === 'GPT' ? 512 : partition.size),
memoryUsage: partition.memoryUsage,
partitionCode: partition.partitionCode,
partitionCode: partition.partitionNumber === 1 && this.partitionCode === 'GPT' ? 'EFI' : partition.partitionCode,
filesystem: partition.filesystem,
sizeBytes: partition.size,
sizeBytes: partition.partitionNumber === 1 && this.partitionCode === 'GPT' ? 512 : partition.size,
format: false,
color: '#1f1b91',
percentage: 0,
@ -254,8 +254,6 @@ export class PartitionAssistantComponent implements OnInit{
if (disk) {
const remainingGB = this.getRemainingGB(disk.partitions, disk.totalDiskSize);
console.log('Remaining GB:', remainingGB);
console.log('Total Disk Size:', disk);
if (remainingGB > 0) {
const removedPartitions = disk.partitions.filter((p) => !p.removed);

View File

@ -101,7 +101,7 @@
<div class="script-preview" [innerHTML]="scriptContent"></div>
</div>
<div class="script-params" *ngIf="parameterNames.length > 0">
<div class="script-params" *ngIf="parameterNames.length > 0 && selectedScript.parameters">
<h3>Ingrese los parámetros:</h3>
<div *ngFor="let paramName of parameterNames">
<mat-form-field appearance="fill" class="full-width">

View File

@ -77,15 +77,12 @@ export class RunScriptAssistantComponent implements OnInit{
if (!ctx) {
return '';
}
// Si es un array de clientes
if (Array.isArray(ctx)) {
return ctx.map(c => c.name).join(', ');
}
// Si es un objeto con propiedad name
if (typeof ctx === 'object' && 'name' in ctx) {
return ctx.name;
}
// Si es un string plano
return String(ctx);
}

View File

@ -177,12 +177,15 @@ export class ManageOrganizationalUnitComponent implements OnInit {
}
onParentChange(event: any): void {
this.setOrganizationalUnitDefaults(event.value);
if (!this.isEditMode) {
this.setOrganizationalUnitDefaults(event.value);
}
}
setOrganizationalUnitDefaults(unitId: string): void {
const selectedUnit: any = this.parentUnitsWithPaths.find(unit => unit.id === unitId);
if (selectedUnit) {
const exclude = this.generalFormGroup.get('excludeParentChanges')?.value;
if (selectedUnit && !exclude) {
this.networkSettingsFormGroup.patchValue({
repository: selectedUnit.repository || null,
hardwareProfile: selectedUnit.hardwareProfile || null,
@ -204,6 +207,127 @@ export class ManageOrganizationalUnitComponent implements OnInit {
}
}
loadData(uuid: string): Promise<void> {
return new Promise((resolve, reject) => {
const url = `${this.baseUrl}/organizational-units/${uuid}`;
this.http.get<any>(url).subscribe(
data => {
const exclude = data.excludeParentChanges;
this.generalFormGroup.patchValue({
name: data.name,
parent: data.parent ? data.parent['@id'] : '',
description: data.description,
type: data.type,
excludeParentChanges: exclude
});
this.additionalInfoFormGroup.patchValue({
comments: data.comments
});
this.networkSettingsFormGroup.patchValue({
proxy: data.networkSettings?.proxy,
dns: data.networkSettings?.dns,
netmask: data.networkSettings?.netmask,
router: data.networkSettings?.router,
ntp: data.networkSettings?.ntp,
netiface: data.networkSettings?.netiface,
p2pMode: data.networkSettings?.p2pMode,
p2pTime: data.networkSettings?.p2pTime,
mcastIp: data.networkSettings?.mcastIp,
mcastSpeed: data.networkSettings?.mcastSpeed,
mcastPort: data.networkSettings?.mcastPort,
mcastMode: data.networkSettings?.mcastMode,
menu: data.networkSettings?.menu ? data.networkSettings.menu['@id'] : null,
hardwareProfile: data.networkSettings?.hardwareProfile ? data.networkSettings.hardwareProfile['@id'] : null,
ogLive: data.networkSettings?.ogLive ? data.networkSettings.ogLive['@id'] : null,
repository: data.networkSettings?.repository ? data.networkSettings.repository['@id'] : null,
pxeTemplate: data.networkSettings?.pxeTemplate ? data.networkSettings.pxeTemplate['@id'] : null
});
this.classroomInfoFormGroup.patchValue({
location: data.location,
projector: data.projector,
board: data.board,
capacity: data.capacity,
remoteCalendar: data.remoteCalendar ? data.remoteCalendar['@id'] : null
});
resolve();
},
error => {
console.error('Error fetching data for edit:', error);
this.toastService.error('Error fetching data');
reject(error);
this.onNoClick();
}
);
});
}
onSubmit() {
if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) {
const parentValue = this.generalFormGroup.value.parent;
const formData = {
name: this.generalFormGroup.value.name,
excludeParentChanges: this.generalFormGroup.value.excludeParentChanges,
parent: parentValue || null,
description: this.generalFormGroup.value.description,
comments: this.additionalInfoFormGroup.value.comments,
remoteCalendar: this.generalFormGroup.value.remoteCalendar,
type: this.generalFormGroup.value.type,
networkSettings: this.networkSettingsFormGroup.value,
location: this.classroomInfoFormGroup.value.location,
projector: this.classroomInfoFormGroup.value.projector,
board: this.classroomInfoFormGroup.value.board,
capacity: this.classroomInfoFormGroup.value.capacity,
};
if (this.isEditMode) {
const putUrl = `${this.baseUrl}/organizational-units/${this.data.uuid}`;
const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
this.http.put<any>(putUrl, formData, { headers }).subscribe(
response => {
this.unitAdded.emit();
this.dialogRef.close({ success: true });
this.toastService.success('Editado exitosamente', 'Éxito');
},
error => {
console.error('Error al realizar PUT:', error);
const errorMessages = error.error['hydra:description'].split('\n');
errorMessages.forEach((message: string) => {
const cleanedMessage = message.replace(/networkSettings\.(\w+):/, 'Error $1:');
this.toastService.error(cleanedMessage);
});
}
);
} else {
const postUrl = `${this.baseUrl}/organizational-units`;
const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
this.http.post<any>(postUrl, formData, { headers }).subscribe(
response => {
this.unitAdded.emit(response);
this.dialogRef.close({ success: true });
this.toastService.success('Creado exitosamente', 'Éxito');
},
error => {
console.error('Error al realizar POST:', error);
const errorMessages = error.error['hydra:description'].split('\n');
errorMessages.forEach((message: string) => {
const cleanedMessage = message.replace(/networkSettings\.(\w+):/, 'Error $1:');
this.toastService.error(cleanedMessage);
});
}
);
}
}
}
getSelectedParentName(): string | undefined {
const parentId = this.generalFormGroup.get('parent')?.value;
return this.parentUnitsWithPaths.find(unit => unit.id === parentId)?.name;
@ -229,14 +353,14 @@ export class ManageOrganizationalUnitComponent implements OnInit {
const url = `${this.baseUrl}/pxe-templates?page=1&itemsPerPage=10000`;
this.http.get<any>(url).subscribe(
response => {
response => {
this.pxeTemplates = response['hydra:member'];
resolve();
},
error => {
},
error => {
console.error('Error fetching pxe templates:', error);
reject(error);
}
}
);
});
}
@ -325,121 +449,6 @@ export class ManageOrganizationalUnitComponent implements OnInit {
this.networkSettingsFormGroup.value.pxeTemplate = event.value;
}
loadData(uuid: string): Promise<void> {
return new Promise((resolve, reject) => {
const url = `${this.baseUrl}/organizational-units/${uuid}`;
this.http.get<any>(url).subscribe(
data => {
this.generalFormGroup.patchValue({
name: data.name,
parent: data.parent ? data.parent['@id'] : '',
description: data.description,
type: data.type,
excludeParentChanges: data.excludeParentChanges
});
this.additionalInfoFormGroup.patchValue({
comments: data.comments
});
this.networkSettingsFormGroup.patchValue({
proxy: data.networkSettings?.proxy,
dns: data.networkSettings?.dns,
netmask: data.networkSettings?.netmask,
router: data.networkSettings?.router,
ntp: data.networkSettings?.ntp,
netiface: data.networkSettings?.netiface,
p2pMode: data.networkSettings?.p2pMode,
p2pTime: data.networkSettings?.p2pTime,
mcastIp: data.networkSettings?.mcastIp,
mcastSpeed: data.networkSettings?.mcastSpeed,
mcastPort: data.networkSettings?.mcastPort,
mcastMode: data.networkSettings?.mcastMode,
menu: data.networkSettings?.menu ? data.networkSettings.menu['@id'] : null,
hardwareProfile: data.networkSettings?.hardwareProfile ? data.networkSettings.hardwareProfile['@id'] : null,
ogLive: data.networkSettings?.ogLive ? data.networkSettings.ogLive['@id'] : null,
repository: data.networkSettings?.repository ? data.networkSettings.repository['@id'] : null,
pxeTemplate: data.networkSettings?.pxeTemplate ? data.networkSettings.pxeTemplate['@id'] : null
});
this.classroomInfoFormGroup.patchValue({
location: data.location,
projector: data.projector,
board: data.board,
capacity: data.capacity,
remoteCalendar: data.remoteCalendar ? data.remoteCalendar['@id'] : null
});
resolve();
},
error => {
console.error('Error fetching data for edit:', error);
this.toastService.error('Error fetching data');
reject(error);
this.onNoClick();
}
);
});
}
onSubmit() {
if (this.generalFormGroup.valid && this.additionalInfoFormGroup.valid && this.networkSettingsFormGroup.valid) {
const parentValue = this.generalFormGroup.value.parent;
const formData = {
name: this.generalFormGroup.value.name,
excludeParentChanges: this.generalFormGroup.value.excludeParentChanges,
parent: parentValue || null,
description: this.generalFormGroup.value.description,
comments: this.additionalInfoFormGroup.value.comments,
remoteCalendar: this.generalFormGroup.value.remoteCalendar,
type: this.generalFormGroup.value.type,
networkSettings: this.networkSettingsFormGroup.value,
location: this.classroomInfoFormGroup.value.location,
projector: this.classroomInfoFormGroup.value.projector,
board: this.classroomInfoFormGroup.value.board,
capacity: this.classroomInfoFormGroup.value.capacity,
};
if (this.isEditMode) {
const putUrl = `${this.baseUrl}/organizational-units/${this.data.uuid}`;
const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
this.http.put<any>(putUrl, formData, { headers }).subscribe(
response => {
this.unitAdded.emit();
this.dialogRef.close({ success: true });
this.toastService.success('Editado exitosamente', 'Éxito');
},
error => {
console.error('Error al realizar PUT:', error);
const errorMessages = error.error['hydra:description'].split('\n');
errorMessages.forEach((message: string) => {
const cleanedMessage = message.replace(/networkSettings\.(\w+):/, 'Error $1:');
this.toastService.error(cleanedMessage);
});
}
);
} else {
const postUrl = `${this.baseUrl}/organizational-units`;
const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
this.http.post<any>(postUrl, formData, { headers }).subscribe(
response => {
this.unitAdded.emit(response);
this.dialogRef.close({ success: true });
this.toastService.success('Creado exitosamente', 'Éxito');
},
error => {
console.error('Error al realizar POST:', error);
const errorMessages = error.error['hydra:description'].split('\n');
errorMessages.forEach((message: string) => {
const cleanedMessage = message.replace(/networkSettings\.(\w+):/, 'Error $1:');
this.toastService.error(cleanedMessage);
});
}
);
}
}
}
onNoClick(): void {
this.dialogRef.close({ success: false });
}

View File

@ -129,8 +129,7 @@ export class CreatePxeTemplateComponent implements OnInit {
this.dialogRef.close(true);
},
error: error => {
this.toastService.error('Error al actualizar la plantilla PXE');
this.dialogRef.close(false);
this.toastService.error(error.error['hydra:description']);
}
});
}

View File

@ -5,7 +5,7 @@
</button>
<div class="header-container-title">
<h2 joyrideStep="titleStep" text="{{ 'titleStepText' | translate }}">{{ 'adminCommandsTitle' |
<h2 joyrideStep="tracesTitleStep" text="{{ 'tracesTitleStepText' | translate }}">{{ 'adminCommandsTitle' |
translate }}</h2>
</div>
@ -17,7 +17,7 @@
</div>
</div>
<div class="search-container">
<div class="search-container" joyrideStep="filtersStep" text="{{ 'filtersStepText' | translate }}">
<mat-form-field appearance="fill" class="search-select">
<mat-label>{{ 'commandSelectStepText' | translate }}</mat-label>
<mat-select (selectionChange)="onOptionCommandSelected($event.value)" #commandSearchInput>
@ -52,8 +52,8 @@
<app-loading [isLoading]="loading"></app-loading>
<div *ngIf="!loading">
<table mat-table [dataSource]="traces" class="mat-elevation-z8" joyrideStep="tableStep"
text="{{ 'tableStepText' | translate }}">
<table mat-table [dataSource]="traces" class="mat-elevation-z8" joyrideStep="tracesTableStep"
text="{{ 'tracesTableStepText' | translate }}">
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
<td mat-cell *matCellDef="let trace">
@ -128,8 +128,8 @@
</td>
</ng-container>
<ng-container matColumnDef="actions" joyrideStep="actionsStep" text="{{ 'actionsStepText' | translate }}">
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'columnActions' | translate }}</th>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'informationLabel' | translate }}</th>
<td mat-cell *matCellDef="let trace" style="text-align: center;">
<button mat-icon-button color="primary" [disabled]="!trace.input" (click)="openInputModal(trace.input)">
<mat-icon>

View File

@ -35,7 +35,6 @@ export class ClientTaskLogsComponent implements OnInit {
mode: ProgressBarMode = 'buffer';
progress = 0;
bufferValue = 0;
dateRange = new FormControl();
filteredCommands2 = Object.keys(COMMAND_TYPES).map(key => ({
name: key,
@ -135,7 +134,9 @@ export class ClientTaskLogsComponent implements OnInit {
}
onOptionCommandSelected(selectedCommand: any): void {
this.filters['command'] = selectedCommand.id;
this.filters['command'] = selectedCommand.id || selectedCommand.uuid;
console.log('Comando seleccionado:', selectedCommand);
console.log('Valor que se usará para el filtro:', selectedCommand.name);
this.loadTraces();
}
@ -191,22 +192,13 @@ export class ClientTaskLogsComponent implements OnInit {
.set('itemsPerPage', this.itemsPerPage.toString());
if (this.filters['command']) {
params = params.set('command.id', this.filters['command']);
params = params.set('command.uuid', this.filters['command']);
}
if (this.filters['status']) {
params = params.set('status', this.filters['status']);
}
const range = this.dateRange?.value;
if (range?.start && range?.end) {
const fromDate = this.datePipe.transform(range.start, 'yyyy-MM-dd');
const toDate = this.datePipe.transform(range.end, 'yyyy-MM-dd');
params = params.set('executedAt[after]', fromDate!);
params = params.set('executedAt[before]', toDate!);
}
const url = `${this.baseUrl}/traces`;
this.http.get<any>(url, { params }).subscribe(
@ -240,7 +232,6 @@ export class ClientTaskLogsComponent implements OnInit {
this.loading = true;
clientSearchCommandInput.value = null;
clientSearchStatusInput.value = null;
this.dateRange.reset();
this.filters = {};
this.loadTraces();
}
@ -290,11 +281,10 @@ export class ClientTaskLogsComponent implements OnInit {
iniciarTour(): void {
this.joyrideService.startTour({
steps: [
'titleStep',
'tracesTitleStep',
'resetFiltersStep',
'clientSelectStep',
'commandSelectStep',
'tableStep',
'filtersStep',
'tracesTableStep',
'paginationStep'
],
showPrevButton: true,

View File

@ -4,7 +4,7 @@
</button>
<div class="header-container-title">
<h2 joyrideStep="titleStep" text="{{ 'titleStepText' | translate }}">{{ 'adminCommandsTitle' |
<h2 joyrideStep="tracesTitleStep" text="{{ 'tracesTitleStepText' | translate }}">{{ 'adminCommandsTitle' |
translate }}</h2>
</div>
@ -16,9 +16,8 @@
</div>
</div>
<div class="search-container">
<mat-form-field appearance="fill" class="search-select" joyrideStep="clientSelectStep"
text="{{ 'clientSelectStepText' | translate }}">
<div class="search-container" joyrideStep="filtersStep" text="{{ 'filtersStepText' | translate }}">
<mat-form-field appearance="fill" class="search-select">
<input type="text" matInput [formControl]="clientControl" [matAutocomplete]="clientAuto" #commandClientInput
placeholder="{{ 'filterClientPlaceholder' | translate }}">
<mat-autocomplete #clientAuto="matAutocomplete" [displayWith]="displayFnClient"
@ -74,8 +73,8 @@
<app-loading [isLoading]="loading"></app-loading>
<div *ngIf="!loading">
<table mat-table [dataSource]="traces" class="mat-elevation-z8" joyrideStep="tableStep"
text="{{ 'tableStepText' | translate }}">
<table mat-table [dataSource]="traces" class="mat-elevation-z8" joyrideStep="tracesTableStep"
text="{{ 'tracesTableStepText' | translate }}">
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
<td mat-cell *matCellDef="let trace">
@ -150,10 +149,11 @@
</td>
</ng-container>
<ng-container matColumnDef="actions" joyrideStep="actionsStep" text="{{ 'actionsStepText' | translate }}">
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'columnActions' | translate }}</th>
<ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef style="text-align: center;">{{ 'informationLabel' | translate }}</th>
<td mat-cell *matCellDef="let trace" style="text-align: center;">
<button mat-icon-button color="primary" [disabled]="!trace.input" (click)="openInputModal(trace.input)">
<button mat-icon-button color="primary" [disabled]="!trace.input || trace.input.length === 0"
(click)="openInputModal(trace.input)">
<mat-icon>
<span class="material-symbols-outlined">
mode_comment

View File

@ -11,8 +11,8 @@ import { ProgressBarMode } from '@angular/material/progress-bar';
import { DeleteModalComponent } from "../../shared/delete_modal/delete-modal/delete-modal.component";
import { ToastrService } from "ngx-toastr";
import { ConfigService } from '@services/config.service';
import {OutputDialogComponent} from "./output-dialog/output-dialog.component";
import {TranslationService} from "@services/translation.service";
import { OutputDialogComponent } from "./output-dialog/output-dialog.component";
import { TranslationService } from "@services/translation.service";
import { COMMAND_TYPES } from '../../shared/constants/command-types';
@Component({
@ -323,11 +323,10 @@ export class TaskLogsComponent implements OnInit {
iniciarTour(): void {
this.joyrideService.startTour({
steps: [
'titleStep',
'tracesTitleStep',
'resetFiltersStep',
'clientSelectStep',
'commandSelectStep',
'tableStep',
'filtersStep',
'tracesTableStep',
'paginationStep'
],
showPrevButton: true,

View File

@ -34,6 +34,7 @@
<span>{{ 'commands' | translate }}</span>
</span>
</mat-list-item>
<!--
<mat-list-item routerLink="/commands-groups" (click)="onItemClick()"
matTooltip="{{ 'TOOLTIP_COMMAND_GROUPS' | translate }}" matTooltipShowDelay="1000">
<span class="entry">
@ -41,6 +42,7 @@
<span>{{ 'commandGroups' | translate }}</span>
</span>
</mat-list-item>
-->
<mat-list-item routerLink="/commands-task" (click)="onItemClick()" matTooltip="{{ 'TOOLTIP_TASKS' | translate }}"
matTooltipShowDelay="1000">
<span class="entry">

View File

@ -80,7 +80,7 @@
"searchGroupNameLabel": "Search group name",
"loadingStepText": "Wait while the command groups are loading.",
"viewCommands": "View commands",
"paginationStepText": "Navigate between command group pages using the paginator.",
"paginationStepText": "Navigate through pages using the paginator.",
"commandGroupDetailsTitle": "Command Group Details",
"createdBy": "Created by",
"groupId": "Group ID",
@ -527,6 +527,8 @@
"gitImage": "Git images",
"gitImageStep": "Git images",
"gitImageStepText": "On this screen you can manage git images.",
"partitions": "Particiones",
"isDefaultLabel": "Default"
}
"isDefaultLabel": "Default",
"tracesTitleStepText": "In this screen, you can see the execution traces of each client, with its id, command, real-time status, date and actions to be performed.",
"filtersStepText": "Here you can see the different filters to apply to the table information.",
"tracesTableStepText": "This is the table with the execution traces updated in real time."
}

View File

@ -25,7 +25,7 @@
"back": "Atrás",
"addClientDialogTitle": "Añadir Cliente",
"dialogTitleEditUser": "Editar usuario",
"dialogTitleChangePassword": "Change password",
"dialogTitleChangePassword": "Cambiar contraseña",
"labelCurrentPassword": "Contraseña actual",
"labelNewPassword": "Nueva contraseña",
"labelRepeatPassword": "Repite la contraseña",
@ -79,7 +79,7 @@
"searchGroupNameLabel": "Buscar nombre de grupo",
"loadingStepText": "Espera mientras se cargan los grupos de comandos.",
"viewCommands": "Ver comandos",
"paginationStepText": "Navega entre las páginas de grupos de comandos usando el paginador.",
"paginationStepText": "Navega entre las páginas usando el paginador.",
"commandGroupDetailsTitle": "Detalles del Grupo de Comandos",
"createdBy": "Creado por",
"groupId": "ID del Grupo",
@ -521,7 +521,7 @@
"remoteAccess": "Disponible acceso remoto",
"noRemoteAccess": "No disponible acceso remoto",
"capacityWarning": "El aforo no puede ser",
"procedimientosCliente": "Procedimientos",
"procedimientosCliente": "Histórico acciones",
"tableDateRepositoryText": "Esta tabla muestra los datos asociados a los repositorios existentes.",
"repositoryTitleStepText": "En esta pantalla se pueden gestionar los repositorios de imágenes.",
"monolithicImageStep": "Imagen monolítica",
@ -530,6 +530,8 @@
"monolithicImage": "Imagenes monolíticas",
"gitImage": "Imágenes Git",
"gitImageStepText": "Esta opción permite visualizar las imágenes Git disponibles en el servidor.",
"partitions": "Particiones",
"isDefaultLabel": "Por defecto"
"isDefaultLabel": "Por defecto",
"tracesTitleStepText": "En esta pantalla, puedes ver las trazas de ejecución de cada cliente, con su id, comando, estado en tiempo real, fecha y acciones a realizar.",
"filtersStepText": "Aquí puedes ver los diferentes filtros que aplicar a la información de la tabla.",
"tracesTableStepText": "Esta es la tabla con las trazas de ejecución actualizadas en tiempo real."
}