2 Copyright 2020 TATA ELXSI
4 Licensed under the Apache License, Version 2.0 (the 'License');
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
8 http://www.apache.org/licenses/LICENSE-2.0
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
16 Author: KUMARAN M (kumaran.m@tataelxsi.co.in), RAJESH S (rajesh.s@tataelxsi.co.in), BARATH KUMAR R (barath.r@tataelxsi.co.in)
19 * @file VNFComposerComponent
21 import { HttpHeaders } from '@angular/common/http';
22 import { Component, ElementRef, Injector, ViewChild, ViewEncapsulation } from '@angular/core';
23 import { ActivatedRoute, Router } from '@angular/router';
24 import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
25 import { TranslateService } from '@ngx-translate/core';
26 import { NotifierService } from 'angular-notifier';
27 import { APIURLHEADER, ERRORDATA, MODALCLOSERESPONSEDATA } from 'CommonModel';
28 import { ConfirmationTopologyComponent } from 'ConfirmationTopology';
29 import * as d3 from 'd3';
30 import { DataService } from 'DataService';
31 import { environment } from 'environment';
32 import * as HttpStatus from 'http-status-codes';
33 import * as jsyaml from 'js-yaml';
34 import { RestService } from 'RestService';
35 import { SharedService } from 'SharedService';
36 import { COMPOSERNODES, EXTCPD, GRAPHDETAILS, INTCPD, IVLD, Tick, TickPath, VDU, VDUINTCPD, VNFD, VNFDATA, VNIR } from 'VNFDModel';
40 * @Component takes VNFComposerComponent.html as template url
43 templateUrl: './VNFComposerComponent.html',
44 styleUrls: ['./VNFComposerComponent.scss'],
45 encapsulation: ViewEncapsulation.None
47 /** Exporting a class @exports VNFComposerComponent */
48 export class VNFComposerComponent {
49 /** To inject services @public */
50 public injector: Injector;
51 /** View child contains graphContainer ref @public */
52 @ViewChild('graphContainer', { static: true }) public graphContainer: ElementRef;
53 /** dataService to pass the data from one component to another @public */
54 public dataService: DataService;
55 /** random number count @public */
56 public randomNumberLength: number;
57 /** Contains the vnfd information @public */
58 public vnfList: string[] = [];
59 /** Contains VNFD Information @public */
60 public vnfdInfo: VNFD = { 'product-name': '', description: '', version: '', id: '', provider: '' };
61 /** Contains right panel box information @public */
62 public showRightSideInfo: string = '';
63 /** Add the fixed class for the freeze @public */
64 public fixedClass: string = 'fixed';
65 /** Check the loading results @public */
66 public isLoadingResults: boolean = true;
67 /** Give the message for the loading @public */
68 public message: string = 'PLEASEWAIT';
69 /** Assign the forcesimulation active @public */
70 public forceSimulationActive: boolean = false;
71 /** Assign pinned class for the button when freezed @public */
72 public classApplied: boolean = false;
73 /** Contains sidebar open status @public */
74 public sideBarOpened: boolean = false;
75 /** Contains SVG attributes @private */
76 // tslint:disable-next-line:no-any
78 /** Contains forced node animations @private */
79 // tslint:disable-next-line:no-any
81 /** Contains the Drag line */
82 // tslint:disable-next-line: no-any
83 private dragLine: any;
84 /** Contains id of the node @private */
85 private identifier: string;
86 /** Contains path information of the node */
87 // tslint:disable-next-line:no-any
89 /** Contains node network @private */
90 // tslint:disable-next-line:no-any
92 /** Contains node network @private */
93 // tslint:disable-next-line:no-any
94 private virutualDeploymentUnit: any;
95 /** Contains node connectionPoint @private */
96 // tslint:disable-next-line:no-any
97 private connectionPoint: any;
98 /** Contains node intConnectionPoint @private */
99 // tslint:disable-next-line:no-any
100 private intConnectionPoint: any;
101 /** Contains the node information @private */
102 private nodes: COMPOSERNODES[] = [];
103 /** Contains the link information of nodes @private */
104 private links: {}[] = [];
105 /** Instance of the rest service @private */
106 private restService: RestService;
107 /** Service holds the router information @private */
108 private router: Router;
109 /** Service contails all the shared service information @private */
110 private sharedService: SharedService;
111 /** Holds teh instance of AuthService class of type AuthService @private */
112 private activatedRoute: ActivatedRoute;
113 /** Notifier service to popup notification @private */
114 private notifierService: NotifierService;
115 /** Controls the header form @private */
116 private headers: HttpHeaders;
117 /** Contains tranlsate instance @private */
118 private translateService: TranslateService;
119 /** Rendered nodes represent network @private */
120 // tslint:disable-next-line:no-any
121 private gNetwork: any;
122 /** Rendered nodes represent VDU @private */
123 // tslint:disable-next-line:no-any
124 private gVirutualDeploymentUnit: any;
125 /** Rendered nodes represent connection point @private */
126 // tslint:disable-next-line:no-any
127 private gConnectionPoint: any;
128 /** Rendered nodes represent internal connection point @private */
129 // tslint:disable-next-line:no-any
130 private gIntConnectionPoint: any;
131 /** Contains all the information about VNF Details @private */
132 private vnfdPackageDetails: VNFD;
133 /** Conatins mousedown action @private */
134 private mousedownNode: COMPOSERNODES = null;
135 /** Conatins mouseup action @private */
136 private mouseupNode: COMPOSERNODES = null;
137 /** Conatins current Selection node action @private */
138 private currentSelectedNode: COMPOSERNODES = null;
139 /** Add the activeNode for the selected @private */
140 private activeNode: string = 'active';
141 /** Contains lastkeypressed instance @private */
142 private lastKeyDown: number = -1;
143 /** Contains VDU Information @private */
144 private vduInfo: VDU;
145 /** Contains VDU Old value Information @private */
146 private oldVDUID: string;
147 /** Contains Internal VL Information @private */
148 private intvlInfo: IVLD;
149 /** Contains Internal VL Old value Information @private */
150 private oldintVLID: string;
151 /** Contains Connection Point Information @private */
152 private cpInfo: EXTCPD;
153 /** Contains Connection Point Old value Information @private */
154 private oldCPID: string;
155 /** Contains Internal Connection Point Information @private */
156 private intcpInfo: VNIR;
157 /** Instance of the modal service @private */
158 private modalService: NgbModal;
160 constructor(injector: Injector) {
161 this.injector = injector;
162 this.restService = this.injector.get(RestService);
163 this.dataService = this.injector.get(DataService);
164 this.router = this.injector.get(Router);
165 this.activatedRoute = this.injector.get(ActivatedRoute);
166 this.notifierService = this.injector.get(NotifierService);
167 this.translateService = this.injector.get(TranslateService);
168 this.sharedService = this.injector.get(SharedService);
169 this.modalService = this.injector.get(NgbModal);
172 * Lifecyle Hooks the trigger before component is instantiate
174 public ngOnInit(): void {
175 // tslint:disable-next-line:no-backbone-get-set-outside-model
176 this.identifier = this.activatedRoute.snapshot.paramMap.get('id');
178 this.headers = new HttpHeaders({
179 'Content-Type': 'application/zip',
180 Accept: 'application/json',
181 'Cache-Control': 'no-cache, no-store, must-revalidate, max-age=0'
185 /** Prepare information for node creation of VNFD @public */
186 public generateData(): void {
187 this.nodes = []; this.links = []; this.vnfdPackageDetails = null;
188 this.showRightSideInfo = 'vnfdInfo';
189 this.restService.getResource(environment.VNFPACKAGESCONTENT_URL + '/' + this.identifier)
190 .subscribe((vnfdPackageDetails: VNFD): void => {
192 delete vnfdPackageDetails._admin;
193 delete vnfdPackageDetails._id;
194 delete vnfdPackageDetails._links;
195 this.vnfdPackageDetails = vnfdPackageDetails;
196 this.generateVDU(vnfdPackageDetails);
197 this.generateCPPoint(vnfdPackageDetails);
198 this.generateInternalVLD(vnfdPackageDetails);
199 this.generateInternalCP(vnfdPackageDetails);
200 this.generateIntVLCPLinks(vnfdPackageDetails);
201 this.generateVDUCPLinks(vnfdPackageDetails);
202 this.createNode(this.nodes);
203 this.generateVNFInfo(vnfdPackageDetails);
205 this.notifierService.notify('error', this.translateService.instant('ERROR'));
207 this.isLoadingResults = false;
208 }, (error: ERRORDATA): void => {
209 error.error = typeof error.error === 'string' ? jsyaml.load(error.error) : error.error;
210 if (error.error.status === HttpStatus.NOT_FOUND || error.error.status === HttpStatus.UNAUTHORIZED) {
211 this.router.navigateByUrl('404', { skipLocationChange: true }).catch();
213 this.restService.handleError(error, 'get');
215 this.isLoadingResults = false;
216 this.showRightSideInfo = '';
219 /** Generate the VNF Package Information */
220 public generateVNFInfo(vnfdPackageDetails: VNFD): void {
221 this.vnfdInfo['product-name'] = vnfdPackageDetails['product-name'];
222 this.vnfdInfo.description = vnfdPackageDetails.description;
223 this.vnfdInfo.version = vnfdPackageDetails.version;
224 this.vnfdInfo.id = vnfdPackageDetails.id;
225 this.vnfdInfo.provider = vnfdPackageDetails.provider;
227 /** Events handles at drag on D3 region @public */
228 // tslint:disable-next-line:no-any
229 public drag(ev: any): void {
230 ev.dataTransfer.setData('text', ev.target.id);
232 /** Events handles drop at D3 region @public */
233 public drop(ev: DragEvent): void {
235 const getDropedName: string = ev.dataTransfer.getData('text');
236 if (getDropedName === 'vdu') {
237 this.svg.selectAll('*').remove();
238 this.vduDropCompose();
239 } else if (getDropedName === 'cp') {
240 this.svg.selectAll('*').remove();
241 this.cpDropCompose();
242 } else if (getDropedName === 'intvl') {
243 this.svg.selectAll('*').remove();
244 this.intvlDropCompose();
247 /** Events handles allow drop on D3 region @public */
248 public allowDrop(ev: DragEvent): void {
251 /** Generate and list VDU @public */
252 public generateVDU(vnfdPackageDetails: VNFD): void {
253 if (vnfdPackageDetails.vdu !== undefined) {
254 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
264 /** Generate and list CP points @public */
265 public generateCPPoint(vnfdPackageDetails: VNFD): void {
266 if (vnfdPackageDetails['ext-cpd'] !== undefined) {
267 vnfdPackageDetails['ext-cpd'].forEach((cp: EXTCPD): void => {
269 id: cp['int-cpd'] !== undefined ? cp['int-cpd'].cpd : cp.id,
277 /** Generate and list Internal VLD @public */
278 public generateInternalVLD(vnfdPackageDetails: VNFD): void {
279 if (vnfdPackageDetails['int-virtual-link-desc'] !== undefined) {
280 vnfdPackageDetails['int-virtual-link-desc'].forEach((ivld: IVLD): void => {
290 /** Generate and list Internal CP @public */
291 public generateInternalCP(vnfdPackageDetails: VNFD): void {
292 if (vnfdPackageDetails.vdu !== undefined) {
293 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
294 if (vdu['int-cpd'] !== undefined) {
295 vdu['int-cpd'].forEach((intcpd: VDUINTCPD): void => {
296 if (intcpd['int-virtual-link-desc'] !== undefined) {
297 intcpd['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
311 /** Generate VDU External and Internal CP Links @public */
312 public generateVDUCPLinks(vnfdPackageDetails: VNFD): void {
313 if (vnfdPackageDetails.vdu !== undefined) {
314 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
315 const vduLink: string = vdu.id;
316 if (vdu['int-cpd'] !== undefined) {
317 vdu['int-cpd'].forEach((intCPD: VDUINTCPD): void => {
318 if (intCPD['int-virtual-link-desc'] !== undefined) {
319 intCPD['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
320 this.links.push({ source: vduLink, target: intCPD.id });
323 this.links.push({ source: vduLink, target: intCPD.id });
330 /** Generate Network/VLD/Internal VirtualLink, CP Links @public */
331 public generateIntVLCPLinks(vnfdPackageDetails: VNFD): void {
332 if (vnfdPackageDetails.vdu !== undefined) {
333 vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
334 if (vdu['int-cpd'] !== undefined) {
335 vdu['int-cpd'].forEach((intCPD: VDUINTCPD): void => {
336 const vldName: string = intCPD['int-virtual-link-desc'];
337 if (intCPD['int-virtual-link-desc'] !== undefined) {
338 intCPD['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
339 this.links.push({ source: vldName, target: intCPD.id });
347 /** VNFD details can be saved on users inputs @public */
348 public saveVNFD(): void {
349 this.vnfdPackageDetails['product-name'] = this.vnfdInfo['product-name'];
350 this.vnfdPackageDetails.description = this.vnfdInfo.description;
351 this.vnfdPackageDetails.version = this.vnfdInfo.version;
352 this.vnfdPackageDetails.id = this.vnfdInfo.id;
353 this.vnfdPackageDetails.provider = this.vnfdInfo.provider;
354 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
356 /** VDU details can be saved on users inputs @public */
357 public saveVDU(getVDUID: string): void {
358 const getOLDVDUID: string = this.oldVDUID;
359 this.vnfdPackageDetails.vdu.forEach((ref: VDU): void => {
360 if (ref.id === getVDUID) {
361 ref.id = this.vduInfo.id;
362 ref.name = this.vduInfo.name;
363 ref.description = this.vduInfo.description !== undefined ? this.vduInfo.description : '';
364 ref['sw-image-desc'] = this.vduInfo['sw-image-desc'];
367 this.vnfdPackageDetails['ext-cpd'].forEach((extCPD: EXTCPD): void => {
368 if (extCPD['int-cpd'] !== undefined) {
369 if (extCPD['int-cpd']['vdu-id'] === getOLDVDUID) {
370 extCPD['int-cpd']['vdu-id'] = this.vduInfo.id;
374 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
376 /** IntVL details can be saved on users inputs @public */
377 public saveIntVL(intVLID: string): void {
378 const getOldID: string = this.oldintVLID;
379 this.vnfdPackageDetails['int-virtual-link-desc'].forEach((ivldDetails: IVLD): void => {
380 if (ivldDetails.id === intVLID) {
381 ivldDetails.id = this.intvlInfo.id;
384 this.vnfdPackageDetails.vdu.forEach((vduDetails: VDU): void => {
385 if (vduDetails['int-cpd'] !== undefined) {
386 vduDetails['int-cpd'].forEach((intCPDDetails: VDUINTCPD): void => {
387 if (intCPDDetails['int-virtual-link-desc'] !== undefined) {
388 if (intCPDDetails['int-virtual-link-desc'] === getOldID) {
389 intCPDDetails['int-virtual-link-desc'] = this.intvlInfo.id;
395 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
397 /** IntVL details can be saved on users inputs @public */
398 public saveCP(cpID: string): void {
399 const getOldCP: string = this.oldCPID;
400 this.vnfdPackageDetails['ext-cpd'].forEach((ref: EXTCPD): void => {
401 if (ref.id === cpID) {
402 ref.id = this.cpInfo.id;
405 if (this.vnfdPackageDetails['mgmt-cp'] === getOldCP) {
406 this.vnfdPackageDetails['mgmt-cp'] = this.cpInfo.id;
408 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
410 /** Edit topology @public */
411 public onEdit(): void {
412 this.router.navigate(['/packages/vnf/edit/', this.identifier]).catch();
414 /** Show Info @public */
415 public showInfo(): void {
416 const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' });
417 modalRef.componentInstance.topologyType = 'Info';
418 modalRef.componentInstance.topologytitle = this.translateService.instant('PAGE.TOPOLOGY.INFO');
419 modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
425 /** Event to freeze the animation @public */
426 public onFreeze(): void {
427 this.classApplied = !this.classApplied;
428 const alreadyFixedIsActive: boolean = d3.select('svg#graphContainer').classed(this.fixedClass);
429 d3.select('svg#graphContainer').classed(this.fixedClass, !alreadyFixedIsActive);
430 if (alreadyFixedIsActive) {
433 this.forceSimulationActive = alreadyFixedIsActive;
434 this.nodes.forEach((d: COMPOSERNODES): void => {
435 d.fx = (alreadyFixedIsActive) ? null : d.x;
436 d.fy = (alreadyFixedIsActive) ? null : d.y;
438 if (alreadyFixedIsActive) {
439 this.force.restart();
442 /** Events handles when dragended @public */
443 public toggleSidebar(): void {
444 this.sideBarOpened = !this.sideBarOpened;
445 this.deselectAllNodes();
446 this.showRightSideInfo = 'vnfdInfo';
448 /** Get the default Configuration of containers @private */
449 private getGraphContainerAttr(): GRAPHDETAILS {
462 sourcePaddingYes: 17,
472 /** Node is created and render at D3 region @private */
473 private createNode(nodes: VNFD[]): void {
474 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
475 d3.selectAll('svg#graphContainer > *').remove();
476 d3.select(window).on('keydown', (): void => { this.keyDown(); });
477 d3.select(window).on('keyup', (): void => { this.keyUp(); });
478 this.svg = d3.select('#graphContainer')
479 .attr('oncontextmenu', 'return false;')
480 .attr('viewBox', `0 0 ${graphContainerAttr.width} ${graphContainerAttr.height}`)
481 .on('mousemove', (): void => { this.mousemove(); });
482 this.force = d3.forceSimulation()
483 .force('link', d3.forceLink().id((d: TickPath): string => d.id).distance(graphContainerAttr.distance))
484 .force('charge', d3.forceManyBody().strength(graphContainerAttr.strength))
485 .force('x', d3.forceX(graphContainerAttr.width / graphContainerAttr.forcex))
486 .force('y', d3.forceY(graphContainerAttr.height / graphContainerAttr.forcey))
487 .on('tick', (): void => { this.tick(); });
488 this.path = this.svg.append('svg:g').selectAll('path');
489 this.dragLine = this.svg.append('svg:path').attr('class', 'link dragline hidden').attr('d', 'M0,0L0,0');
490 this.network = this.svg.append('svg:g').selectAll('network');
491 this.virutualDeploymentUnit = this.svg.append('svg:g').selectAll('virutualDeploymentUnit');
492 this.connectionPoint = this.svg.append('svg:g').selectAll('connectionPoint');
493 this.intConnectionPoint = this.svg.append('svg:g').selectAll('intConnectionPoint');
496 /** Update force layout (called automatically each iteration) @private */
497 private tick(): void {
498 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
499 this.path.attr('d', (d: Tick): string => {
500 const deltaX: number = d.target.x - d.source.x; const deltaY: number = d.target.y - d.source.y;
501 const dist: number = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
502 const normX: number = deltaX / dist; const normY: number = deltaY / dist;
503 const sourcePadding: number = d.left ? graphContainerAttr.sourcePaddingYes : graphContainerAttr.sourcePaddingNo;
504 const targetPadding: number = d.right ? graphContainerAttr.targetPaddingYes : graphContainerAttr.targetPaddingNo;
505 const sourceX: number = d.source.x + (sourcePadding * normX); const sourceY: number = d.source.y + (sourcePadding * normY);
506 const targetX: number = d.target.x - (targetPadding * normX); const targetY: number = d.target.y - (targetPadding * normY);
507 return `M${sourceX},${sourceY}L${targetX},${targetY}`;
508 }).on('dblclick', (d: Tick): void => { this.getDeleteLinkConfirmation(d); });
509 this.network.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
510 this.virutualDeploymentUnit.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
511 this.connectionPoint.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
512 this.intConnectionPoint.attr('transform', (d: TickPath): string => `translate(${d.x},${d.y})`);
514 /** Update graph (called when needed) @private */
515 private restart(nodes: VNFD[]): void {
516 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
517 this.path = this.path.data(this.links);
518 const cpNodes: {}[] = []; const vduNodes: {}[] = []; const vlNodes: {}[] = []; const intcpNodes: {}[] = []; //Nodes are known by id
519 nodes.forEach((nodeList: COMPOSERNODES): void => {
520 if (nodeList.type === 'cp') { cpNodes.push(nodeList); }
521 else if (nodeList.type === 'vdu') { vduNodes.push(nodeList); }
522 else if (nodeList.type === 'intvl') { vlNodes.push(nodeList); }
523 else if (nodeList.type === 'intcp') { intcpNodes.push(nodeList); }
525 this.network = this.network.data(vlNodes, (d: VNFD): string => d.id);
526 this.virutualDeploymentUnit = this.virutualDeploymentUnit.data(vduNodes, (d: VNFD): string => d.id);
527 this.connectionPoint = this.connectionPoint.data(cpNodes, (d: VNFD): string => d.id);
528 this.intConnectionPoint = this.intConnectionPoint.data(intcpNodes, (d: VNFD): string => d.id);
529 this.resetAndCreateNodes();
530 this.force.nodes(nodes).force('link').links(this.links); //Set the graph in motion
531 this.force.alphaTarget(graphContainerAttr.alphaTarget).restart();
533 /** Rest and create nodes @private */
534 private resetAndCreateNodes(): void {
535 this.path.exit().remove();
536 this.network.exit().remove();
537 this.virutualDeploymentUnit.exit().remove();
538 this.connectionPoint.exit().remove();
539 this.intConnectionPoint.exit().remove();
542 this.getgVirutualDeploymentUnit();
543 this.getgConnectionPoint();
544 this.getgIntConnectionPoint();
545 this.network = this.gNetwork.merge(this.network);
546 this.virutualDeploymentUnit = this.gVirutualDeploymentUnit.merge(this.virutualDeploymentUnit);
547 this.connectionPoint = this.gConnectionPoint.merge(this.connectionPoint);
548 this.intConnectionPoint = this.gIntConnectionPoint.merge(this.intConnectionPoint);
549 this.path.merge(this.path);
551 /** Setting the Path @private */
552 private getPathNodes(): void {
553 this.path = this.path.enter().append('svg:path').attr('class', 'link');
555 /** Settings all the network attributes of nodes @private */
556 private getgNetwork(): void {
557 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
558 this.gNetwork = this.network.enter().append('svg:g');
559 this.gNetwork.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
560 this.gNetwork.append('svg:image')
562 .attr('x', graphContainerAttr.imageX)
563 .attr('y', graphContainerAttr.imageY)
564 .call(this.onDragDrop())
565 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
566 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
567 .attr('xlink:href', 'assets/images/INTVL.svg')
568 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
569 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
570 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.network, d); this.onNodeClickToggleSidebar(); })
571 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
572 this.gNetwork.append('svg:text')
573 .attr('class', 'node_text')
574 .attr('y', graphContainerAttr.textY)
575 .text((d: COMPOSERNODES): string => d.id);
577 /** Settings all the connection point attributes of nodes @private */
578 private getgVirutualDeploymentUnit(): void {
579 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
580 this.gVirutualDeploymentUnit = this.virutualDeploymentUnit.enter().append('svg:g');
581 this.gVirutualDeploymentUnit.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
582 this.gVirutualDeploymentUnit.append('svg:image')
584 .attr('x', graphContainerAttr.imageX)
585 .attr('y', graphContainerAttr.imageY)
586 .call(this.onDragDrop())
587 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
588 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
589 .attr('xlink:href', 'assets/images/VDU.svg')
590 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
591 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
592 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.virutualDeploymentUnit, d); this.onNodeClickToggleSidebar(); })
593 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
594 this.gVirutualDeploymentUnit.append('svg:text')
595 .attr('class', 'node_text')
596 .attr('y', graphContainerAttr.textY)
597 .text((d: COMPOSERNODES): string => d.id);
599 /** Settings all the connection point attributes of nodes @private */
600 private getgConnectionPoint(): void {
601 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
602 this.gConnectionPoint = this.connectionPoint.enter().append('svg:g');
603 this.gVirutualDeploymentUnit.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
604 this.gConnectionPoint.append('svg:image')
606 .attr('x', graphContainerAttr.imageX)
607 .attr('y', graphContainerAttr.imageY)
608 .call(this.onDragDrop())
609 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
610 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
611 .attr('xlink:href', 'assets/images/CP-VNF.svg')
612 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
613 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
614 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.connectionPoint, d); this.onNodeClickToggleSidebar(); })
615 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
616 this.gConnectionPoint.append('svg:text')
617 .attr('class', 'node_text')
618 .attr('y', graphContainerAttr.textY)
619 .text((d: COMPOSERNODES): string => d.name);
621 /** Settings all the internal connection point attributes of nodes @private */
622 private getgIntConnectionPoint(): void {
623 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
624 this.gIntConnectionPoint = this.intConnectionPoint.enter().append('svg:g');
625 this.gIntConnectionPoint.append('svg:circle').attr('r', graphContainerAttr.radius).style('fill', '#eeeeee');
626 this.gIntConnectionPoint.append('svg:image')
628 .attr('x', graphContainerAttr.imageX)
629 .attr('y', graphContainerAttr.imageY)
630 .call(this.onDragDrop())
631 .attr('id', (d: COMPOSERNODES): string => { return d.id; })
632 .attr('class', 'node').attr('width', graphContainerAttr.nodeWidth).attr('height', graphContainerAttr.nodeHeight)
633 .attr('xlink:href', 'assets/images/INTCP.svg')
634 .on('mousedown', (d: COMPOSERNODES): void => { this.mouseDown(d); })
635 .on('mouseup', (d: COMPOSERNODES): void => { this.mouseUp(d); })
636 .on('click', (d: COMPOSERNODES): void => { this.singleClick(this.intConnectionPoint, d); this.onNodeClickToggleSidebar(); })
637 .on('dblclick', (d: COMPOSERNODES): void => { this.getDeleteNodeConfirmation(d); this.onNodedblClickToggleSidebar(); });
638 this.gIntConnectionPoint.append('svg:text')
639 .attr('class', 'node_text')
640 .attr('y', graphContainerAttr.textY)
641 .text((d: COMPOSERNODES): string => d.name);
643 /** Drop VDU Composer Data @private */
644 private vduDropCompose(): void {
645 const randomID: string = this.sharedService.randomString();
646 if (this.vnfdPackageDetails.vdu === undefined) {
647 this.vnfdPackageDetails.vdu = [];
649 this.vnfdPackageDetails.vdu.push({
650 id: 'vdu_' + randomID,
651 name: 'vdu_' + randomID,
653 'sw-image-desc': 'ubuntu',
655 'monitoring-parameter': [],
656 'virtual-compute-desc': '',
657 'virtual-storage-desc': []
659 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
661 /** Drop CP Composer Data @private */
662 private cpDropCompose(): void {
663 const randomID: string = this.sharedService.randomString();
664 if (this.vnfdPackageDetails['ext-cpd'] === undefined) {
665 this.vnfdPackageDetails['ext-cpd'] = [];
666 this.vnfdPackageDetails['mgmt-cp'] = 'cp_' + randomID;
668 this.vnfdPackageDetails['ext-cpd'].push({
669 id: 'cp_' + randomID,
672 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
674 /** Drop IntVL Composer Data @private */
675 private intvlDropCompose(): void {
676 const randomID: string = this.sharedService.randomString();
677 if (this.vnfdPackageDetails['int-virtual-link-desc'] === undefined) {
678 this.vnfdPackageDetails['int-virtual-link-desc'] = [];
680 this.vnfdPackageDetails['int-virtual-link-desc'].push({
681 id: 'vnf_vl_' + randomID
683 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
685 /** Add the Add Nodes Data @private */
686 private addNodes(apiURL: string, identifier: string, data: VNFD): void {
687 this.isLoadingResults = true;
688 const apiURLHeader: APIURLHEADER = {
689 url: apiURL + '/' + identifier + '/package_content',
690 httpOptions: { headers: this.headers }
692 const vnfData: VNFDATA = {};
694 const descriptorInfo: string = jsyaml.dump(vnfData, { sortKeys: true });
695 this.sharedService.targzFile({ packageType: 'vnfd', id: this.identifier, descriptor: descriptorInfo })
696 .then((content: ArrayBuffer): void => {
697 this.restService.putResource(apiURLHeader, content).subscribe((res: {}): void => {
699 this.notifierService.notify('success', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.UPDATEDSUCCESSFULLY'));
700 this.isLoadingResults = false;
701 }, (error: ERRORDATA): void => {
703 this.restService.handleError(error, 'put');
704 this.isLoadingResults = false;
706 }).catch((): void => {
707 this.notifierService.notify('error', this.translateService.instant('ERROR'));
708 this.isLoadingResults = false;
711 /** Events handles when mousedown click it will capture the selected node data @private */
712 private mouseDown(d: COMPOSERNODES): void {
713 event.preventDefault();
714 if (d3.event.ctrlKey) { return; }
715 if (d3.event.shiftKey) {
716 this.mousedownNode = d;
717 this.currentSelectedNode = (this.mousedownNode === this.currentSelectedNode) ? null : this.mousedownNode;
718 this.dragLine.classed('hidden', false)
719 .attr('d', `M${this.mousedownNode.x},${this.mousedownNode.y}L${this.mousedownNode.x},${this.mousedownNode.y}`);
722 /** Event handles when mouseup event occures @private */
723 private mouseUp(d: COMPOSERNODES): void {
724 if (!this.mousedownNode) { return; }
725 this.dragLine.classed('hidden', true);
726 this.mouseupNode = d;
727 if (this.mousedownNode.type === 'vdu') {
728 this.vduMouseDownNode();
729 } else if (this.mousedownNode.type === 'cp') {
730 this.cpMouseDownNode();
731 } else if (this.mousedownNode.type === 'intvl') {
732 this.intVLMouseDownNode();
733 } else if (this.mousedownNode.type === 'intcp') {
734 this.intCPMouseDownNode();
736 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
739 this.resetMouseActions();
740 this.currentSelectedNode = null;
742 /** Establish a connection point between vdu and other nodes @private */
743 private vduMouseDownNode(): void {
744 if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'cp') {
745 this.vduCPConnection(this.mousedownNode.id, this.mouseupNode.id);
746 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intcp') {
747 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDINTCP'));
749 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'vdu') {
750 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVDUANDVDU'));
752 } else if (this.mousedownNode.type === 'vdu' && this.mouseupNode.type === 'intvl') {
753 this.vduIntvlConnection(this.mousedownNode.id, this.mouseupNode.id);
756 /** Establish a connection point between cp and other nodes @private */
757 private cpMouseDownNode(): void {
758 if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'vdu') {
759 this.vduCPConnection(this.mouseupNode.id, this.mousedownNode.id);
760 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intvl') {
761 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDVNFVL'));
763 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'intcp') {
764 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDINTCP'));
766 } else if (this.mousedownNode.type === 'cp' && this.mouseupNode.type === 'cp') {
767 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKCPANDCP'));
771 /** Establish a connection piont between intvl and other nodes @private */
772 private intVLMouseDownNode(): void {
773 if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'cp') {
774 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDCP'));
776 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'vdu') {
777 this.vduIntvlConnection(this.mouseupNode.id, this.mousedownNode.id);
778 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intvl') {
779 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDVNFVL'));
781 } else if (this.mousedownNode.type === 'intvl' && this.mouseupNode.type === 'intcp') {
782 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKVNFVLANDONTCP'));
786 /** Establish a connection point between intcp and other nodes @private */
787 private intCPMouseDownNode(): void {
788 if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'vdu') {
789 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVDU'));
791 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'cp') {
792 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDCP'));
794 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intvl') {
795 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDVNFVL'));
797 } else if (this.mousedownNode.type === 'intcp' && this.mouseupNode.type === 'intcp') {
798 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.CANNOTLINKINTCPANDINTCP'));
802 /** Establish a connection between VDU & CP vice versa @private */
803 private vduCPConnection(nodeA: string, nodeB: string): void {
804 const vduExternalID: string = nodeA + '-eth_' + this.sharedService.randomString();
805 if (this.vnfdPackageDetails.vdu !== undefined) {
806 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
807 const vduID: string = vdu.id;
808 if (vdu.id === nodeA) {
809 if (this.vnfdPackageDetails['ext-cpd'] !== undefined) {
810 this.vnfdPackageDetails['ext-cpd'].forEach((extcpd: EXTCPD, index: number): void => {
811 if (extcpd.id === nodeB) {
812 if (vdu['int-cpd'] === undefined) {
815 if (extcpd['int-cpd'] === undefined) {
816 vdu['int-cpd'].push({
818 'virtual-network-interface-requirement': [
822 'virtual-interface': { type: 'PARAVIRT' }
826 this.vnfdPackageDetails['ext-cpd'][index] = {
840 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
843 /** Establish a connection between vdu & intvl and vice versa @private */
844 private vduIntvlConnection(nodeA: string, nodeB: string): void {
845 const vduInternalID: string = nodeA + '-eth_' + this.sharedService.randomString();
846 if (this.vnfdPackageDetails.vdu !== undefined) {
847 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
848 if (vdu.id === nodeA) {
849 if (vdu['int-cpd'] === undefined) {
852 vdu['int-cpd'].push({
854 'int-virtual-link-desc': nodeB,
855 'virtual-network-interface-requirement': [
859 'virtual-interface': { type: 'PARAVIRT' }
866 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
869 /** Events handles when mousemove it will capture the selected node data @private */
870 private mousemove(): void {
871 if (!this.mousedownNode) { return; }
872 this.dragLine.attr('d',
873 `M${this.mousedownNode.x},${this.mousedownNode.y}L${d3.mouse(d3.event.currentTarget)[0]},${d3.mouse(d3.event.currentTarget)[1]}`);
875 /** reset Mouse varaibles @private */
876 private resetMouseActions(): void {
877 this.mousedownNode = null;
878 this.mouseupNode = null;
880 /** drag event @private */
881 // tslint:disable-next-line: no-any
882 private onDragDrop(): any {
883 return d3.drag().filter(this.dragFilter)
884 .on('start', this.dragstarted)
885 .on('drag', this.dragged)
886 .on('end', this.dragended);
888 /** Key press event @private */
889 private keyDown(): void {
890 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
891 if (this.lastKeyDown !== -1) { return; }
892 this.lastKeyDown = d3.event.keyCode;
893 if (d3.event.keyCode === graphContainerAttr.shiftKeyCode) {
894 this.svg.classed('ctrl', true);
897 /** Key realse event @private */
898 private keyUp(): void {
899 const graphContainerAttr: GRAPHDETAILS = this.getGraphContainerAttr();
900 this.lastKeyDown = -1;
901 if (d3.event.keyCode === graphContainerAttr.shiftKeyCode) {
902 this.gNetwork.on('.drag', null);
903 this.gVirutualDeploymentUnit.on('.drag', null);
904 this.gConnectionPoint.on('.drag', null);
905 this.gIntConnectionPoint.on('.drag', null);
906 this.svg.classed('ctrl', false);
909 /** Mosue Drag Line false if it is not satisfied @private */
910 private deselectPath(): void {
911 this.dragLine.classed('hidden', true).attr('d', 'M0,0L0,0');
913 /** Events handles when Shift Click to perform create cp @private */
914 // tslint:disable-next-line: no-any
915 private singleClick(nodeSelected: any, d: COMPOSERNODES): void {
916 this.selectedNode(nodeSelected, d);
918 /** Get confirmation Before Deleting the Node in Topology @private */
919 private getDeleteNodeConfirmation(d: COMPOSERNODES): void {
920 const modalRef: NgbModalRef = this.modalService.open(ConfirmationTopologyComponent, { backdrop: 'static' });
921 modalRef.componentInstance.topologyType = 'Delete';
922 modalRef.componentInstance.topologyname = d.name;
923 if (d.type === 'vdu') {
924 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.VDU';
925 } else if (d.type === 'intvl') {
926 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTVL';
927 } else if (d.type === 'cp') {
928 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.CONNECTIONPOINT';
929 } else if (d.type === 'intcp') {
930 modalRef.componentInstance.topologytitle = 'PAGE.TOPOLOGY.INTCP';
932 modalRef.result.then((result: MODALCLOSERESPONSEDATA): void => {
938 /** Delete nodes @private */
939 private deleteNode(d: COMPOSERNODES): void {
940 // tslint:disable-next-line: max-func-body-length
941 this.nodes.forEach((node: VNFD): void => {
942 if (node.id === d.id) {
943 if (d.type === 'cp') {
944 if (this.vnfdPackageDetails['ext-cpd'] !== undefined) {
945 let getRelatedVDUCPD: string; let getRelatedVDUID: string;
946 const posExtCPD: number = this.vnfdPackageDetails['ext-cpd'].findIndex((e: EXTCPD): boolean => {
947 if (e.id === d.name) {
948 if (e['int-cpd'] !== undefined) {
949 getRelatedVDUCPD = e['int-cpd'].cpd; getRelatedVDUID = e['int-cpd']['vdu-id'];
956 if (posExtCPD !== -1) {
957 this.vnfdPackageDetails['ext-cpd'].splice(posExtCPD, 1);
959 if (getRelatedVDUCPD !== undefined && getRelatedVDUID !== undefined) {
960 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
961 if (vdu.id === getRelatedVDUID) {
962 const posINTCPD: number = vdu['int-cpd'].findIndex((intCPD: VDUINTCPD): boolean => {
963 return intCPD.id === getRelatedVDUCPD;
965 if (posINTCPD !== -1) {
966 vdu['int-cpd'].splice(posINTCPD, 1);
972 } else if (d.type === 'intcp') {
973 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
974 const posINTCPD: number = vdu['int-cpd'].findIndex((intCPD: VDUINTCPD): boolean => {
975 return intCPD.id === d.id;
977 if (posINTCPD !== -1) {
978 vdu['int-cpd'].splice(posINTCPD, 1);
981 } else if (d.type === 'intvl') {
982 const posINTVLD: number = this.vnfdPackageDetails['int-virtual-link-desc'].findIndex((intVLD: IVLD): boolean => {
983 return intVLD.id === d.id;
985 if (posINTVLD !== -1) {
986 this.vnfdPackageDetails['int-virtual-link-desc'].splice(posINTVLD, 1);
988 if (this.vnfdPackageDetails.vdu !== undefined) {
989 this.vnfdPackageDetails.vdu.forEach((vduDetails: VDU): void => {
990 if (vduDetails['int-cpd'] !== undefined) {
991 const newVDUintCPDArray: VDUINTCPD[] = vduDetails['int-cpd'].filter((item: VDUINTCPD): boolean => {
992 return item['int-virtual-link-desc'] !== undefined ? item['int-virtual-link-desc'] !== d.id ? true : false : true;
994 vduDetails['int-cpd'] = newVDUintCPDArray;
998 } else if (d.type === 'vdu') {
999 const getRelatedExtCPD: string[] = [];
1000 const posVDU: number = this.vnfdPackageDetails.vdu.findIndex((vduDetails: VDU): boolean => {
1001 if (vduDetails.id === d.id) {
1002 if (vduDetails['int-cpd'] !== undefined) {
1003 vduDetails['int-cpd'].forEach((intCPDDetails: VDUINTCPD): void => {
1004 if (intCPDDetails['int-virtual-link-desc'] === undefined) {
1005 getRelatedExtCPD.push(intCPDDetails.id);
1014 if (posVDU !== -1) {
1015 this.vnfdPackageDetails.vdu.splice(posVDU, 1);
1017 getRelatedExtCPD.forEach((CPDID: string, index: number): void => {
1018 this.vnfdPackageDetails['ext-cpd'].forEach((extCPD: EXTCPD): void => {
1019 if (extCPD['int-cpd'] !== undefined) {
1020 if (extCPD['int-cpd'].cpd === CPDID) {
1021 delete extCPD['int-cpd'];
1027 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.INVALIDSELECTION'));
1029 this.addNodes(environment.VNFPACKAGES_URL, this.identifier, this.vnfdPackageDetails);
1033 /** Get confirmation before deleting the ink in Topology @private */
1034 private getDeleteLinkConfirmation(d: Tick): void {
1035 this.notifierService.notify('warning', this.translateService.instant('PAGE.VNFPACKAGE.VNFCOMPOSE.YOUCANNOTDELETELINK'));
1037 /** Selected nodes @private */
1038 // tslint:disable-next-line: no-any
1039 private selectedNode(nodeSeleced: any, d: COMPOSERNODES): void {
1040 const alreadyIsActive: boolean = nodeSeleced.select('#' + d.id).classed(this.activeNode);
1041 this.deselectAllNodes();
1042 nodeSeleced.select('#' + d.id).classed(this.activeNode, !alreadyIsActive);
1043 if (d.type === 'vdu' && !alreadyIsActive) {
1044 this.vnfdPackageDetails.vdu.forEach((res: VDU): void => {
1045 if (res.id === d.id) {
1046 this.showRightSideInfo = 'vduInfo';
1048 this.oldVDUID = res.id;
1051 } else if (d.type === 'cp' && !alreadyIsActive) {
1052 this.vnfdPackageDetails['ext-cpd'].forEach((cp: EXTCPD): void => {
1053 const getCPDID: string = cp['int-cpd'] !== undefined ? cp['int-cpd'].cpd : cp.id;
1054 if (getCPDID === d.id) {
1055 this.showRightSideInfo = 'cpInfo';
1057 this.oldCPID = cp.id;
1060 } else if (d.type === 'intvl' && !alreadyIsActive) {
1061 this.vnfdPackageDetails['int-virtual-link-desc'].forEach((ivld: IVLD): void => {
1062 if (ivld.id === d.id) {
1063 this.showRightSideInfo = 'intvlInfo';
1064 this.intvlInfo = ivld;
1065 this.oldintVLID = ivld.id;
1068 } else if (d.type === 'intcp' && !alreadyIsActive) {
1069 this.vnfdPackageDetails.vdu.forEach((vdu: VDU): void => {
1070 vdu['int-cpd'].forEach((intcpd: VDUINTCPD): void => {
1071 if (intcpd.id === d.id) {
1072 if (intcpd['int-virtual-link-desc'] !== undefined) {
1073 intcpd['virtual-network-interface-requirement'].forEach((vnir: VNIR): void => {
1074 this.intcpInfo = vnir;
1075 this.showRightSideInfo = 'intcpInfo';
1082 this.showRightSideInfo = 'vnfdInfo';
1085 /** De-select all the selected nodes @private */
1086 private deselectAllNodes(): void {
1087 this.network.select('image').classed(this.activeNode, false);
1088 this.virutualDeploymentUnit.select('image').classed(this.activeNode, false);
1089 this.connectionPoint.select('image').classed(this.activeNode, false);
1090 this.intConnectionPoint.select('image').classed(this.activeNode, false);
1092 /** Events handles when to drag using filter for the keys @private */
1093 private dragFilter(): boolean {
1094 return d3.event.ctrlKey && !d3.event.button;
1096 /** Events handles when dragstarted @private */
1097 private dragstarted(d: COMPOSERNODES): void {
1101 /** Events handles when dragged @private */
1102 private dragged(d: COMPOSERNODES): void {
1103 d.fx = d.x = d3.event.x;
1104 d.fy = d.y = d3.event.y;
1106 /** Events handles when dragended @private */
1107 private dragended(d: COMPOSERNODES): void {
1108 if (this.forceSimulationActive) {
1114 this.forceSimulationActive = false;
1117 /** Events handles when node double click @private */
1118 private onNodedblClickToggleSidebar(): void {
1119 this.sideBarOpened = false;
1121 /** Events handles when node single click @private */
1122 private onNodeClickToggleSidebar(): void {
1123 this.sideBarOpened = true;