Allow users to compute Idle-PC values

This commit is contained in:
grossmj 2025-02-22 16:51:23 +10:00
parent 445ce5a864
commit 6a9505fc0a
No known key found for this signature in database
GPG Key ID: 1E7DD6DBB53FF3D7
10 changed files with 149 additions and 2 deletions

View File

@ -119,6 +119,7 @@ import { EditTextActionComponent } from './components/project-map/context-menu/a
import { ExportConfigActionComponent } from './components/project-map/context-menu/actions/export-config/export-config-action.component';
import { HttpConsoleNewTabActionComponent } from './components/project-map/context-menu/actions/http-console-new-tab/http-console-new-tab-action.component';
import { HttpConsoleActionComponent } from './components/project-map/context-menu/actions/http-console/http-console-action.component';
import { IdlePcActionComponent } from "./components/project-map/context-menu/actions/idle-pc-action/idle-pc-action.component";
import { ImportConfigActionComponent } from './components/project-map/context-menu/actions/import-config/import-config-action.component';
import { LockActionComponent } from './components/project-map/context-menu/actions/lock-action/lock-action.component';
import { MoveLayerDownActionComponent } from './components/project-map/context-menu/actions/move-layer-down-action/move-layer-down-action.component';
@ -134,11 +135,12 @@ import { StartNodeActionComponent } from './components/project-map/context-menu/
import { StopCaptureActionComponent } from './components/project-map/context-menu/actions/stop-capture/stop-capture-action.component';
import { IsolateNodeActionComponent } from './components/project-map/context-menu/actions/isolate-node-action/isolate-node-action.component';
import { UnisolateNodeActionComponent } from './components/project-map/context-menu/actions/unisolate-node-action/unisolate-node-action.component';
import {StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component';
import { StopNodeActionComponent } from './components/project-map/context-menu/actions/stop-node-action/stop-node-action.component';
import { SuspendLinkActionComponent } from './components/project-map/context-menu/actions/suspend-link/suspend-link-action.component';
import { SuspendNodeActionComponent } from './components/project-map/context-menu/actions/suspend-node-action/suspend-node-action.component';
import { ContextMenuComponent } from './components/project-map/context-menu/context-menu.component';
import { ConfigDialogComponent } from './components/project-map/context-menu/dialogs/config-dialog/config-dialog.component';
import { IdlePCDialogComponent } from "./components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component";
import { DrawLinkToolComponent } from './components/project-map/draw-link-tool/draw-link-tool.component';
import { StyleEditorDialogComponent } from './components/project-map/drawings-editors/style-editor/style-editor.component';
import { LinkStyleEditorDialogComponent } from './components/project-map/drawings-editors/link-style-editor/link-style-editor.component';
@ -494,6 +496,7 @@ import { DeleteResourceConfirmationDialogComponent } from './components/resource
AlignVerticallyActionComponent,
ConfirmationBottomSheetComponent,
ConfigDialogComponent,
IdlePCDialogComponent,
ImportApplianceComponent,
DirectLinkComponent,
SystemStatusComponent,
@ -501,6 +504,7 @@ import { DeleteResourceConfirmationDialogComponent } from './components/resource
StatusChartComponent,
OpenFileExplorerActionComponent,
HttpConsoleActionComponent,
IdlePcActionComponent,
WebConsoleComponent,
ConsoleWrapperComponent,
HttpConsoleNewTabActionComponent,

View File

@ -0,0 +1,8 @@
<button
mat-menu-item
*ngIf="node.node_type === 'dynamips'"
(click)="idlePC()"
>
<mat-icon>query_builder</mat-icon>
<span>Idle-PC</span>
</button>

View File

@ -0,0 +1,28 @@
import { Component, Input } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Node } from '../../../../../cartography/models/node';
import { Controller } from '../../../../../models/controller';
import { IdlePCDialogComponent } from "@components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component";
import { NodeService } from "@services/node.service";
@Component({
selector: 'app-idle-pc-action',
templateUrl: './idle-pc-action.component.html',
})
export class IdlePcActionComponent {
@Input() controller:Controller ;
@Input() node: Node;
constructor(private nodeService: NodeService, private dialog: MatDialog) {}
idlePC() {
const dialogRef = this.dialog.open(IdlePCDialogComponent, {
width: '500px',
autoFocus: false,
disableClose: true,
});
let instance = dialogRef.componentInstance;
instance.controller = this.controller;
instance.node = this.node;
}
}

View File

@ -94,6 +94,11 @@
[controller]="controller"
[node]="nodes[0]"
></app-import-config-action>
<app-idle-pc-action
*ngIf="nodes.length === 1 && nodes[0].node_type === 'dynamips'"
[controller]="controller"
[node]="nodes[0]"
></app-idle-pc-action>
<app-move-layer-up-action
*ngIf="!projectService.isReadOnly(project) && (drawings.length || nodes.length)"
[controller]="controller"

View File

@ -0,0 +1,23 @@
<div *ngIf="isComputing">
<h6 align="center">Computing Idle-PC values, please wait...</h6>
<div mat-dialog-content align="center">
<mat-spinner color="accent"></mat-spinner>
</div>
</div>
<div *ngIf="!isComputing">
<h1 mat-dialog-title>Choose an Idle-PC value</h1>
<mat-form-field class="form-field">
<mat-select
placeholder="Idle-PC"
[ngModelOptions]="{standalone: true}"
[(ngModel)]="idlePC"
>
<mat-option *ngFor="let idlepc of idlepcs" [value]="idlepc.key"> {{ idlepc.name }} </mat-option>
</mat-select>
</mat-form-field>
</div>
<div mat-dialog-actions>
<button mat-button *ngIf="!isComputing" (click)="onCompute()" color="accent">Compute</button>
<button mat-button *ngIf="!isComputing" (click)="onApply()" color="accent">Apply</button>
<button mat-button (click)="onClose()" color="accent">Close</button>
</div>

View File

@ -0,0 +1,5 @@
.container {
width: 100%;
display: flex;
justify-content: space-between;
}

View File

@ -0,0 +1,66 @@
import {ChangeDetectorRef, Component, Inject, Input, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
import {Controller} from "@models/controller";
import {Node} from '../../../../../cartography/models/node';
import {NodeService} from "@services/node.service";
import {ToasterService} from "@services/toaster.service";
@Component({
selector: 'app-idle-pc-dialog',
templateUrl: './idle-pc-dialog.component.html',
styleUrls: ['./idle-pc-dialog.component.scss'],
})
export class IdlePCDialogComponent implements OnInit {
@Input() controller: Controller;
@Input() node: Node;
idlepcs = [];
idlePC: string = '';
isComputing: boolean = false;
constructor(
private nodeService: NodeService,
public dialogRef: MatDialogRef<IdlePCDialogComponent>,
private toasterService: ToasterService) {}
ngOnInit() {
this.onCompute();
}
onCompute() {
this.isComputing = true;
this.nodeService.getIdlePCProposals(this.controller, this.node).subscribe((idlepcs: any) => {
let idlepcs_values = [];
for (let value of idlepcs) {
// validate idle-pc format, e.g. 0x60c09aa0
const match = value.match(/^(0x[0-9a-f]{8})\s+\[(\d+)\]$/);
if (match) {
const idlepc = match[1];
const count = parseInt(match[2], 10);
if (50 <= count && count <= 60) {
value += "*";
}
idlepcs_values.push({'key': idlepc, 'name': value})
}
}
this.idlepcs = idlepcs_values;
if (this.idlepcs.length > 0) {
this.idlePC = this.idlepcs[0].key;
}
this.isComputing = false;
});
}
onClose() {
this.dialogRef.close();
}
onApply() {
if (this.idlePC && this.idlePC !== '0x0') {
this.node.properties.idlepc = this.idlePC;
this.nodeService.updateNode(this.controller, this.node).subscribe(() => {
this.toasterService.success(`Node ${this.node.name} updated with idle-PC value ${this.idlePC}`);
});
}
}
}

View File

@ -10,7 +10,7 @@ import { ProjectService } from '../../../services/project.service';
styleUrls: ['./choose-name-dialog.component.scss'],
})
export class ChooseNameDialogComponent implements OnInit {
@Input() controller:Controller ;
@Input() controller: Controller;
@Input() project: Project;
name: string;

View File

@ -232,4 +232,12 @@ export class NodeService {
return this.httpController.post(controller, urlPath, configuration);
}
getIdlePCProposals(controller:Controller, node: Node) {
return this.httpController.get(controller, `/projects/${node.project_id}/nodes/${node.node_id}/dynamips/idlepc_proposals`);
}
getAutoIdlePC(controller:Controller, node: Node) {
return this.httpController.get(controller, `/projects/${node.project_id}/nodes/${node.node_id}/dynamips/auto_idlepc`);
}
}