Added constraint create client form (Mac). Updated groups tree UX
parent
7bff91aa42
commit
edfab0be94
|
@ -98,7 +98,7 @@
|
||||||
<div class="tree-container">
|
<div class="tree-container">
|
||||||
<mat-tree [dataSource]="treeDataSource" [treeControl]="treeControl">
|
<mat-tree [dataSource]="treeDataSource" [treeControl]="treeControl">
|
||||||
<mat-tree-node [ngClass]="{'selected-node': selectedNode?.id === node.id}"
|
<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"
|
<button mat-icon-button matTreeNodeToggle [disabled]="!node.expandable"
|
||||||
[ngClass]="{'disabled-toggle': !node.expandable}">
|
[ngClass]="{'disabled-toggle': !node.expandable}">
|
||||||
<mat-icon>{{ treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right' }}</mat-icon>
|
<mat-icon>{{ treeControl.isExpanded(node) ? 'expand_more' : 'chevron_right' }}</mat-icon>
|
||||||
|
@ -114,12 +114,12 @@
|
||||||
}}
|
}}
|
||||||
</mat-icon>
|
</mat-icon>
|
||||||
<span>{{ node.name }}</span>
|
<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>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-tree-node>
|
</mat-tree-node>
|
||||||
<mat-tree-node [ngClass]="{'selected-node': selectedNode?.id === node.id}"
|
<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>
|
<button mat-icon-button matTreeNodeToggle [disabled]="true" class="disabled-toggle"></button>
|
||||||
<mat-icon style="color: green;">
|
<mat-icon style="color: green;">
|
||||||
{{
|
{{
|
||||||
|
@ -135,7 +135,7 @@
|
||||||
<ng-container *ngIf="node.type === 'client'">
|
<ng-container *ngIf="node.type === 'client'">
|
||||||
<span> - IP: {{ node.ip }}</span>
|
<span> - IP: {{ node.ip }}</span>
|
||||||
</ng-container>
|
</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>
|
<mat-icon>more_vert</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-tree-node>
|
</mat-tree-node>
|
||||||
|
|
|
@ -196,6 +196,7 @@ export class GroupsComponent implements OnInit, OnDestroy {
|
||||||
hasClients: node.hasClients,
|
hasClients: node.hasClients,
|
||||||
ip: node.ip,
|
ip: node.ip,
|
||||||
'@id': node['@id'],
|
'@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.selectedNode = node;
|
||||||
this.fetchClientsForNode(node);
|
this.fetchClientsForNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMenuClick(event: Event, node: any): void {
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public fetchClientsForNode(node: any, selectedClientsBeforeEdit: string[] = []): void {
|
public fetchClientsForNode(node: any, selectedClientsBeforeEdit: string[] = []): void {
|
||||||
const params = new HttpParams({ fromObject: this.filters });
|
const params = new HttpParams({ fromObject: this.filters });
|
||||||
|
|
|
@ -71,6 +71,7 @@ export interface TreeNode {
|
||||||
hasClients?: boolean;
|
hasClients?: boolean;
|
||||||
clients?: Client[];
|
clients?: Client[];
|
||||||
ip?: string;
|
ip?: string;
|
||||||
|
networkSettings?: Object;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FlatNode {
|
export interface FlatNode {
|
||||||
|
@ -80,6 +81,7 @@ export interface FlatNode {
|
||||||
level: number;
|
level: number;
|
||||||
expandable: boolean;
|
expandable: boolean;
|
||||||
hasClients?: boolean;
|
hasClients?: boolean;
|
||||||
|
networkSettings?: Object;
|
||||||
ip?: string;
|
ip?: string;
|
||||||
'@id'?: string;
|
'@id'?: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ export class ManageClientComponent implements OnInit {
|
||||||
serialNumber: [''],
|
serialNumber: [''],
|
||||||
netiface: null,
|
netiface: null,
|
||||||
netDriver: null,
|
netDriver: null,
|
||||||
mac: ['', Validators.required],
|
mac: ['', Validators.pattern(/^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$/)],
|
||||||
ip: ['', Validators.required],
|
ip: ['', Validators.required],
|
||||||
template: [null],
|
template: [null],
|
||||||
hardwareProfile: [null],
|
hardwareProfile: [null],
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
<mat-form-field class="form-field" appearance="fill">
|
<mat-form-field class="form-field" appearance="fill">
|
||||||
<mat-label>Padre</mat-label>
|
<mat-label>Padre</mat-label>
|
||||||
<mat-select formControlName="parent">
|
<mat-select formControlName="parent" (selectionChange)="onParentChange($event)">
|
||||||
<mat-select-trigger>
|
<mat-select-trigger>
|
||||||
{{ getSelectedParentName() }}
|
{{ getSelectedParentName() }}
|
||||||
</mat-select-trigger>
|
</mat-select-trigger>
|
||||||
|
|
|
@ -128,8 +128,28 @@ export class ManageOrganizationalUnitComponent implements OnInit {
|
||||||
this.parentUnitsWithPaths = this.parentUnits.map(unit => ({
|
this.parentUnitsWithPaths = this.parentUnits.map(unit => ({
|
||||||
id: unit['@id'],
|
id: unit['@id'],
|
||||||
name: unit.name,
|
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;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
error => {
|
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 {
|
getSelectedParentName(): string | undefined {
|
||||||
const parentId = this.generalFormGroup.get('parent')?.value;
|
const parentId = this.generalFormGroup.get('parent')?.value;
|
||||||
return this.parentUnitsWithPaths.find(unit => unit.id === parentId)?.name;
|
return this.parentUnitsWithPaths.find(unit => unit.id === parentId)?.name;
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dialog-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
.spacing-container {
|
.spacing-container {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<h2 mat-dialog-title>{{ isEditMode ? 'Editar' : 'Añadir' }} subred</h2>
|
<h2 mat-dialog-title>{{ isEditMode ? 'Editar' : 'Añadir' }} subred</h2>
|
||||||
|
|
||||||
<mat-dialog-content>
|
<mat-dialog-content class="dialog-content">
|
||||||
<form [formGroup]="subnetForm">
|
<form [formGroup]="subnetForm">
|
||||||
<div class="spacing-container">
|
<div class="spacing-container">
|
||||||
<mat-form-field appearance="fill" class="full-width">
|
<mat-form-field appearance="fill" class="full-width">
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
.dialog-content {
|
.dialog-content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
padding: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.repository-form {
|
.repository-form {
|
||||||
|
|
Loading…
Reference in New Issue