refs #1136 Add joyride in all components
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
testing/ogGui-multibranch/pipeline/head There was a failure building this commit
Details
parent
4109188913
commit
c168c87fc9
|
@ -1,11 +1,16 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminCommandGroupsTitle">Administrar Grupos de Comandos</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminCommandGroupsTitle" joyrideStep="titleStep" text="Desde aquí puedes gestionar los grupos de comandos.">Administrar Grupos de Comandos</h2>
|
||||
<div class="command-groups-button-row">
|
||||
<button mat-flat-button color="primary" (click)="openCreateCommandGroupModal()">Añadir Grupo de Comandos</button>
|
||||
<button mat-flat-button color="primary" (click)="openCreateCommandGroupModal()" joyrideStep="addCommandGroupStep" text="Haz clic para añadir un nuevo grupo de comandos.">Añadir Grupo de Comandos</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<div class="search-container">
|
||||
|
||||
<div class="search-container" joyrideStep="searchStep" text="Busca un grupo de comandos específico ingresando su nombre y pulsando 'Enter'.">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de grupo</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
|
@ -14,12 +19,12 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loading" class="loading-container">
|
||||
<div *ngIf="loading" class="loading-container" joyrideStep="loadingStep" text="Espera mientras se cargan los grupos de comandos.">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loading">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se muestra la lista de grupos de comandos disponibles.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let commandGroup">
|
||||
|
@ -27,7 +32,7 @@
|
|||
{{ column.cell(commandGroup) }}
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="column.columnDef === 'commands'">
|
||||
<ng-container *ngIf="column.columnDef === 'commands'" joyrideStep="viewCommandsStep" text="Haz clic para ver los comandos en este grupo.">
|
||||
<button mat-button [matMenuTriggerFor]="menu">Ver comandos</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item *ngFor="let command of commandGroup.commands">
|
||||
|
@ -37,11 +42,12 @@
|
|||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;">
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;" joyrideStep="actionsStep" text="Usa estas opciones para ver, editar o eliminar un grupo de comandos.">
|
||||
<button mat-icon-button color="info" (click)="viewGroupDetails(client)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editCommandGroup(client)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editCommandGroup(client)" i18n="@@editImage"><mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="deleteCommandGroup(client)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
</button>
|
||||
|
@ -53,7 +59,7 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<div class="paginator-container">
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de grupos de comandos usando el paginador.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
|
|
|
@ -7,6 +7,7 @@ import { DetailCommandGroupComponent } from './detail-command-group/detail-comma
|
|||
import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component';
|
||||
import { MatTableDataSource } from "@angular/material/table";
|
||||
import { DatePipe } from "@angular/common";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-commands-groups',
|
||||
|
@ -48,7 +49,8 @@ export class CommandsGroupsComponent implements OnInit {
|
|||
displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];
|
||||
private apiUrl = `${this.baseUrl}/command-groups`;
|
||||
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {}
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.search();
|
||||
|
@ -114,4 +116,21 @@ export class CommandsGroupsComponent implements OnInit {
|
|||
this.length = event.length;
|
||||
this.search();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'addCommandGroupStep',
|
||||
'searchStep',
|
||||
'tableStep',
|
||||
'viewCommandsStep',
|
||||
'actionsStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title">Administrar Tareas</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" joyrideStep="titleStep" text="Desde aquí puedes gestionar las tareas de manera centralizada.">Administrar Tareas</h2>
|
||||
<div class="task-button-row">
|
||||
<button mat-flat-button color="primary" (click)="openCreateTaskModal()">Añadir Tarea</button>
|
||||
<button mat-flat-button color="primary" (click)="openCreateTaskModal()" joyrideStep="addTaskStep" text="Haz clic para añadir una nueva tarea.">Añadir Tarea</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container">
|
||||
<div class="search-container" joyrideStep="searchStep" text="Busca una tarea específica ingresando su nombre y pulsando 'Enter'.">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label>Buscar tarea</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" />
|
||||
|
@ -16,12 +19,8 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loading" class="loading-container">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loading">
|
||||
<table mat-table [dataSource]="tasks" class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="tasks" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se muestra la lista de tareas disponibles.">
|
||||
<ng-container matColumnDef="taskid">
|
||||
<th mat-header-cell *matHeaderCellDef> Id</th>
|
||||
<td mat-cell *matCellDef="let task"> {{ task.id }} </td>
|
||||
|
@ -49,9 +48,9 @@
|
|||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let task" style="text-align: center;">
|
||||
<td mat-cell *matCellDef="let task" style="text-align: center;" joyrideStep="actionsStep" text="Usa estas opciones para ver, editar o eliminar una tarea.">
|
||||
<button mat-icon-button color="info" (click)="viewTaskDetails(task)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editTask(task)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editTask(task)" i18n="@@editImage"><mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="deleteTask(task)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
</button>
|
||||
|
@ -63,7 +62,8 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<mat-paginator [length]="length"
|
||||
<mat-paginator joyrideStep="paginationStep" text="Navega entre las páginas de tareas usando el paginador."
|
||||
[length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageSizeOptions]="pageSizeOptions"
|
||||
(page)="onPageChange($event)">
|
||||
|
|
|
@ -5,6 +5,7 @@ import { ToastrService } from 'ngx-toastr';
|
|||
import { CreateTaskComponent } from './create-task/create-task.component';
|
||||
import { DetailTaskComponent } from './detail-task/detail-task.component';
|
||||
import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component';
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-commands-task',
|
||||
|
@ -23,7 +24,8 @@ export class CommandsTaskComponent implements OnInit {
|
|||
loading: boolean = false;
|
||||
private apiUrl = `${this.baseUrl}/command-tasks`;
|
||||
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {}
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadTasks();
|
||||
|
@ -93,4 +95,20 @@ export class CommandsTaskComponent implements OnInit {
|
|||
this.itemsPerPage = event.pageSize;
|
||||
this.loadTasks();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'addTaskStep',
|
||||
'searchStep',
|
||||
'tableStep',
|
||||
'actionsStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminCommandsTitle">Trazas de comandos y procedimientos</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminCommandsTitle" joyrideStep="titleStep" text="Desde aquí puedes ver las trazas y logs de las ejecuciones de comandos y procedimientos.">Trazas de comandos y procedimientos</h2>
|
||||
<div class="images-button-row">
|
||||
<button mat-flat-button color="primary" (click)="resetFilters()">Reiniciar filtros</button>
|
||||
<button mat-flat-button color="primary" (click)="resetFilters()" joyrideStep="resetFiltersStep" text="Haz clic para reiniciar los filtros aplicados y ver todas las trazas.">Reiniciar filtros</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-select">
|
||||
<mat-form-field appearance="fill" class="search-select" joyrideStep="clientSelectStep" text="Selecciona un cliente para ver las trazas asociadas.">
|
||||
<input type="text" matInput [formControl]="clientControl" [matAutocomplete]="clientAuto" placeholder="Seleccione un cliente">
|
||||
<mat-autocomplete #clientAuto="matAutocomplete" [displayWith]="displayFnClient" (optionSelected)="onOptionClientSelected($event.option.value)">
|
||||
<mat-option *ngFor="let client of filteredClients | async" [value]="client">
|
||||
|
@ -16,7 +20,7 @@
|
|||
</mat-autocomplete>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="search-select">
|
||||
<mat-form-field appearance="fill" class="search-select" joyrideStep="commandSelectStep" text="Selecciona un comando para ver las trazas específicas de ese comando.">
|
||||
<input type="text" matInput [formControl]="commandControl" [matAutocomplete]="commandAuto" placeholder="Seleccione un comando">
|
||||
<mat-autocomplete #commandAuto="matAutocomplete" [displayWith]="displayFnCommand" (optionSelected)="onOptionCommandSelected($event.option.value)">
|
||||
<mat-option *ngFor="let command of filteredCommands | async" [value]="command">
|
||||
|
@ -26,14 +30,12 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<!-- Indicador de carga -->
|
||||
<div *ngIf="loading" class="loading-container">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
|
||||
<!-- Tabla de trazas -->
|
||||
<div *ngIf="!loading">
|
||||
<table mat-table [dataSource]="traces" class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="traces" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se muestra la lista de trazas de comandos y procedimientos, según los filtros aplicados.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let trace">
|
||||
|
@ -46,7 +48,7 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<div class="paginator-container">
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de trazas usando el paginador.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Observable } from 'rxjs';
|
|||
import { FormControl } from '@angular/forms';
|
||||
import { map, startWith } from 'rxjs/operators';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-task-logs',
|
||||
|
@ -63,7 +64,8 @@ export class TaskLogsComponent implements OnInit {
|
|||
filteredCommands!: Observable<any[]>;
|
||||
commandControl = new FormControl();
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
constructor(private http: HttpClient,
|
||||
private joyrideService: JoyrideService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadTraces();
|
||||
|
@ -183,4 +185,20 @@ export class TaskLogsComponent implements OnInit {
|
|||
this.length = event.length;
|
||||
this.loadTraces();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'resetFiltersStep',
|
||||
'clientSelectStep',
|
||||
'commandSelectStep',
|
||||
'tableStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminCommandsTitle">Administrar Comandos</h2>
|
||||
<div class="command-button-row">
|
||||
<button mat-flat-button color="primary" (click)="openCreateCommandModal()">Añadir Comando</button>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminCommandsTitle" joyrideStep="titleStep" text="Desde aquí puedes gestionar los comandos disponibles.">Administrar Comandos</h2>
|
||||
<div class="command-button-row" joyrideStep="addCommandStep" text="Haz clic para añadir un nuevo comando.">
|
||||
<button mat-flat-button color="primary" (click)="openCreateCommandModal()" >Añadir Comando</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container">
|
||||
<div class="search-container" joyrideStep="searchStep" text="Busca un comando específico ingresando su nombre y pulsando 'Enter'.">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de comando</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
|
@ -15,12 +19,12 @@
|
|||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loading" class="loading-container">
|
||||
<div *ngIf="loading" class="loading-container" joyrideStep="loadingStep" text="Espera mientras se cargan los comandos.">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loading">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se muestra la lista de comandos disponibles.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let command">
|
||||
|
@ -36,10 +40,10 @@
|
|||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let command" style="text-align: center;">
|
||||
<td mat-cell *matCellDef="let command" style="text-align: center;" joyrideStep="actionsStep" text="Usa estos botones para ejecutar, ver, editar o eliminar un comando.">
|
||||
<button mat-icon-button color="info" (click)="executeCommand($event, command)"><mat-icon>play_arrow</mat-icon></button>
|
||||
<button mat-icon-button color="info" (click)="viewDetails($event, command)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" [disabled]="command.readOnly" (click)="editCommand($event, command)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="primary" [disabled]="command.readOnly" (click)="editCommand($event, command)" i18n="@@editImage"><mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" [disabled]="command.readOnly" (click)="deleteCommand($event, command)"><mat-icon i18n="@@deleteElementTooltip">delete</mat-icon></button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
@ -49,7 +53,7 @@
|
|||
</table>
|
||||
</div>
|
||||
|
||||
<div class="paginator-container">
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de comandos usando el paginador.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
|
|
|
@ -8,6 +8,7 @@ import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/
|
|||
import { MatTableDataSource } from '@angular/material/table';
|
||||
import { DatePipe } from '@angular/common';
|
||||
import { ExecuteCommandComponent } from './execute-command/execute-command.component';
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-commands',
|
||||
|
@ -49,7 +50,8 @@ export class CommandsComponent implements OnInit {
|
|||
displayedColumns = [...this.columns.map(column => column.columnDef), 'actions'];
|
||||
private apiUrl = `${this.baseUrl}/commands`;
|
||||
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService) {}
|
||||
constructor(private http: HttpClient, private dialog: MatDialog, private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.search();
|
||||
|
@ -131,4 +133,19 @@ export class CommandsComponent implements OnInit {
|
|||
this.length = event.length;
|
||||
this.search();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'addCommandStep',
|
||||
'searchStep',
|
||||
'tableStep',
|
||||
'actionsStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,89 +1,96 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Administrar clientes</h2>
|
||||
<div class="images-button-row">
|
||||
<button mat-flat-button color="primary" (click)="resetFilters()">Reiniciar filtros</button>
|
||||
<button mat-flat-button color="primary" (click)="addClient($event)">Añadir cliente</button>
|
||||
</div>
|
||||
<div class="header-container">
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminImagesTitle" joyrideStep="title3Step" text="En esta pantalla se podran administrar todos los clientes del sistema sin jerarquias.">Administrar clientes</h2>
|
||||
<div class="images-button-row">
|
||||
<button mat-flat-button color="primary" (click)="resetFilters()" joyrideStep="resetFiltersStep" text="Reinicia los filtros aplicados para mostrar todos los clientes.">Reiniciar filtros</button>
|
||||
<button mat-flat-button color="primary" (click)="addClient($event)" joyrideStep="addClientStep" text="Añade un nuevo cliente a la lista.">Añadir cliente</button>
|
||||
</div>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<div class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de cliente</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar IP</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['ip']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar MAC</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['mac']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-select">
|
||||
<mat-label i18n="@@organizational-unit-label">U. Organizativa</mat-label>
|
||||
<mat-select [(ngModel)]="filters['organizationalUnit.id']" (selectionChange)="search()">
|
||||
<mat-option *ngFor="let unit of organizationalUnits" [value]="unit.id" >
|
||||
{{ unit.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loading" class="loading-container">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loading">
|
||||
<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 client" >
|
||||
<ng-container *ngIf="column.columnDef === 'name'">
|
||||
<div class="client-info">
|
||||
<div class="client-name">{{ client.name }}</div>
|
||||
<div class="client-ip">{{ client.ip }}</div>
|
||||
<div class="client-mac">{{ client.mac }}</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef === 'status'">
|
||||
<mat-chip>
|
||||
{{ client.status }}
|
||||
</mat-chip>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef !== 'status' && column.columnDef !== 'name'" >
|
||||
{{ column.cell(client) }}
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;">
|
||||
<button *ngIf="!syncStatus" mat-icon-button color="primary" (click)="getStatus(client)"><mat-icon>sync</mat-icon></button>
|
||||
<button *ngIf="syncStatus" mat-icon-button color="primary"><mat-spinner diameter="24"></mat-spinner></button>
|
||||
<button mat-icon-button color="info" (click)="handleClientClick($event, client)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="onEditClick($event, client.uuid)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="onDeleteClick($event, client)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
</button>
|
||||
</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]="pageSizeOptions"
|
||||
(page)="onPageChange($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container" joyrideStep="searchContainerStep" text="Filtra los clientes por nombre, IP, MAC o unidad organizativa.">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de cliente</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar IP</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['ip']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar MAC</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['mac']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="search-select" >
|
||||
<mat-label i18n="@@organizational-unit-label">U. Organizativa</mat-label>
|
||||
<mat-select [(ngModel)]="filters['organizationalUnit.id']" (selectionChange)="search()">
|
||||
<mat-option *ngFor="let unit of organizationalUnits" [value]="unit.id" >
|
||||
{{ unit.name }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div *ngIf="!loading" class="loading-container">
|
||||
<mat-spinner></mat-spinner>
|
||||
</div>
|
||||
|
||||
<div *ngIf="loading">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Lista de clientes filtrados por tus criterios de búsqueda.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let client" >
|
||||
<ng-container *ngIf="column.columnDef === 'name'">
|
||||
<div class="client-info">
|
||||
<div class="client-name">{{ client.name }}</div>
|
||||
<div class="client-ip">{{ client.ip }}</div>
|
||||
<div class="client-mac">{{ client.mac }}</div>
|
||||
</div>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef === 'status'">
|
||||
<mat-chip>{{ client.status }}</mat-chip>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef !== 'status' && column.columnDef !== 'name'">
|
||||
{{ column.cell(client) }}
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;" joyrideStep="actionsStep" text="Acciones disponibles para cada cliente, como ver, editar o eliminar.">
|
||||
<button *ngIf="!syncStatus" mat-icon-button color="primary" (click)="getStatus(client)"><mat-icon>sync</mat-icon></button>
|
||||
<button *ngIf="syncStatus" mat-icon-button color="primary"><mat-spinner diameter="24"></mat-spinner></button>
|
||||
<button mat-icon-button color="info" (click)="handleClientClick($event, client)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="onEditClick($event, client.uuid)" i18n="@@editImage"><mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="onDeleteClick($event, client)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de resultados utilizando el paginador.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
[pageSizeOptions]="pageSizeOptions"
|
||||
(page)="onPageChange($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -13,6 +13,7 @@ import { throwError } from 'rxjs';
|
|||
import { catchError } from 'rxjs/operators';
|
||||
import {ClientViewComponent} from "../../shared/client-view/client-view.component";
|
||||
import { Router } from '@angular/router';
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-client-tab-view',
|
||||
|
@ -78,7 +79,8 @@ export class ClientTabViewComponent {
|
|||
public dialog: MatDialog,
|
||||
private toastService: ToastrService,
|
||||
private http: HttpClient,
|
||||
private router: Router
|
||||
private router: Router,
|
||||
private joyrideService: JoyrideService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -190,4 +192,20 @@ export class ClientTabViewComponent {
|
|||
this.length = event.length;
|
||||
this.getClients();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'title3Step',
|
||||
'resetFiltersStep',
|
||||
'addClientStep',
|
||||
'searchContainerStep',
|
||||
'tableStep',
|
||||
'actionsStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Administrar unidades organizativas</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminImagesTitle" joyrideStep="titleS4tep" text="Gestiona las unidades organizativas desde esta pantalla.">Administrar unidades organizativas</h2>
|
||||
<div class="button-row">
|
||||
<button mat-flat-button color="primary" (click)="resetFilters()">Reiniciar filtros</button>
|
||||
<button mat-flat-button color="primary" (click)="addOrganizationalUnit($event)">Añadir OU</button>
|
||||
<button mat-flat-button color="primary" (click)="resetFilters()" joyrideStep="resetFiltersStep" text="Reinicia los filtros aplicados para mostrar todas las unidades organizativas.">Reiniciar filtros</button>
|
||||
<button mat-flat-button color="primary" (click)="addOrganizationalUnit($event)" joyrideStep="addOUStep" text="Añade una nueva unidad organizativa.">Añadir OU</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<div class="search-container">
|
||||
|
||||
<div class="search-container" joyrideStep="searchContainerStep" text="Filtra las unidades organizativas por nombre o tipo.">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de OU</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="search-boolean">
|
||||
<mat-label i18n="@@searchLabel">Tipo</mat-label>
|
||||
<mat-select [(ngModel)]="filters['type']" (selectionChange)="search()" placeholder="Seleccionar opción" >
|
||||
<mat-select [(ngModel)]="filters['type']" (selectionChange)="search()" placeholder="Seleccionar opción">
|
||||
<mat-option [value]="''">Todos</mat-option>
|
||||
<mat-option [value]="'organizational-unit'">Centro</mat-option>
|
||||
<mat-option [value]="'classrooms-group'">Grupos de aulas</mat-option>
|
||||
|
@ -24,28 +30,29 @@
|
|||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se muestran las unidades organizativas según los filtros aplicados.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let ou" >
|
||||
<td mat-cell *matCellDef="let ou">
|
||||
<ng-container *ngIf="column.columnDef !== 'available' && column.columnDef !== 'type'">
|
||||
{{ column.cell(ou) }}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef === 'available'" >
|
||||
<ng-container *ngIf="column.columnDef === 'available'">
|
||||
<mat-chip *ngIf="ou.available" class="mat-chip-success"><mat-icon class="calendar-ico">event_available</mat-icon></mat-chip>
|
||||
<mat-chip *ngIf="!ou.available" class="mat-chip-error"><mat-icon class="calendar-ico">event_busy</mat-icon></mat-chip>
|
||||
<mat-chip *ngIf="!ou.available" class="mat-chip-error"><mat-icon class="calendar-ico">event_busy</mat-icon></mat-chip>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef === 'type'" >
|
||||
<mat-chip> {{ ou.type }} </mat-chip>
|
||||
<ng-container *ngIf="column.columnDef === 'type'">
|
||||
<mat-chip>{{ ou.type }}</mat-chip>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let ou" style="text-align: center;">
|
||||
<td mat-cell *matCellDef="let ou" style="text-align: center;" joyrideStep="actionsStep" text="Usa estas opciones para ver, editar o eliminar una unidad organizativa.">
|
||||
<button mat-icon-button color="info" (click)="onShowClick($event, ou)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="onEditClick($event, ou.uuid)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="onEditClick($event, ou.uuid)" i18n="@@editImage"><mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="onDeleteClick($event, ou)"><mat-icon>delete</mat-icon></button>
|
||||
<button mat-icon-button color="info" [matMenuTriggerFor]="menu">
|
||||
<mat-icon>menu</mat-icon>
|
||||
|
@ -64,7 +71,8 @@
|
|||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<div class="paginator-container">
|
||||
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de unidades organizativas con el paginador.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
} from "../../shared/organizational-units/edit-organizational-unit/edit-organizational-unit.component";
|
||||
import {ClassroomViewDialogComponent} from "../../shared/classroom-view/classroom-view-modal";
|
||||
import {TreeViewComponent} from "../../shared/tree-view/tree-view.component";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-organizational-unit-tab-view',
|
||||
|
@ -79,7 +80,8 @@ export class OrganizationalUnitTabViewComponent {
|
|||
private dataService: DataService,
|
||||
public dialog: MatDialog,
|
||||
private toastService: ToastrService,
|
||||
private http: HttpClient
|
||||
private http: HttpClient,
|
||||
private joyrideService: JoyrideService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -169,4 +171,21 @@ export class OrganizationalUnitTabViewComponent {
|
|||
this.length = event.length;
|
||||
this.getOrganizationalUnits();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleS4tep',
|
||||
'resetFiltersStep',
|
||||
'addOUStep',
|
||||
'searchContainerStep',
|
||||
'tableStep',
|
||||
'actionsStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,53 +1,63 @@
|
|||
<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>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" joyrideStep="imagesTitleStep" text="En esta pantalla, puedes gestionar las imágenes disponibles.">
|
||||
Administrar imágenes
|
||||
</h2>
|
||||
<div class="images-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addImage()" joyrideStep="addImageButton" text="Añade una nueva imagen a la lista.">
|
||||
Añadir imagen
|
||||
</button>
|
||||
</div>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
</div>
|
||||
|
||||
<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>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<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" >
|
||||
<ng-container *ngIf="column.columnDef === 'remotePc'">
|
||||
<mat-icon [color]="image[column.columnDef] ? 'primary' : 'warn'">
|
||||
{{ image[column.columnDef] ? 'check_circle' : 'cancel' }}
|
||||
</mat-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef !== 'remotePc'">
|
||||
{{ column.cell(image) }}
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
<div class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-string" joyrideStep="searchImageField" text="Busca una imagen por nombre. Pulsa 'enter' para iniciar la búsqueda.">
|
||||
<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>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;">
|
||||
<button mat-icon-button color="primary" (click)="editImage($event, client)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="deleteImage($event, client)">
|
||||
<mat-icon i18n="@@deleteElementTooltip">delete</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="imagesTable" text="Esta tabla muestra las imágenes disponibles.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let image">
|
||||
<ng-container *ngIf="column.columnDef === 'remotePc'">
|
||||
<mat-icon [color]="image[column.columnDef] ? 'primary' : 'warn'">
|
||||
{{ image[column.columnDef] ? 'check_circle' : 'cancel' }}
|
||||
</mat-icon>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef !== 'remotePc'">
|
||||
{{ column.cell(image) }}
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<div class="paginator-container">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
[pageSizeOptions]="[5, 10, 20, 40, 100]"
|
||||
(page)="onPageChange($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;" joyrideStep="actionsHeader" text="Acciones disponibles para cada imagen.">Acciones</th>
|
||||
<td mat-cell *matCellDef="let client" style="text-align: center;">
|
||||
<button mat-icon-button color="primary" (click)="editImage($event, client)" joyrideStep="editImageButton" text="Editar la imagen seleccionada.">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="deleteImage($event, client)" joyrideStep="deleteImageButton" text="Eliminar la imagen seleccionada.">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
|
||||
<div class="paginator-container" joyrideStep="imagesPagination" text="Navega entre las páginas de imágenes.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
[pageSizeOptions]="[5, 10, 20, 40, 100]"
|
||||
(page)="onPageChange($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
|
|
|
@ -7,6 +7,7 @@ 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 { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-images',
|
||||
|
@ -61,7 +62,8 @@ export class ImagesComponent implements OnInit {
|
|||
constructor(
|
||||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private toastService: ToastrService
|
||||
private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -127,4 +129,22 @@ export class ImagesComponent implements OnInit {
|
|||
this.length = event.length;
|
||||
this.search();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'imagesTitleStep',
|
||||
'addImageButton',
|
||||
'searchImageField',
|
||||
'imagesTable',
|
||||
'actionsHeader',
|
||||
'editImageButton',
|
||||
'deleteImageButton',
|
||||
'imagesPagination'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
|
||||
.header-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.disk-usage-info{
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
|
|
|
@ -1,59 +1,64 @@
|
|||
<div class="dashboard">
|
||||
<h2>OgBoot server Status</h2>
|
||||
|
||||
<div class="disk-usage-container">
|
||||
<div class="disk-usage">
|
||||
<h3>Uso de disco</h3>
|
||||
<ngx-charts-pie-chart
|
||||
[view]="view"
|
||||
[scheme]="colorScheme"
|
||||
[results]="diskUsageChartData"
|
||||
[gradient]="gradient"
|
||||
[doughnut]="isDoughnut"
|
||||
[labels]="showLabels"
|
||||
[legend]="showLegend">
|
||||
</ngx-charts-pie-chart>
|
||||
<div class="disk-usage-info">
|
||||
<p>Total: {{ formatBytes(diskUsage.total) }}</p>
|
||||
<p>Ocupado: {{ formatBytes(diskUsage.used) }}</p>
|
||||
<p>Disponible: {{ formatBytes(diskUsage.available) }}</p>
|
||||
<p>Libre: {{ diskUsage.percentage }}%</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="services-status">
|
||||
<h3>Servicios</h3>
|
||||
<ul>
|
||||
<li *ngFor="let service of getServices()">
|
||||
<span
|
||||
class="status-led"
|
||||
[ngClass]="{ 'active': service.status === 'active', 'inactive': service.status !== 'active' }"
|
||||
></span>
|
||||
{{ service.name }}: {{ service.status }}
|
||||
</li>
|
||||
</ul>
|
||||
<div class="header-container" >
|
||||
<h2 joyrideStep="titleStep" text="Esta sección muestra el estado general del servidor OgBoot.">OgBoot server Status</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="disk-usage-container">
|
||||
<div class="disk-usage" joyrideStep="diskUsageStep" text="Visualiza el uso del disco del servidor.">
|
||||
<h3>Uso de disco</h3>
|
||||
<ngx-charts-pie-chart
|
||||
[view]="view"
|
||||
[scheme]="colorScheme"
|
||||
[results]="diskUsageChartData"
|
||||
[gradient]="gradient"
|
||||
[doughnut]="isDoughnut"
|
||||
[labels]="showLabels"
|
||||
[legend]="showLegend">
|
||||
</ngx-charts-pie-chart>
|
||||
<div class="disk-usage-info">
|
||||
<p>Total: {{ formatBytes(diskUsage.total) }}</p>
|
||||
<p>Ocupado: {{ formatBytes(diskUsage.used) }}</p>
|
||||
<p>Disponible: {{ formatBytes(diskUsage.available) }}</p>
|
||||
<p>Libre: {{ diskUsage.percentage }}%</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="installed-oglives">
|
||||
<h3>OGLives instalados</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Kernel</th>
|
||||
<th>Architecture</th>
|
||||
<th>Revision</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let oglive of installedOglives">
|
||||
<td>{{ oglive.id }}</td>
|
||||
<td>{{ oglive.kernel }}</td>
|
||||
<td>{{ oglive.architecture }}</td>
|
||||
<td>{{ oglive.revision }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="services-status" joyrideStep="servicesStatusStep" text="Aquí puedes ver el estado de los servicios importantes del servidor.">
|
||||
<h3>Servicios</h3>
|
||||
<ul>
|
||||
<li *ngFor="let service of getServices()">
|
||||
<span
|
||||
class="status-led"
|
||||
[ngClass]="{ 'active': service.status === 'active', 'inactive': service.status !== 'active' }"
|
||||
></span>
|
||||
{{ service.name }}: {{ service.status }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="installed-oglives" joyrideStep="oglivesStep" text="Consulta la información de los OGLives instalados en el servidor.">
|
||||
<h3>OGLives instalados</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Kernel</th>
|
||||
<th>Architecture</th>
|
||||
<th>Revision</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let oglive of installedOglives">
|
||||
<td>{{ oglive.id }}</td>
|
||||
<td>{{ oglive.kernel }}</td>
|
||||
<td>{{ oglive.architecture }}</td>
|
||||
<td>{{ oglive.revision }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-ogboot-status',
|
||||
|
@ -23,7 +24,7 @@ export class OgbootStatusComponent implements OnInit {
|
|||
domain: ['#FF6384', '#3f51b5']
|
||||
};
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
constructor(private http: HttpClient, private joyrideService: JoyrideService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadStatus();
|
||||
|
@ -68,4 +69,18 @@ export class OgbootStatusComponent implements OnInit {
|
|||
return bytes + ' B';
|
||||
}
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'diskUsageStep',
|
||||
'servicesStatusStep',
|
||||
'oglivesStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
|
||||
<div class="header-container">
|
||||
<h2 class="title">Netboot avanzado</h2>
|
||||
<h2 class="title" joyrideStep="titleStep" text="Esta sección permite la asignación masiva de plantillas de arranque a clientes.">Netboot avanzado</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div [formGroup]="taskForm" class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-boolean">
|
||||
<mat-form-field appearance="fill" class="search-boolean" joyrideStep="selectUnitStep" text="Selecciona la Unidad Organizacional para listar las aulas disponibles.">
|
||||
<mat-label>Selecciona Unidad Organizacional</mat-label>
|
||||
<mat-select formControlName="organizationalUnit" (selectionChange)="onOrganizationalUnitChange()">
|
||||
<mat-option *ngIf="loadingUnits" disabled>Cargando unidades...</mat-option>
|
||||
|
@ -15,7 +17,7 @@
|
|||
<mat-error *ngIf="taskForm.get('organizationalUnit')?.invalid">Este campo es obligatorio</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field appearance="fill" class="search-boolean">
|
||||
<mat-form-field appearance="fill" class="search-boolean" joyrideStep="selectClassStep" text="Selecciona el aula para configurar las plantillas en sus dispositivos.">
|
||||
<mat-label>Selecciona aula</mat-label>
|
||||
<mat-select formControlName="selectedChild" (selectionChange)="onChildChange()">
|
||||
<mat-option *ngIf="selectedUnitChildren.length === 0" disabled>No hay aulas disponibles</mat-option>
|
||||
|
@ -29,17 +31,17 @@
|
|||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="global-selectors">
|
||||
<mat-form-field appearance="fill" class="selected-global">
|
||||
<mat-form-field appearance="fill" class="selected-global" joyrideStep="applyToAllStep" text="Selecciona una plantilla para aplicarla a todos los clientes de esta aula.">
|
||||
<mat-label>Seleccione plantilla para aplicar a todos los clientes</mat-label>
|
||||
<mat-select [(value)]="globalOgLive" (selectionChange)="applyToAll()" >
|
||||
<mat-select [(value)]="globalOgLive" (selectionChange)="applyToAll()">
|
||||
<mat-option *ngFor="let option of ogLiveOptions" [value]="option['@id']">{{ option.name }}</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<button mat-flat-button color="primary" [disabled]="selectedUnitChildren.length === 0" (click)="saveOgLiveTemplates()">Guardar</button>
|
||||
<button mat-flat-button color="primary" [disabled]="selectedUnitChildren.length === 0" (click)="saveOgLiveTemplates()" joyrideStep="saveButtonStep" text="Haz clic para guardar la configuración actual de plantillas.">Guardar</button>
|
||||
</div>
|
||||
|
||||
<mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Administra las plantillas de Netboot para cada cliente en esta tabla.">
|
||||
<ng-container matColumnDef="id">
|
||||
<mat-header-cell *matHeaderCellDef> Id </mat-header-cell>
|
||||
<mat-cell *matCellDef="let element"> {{element.id}} </mat-cell>
|
||||
|
@ -53,7 +55,7 @@
|
|||
<ng-container matColumnDef="ogLive">
|
||||
<mat-header-cell *matHeaderCellDef> Plantilla </mat-header-cell>
|
||||
<mat-cell *matCellDef="let client">
|
||||
<mat-form-field appearance="fill">
|
||||
<mat-form-field appearance="fill" joyrideStep="selectTemplateStep" text="Selecciona una plantilla específica para cada cliente.">
|
||||
<mat-label>Seleccione una plantilla</mat-label>
|
||||
<mat-select [(ngModel)]="client.ogLive" [name]="'ogLive' + client.id">
|
||||
<mat-option [value]="null">Ninguna</mat-option>
|
||||
|
@ -65,7 +67,6 @@
|
|||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
|
||||
<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
|
||||
<mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
|
||||
</mat-table>
|
||||
|
|
|
@ -5,6 +5,7 @@ import { ToastrService } from 'ngx-toastr';
|
|||
import { PageEvent } from '@angular/material/paginator';
|
||||
import {Observable} from "rxjs";
|
||||
import {ServerInfoDialogComponent} from "../../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pxe-boot-files',
|
||||
|
@ -32,7 +33,8 @@ export class PxeBootFilesComponent implements OnInit {
|
|||
constructor(
|
||||
private fb: FormBuilder,
|
||||
private http: HttpClient,
|
||||
private toastService: ToastrService
|
||||
private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService
|
||||
) {
|
||||
this.taskForm = this.fb.group({
|
||||
organizationalUnit: ['', Validators.required],
|
||||
|
@ -155,4 +157,21 @@ export class PxeBootFilesComponent implements OnInit {
|
|||
this.itemsPerPage = event.pageSize;
|
||||
this.fetchPxeTemplates();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'selectUnitStep',
|
||||
'selectClassStep',
|
||||
'applyToAllStep',
|
||||
'saveButtonStep',
|
||||
'tableStep',
|
||||
'selectTemplateStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,41 +1,47 @@
|
|||
<mat-accordion class="example-headers-align">
|
||||
<mat-expansion-panel hideToggle>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-expansion-panel-header joyrideStep="serverInfoStep" text="Accede a información y opciones de sincronización en el servidor OgBoot.">
|
||||
<mat-panel-title> Información en servidor ogBoot </mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<div class="button-row">
|
||||
<button mat-flat-button color="primary" (click)="syncOgBoot()"> Sincronizar base de datos</button>
|
||||
<button mat-flat-button color="primary" (click)="syncOgBoot()" > Sincronizar base de datos</button>
|
||||
</div>
|
||||
<div class="button-row">
|
||||
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()">Ver Información</button>
|
||||
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()" >Ver Información</button>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Administrar imágenes</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminImagesTitle" joyrideStep="titleStep" text="Desde aquí puedes gestionar las imágenes configuradas en el servidor OgBoot.">Administrar imágenes</h2>
|
||||
<div class="images-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addImage()">Añadir imagen</button>
|
||||
<button mat-flat-button color="primary" (click)="addImage()" joyrideStep="addImageStep" text="Haz clic para añadir una nueva imagen.">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-form-field appearance="fill" class="search-string" joyrideStep="searchNameStep" text="Busca imágenes por nombre para encontrar rápidamente una imagen específica.">
|
||||
<mat-label i18n="@@searchLabel">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 i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-boolean">
|
||||
|
||||
<mat-form-field appearance="fill" class="search-boolean" joyrideStep="searchDefaultImageStep" text="Filtra las imágenes para mostrar solo las imágenes por defecto o no por defecto.">
|
||||
<mat-label i18n="@@searchLabel">Imagen por defecto</mat-label>
|
||||
<mat-select [(ngModel)]="filters['isDefault']" (selectionChange)="search()" placeholder="Seleccionar opción" >
|
||||
<mat-select [(ngModel)]="filters['isDefault']" (selectionChange)="search()" placeholder="Seleccionar opción">
|
||||
<mat-option [value]="''">Todos</mat-option>
|
||||
<mat-option [value]="true">Sí</mat-option>
|
||||
<mat-option [value]="false">No</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-boolean">
|
||||
|
||||
<mat-form-field appearance="fill" class="search-boolean" joyrideStep="searchInstalledStep" text="Filtra las imágenes para mostrar solo las instaladas en el servidor OgBoot.">
|
||||
<mat-label i18n="@@searchLabel">Instalado servidor ogBoot</mat-label>
|
||||
<mat-select [(ngModel)]="filters['installed']" (selectionChange)="search()" placeholder="Seleccionar opción">
|
||||
<mat-option [value]="''">Todos</mat-option>
|
||||
|
@ -44,11 +50,11 @@
|
|||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se muestra la lista de imágenes disponibles para administrar.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let image" >
|
||||
|
||||
<td mat-cell *matCellDef="let image">
|
||||
<ng-container *ngIf="column.columnDef === 'isDefault' || column.columnDef === 'installed'">
|
||||
<mat-icon [color]="image[column.columnDef] ? 'primary' : 'warn'">
|
||||
{{ image[column.columnDef] ? 'check_circle' : 'cancel' }}
|
||||
|
@ -76,15 +82,14 @@
|
|||
<ng-container *ngIf="column.columnDef !== 'isDefault' && column.columnDef !== 'installed' && column.columnDef !== 'downloadUrl' && column.columnDef !== 'status' && column.columnDef !== 'name' ">
|
||||
{{ column.cell(image) }}
|
||||
</ng-container>
|
||||
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions">Acciones</th>
|
||||
<td mat-cell *matCellDef="let image">
|
||||
<td mat-cell *matCellDef="let image" joyrideStep="actionsStep" text="Administra cada imagen con opciones para ver, editar, eliminar y más.">
|
||||
<button mat-icon-button color="info" (click)="showOgLive($event, image)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editImage(image)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editImage(image)" i18n="@@editImage"><mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="deleteImage(image)" i18n="@@buttonDelete"><mat-icon>delete</mat-icon></button>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>menu</mat-icon>
|
||||
|
@ -100,7 +105,8 @@
|
|||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<div class="paginator-container">
|
||||
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de imágenes usando el paginador.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
|
|
|
@ -12,6 +12,7 @@ import {DataService} from "./data.service";
|
|||
import {ServerInfoDialogComponent} from "../../ogdhcp/og-dhcp-subnets/server-info-dialog/server-info-dialog.component";
|
||||
import {ShowTemplateContentComponent} from "../pxe/show-template-content/show-template-content.component";
|
||||
import {Observable} from "rxjs";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pxe-images',
|
||||
|
@ -77,7 +78,8 @@ export class PXEimagesComponent implements OnInit {
|
|||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private dataService: DataService,
|
||||
private toastService: ToastrService
|
||||
private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -254,4 +256,23 @@ export class PXEimagesComponent implements OnInit {
|
|||
this.toastService.error('Error al sincronizar');
|
||||
});
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'serverInfoStep',
|
||||
'titleStep',
|
||||
'addImageStep',
|
||||
'searchNameStep',
|
||||
'searchDefaultImageStep',
|
||||
'searchInstalledStep',
|
||||
'tableStep',
|
||||
'actionsStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<mat-accordion class="example-headers-align">
|
||||
<mat-expansion-panel hideToggle>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-expansion-panel-header joyrideStep="serverInfoStep" text="Accede a información y opciones de sincronización en el servidor OgBoot.">
|
||||
<mat-panel-title> Información en servidor ogBoot </mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div class="example-button-row">
|
||||
<button mat-flat-button color="primary" (click)="syncTemplates()"> Sincronizar base de datos</button>
|
||||
<button mat-flat-button color="primary" (click)="syncTemplates()" > Sincronizar base de datos</button>
|
||||
</div>
|
||||
<div class="example-button-row">
|
||||
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()">Ver Información</button>
|
||||
|
@ -12,34 +12,39 @@
|
|||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
|
||||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminPXETitle">Administrar plantillas PXE</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminPXETitle" joyrideStep="titleStep" text="Desde aquí puedes gestionar las plantillas PXE configuradas en el servidor OgBoot.">Administrar plantillas PXE</h2>
|
||||
<div class="pxe-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addPxeTemplate()">Añadir plantilla PXE</button>
|
||||
<button mat-flat-button color="primary" (click)="addPxeTemplate()" joyrideStep="addTemplateStep" text="Haz clic para añadir una nueva plantilla PXE.">Añadir plantilla PXE</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-form-field appearance="fill" class="search-string" joyrideStep="searchNameStep" text="Busca plantillas PXE por nombre para localizar rápidamente una plantilla específica.">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de plantilla</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-boolean">
|
||||
<mat-form-field appearance="fill" class="search-boolean" joyrideStep="searchSyncStep" text="Filtra para ver solo las plantillas creadas en el servidor OgBoot.">
|
||||
<mat-label i18n="@@searchLabel">Creada en ogBoot</mat-label>
|
||||
<mat-select [(ngModel)]="filters['synchronized']" (selectionChange)="search()" placeholder="Seleccionar opción" >
|
||||
<mat-select [(ngModel)]="filters['synchronized']" (selectionChange)="search()" placeholder="Seleccionar opción">
|
||||
<mat-option [value]="''">Todos</mat-option>
|
||||
<mat-option [value]="true">Sí</mat-option>
|
||||
<mat-option [value]="false">No</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se muestra la lista de plantillas PXE disponibles para administrar.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let image" >
|
||||
<td mat-cell *matCellDef="let image">
|
||||
<ng-container *ngIf="column.columnDef === 'synchronized'">
|
||||
<mat-icon [color]="image[column.columnDef] ? 'primary' : 'warn'">
|
||||
{{ image[column.columnDef] ? 'check_circle' : 'cancel' }}
|
||||
|
@ -52,19 +57,19 @@
|
|||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions" >
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let template" style="text-align: center;">
|
||||
<td mat-cell *matCellDef="let template" style="text-align: center;" joyrideStep="actionsStep" text="Gestiona cada plantilla PXE con opciones para ver, editar, eliminar y más.">
|
||||
<button mat-icon-button color="info" (click)="showTemplate($event, template)"><mat-icon i18n="@@deleteElementTooltip">visibility</mat-icon></button>
|
||||
<button mat-icon-button color="info" [disabled]="template.clientsLength === 0" (click)="editClients($event, template)"><mat-icon i18n="@@deleteElementTooltip">computer</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editPxeTemplate(template)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="info" [disabled]="template.clientsLength === 0" (click)="editClients($event, template)"><mat-icon i18n="@@deleteElementTooltip">computer</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editPxeTemplate(template)" i18n="@@editImage"><mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>menu</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item (click)="toggleAction(template, 'create')">Crear en servidor ogBoot</button>
|
||||
<button mat-menu-item (click)="addClientsToPxe(template)">Añadir cliente</button>
|
||||
<button mat-menu-item (click)="addClientsToPxe(template)">Añadir cliente</button>
|
||||
<button mat-menu-item (click)="toggleAction(template, 'sync')">Sincronizar base de datos</button>
|
||||
<button mat-menu-item (click)="toggleAction(template, 'delete')">Eliminar</button>
|
||||
</mat-menu>
|
||||
|
@ -74,7 +79,8 @@
|
|||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<div class="paginator-container">
|
||||
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de plantillas PXE usando el paginador.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
|
|
|
@ -20,6 +20,7 @@ import {Subnet} from "../../ogdhcp/og-dhcp-subnets/og-dhcp-subnets.component";
|
|||
import {AddClientsToPxeComponent} from "./add-clients-to-pxe/add-clients-to-pxe.component";
|
||||
import {Observable} from "rxjs";
|
||||
import {ClientsComponent} from "./clients/clients.component";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-pxe',
|
||||
|
@ -72,7 +73,8 @@ export class PxeComponent {
|
|||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private toastService: ToastrService,
|
||||
private dataService: DataService
|
||||
private dataService: DataService,
|
||||
private joyrideService: JoyrideService
|
||||
) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -228,4 +230,22 @@ export class PxeComponent {
|
|||
this.itemsPerPage = event.pageSize;
|
||||
this.applyFilter();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'serverInfoStep',
|
||||
'titleStep',
|
||||
'addTemplateStep',
|
||||
'searchNameStep',
|
||||
'searchSyncStep',
|
||||
'tableStep',
|
||||
'actionsStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,57 +1,62 @@
|
|||
<mat-accordion class="example-headers-align">
|
||||
<mat-expansion-panel hideToggle>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-expansion-panel-header joyrideStep="serverInfoStep" text="Despliega este contenedor para acceder a la información y opciones de sincronización en el servidor OgDHCP.">
|
||||
<mat-panel-title> Información en servidor ogDHCP </mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
<div class="example-button-row">
|
||||
<button mat-flat-button color="primary" (click)="syncSubnets()"> Sincronizar base de datos</button>
|
||||
<button mat-flat-button color="primary" (click)="syncSubnets()" joyrideStep="syncDbStep" text="Sincroniza la base de datos del servidor OgDHCP para actualizar la información de las subredes."> Sincronizar base de datos</button>
|
||||
</div>
|
||||
<div class="example-button-row">
|
||||
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()">Ver Información</button>
|
||||
<button mat-flat-button color="accent" (click)="openSubnetInfoDialog()" joyrideStep="viewInfoStep" text="Haz clic para ver información detallada de las subredes en el servidor.">Ver Información</button>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
|
||||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@subnetsTitle">Administrar Subredes</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@subnetsTitle" joyrideStep="titleStep" text="Desde aquí puedes gestionar las subredes configuradas en el servidor OgDHCP.">Administrar Subredes</h2>
|
||||
<div class="subnets-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addSubnet()">Añadir Subred</button>
|
||||
<button mat-flat-button color="primary" (click)="addSubnet()" joyrideStep="addSubnetStep" text="Haz clic para añadir una nueva subred.">Añadir Subred</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-form-field appearance="fill" class="search-string" joyrideStep="searchNameStep" text="Busca subredes por nombre para localizar una subred específica rápidamente.">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de la subred</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" i18n-placeholder="@@searchPlaceholder">
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-form-field appearance="fill" class="search-string" joyrideStep="searchNetmaskStep" text="Busca subredes usando una netmask específica.">
|
||||
<mat-label i18n="@@searchLabel">Buscar netmask</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['netmask']" i18n-placeholder="@@searchPlaceholder">
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['netmask']" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-form-field appearance="fill" class="search-string" joyrideStep="searchIpStep" text="Busca subredes por dirección IP.">
|
||||
<mat-label i18n="@@searchLabel">Buscar IP</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['ip']" i18n-placeholder="@@searchPlaceholder">
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['ip']" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-form-field appearance="fill" class="search-string" joyrideStep="searchBootFileStep" text="Busca subredes según el nombre del archivo de arranque.">
|
||||
<mat-label i18n="@@searchLabel">Buscar Boot file name</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['bootFileName']" i18n-placeholder="@@searchPlaceholder">
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['bootFileName']" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Visualiza y administra las subredes listadas según los filtros aplicados.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let subnet">
|
||||
|
||||
<ng-container *ngIf="column.columnDef === 'synchronized'">
|
||||
<mat-icon [color]="subnet[column.columnDef] ? 'primary' : 'warn'">
|
||||
{{ subnet[column.columnDef] ? 'check_circle' : 'cancel' }}
|
||||
|
@ -75,9 +80,10 @@
|
|||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let subnet" style="text-align: center;">
|
||||
<td mat-cell *matCellDef="let subnet" style="text-align: center;" joyrideStep="actionsStep" text="Gestiona cada subred con opciones para editar, eliminar y más.">
|
||||
<button mat-icon-button color="primary" (click)="editSubnet(subnet)" i18n="@@editSubnet">
|
||||
<mat-icon>edit</mat-icon></button>
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="toggleAction(subnet, 'delete')"><mat-icon>delete</mat-icon></button>
|
||||
<button mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>menu</mat-icon>
|
||||
|
@ -93,8 +99,8 @@
|
|||
<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]="pageSizeOptions"
|
||||
(page)="onPageChange($event)">
|
||||
|
||||
<div class="paginator-container" joyrideStep="paginationStep" text="Navega entre las páginas de subredes usando el paginador.">
|
||||
<mat-paginator [length]="length" [pageSize]="itemsPerPage" [pageIndex]="page" [pageSizeOptions]="pageSizeOptions" (page)="onPageChange($event)">
|
||||
</mat-paginator>
|
||||
</div>
|
||||
|
|
|
@ -7,8 +7,9 @@ import { HttpClient } from '@angular/common/http';
|
|||
import { DeleteModalComponent } from '../../../shared/delete_modal/delete-modal/delete-modal.component';
|
||||
import { ToastrService } from 'ngx-toastr';
|
||||
import { AddClientsToSubnetComponent } from './add-clients-to-subnet/add-clients-to-subnet.component';
|
||||
import {ServerInfoDialogComponent} from "./server-info-dialog/server-info-dialog.component";
|
||||
import {Observable} from "rxjs";
|
||||
import { ServerInfoDialogComponent } from "./server-info-dialog/server-info-dialog.component";
|
||||
import { Observable } from "rxjs";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
export interface Subnet {
|
||||
'@id': string;
|
||||
|
@ -32,7 +33,7 @@ export interface Subnet {
|
|||
templateUrl: './og-dhcp-subnets.component.html',
|
||||
styleUrls: ['./og-dhcp-subnets.component.css']
|
||||
})
|
||||
export class OgDhcpSubnetsComponent {
|
||||
export class OgDhcpSubnetsComponent {
|
||||
baseUrl: string = import.meta.env.NG_APP_BASE_API_URL;
|
||||
displayedColumns: string[] = ['id', 'name', 'netmask', 'ipAddress', 'nextServer', 'bootFileName', 'synchronized', 'serverId', 'clients', 'actions'];
|
||||
dataSource = new MatTableDataSource<Subnet>([]);
|
||||
|
@ -52,14 +53,15 @@ export class OgDhcpSubnetsComponent {
|
|||
{ columnDef: 'ipAddress', header: 'IP Address', cell: (subnet: Subnet) => subnet.ipAddress },
|
||||
{ columnDef: 'nextServer', header: 'Next Server', cell: (subnet: Subnet) => subnet.nextServer },
|
||||
{ columnDef: 'bootFileName', header: 'Boot File Name', cell: (subnet: Subnet) => subnet.bootFileName },
|
||||
{ columnDef: 'synchronized', header: 'Sincronizado', cell: (subnet: Subnet) => `${subnet.synchronized}`},
|
||||
{ columnDef: 'synchronized', header: 'Sincronizado', cell: (subnet: Subnet) => `${subnet.synchronized}` },
|
||||
{ columnDef: 'serverId', header: 'Id Servidor DHCP', cell: (subnet: Subnet) => subnet.serverId },
|
||||
{ columnDef: 'clients', header: 'Lista de clientes', cell: (subnet: Subnet) => `${subnet.clients}`},
|
||||
{ columnDef: 'clients', header: 'Lista de clientes', cell: (subnet: Subnet) => `${subnet.clients}` },
|
||||
];
|
||||
|
||||
private apiUrl = `${this.baseUrl}/subnets`;
|
||||
|
||||
constructor(public dialog: MatDialog, private http: HttpClient, private toastService: ToastrService) {}
|
||||
constructor(public dialog: MatDialog, private http: HttpClient, private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.loadSubnets();
|
||||
|
@ -93,7 +95,7 @@ export class OgDhcpSubnetsComponent {
|
|||
});
|
||||
}
|
||||
|
||||
toggleAction(subnet: any, action:string): void {
|
||||
toggleAction(subnet: any, action: string): void {
|
||||
switch (action) {
|
||||
case 'get':
|
||||
this.http.post(`${this.baseUrl}/og-dhcp/server/${subnet.uuid}/get`, {}).subscribe({
|
||||
|
@ -149,7 +151,8 @@ export class OgDhcpSubnetsComponent {
|
|||
this.toastService.error(error.error['hydra:description']);
|
||||
}
|
||||
});
|
||||
}})
|
||||
}
|
||||
})
|
||||
break;
|
||||
default:
|
||||
console.error('Acción no soportada:', action);
|
||||
|
@ -216,4 +219,26 @@ export class OgDhcpSubnetsComponent {
|
|||
this.itemsPerPage = event.pageSize;
|
||||
this.loadSubnets();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'serverInfoStep',
|
||||
'syncDbStep',
|
||||
'viewInfoStep',
|
||||
'titleStep',
|
||||
'addSubnetStep',
|
||||
'searchNameStep',
|
||||
'searchNetmaskStep',
|
||||
'searchIpStep',
|
||||
'searchBootFileStep',
|
||||
'tableStep',
|
||||
'actionsStep',
|
||||
'paginationStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,11 +78,17 @@ th {
|
|||
.button-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px; /* Espacio entre botones */
|
||||
gap: 10px;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
|
||||
.header-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
height: 100px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.btn:first-child {
|
||||
margin-left: 0;
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
<div class="dashboard">
|
||||
<h2>OgDhcp server Status</h2>
|
||||
<div class="header-container" >
|
||||
|
||||
<h2 joyrideStep="titleStep" text="Esta sección muestra el estado general del servidor OgDhcp.">OgDhcp server Status</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="disk-usage-container">
|
||||
<div class="disk-usage">
|
||||
<div class="disk-usage" joyrideStep="diskUsageStep" text="Visualiza el uso del disco del servidor.">
|
||||
<h3>Uso de disco</h3>
|
||||
<ngx-charts-pie-chart
|
||||
[view]="view"
|
||||
|
@ -21,40 +26,40 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="services-status">
|
||||
<div class="services-status" joyrideStep="servicesStatusStep" text="Aquí puedes ver el estado de los servicios importantes del servidor.">
|
||||
<h3>Servicios</h3>
|
||||
<ul>
|
||||
<li *ngFor="let service of getServices()">
|
||||
<span
|
||||
class="status-led"
|
||||
[ngClass]="{ 'active': service.status === 'active', 'inactive': service.status !== 'active' }"
|
||||
></span>
|
||||
<span
|
||||
class="status-led"
|
||||
[ngClass]="{ 'active': service.status === 'active', 'inactive': service.status !== 'active' }"
|
||||
></span>
|
||||
{{ service.name }}: {{ service.status }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="installed-oglives">
|
||||
<div class="installed-oglives" joyrideStep="subnetsStep" text="Consulta la información de las subredes configuradas en el servidor.">
|
||||
<h3>Subredes</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Boot file name</th>
|
||||
<th>Next server</th>
|
||||
<th>Ip</th>
|
||||
<th>Ordenadores</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Boot file name</th>
|
||||
<th>Next server</th>
|
||||
<th>Ip</th>
|
||||
<th>Ordenadores</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr *ngFor="let subnet of subnets">
|
||||
<td>{{ subnet.id }}</td>
|
||||
<td>{{ subnet['boot-file-name'] }}</td>
|
||||
<td>{{ subnet['next-server'] }}</td>
|
||||
<td>{{ subnet.subnet }}</td>
|
||||
<td>{{ subnet.reservations.length }}</td>
|
||||
</tr>
|
||||
<tr *ngFor="let subnet of subnets">
|
||||
<td>{{ subnet.id }}</td>
|
||||
<td>{{ subnet['boot-file-name'] }}</td>
|
||||
<td>{{ subnet['next-server'] }}</td>
|
||||
<td>{{ subnet.subnet }}</td>
|
||||
<td>{{ subnet.reservations.length }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Component } from '@angular/core';
|
||||
import {HttpClient} from "@angular/common/http";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-status',
|
||||
|
@ -23,7 +24,8 @@ export class StatusComponent {
|
|||
domain: ['#FF6384', '#3f51b5']
|
||||
};
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
constructor(private http: HttpClient,
|
||||
private joyrideService: JoyrideService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.loadStatus();
|
||||
|
@ -55,4 +57,18 @@ export class StatusComponent {
|
|||
status: this.servicesStatus[key]
|
||||
}));
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'diskUsageStep',
|
||||
'servicesStatusStep',
|
||||
'subnetsStep'
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,22 +1,30 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Administrar sistemas operativos</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminImagesTitle" joyrideStep="osTitleStep" text="En esta pantalla, puedes gestionar los sistemas operativos disponibles.">
|
||||
Administrar sistemas operativos
|
||||
</h2>
|
||||
<div class="calendar-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addSoftware()">Añadir sistema operativo</button>
|
||||
<button mat-flat-button color="primary" (click)="addSoftware()" joyrideStep="addOsButton" text="Añade un nuevo sistema operativo a la lista.">Añadir sistema operativo</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
|
||||
<div class="search-container">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-form-field appearance="fill" class="search-string" joyrideStep="searchField" text="Busca un sistema operativo por nombre. Pulsa 'enter' para iniciar la búsqueda.">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de sistema operativo</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
<mat-icon matSuffix>search</mat-icon>
|
||||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="table" text="Esta tabla muestra los sistemas operativos existentes.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let image" >
|
||||
<td mat-cell *matCellDef="let image">
|
||||
<ng-container>
|
||||
{{ column.cell(image) }}
|
||||
</ng-container>
|
||||
|
@ -24,17 +32,22 @@
|
|||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;" joyrideStep="actionsHeader" text="Acciones disponibles para cada sistema operativo.">Acciones</th>
|
||||
<td mat-cell *matCellDef="let calendar" style="text-align: center;">
|
||||
<button mat-icon-button color="primary" (click)="editSoftware(calendar)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
<button mat-icon-button color="warn" (click)="deleteSoftware(calendar)" i18n="@@buttonDelete"><mat-icon>delete</mat-icon></button>
|
||||
<button mat-icon-button color="primary" (click)="editSoftware(calendar)" i18n="@@editImage" joyrideStep="editButton" text="Editar el sistema operativo seleccionado.">
|
||||
<mat-icon>edit</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button color="warn" (click)="deleteSoftware(calendar)" i18n="@@buttonDelete" joyrideStep="deleteButton" text="Eliminar el sistema operativo seleccionado.">
|
||||
<mat-icon>delete</mat-icon>
|
||||
</button>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
<div class="paginator-container">
|
||||
|
||||
<div class="paginator-container" joyrideStep="pagination" text="Navega entre las páginas de sistemas operativos.">
|
||||
<mat-paginator [length]="length"
|
||||
[pageSize]="itemsPerPage"
|
||||
[pageIndex]="page"
|
||||
|
|
|
@ -9,6 +9,7 @@ import {CreateSoftwareComponent} from "../software/create-software/create-softwa
|
|||
import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component";
|
||||
import {PageEvent} from "@angular/material/paginator";
|
||||
import {CreateOperativeSystemComponent} from "./create-operative-system/create-operative-system.component";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-operative-system',
|
||||
|
@ -53,7 +54,8 @@ export class OperativeSystemComponent {
|
|||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private dataService: DataService,
|
||||
private toastService: ToastrService
|
||||
private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -124,4 +126,13 @@ export class OperativeSystemComponent {
|
|||
this.length = event.length;
|
||||
this.search();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: ['osTitleStep', 'addOsButton', 'searchField', 'table', 'actionsHeader', 'editButton', 'deleteButton', 'pagination'],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Administrar perfiles software</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminImagesTitle" joyrideStep="titleStep" text="En esta pantalla podrás administrar los diferentes perfiles de software">Administrar perfiles software</h2>
|
||||
<div class="calendar-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addSoftware()">Añadir perfil software</button>
|
||||
<button mat-flat-button color="primary" (click)="addSoftware()" joyrideStep="addStep" text="Crea nuevos perfiles de software.">Añadir perfil software</button>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<div class="search-container">
|
||||
<div class="search-container" joyrideStep="filterStep" text="Utiliza los filtros para buscar entre los perfiles de software existentes." >
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de perfil</mat-label>
|
||||
<input matInput placeholder="Búsqueda" [(ngModel)]="filters['description']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
|
@ -13,7 +16,7 @@
|
|||
<mat-hint i18n="@@searchHint">Pulsar 'enter' para buscar</mat-hint>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyrideStep="tableStep" text="Aquí se listarán los perfiles existentes y sus detalles.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let image" >
|
||||
|
@ -29,7 +32,7 @@
|
|||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
<ng-container matColumnDef="actions" joyrideStep="actionsStep" text="Utiliza los botones dedicados para realizar diferentes acciones sobre los perfiles.">
|
||||
<th mat-header-cell *matHeaderCellDef i18n="@@columnActions" style="text-align: center;">Acciones</th>
|
||||
<td mat-cell *matCellDef="let calendar" style="text-align: center;">
|
||||
<button mat-icon-button color="primary" (click)="editSoftware(calendar)" i18n="@@editImage"> <mat-icon>edit</mat-icon></button>
|
||||
|
|
|
@ -8,6 +8,7 @@ import {ToastrService} from "ngx-toastr";
|
|||
import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component";
|
||||
import {PageEvent} from "@angular/material/paginator";
|
||||
import {CreateSoftwareProfileComponent} from "./create-software-profile/create-software-profile.component";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-software-profile',
|
||||
|
@ -57,7 +58,8 @@ export class SoftwareProfileComponent {
|
|||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private dataService: DataService,
|
||||
private toastService: ToastrService
|
||||
private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -128,4 +130,12 @@ export class SoftwareProfileComponent {
|
|||
this.length = event.length;
|
||||
this.search();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: ['titleStep','addStep', 'filterStep', 'tableStep', 'actionsStep'],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Administrar Software</h2>
|
||||
<button mat-icon-button color="primary" (click)="iniciarTour()">
|
||||
<mat-icon>help</mat-icon>
|
||||
</button>
|
||||
<h2 class="title" i18n="@@adminImagesTitle" joyrideStep="titleStep" text="Administra el software deisponible desde este componente.">Administrar Software</h2>
|
||||
<div class="calendar-button-row">
|
||||
<button mat-flat-button color="primary" (click)="addSoftware()">Añadir software</button>
|
||||
<button mat-flat-button color="primary" (click)="addSoftware()" joyrideStep="addSoftwareStep" text="Utiliza este botón par añadir software nuevo.">Añadir software</button>
|
||||
</div>
|
||||
</div>
|
||||
<mat-divider class="divider"></mat-divider>
|
||||
<div class="search-container">
|
||||
<div class="search-container" joyrideStep="searchStep" text="Utiliza los filtros para buscar entre el software listado.">
|
||||
<mat-form-field appearance="fill" class="search-string">
|
||||
<mat-label i18n="@@searchLabel">Buscar nombre de software</mat-label>
|
||||
<input matInput name="searchBar" placeholder="Búsqueda" [(ngModel)]="filters['name']" (keyup.enter)="search()" i18n-placeholder="@@searchPlaceholder">
|
||||
|
@ -21,7 +24,7 @@
|
|||
</mat-select>
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8">
|
||||
<table mat-table [dataSource]="dataSource" class="mat-elevation-z8" joyride="tableStep" text="Aquí se mostrará todo el software disponible y sus características.">
|
||||
<ng-container *ngFor="let column of columns" [matColumnDef]="column.columnDef">
|
||||
<th mat-header-cell *matHeaderCellDef> {{ column.header }} </th>
|
||||
<td mat-cell *matCellDef="let image" >
|
||||
|
|
|
@ -5,10 +5,10 @@ import {MatDialog} from "@angular/material/dialog";
|
|||
import {HttpClient} from "@angular/common/http";
|
||||
import {DataService} from "./data.service";
|
||||
import {ToastrService} from "ngx-toastr";
|
||||
import {CreateCalendarComponent} from "../calendar/create-calendar/create-calendar.component";
|
||||
import {DeleteModalComponent} from "../../shared/delete_modal/delete-modal/delete-modal.component";
|
||||
import {PageEvent} from "@angular/material/paginator";
|
||||
import {CreateSoftwareComponent} from "./create-software/create-software.component";
|
||||
import { JoyrideService } from 'ngx-joyride';
|
||||
|
||||
@Component({
|
||||
selector: 'app-software',
|
||||
|
@ -63,7 +63,8 @@ export class SoftwareComponent {
|
|||
public dialog: MatDialog,
|
||||
private http: HttpClient,
|
||||
private dataService: DataService,
|
||||
private toastService: ToastrService
|
||||
private toastService: ToastrService,
|
||||
private joyrideService: JoyrideService
|
||||
) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@ -134,4 +135,18 @@ export class SoftwareComponent {
|
|||
this.length = event.length;
|
||||
this.search();
|
||||
}
|
||||
|
||||
iniciarTour(): void {
|
||||
this.joyrideService.startTour({
|
||||
steps: [
|
||||
'titleStep',
|
||||
'addSoftwareStep',
|
||||
'searchStep',
|
||||
'tableStep',
|
||||
],
|
||||
showPrevButton: true,
|
||||
themeColor: '#3f51b5'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue