Added constraint create client form (Mac). Updated groups tree UX

pull/19/head
Manuel Aranda Rosales 2025-03-26 21:49:42 +01:00
parent 7bff91aa42
commit edfab0be94
9 changed files with 74 additions and 12 deletions

View File

@ -98,7 +98,7 @@
<div class="tree-container">
<mat-tree [dataSource]="treeDataSource" [treeControl]="treeControl">
<mat-tree-node [ngClass]="{'selected-node': selectedNode?.id === node.id}"
*matTreeNodeDef="let node; when: hasChild" matTreeNodePadding (click)="onNodeClick(node)">
*matTreeNodeDef="let node; when: hasChild" matTreeNodePadding (click)="onNodeClick($event, node)">
<button mat-icon-button matTreeNodeToggle [disabled]="!node.expandable"
[ngClass]="{'disabled-toggle': !node.expandable}">
<mat-icon>{{ treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right' }}</mat-icon>
@ -114,12 +114,12 @@
}}
</mat-icon>
<span>{{ node.name }}</span>
<button mat-icon-button [matMenuTriggerFor]="menuNode" (click)="onNodeClick(node)">
<button mat-icon-button [matMenuTriggerFor]="menuNode" (click)="onMenuClick($event, node)">
<mat-icon>more_vert</mat-icon>
</button>
</mat-tree-node>
<mat-tree-node [ngClass]="{'selected-node': selectedNode?.id === node.id}"
*matTreeNodeDef="let node; when: isLeafNode" matTreeNodePadding (click)="onNodeClick(node)">
*matTreeNodeDef="let node; when: isLeafNode" matTreeNodePadding (click)="onNodeClick($event, node)">
<button mat-icon-button matTreeNodeToggle [disabled]="true" class="disabled-toggle"></button>
<mat-icon style="color: green;">
{{
@ -135,7 +135,7 @@
<ng-container *ngIf="node.type === 'client'">
<span> - IP: {{ node.ip }}</span>
</ng-container>
<button mat-icon-button [matMenuTriggerFor]="menuNode" (click)="onNodeClick(node)">
<button mat-icon-button [matMenuTriggerFor]="menuNode" (click)="onMenuClick($event, node)">
<mat-icon>more_vert</mat-icon>
</button>
</mat-tree-node>
@ -404,4 +404,4 @@
</div>
</ng-template>
</div>
</div>

View File

@ -196,6 +196,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
hasClients: node.hasClients,
ip: node.ip,
'@id': node['@id'],
networkSettings: node.networkSettings,
});
@ -350,11 +351,16 @@ export class GroupsComponent implements OnInit, OnDestroy {
}
onNodeClick(node: TreeNode): void {
onNodeClick(event: MouseEvent, node: TreeNode): void {
event.stopPropagation();
this.selectedNode = node;
this.fetchClientsForNode(node);
}
onMenuClick(event: Event, node: any): void {
event.stopPropagation();
}
public fetchClientsForNode(node: any, selectedClientsBeforeEdit: string[] = []): void {
const params = new HttpParams({ fromObject: this.filters });

View File

@ -71,6 +71,7 @@ export interface TreeNode {
hasClients?: boolean;
clients?: Client[];
ip?: string;
networkSettings?: Object;
}
export interface FlatNode {
@ -80,6 +81,7 @@ export interface FlatNode {
level: number;
expandable: boolean;
hasClients?: boolean;
networkSettings?: Object;
ip?: string;
'@id'?: string;
}

View File

@ -84,7 +84,7 @@ export class ManageClientComponent implements OnInit {
serialNumber: [''],
netiface: null,
netDriver: null,
mac: ['', Validators.required],
mac: ['', Validators.pattern(/^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/)],
ip: ['', Validators.required],
template: [null],
hardwareProfile: [null],

View File

@ -20,7 +20,7 @@
</mat-form-field>
<mat-form-field class="form-field" appearance="fill">
<mat-label>Padre</mat-label>
<mat-select formControlName="parent">
<mat-select formControlName="parent" (selectionChange)="onParentChange($event)">
<mat-select-trigger>
{{ getSelectedParentName() }}
</mat-select-trigger>

View File

@ -75,7 +75,7 @@ export class ManageOrganizationalUnitComponent implements OnInit {
});
this.networkSettingsFormGroup = this._formBuilder.group({
ogLive: [null],
ogLive: [ null],
repository: [null],
proxy: [null],
dns: [null],
@ -128,8 +128,28 @@ export class ManageOrganizationalUnitComponent implements OnInit {
this.parentUnitsWithPaths = this.parentUnits.map(unit => ({
id: unit['@id'],
name: unit.name,
path: this.dataService.getOrganizationalUnitPath(unit, this.parentUnits)
path: this.dataService.getOrganizationalUnitPath(unit, this.parentUnits),
repository: unit.networkSettings?.repository?.['@id'],
hardwareProfile: unit.networkSettings?.hardwareProfile?.['@id'],
ogLive: unit.networkSettings?.ogLive?.['@id'],
menu: unit.networkSettings?.menu?.['@id'],
mcastIp: unit.networkSettings?.mcastIp,
mcastSpeed: unit.networkSettings?.mcastSpeed,
mcastPort: unit.networkSettings?.mcastPort,
mcastMode: unit.networkSettings?.mcastMode,
netiface: unit.networkSettings?.netiface,
p2pMode: unit.networkSettings?.p2pMode,
p2pTime: unit.networkSettings?.p2pTime,
dns: unit.networkSettings?.dns,
netmask: unit.networkSettings?.netmask,
router: unit.networkSettings?.router,
ntp: unit.networkSettings?.ntp
}));
const initialUnitId = this.generalFormGroup.get('parent')?.value;
if (initialUnitId) {
this.setOrganizationalUnitDefaults(initialUnitId);
}
this.loading = false;
},
error => {
@ -139,6 +159,33 @@ export class ManageOrganizationalUnitComponent implements OnInit {
);
}
onParentChange(event: any): void {
this.setOrganizationalUnitDefaults(event.value);
}
setOrganizationalUnitDefaults(unitId: string): void {
const selectedUnit: any = this.parentUnitsWithPaths.find(unit => unit.id === unitId);
if (selectedUnit) {
this.networkSettingsFormGroup.patchValue({
repository: selectedUnit.repository || null,
hardwareProfile: selectedUnit.hardwareProfile || null,
ogLive: selectedUnit.ogLive || null,
menu: selectedUnit.menu || null,
mcastIp: selectedUnit.mcastIp || null,
mcastSpeed: selectedUnit.mcastSpeed || null,
mcastPort: selectedUnit.mcastPort || null,
mcastMode: selectedUnit.mcastMode || null,
netiface: selectedUnit.netiface || null,
p2pMode: selectedUnit.p2pMode || null,
p2pTime: selectedUnit.p2pTime || null,
dns: selectedUnit.dns || null,
netmask: selectedUnit.netmask || null,
router: selectedUnit.router || null,
ntp: selectedUnit.ntp || null
});
}
}
getSelectedParentName(): string | undefined {
const parentId = this.generalFormGroup.get('parent')?.value;
return this.parentUnitsWithPaths.find(unit => unit.id === parentId)?.name;

View File

@ -2,6 +2,12 @@
width: 100%;
}
.dialog-content {
display: flex;
flex-direction: column;
padding: 40px;
}
.spacing-container {
margin-top: 20px;
margin-bottom: 16px;

View File

@ -1,6 +1,6 @@
<h2 mat-dialog-title>{{ isEditMode ? 'Editar' : 'Añadir' }} subred</h2>
<mat-dialog-content>
<mat-dialog-content class="dialog-content">
<form [formGroup]="subnetForm">
<div class="spacing-container">
<mat-form-field appearance="fill" class="full-width">

View File

@ -1,6 +1,7 @@
.dialog-content {
display: flex;
flex-direction: column;
padding: 40px;
}
.repository-form {
@ -36,4 +37,4 @@
margin-left: 0;
margin-bottom: 8px;
}
}
}