refs #1889 Add PartitionTypeOrganizatorComponent: implement partition management modal and integrate into GroupsComponent
testing/ogGui-multibranch/pipeline/head This commit looks good Details

develop
Lucas Lara García 2025-04-25 14:02:15 +02:00
parent 2bc17e8b56
commit 6fd04fb46e
9 changed files with 186 additions and 4 deletions

View File

@ -143,6 +143,7 @@ import { EditImageComponent } from './components/repositories/edit-image/edit-im
import { ShowGitImagesComponent } from './components/repositories/show-git-images/show-git-images.component';
import { RenameImageComponent } from './components/repositories/rename-image/rename-image.component';
import { ClientDetailsComponent } from './components/groups/shared/client-details/client-details.component';
import { PartitionTypeOrganizatorComponent } from './components/groups/shared/partition-type-organizator/partition-type-organizator.component';
export function HttpLoaderFactory(http: HttpClient) {
return new TranslateHttpLoader(http, './locale/', '.json');
@ -243,7 +244,8 @@ registerLocaleData(localeEs, 'es-ES');
EditImageComponent,
ShowGitImagesComponent,
RenameImageComponent,
ClientDetailsComponent
ClientDetailsComponent,
PartitionTypeOrganizatorComponent
],
bootstrap: [AppComponent],
imports: [BrowserModule,

View File

@ -198,6 +198,10 @@
<mat-icon>delete</mat-icon>
<span>{{ 'delete' | translate }}</span>
</button>
<button mat-menu-item (click)="openPartitionTypeModal($event, selectedNode)">
<mat-icon>storage</mat-icon>
<span>{{ 'partitions' | translate }}</span>
</button>
<app-execute-command [clientData]="selectedNode?.clients || []" [buttonType]="'menu-item'"
[buttonText]="'Ejecutar comandos'" [icon]="'terminal'"
[disabled]="!((selectedNode?.clients ?? []).length > 0)" [runScriptContext]="selectedNode?.name || ''"

View File

@ -27,6 +27,7 @@ import { ConfigService } from '@services/config.service';
import { BreakpointObserver } from '@angular/cdk/layout';
import { MatMenuTrigger } from '@angular/material/menu';
import { ClientDetailsComponent } from './shared/client-details/client-details.component';
import { PartitionTypeOrganizatorComponent } from './shared/partition-type-organizator/partition-type-organizator.component';
enum NodeType {
OrganizationalUnit = 'organizational-unit',
@ -846,4 +847,18 @@ export class GroupsComponent implements OnInit, OnDestroy {
}
return '';
}
openPartitionTypeModal(event: MouseEvent, node: TreeNode | null = null): void {
event.stopPropagation();
const simplifiedClientsData = node?.clients?.map((client: any) => ({
name: client.name,
partitions: client.partitions
}));
this.dialog.open(PartitionTypeOrganizatorComponent, {
width: '1200px',
data: simplifiedClientsData
});
}
}

View File

@ -0,0 +1,46 @@
.modal-content {
max-height: 80vh;
overflow-y: auto;
background-color: #fff;
display: flex;
flex-direction: column;
padding: 1em 4em 2em 4em;
box-sizing: border-box;
}
.client-section {
margin-bottom: 2em;
}
.client-title {
font-size: 1.5em;
font-weight: 500;
color: #3f51b5;
margin-bottom: 1em;
border-bottom: 2px solid #e0e0e0;
padding-bottom: 0.25em;
}
.partition-table {
width: 100%;
border-spacing: 0;
border-collapse: collapse;
}
.partition-table th,
.partition-table td {
padding: 0.75em 1em;
text-align: left;
font-size: 0.95em;
border-bottom: 1px solid #ddd;
}
.partition-table th {
background-color: #f5f5f5;
font-weight: 500;
color: #444;
}
.partition-table tr:hover td {
background-color: #f9f9f9;
}

View File

@ -0,0 +1,42 @@
<mat-dialog-content class="modal-content">
<div *ngFor="let client of simplifiedData" class="client-section">
<h3 class="client-title">{{ client.name }}</h3>
<table mat-table [dataSource]="client.partitions" class="mat-elevation-z1 partition-table">
<ng-container matColumnDef="diskNumber">
<th mat-header-cell *matHeaderCellDef>Disk</th>
<td mat-cell *matCellDef="let element">{{ element.diskNumber }}</td>
</ng-container>
<ng-container matColumnDef="partitionNumber">
<th mat-header-cell *matHeaderCellDef>Partition #</th>
<td mat-cell *matCellDef="let element">{{ element.partitionNumber }}</td>
</ng-container>
<ng-container matColumnDef="partitionCode">
<th mat-header-cell *matHeaderCellDef>Code</th>
<td mat-cell *matCellDef="let element">{{ element.partitionCode }}</td>
</ng-container>
<ng-container matColumnDef="size">
<th mat-header-cell *matHeaderCellDef>Size</th>
<td mat-cell *matCellDef="let element">{{ element.size }}</td>
</ng-container>
<ng-container matColumnDef="filesystem">
<th mat-header-cell *matHeaderCellDef>FS</th>
<td mat-cell *matCellDef="let element">{{ element.filesystem }}</td>
</ng-container>
<ng-container matColumnDef="memoryUsage">
<th mat-header-cell *matHeaderCellDef>Memory</th>
<td mat-cell *matCellDef="let element">{{ element.memoryUsage }}</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
</mat-dialog-content>

View File

@ -0,0 +1,42 @@
import { TestBed } from '@angular/core/testing';
import { MAT_DIALOG_DATA, MatDialogModule, MatDialogRef } from '@angular/material/dialog';
import { PartitionTypeOrganizatorComponent } from './partition-type-organizator.component';
import { MatTableModule } from '@angular/material/table';
describe('PartitionTypeOrganizatorComponent', () => {
let component: PartitionTypeOrganizatorComponent;
let fixture: any;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [PartitionTypeOrganizatorComponent],
imports: [
MatDialogModule,
MatTableModule
],
providers: [
{ provide: MatDialogRef, useValue: {} },
{
provide: MAT_DIALOG_DATA,
useValue: [
{
name: 'Client 1',
partitions: [
{ diskNumber: 1, partitionNumber: 1, partitionCode: 'EXT4', size: 1024, filesystem: 'ext4', memoryUsage: 50 },
{ diskNumber: 1, partitionNumber: 2, partitionCode: 'NTFS', size: 2048, filesystem: 'ntfs', memoryUsage: 75 }
]
}
]
}
]
}).compileComponents();
fixture = TestBed.createComponent(PartitionTypeOrganizatorComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,29 @@
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA } from '@angular/material/dialog';
@Component({
selector: 'app-partition-type-organizator',
templateUrl: './partition-type-organizator.component.html',
styleUrl: './partition-type-organizator.component.css'
})
export class PartitionTypeOrganizatorComponent implements OnInit {
constructor(@Inject(MAT_DIALOG_DATA) public data: any) { }
public simplifiedData: any[] = [];
displayedColumns: string[] = ['diskNumber', 'partitionNumber', 'partitionCode', 'size', 'filesystem', 'memoryUsage'];
ngOnInit(): void {
this.simplifiedData = this.data.map((client: any) => ({
name: client.name,
partitions: client.partitions.map((p: any) => ({
diskNumber: p.diskNumber,
partitionNumber: p.partitionNumber,
partitionCode: p.partitionCode,
size: p.size,
filesystem: p.filesystem,
memoryUsage: p.memoryUsage
}))
}));
}
}

View File

@ -482,5 +482,6 @@
"processes": "Processes",
"usedPercentageLabel": "Used",
"errorLoadingData": "Error fetching data. Service not available",
"repositoryTitleStep": "On this screen you can manage image repositories."
"repositoryTitleStep": "On this screen you can manage image repositories.",
"partitions": "Particiones"
}

View File

@ -484,5 +484,6 @@
"processes": "Procesos",
"usedPercentageLabel": "Usado",
"errorLoadingData": "Error al cargar los datos. Servicio inactivo",
"repositoryTitleStep": "En esta pantalla se pueden gestionar los repositorios de imágenes."
"repositoryTitleStep": "En esta pantalla se pueden gestionar los repositorios de imágenes.",
"partitions": "Particiones"
}