refs #1318 No clients view added and minor upgrades.
testing/ogGui-multibranch/pipeline/head There was a failure building this commit Details

pull/10/head
Lucas Lara García 2025-01-08 12:04:00 +01:00
parent e9baede635
commit d469b93a96
4 changed files with 147 additions and 112 deletions

View File

@ -599,4 +599,11 @@ button[mat-raised-button] {
font-size: x-large;
display: block;
margin-bottom: 1.5rem;
}
.no-clients-info {
display: flex;
align-items: center;
gap: 10px;
margin-top: 1.5rem;
}

View File

@ -1,3 +1,4 @@
<!-- Header -->
<div class="header-container" joyrideStep="tabsStep" text="{{ 'tabsStepText' | translate }}">
<button mat-icon-button color="primary" (click)="iniciarTour()">
<mat-icon>help</mat-icon>
@ -22,6 +23,7 @@
</div>
</div>
<!-- Filters Panel -->
<mat-expansion-panel *ngIf="isTreeViewActive" class="filters-panel" joyrideStep="filtersPanelStep" text="{{ 'filtersPanelStepText' | translate }}">
<mat-expansion-panel-header>
<mat-panel-title>{{ 'filters' | translate }}</mat-panel-title>
@ -54,6 +56,7 @@
</div>
</mat-expansion-panel>
<!-- Main units cards -->
<div *ngIf="!selectedUnidad; else detailsTemplate" class="card-container" joyrideStep="organizationalUnitsStep" text="{{ 'organizationalUnitsStepText' | translate }}">
<mat-card *ngFor="let unidad of organizationalUnits"
[ngClass]="{'selected-item': unidad === selectedUnidad, 'clickable-item': true}"
@ -100,7 +103,9 @@
</mat-card>
</div>
<!-- Unit details view-->
<ng-template #detailsTemplate>
<!-- Header -->
<div class="header-actions-container">
<button mat-raised-button color="primary" (click)="clearSelection()" class="back-button">
<mat-icon>arrow_back</mat-icon>
@ -116,6 +121,7 @@
</div>
</div>
<div class="main-container">
<!-- Tree view -->
<div class="tree-container">
<h2>{{ selectedUnidad?.name }}</h2>
<mat-tree [dataSource]="treeDataSource" [treeControl]="treeControl">
@ -160,8 +166,10 @@
</mat-tree-node>
</mat-tree>
</div>
<mat-divider [vertical]="true"></mat-divider>
<!-- Tree node actions -->
<mat-menu restoreFocus=false #commandMenu="matMenu">
<button mat-menu-item *ngFor="let command of commands" (click)="executeCommand(command, selectedNode)">
<span>{{ command.name }}</span>
@ -193,22 +201,69 @@
<span>{{ 'delete' | translate }}</span>
</button>
</mat-menu>
<div class="clients-container" *ngIf="(selectedClients.data?.length || 0) > 0">
<span class="clients-title-name">{{ 'clients' | translate }} <strong>{{ selectedNode?.name ? ' ' + selectedNode?.name : ' ' + selectedUnidad?.name }}</strong></span>
<div class="clients-grid" *ngIf="currentView === 'card'">
<div *ngFor="let client of selectedClients.data" class="client-item">
<div class="client-card">
<img
[src]="'assets/images/ordenador_' + client.status + '.png'"
alt="Client Icon"
class="client-image" />
<div class="client-details">
<span class="client-name">{{ client.name }}</span>
<span class="client-ip">{{ client.ip }}</span>
<span class="client-ip">{{ client.mac }}</span>
<!-- Clients view -->
<div class="clients-container">
<span class="clients-title-name">{{ 'clients' | translate }}
<strong>{{ selectedNode?.name ? ' ' + selectedNode?.name : ' ' + selectedUnidad?.name }}</strong>
</span>
<div class="action-icons">
<mat-divider></mat-divider>
<div *ngIf="(selectedClients.data?.length || 0) > 0; else noClientsTemplate">
<!-- Cards view -->
<div class="clients-grid" *ngIf="currentView === 'card'">
<div *ngFor="let client of selectedClients.data" class="client-item">
<div class="client-card">
<img
[src]="'assets/images/ordenador_' + client.status + '.png'"
alt="Client Icon"
class="client-image" />
<div class="client-details">
<span class="client-name">{{ client.name }}</span>
<span class="client-ip">{{ client.ip }}</span>
<span class="client-ip">{{ client.mac }}</span>
<div class="action-icons">
<button
*ngIf="(!syncStatus || syncingClientId !== client.uuid)"
mat-icon-button color="primary"
(click)="getStatus(client, selectedNode)">
<mat-icon>sync</mat-icon>
</button>
<button
*ngIf="syncStatus && syncingClientId === client.uuid"
mat-icon-button color="primary">
<mat-spinner diameter="24"></mat-spinner>
</button>
<button mat-icon-button color="primary" (click)="onShowClientDetail($event, client)">
<mat-icon>visibility</mat-icon>
</button>
<app-execute-command [clientData]="client['@id']"></app-execute-command>
</div>
</div>
</div>
</div>
</div>
<!-- List view -->
<div class="clients-table" *ngIf="currentView === 'list'">
<table mat-table matSort [dataSource]="selectedClients" class="mat-elevation-z8">
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'status' | translate }} </th>
<td mat-cell *matCellDef="let client">
<img
[src]="'assets/images/ordenador_' + client.status + '.png'"
alt="Client Icon"
class="client-image" />
</td>
</ng-container>
<ng-container matColumnDef="sync">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'sync' | translate }} </th>
<td mat-cell *matCellDef="let client">
<button
*ngIf="(!syncStatus || syncingClientId !== client.uuid)"
mat-icon-button color="primary"
@ -221,107 +276,78 @@
mat-icon-button color="primary">
<mat-spinner diameter="24"></mat-spinner>
</button>
</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'name' | translate }} </th>
<td mat-cell *matCellDef="let client">
<div class="client-info">
<div class="client-name">{{ client.name }}</div>
<div class="client-ip">{{ client.ip }}</div>
<div class="client-ip">{{ client.mac }}</div>
</div>
</td>
</ng-container>
<ng-container matColumnDef="oglive">
<th mat-header-cell *matHeaderCellDef mat-sort-header> OG Live </th>
<td mat-cell *matCellDef="let client"> {{ (client.ogLive?.filename || '').slice(0, 15) }}{{ (client.ogLive?.filename?.length > 15) ? '...' : '' }} </td>
</ng-container>
<button mat-icon-button color="primary" (click)="onShowClientDetail($event, client)">
<mat-icon>visibility</mat-icon>
<ng-container matColumnDef="maintenace">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'maintenance' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.maintenance }} </td>
</ng-container>
<ng-container matColumnDef="subnet">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'subnet' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.subnet }} </td>
</ng-container>
<ng-container matColumnDef="pxeTemplate">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'pxeTemplate' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.template?.name }} </td>
</ng-container>
<ng-container matColumnDef="parentName">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'parent' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.parentName }} </td>
</ng-container>
<ng-container matColumnDef="actions" >
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'actions' | translate }} </th>
<td mat-cell *matCellDef="let client">
<button mat-icon-button [matMenuTriggerFor]="clientMenu">
<mat-icon>more_vert</mat-icon>
</button>
<app-execute-command [clientData]="client['@id']"></app-execute-command>
</div>
</div>
</div>
<mat-menu #clientMenu="matMenu">
<button mat-menu-item (click)="onEditClick($event, client.type, client.uuid)">
<mat-icon>edit</mat-icon>
<span>{{ 'edit' | translate }}</span>
</button>
<button mat-menu-item (click)="onShowClientDetail($event, client)">
<mat-icon>visibility</mat-icon>
<span>{{ 'viewDetails' | translate }}</span>
</button>
<button mat-menu-item (click)="onDeleteClick($event, client, selectedNode)">
<mat-icon>delete</mat-icon>
<span>{{ 'delete' | translate }}</span>
</button>
</mat-menu>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
</div>
</div>
<div class="clients-table" *ngIf="currentView === 'list'">
<table mat-table matSort [dataSource]="selectedClients" class="mat-elevation-z8">
<ng-container matColumnDef="status">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'status' | translate }} </th>
<td mat-cell *matCellDef="let client">
<img
[src]="'assets/images/ordenador_' + client.status + '.png'"
alt="Client Icon"
class="client-image" />
</td>
</ng-container>
<ng-container matColumnDef="sync">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'sync' | translate }} </th>
<td mat-cell *matCellDef="let client">
<button
*ngIf="(!syncStatus || syncingClientId !== client.uuid)"
mat-icon-button color="primary"
(click)="getStatus(client, selectedNode)">
<mat-icon>sync</mat-icon>
</button>
<button
*ngIf="syncStatus && syncingClientId === client.uuid"
mat-icon-button color="primary">
<mat-spinner diameter="24"></mat-spinner>
</button>
</td>
</ng-container>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'name' | translate }} </th>
<td mat-cell *matCellDef="let client">
<div class="client-info">
<div class="client-name">{{ client.name }}</div>
<div class="client-ip">{{ client.ip }}</div>
<div class="client-ip">{{ client.mac }}</div>
</div>
</td>
</ng-container>
<ng-container matColumnDef="oglive">
<th mat-header-cell *matHeaderCellDef mat-sort-header> OG Live </th>
<td mat-cell *matCellDef="let client"> {{ (client.ogLive?.filename || '').slice(0, 15) }}{{ (client.ogLive?.filename?.length > 15) ? '...' : '' }} </td>
</ng-container>
<ng-container matColumnDef="maintenace">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'maintenance' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.maintenance }} </td>
</ng-container>
<ng-container matColumnDef="subnet">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'subnet' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.subnet }} </td>
</ng-container>
<ng-container matColumnDef="pxeTemplate">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'pxeTemplate' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.template?.name }} </td>
</ng-container>
<ng-container matColumnDef="parentName">
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'parent' | translate }} </th>
<td mat-cell *matCellDef="let client"> {{ client.parentName }} </td>
</ng-container>
<ng-container matColumnDef="actions" >
<th mat-header-cell *matHeaderCellDef mat-sort-header> {{ 'actions' | translate }} </th>
<td mat-cell *matCellDef="let client">
<button mat-icon-button [matMenuTriggerFor]="clientMenu">
<mat-icon>more_vert</mat-icon>
</button>
<app-execute-command [clientData]="client['@id']"></app-execute-command>
<mat-menu #clientMenu="matMenu">
<button mat-menu-item (click)="onEditClick($event, client.type, client.uuid)">
<mat-icon>edit</mat-icon>
<span>{{ 'edit' | translate }}</span>
</button>
<button mat-menu-item (click)="onShowClientDetail($event, client)">
<mat-icon>visibility</mat-icon>
<span>{{ 'viewDetails' | translate }}</span>
</button>
<button mat-menu-item (click)="onDeleteClick($event, client, selectedNode)">
<mat-icon>delete</mat-icon>
<span>{{ 'delete' | translate }}</span>
</button>
</mat-menu>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
<mat-paginator [pageSize]="10" [pageSizeOptions]="[5, 10, 20]" showFirstLastButtons></mat-paginator>
</div>
</div>
<!-- No clients view -->
<ng-template #noClientsTemplate>
<div class="no-clients-info">
<mat-icon>error_outline</mat-icon>
<span>{{ 'noClients' | translate }}</span>
</div>
</ng-template>
</div>
</ng-template>

View File

@ -449,5 +449,6 @@
"adminUsersTitle": "Manage users",
"filtersPanelStepText": "Use these filters to search or load configurations.",
"organizationalUnitsStepText": "List of Organizational Units. Click on one to view details.",
"defaultMenuLabel": "Main menu"
"defaultMenuLabel": "Main menu",
"noClients": "No clients"
}

View File

@ -451,5 +451,6 @@
"adminUsersTitle": "Administrar usuarios",
"filtersPanelStepText": "Utiliza estos filtros para buscar o cargar configuraciones.",
"organizationalUnitsStepText": "Lista de Unidades Organizacionales. Haz clic en una para ver detalles.",
"defaultMenuLabel": "Menú por defecto"
"defaultMenuLabel": "Menú por defecto",
"noClients": "No hay clientes"
}