diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 1df168e3..e2640885 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -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, diff --git a/src/app/components/project-map/context-menu/actions/idle-pc-action/idle-pc-action.component.html b/src/app/components/project-map/context-menu/actions/idle-pc-action/idle-pc-action.component.html new file mode 100644 index 00000000..7d62bcfb --- /dev/null +++ b/src/app/components/project-map/context-menu/actions/idle-pc-action/idle-pc-action.component.html @@ -0,0 +1,8 @@ + diff --git a/src/app/components/project-map/context-menu/actions/idle-pc-action/idle-pc-action.component.ts b/src/app/components/project-map/context-menu/actions/idle-pc-action/idle-pc-action.component.ts new file mode 100644 index 00000000..040f0461 --- /dev/null +++ b/src/app/components/project-map/context-menu/actions/idle-pc-action/idle-pc-action.component.ts @@ -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; + } +} diff --git a/src/app/components/project-map/context-menu/context-menu.component.html b/src/app/components/project-map/context-menu/context-menu.component.html index 5d51d8b2..f26dfd80 100644 --- a/src/app/components/project-map/context-menu/context-menu.component.html +++ b/src/app/components/project-map/context-menu/context-menu.component.html @@ -94,6 +94,11 @@ [controller]="controller" [node]="nodes[0]" > + +
Computing Idle-PC values, please wait...
+
+ +
+ +
+

Choose an Idle-PC value

+ + + {{ idlepc.name }} + + +
+
+ + + +
diff --git a/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.scss b/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.scss new file mode 100644 index 00000000..add91a3f --- /dev/null +++ b/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.scss @@ -0,0 +1,5 @@ +.container { + width: 100%; + display: flex; + justify-content: space-between; +} diff --git a/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.spec.ts b/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.spec.ts new file mode 100644 index 00000000..e69de29b diff --git a/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.ts b/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.ts new file mode 100644 index 00000000..c6b64968 --- /dev/null +++ b/src/app/components/project-map/context-menu/dialogs/idle-pc-dialog/idle-pc-dialog.component.ts @@ -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, + 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}`); + }); + } + } +} diff --git a/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.ts b/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.ts index cd80f331..cbdd8de5 100644 --- a/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.ts +++ b/src/app/components/projects/choose-name-dialog/choose-name-dialog.component.ts @@ -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; diff --git a/src/app/services/node.service.ts b/src/app/services/node.service.ts index 1ad20419..b5785baa 100644 --- a/src/app/services/node.service.ts +++ b/src/app/services/node.service.ts @@ -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`); + } }