refs #1931 Refactor ClientDetailsComponent to enhance layout and improve data handling in client details view
testing/ogGui-multibranch/pipeline/head This commit looks good
Details
testing/ogGui-multibranch/pipeline/head This commit looks good
Details
parent
a40be684b5
commit
70e21c6ca2
|
@ -1,326 +1,88 @@
|
|||
.header-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.client-container {
|
||||
flex-grow: 1;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
.modal-content {
|
||||
max-height: 80vh;
|
||||
overflow-y: auto;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0rem 1rem 0rem 0.5rem;
|
||||
}
|
||||
|
||||
.client-icon {
|
||||
flex-shrink: 0;
|
||||
margin-right: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 120px;
|
||||
min-height: 120px;
|
||||
.section-header {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.row-container {
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.charts-wrapper {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.charts-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.disk-usage {
|
||||
text-align: center;
|
||||
flex: 1;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.circular-chart {
|
||||
max-width: 150px;
|
||||
max-height: 150px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.chart {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon-pc {
|
||||
font-size: 25px;
|
||||
color: #3b82f6;
|
||||
}
|
||||
|
||||
.client-title h1 {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.client-title p {
|
||||
margin: 2px 0;
|
||||
font-size: 1rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.client-info {
|
||||
margin: 20px 0;
|
||||
.client-info-card {
|
||||
background-color: #e4e4e4;
|
||||
padding: 24px;
|
||||
border-radius: 12px;
|
||||
background-color: #f5f7fa;
|
||||
padding: 20px;
|
||||
border: 2px solid #d1d9e6;
|
||||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 2em;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background-color: #fff;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.two-column-table {
|
||||
.info-columns {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 10px;
|
||||
margin-top: 15px;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.mat-elevation-z8 {
|
||||
box-shadow: 0px 0px 0px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.table-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 10px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
}
|
||||
|
||||
.column.property {
|
||||
font-weight: bold;
|
||||
text-align: left;
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.column.value {
|
||||
text-align: right;
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
.mat-tab-group {
|
||||
min-height: 400px;
|
||||
}
|
||||
|
||||
.mat-tab-body-wrapper {
|
||||
min-height: inherit;
|
||||
}
|
||||
|
||||
.info-section h2 {
|
||||
font-size: 1.4rem;
|
||||
margin-bottom: 10px;
|
||||
color: #0056b3;
|
||||
}
|
||||
|
||||
.info-section p {
|
||||
font-size: 1rem;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.second-section {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.client-button-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.buttons-row {
|
||||
.info-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
padding: 20px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
justify-content: flex-start;
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.buttons-row button {
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
.info-pair {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.circular-chart {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
max-height: 150px;
|
||||
.label {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 550;
|
||||
color: #3f51b5;
|
||||
}
|
||||
|
||||
.circle-bg {
|
||||
fill: none;
|
||||
stroke: #f0f0f0;
|
||||
stroke-width: 3.8;
|
||||
}
|
||||
|
||||
.circle {
|
||||
fill: none;
|
||||
stroke-width: 3.8;
|
||||
stroke: #00bfa5;
|
||||
stroke-linecap: round;
|
||||
animation: progress 1s ease-out forwards;
|
||||
}
|
||||
|
||||
.percentage {
|
||||
fill: #333;
|
||||
font-size: 0.7rem;
|
||||
text-anchor: middle;
|
||||
}
|
||||
|
||||
.disk-usage h3 {
|
||||
margin: 0 0 10px 0;
|
||||
font-size: 1.2rem;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
@keyframes progress {
|
||||
0% {
|
||||
stroke-dasharray: 0, 100;
|
||||
}
|
||||
}
|
||||
|
||||
.assistants-container {
|
||||
background-color: #fff;
|
||||
margin-top: 10px;
|
||||
padding: 20px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.circular-chart {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
max-height: 150px;
|
||||
}
|
||||
|
||||
.circle-bg {
|
||||
fill: none;
|
||||
stroke: #f0f0f0;
|
||||
stroke-width: 3.8;
|
||||
}
|
||||
|
||||
.circle {
|
||||
fill: none;
|
||||
stroke-width: 3.8;
|
||||
stroke-linecap: round;
|
||||
animation: progress 1s ease-out forwards;
|
||||
}
|
||||
|
||||
.partition-0 {
|
||||
stroke: #00bfa5;
|
||||
}
|
||||
|
||||
.partition-1 {
|
||||
stroke: #ff6f61;
|
||||
}
|
||||
|
||||
.partition-2 {
|
||||
stroke: #ffb400;
|
||||
}
|
||||
|
||||
.partition-3 {
|
||||
stroke: #3498db;
|
||||
}
|
||||
|
||||
.percentage {
|
||||
fill: #333;
|
||||
font-size: 0.7rem;
|
||||
text-anchor: middle;
|
||||
.value {
|
||||
font-size: 1rem;
|
||||
color: #222;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.disk-container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 20px;
|
||||
background-color: #f5f7fa;
|
||||
border: 2px solid #d1d9e6;
|
||||
border-radius: 10px;
|
||||
padding: 20px;
|
||||
margin-top: 20px;
|
||||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: stretch;
|
||||
margin-bottom: 20px;
|
||||
flex-direction: column;
|
||||
gap: 32px;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
flex: 3;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
table.mat-elevation-z8 {
|
||||
width: 100%;
|
||||
max-width: 800px;
|
||||
background-color: white;
|
||||
overflow-x: auto;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.mat-header-cell {
|
||||
background-color: #d1d9e6 !important;
|
||||
color: #333;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mat-cell {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mat-chip {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
.mat-elevation-z8 {
|
||||
width: 100%;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.charts-container {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.disk-usage {
|
||||
background-color: white;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
justify-self: center;
|
||||
box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
|
||||
text-align: center;
|
||||
flex: 1 1 300px;
|
||||
padding: 16px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.chart {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
<app-loading [isLoading]="loading"></app-loading>
|
||||
<mat-dialog-content class="modal-content">
|
||||
<app-loading [isLoading]="loading"></app-loading>
|
||||
|
||||
<div class="client-container">
|
||||
<div class="header-container">
|
||||
<h2 class="title">{{ 'clientDetailsTitle' | translate }} {{ clientData.name }}</h2>
|
||||
</div>
|
||||
<div class="client-container" *ngIf="!loading">
|
||||
<div class="header-container">
|
||||
<h2 class="title">{{ 'clientDetailsTitle' | translate }} {{ clientData.name }}</h2>
|
||||
</div>
|
||||
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div *ngIf="!loading" class="client-info">
|
||||
<div class="info-section">
|
||||
<div class="two-column-table">
|
||||
<div class="table-row" *ngFor="let clientData of generalData">
|
||||
<div class="column property">{{ clientData?.property }}</div>
|
||||
<div class="column value">{{ clientData?.value }}</div>
|
||||
<div class="client-info-card">
|
||||
<div class="info-columns">
|
||||
<div class="info-column">
|
||||
<div class="info-pair" *ngFor="let data of generalData">
|
||||
<div class="label">{{ data?.property }}</div>
|
||||
<div class="value">{{ data?.value || '--' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="two-column-table">
|
||||
<div class="table-row" *ngFor="let clientData of networkData">
|
||||
<div class="column property">{{ clientData?.property }}</div>
|
||||
<div class="column value">{{ clientData?.value }}</div>
|
||||
<div class="info-column">
|
||||
<div class="info-pair" *ngFor="let data of networkData">
|
||||
<div class="label">{{ data?.property }}</div>
|
||||
<div class="value">{{ data?.value || '--' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-container">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Discos/Particiones</h2>
|
||||
</div>
|
||||
|
||||
<div class="disk-container">
|
||||
<div class="table-container">
|
||||
<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 !== 'size'">
|
||||
{{ column.cell(image) }}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef === 'size'">
|
||||
<mat-chip color="primary">
|
||||
{{ (image.size / 1024).toFixed(2) }} GB
|
||||
</mat-chip>
|
||||
</ng-container>
|
||||
</td>
|
||||
<div class="section-header">
|
||||
<h2 class="title" i18n="@@adminImagesTitle">Discos/Particiones</h2>
|
||||
</div>
|
||||
|
||||
<div class="disk-container">
|
||||
<div class="table-container">
|
||||
<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 !== 'size'">
|
||||
{{ column.cell(image) }}
|
||||
</ng-container>
|
||||
<ng-container *ngIf="column.columnDef === 'size'">
|
||||
<mat-chip color="primary">
|
||||
{{ (image.size / 1024).toFixed(2) }} GB
|
||||
</mat-chip>
|
||||
</ng-container>
|
||||
</td>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="charts-container">
|
||||
<ng-container *ngIf="diskUsageData && diskUsageData.length > 0">
|
||||
<div *ngFor="let disk of chartDisk" class="disk-usage">
|
||||
<ngx-charts-pie-chart class="chart" [view]="view" [results]="disk.chartData" [doughnut]="true">
|
||||
</ngx-charts-pie-chart>
|
||||
<h3>Disco {{ disk.diskNumber }}</h3>
|
||||
<p>Usado: {{ (disk.used).toFixed(2) }} GB ({{ disk.percentage }}%)</p>
|
||||
<p>Total: {{ disk.total }} GB</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
|
||||
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="charts-container">
|
||||
<ng-container *ngIf="diskUsageData && diskUsageData.length > 0">
|
||||
<div *ngFor="let disk of chartDisk" class="disk-usage">
|
||||
<ngx-charts-pie-chart class="chart" [view]="view" [results]="disk.chartData" [doughnut]="true">
|
||||
</ngx-charts-pie-chart>
|
||||
|
||||
<h3>Disco {{ disk.diskNumber }}</h3>
|
||||
<p>Usado: {{ (disk.used).toFixed(2) }} GB ({{ disk.percentage }}%)</p>
|
||||
<p>Total: {{ disk.total }} GB</p>
|
||||
</div>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</mat-dialog-content>
|
|
@ -198,7 +198,6 @@ export class ClientDetailsComponent {
|
|||
});
|
||||
|
||||
this.diskUsageData = this.chartDisk;
|
||||
console.log(this.chartDisk)
|
||||
this.isDiskUsageEmpty = this.diskUsageData.length === 0;
|
||||
}
|
||||
|
||||
|
@ -216,11 +215,9 @@ export class ClientDetailsComponent {
|
|||
|
||||
this.http.get<any>(`${this.baseUrl}/partitions?client.id=${this.clientData.id}&order[diskNumber, partitionNumber]=ASC`).subscribe({
|
||||
next: data => {
|
||||
console.log(data)
|
||||
const filteredPartitions = data['hydra:member'].filter((partition: any) => partition.partitionNumber !== 0);
|
||||
this.dataSource = filteredPartitions;
|
||||
this.partitions = filteredPartitions;
|
||||
console.log(this.partitions)
|
||||
this.calculateDiskUsage();
|
||||
},
|
||||
error: error => {
|
||||
|
|
Loading…
Reference in New Issue