From 16a9fce0e104a38371a9e5a567ec611ae3fc7f33 Mon Sep 17 00:00:00 2001 From: ys9693 Date: Sun, 19 Jan 2020 13:50:02 +0200 Subject: Catalog alignment Issue-ID: SDC-2724 Signed-off-by: ys9693 Change-Id: I52b4aacb58cbd432ca0e1ff7ff1f7dd52099c6fe --- .../graph/utils/composition-graph-nodes-utils.ts | 202 +++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 catalog-ui/src/app/ng2/pages/composition/graph/utils/composition-graph-nodes-utils.ts (limited to 'catalog-ui/src/app/ng2/pages/composition/graph/utils/composition-graph-nodes-utils.ts') diff --git a/catalog-ui/src/app/ng2/pages/composition/graph/utils/composition-graph-nodes-utils.ts b/catalog-ui/src/app/ng2/pages/composition/graph/utils/composition-graph-nodes-utils.ts new file mode 100644 index 0000000000..ea876c6d1a --- /dev/null +++ b/catalog-ui/src/app/ng2/pages/composition/graph/utils/composition-graph-nodes-utils.ts @@ -0,0 +1,202 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +import { Injectable } from '@angular/core'; +import { Component as TopologyTemplate } from 'app/models'; +import { + ComponentInstance, + CompositionCiNodeVl, Service +} from 'app/models'; +import { CompositionCiServicePathLink } from 'app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link'; +import { WorkspaceService } from 'app/ng2/pages/workspace/workspace.service'; +import { ServiceServiceNg2 } from 'app/ng2/services/component-services/service.service'; +import { TopologyTemplateService } from 'app/ng2/services/component-services/topology-template.service'; +import { ServiceGenericResponse } from 'app/ng2/services/responses/service-generic-response'; +import { QueueServiceUtils } from 'app/ng2/utils/queue-service-utils'; +import { EventListenerService } from 'app/services'; +import { GRAPH_EVENTS } from 'app/utils'; +import * as _ from 'lodash'; +import { SdcUiServices } from 'onap-ui-angular'; +import { CompositionService } from '../../composition.service'; +import { CommonGraphUtils } from '../common/common-graph-utils'; +import { CompositionGraphGeneralUtils } from './composition-graph-general-utils'; + +/** + * Created by obarda on 11/9/2016. + */ +@Injectable() +export class CompositionGraphNodesUtils { + constructor(private generalGraphUtils: CompositionGraphGeneralUtils, + private commonGraphUtils: CommonGraphUtils, + private eventListenerService: EventListenerService, + private queueServiceUtils: QueueServiceUtils, + private serviceService: ServiceServiceNg2, + private loaderService: SdcUiServices.LoaderService, + private compositionService: CompositionService, + private topologyTemplateService: TopologyTemplateService, + private workspaceService: WorkspaceService) { + } + + /** + * Returns component instances for all nodes passed in + * @param nodes - Cy nodes + * @returns {any[]} + */ + public getAllNodesData(nodes: Cy.CollectionNodes) { + return _.map(nodes, (node: Cy.CollectionFirstNode) => { + return node.data(); + }); + } + + public highlightMatchingNodesByName = (cy: Cy.Instance, nameToMatch: string) => { + + cy.batch(() => { + cy.nodes("[name !@^= '" + nameToMatch + "']").style({'background-image-opacity': 0.4}); + cy.nodes("[name @^= '" + nameToMatch + "']").style({'background-image-opacity': 1}); + }); + + } + + // Returns all nodes whose name starts with searchTerm + public getMatchingNodesByName = (cy: Cy.Instance, nameToMatch: string): Cy.CollectionNodes => { + return cy.nodes("[name @^= '" + nameToMatch + "']"); + } + + /** + * Deletes component instances on server and then removes it from the graph as well + * @param cy + * @param component + * @param nodeToDelete + */ + public deleteNode(cy: Cy.Instance, component: TopologyTemplate, nodeToDelete: Cy.CollectionNodes): void { + + this.loaderService.activate(); + const onSuccess: (response: ComponentInstance) => void = (response: ComponentInstance) => { + // check whether the node is connected to any VLs that only have one other connection. If so, delete that VL as well + this.loaderService.deactivate(); + this.compositionService.deleteComponentInstance(response.uniqueId); + + const nodeToDeleteIsNotVl = nodeToDelete.data().componentInstance && !(nodeToDelete.data().componentInstance.isVl()); + if (nodeToDeleteIsNotVl) { + const connectedVls: Cy.CollectionFirstNode[] = this.getConnectedVlToNode(nodeToDelete); + this.handleConnectedVlsToDelete(connectedVls); + } + + // check whether there is a service path going through this node, and if so clean it from the graph. + const nodeId = nodeToDelete.data().id; + const connectedPathLinks = cy.collection(`[type="${CompositionCiServicePathLink.LINK_TYPE}"][source="${nodeId}"], [type="${CompositionCiServicePathLink.LINK_TYPE}"][target="${nodeId}"]`); + _.forEach(connectedPathLinks, (link, key) => { + cy.remove(`[pathId="${link.data().pathId}"]`); + }); + + // update service path list + this.serviceService.getComponentCompositionData(component).subscribe((serviceResponse: ServiceGenericResponse) => { + (component as Service).forwardingPaths = serviceResponse.forwardingPaths; + }); + + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE_SUCCESS, nodeId); + + // update UI + cy.remove(nodeToDelete); + }; + + const onFailed: (response: any) => void = (response: any) => { + this.loaderService.deactivate(); + }; + + this.queueServiceUtils.addBlockingUIAction( + () => { + const uniqueId = this.workspaceService.metadata.uniqueId; + const componentType = this.workspaceService.metadata.componentType; + this.topologyTemplateService.deleteComponentInstance(componentType, uniqueId, nodeToDelete.data().componentInstance.uniqueId).subscribe(onSuccess, onFailed); + } + ); + } + + /** + * Finds all VLs connected to a single node + * @param node + * @returns {Array} + */ + public getConnectedVlToNode = (node: Cy.CollectionNodes): Cy.CollectionFirstNode[] => { + const connectedVls: Cy.CollectionFirstNode[] = new Array(); + _.forEach(node.connectedEdges().connectedNodes(), (connectedNode: Cy.CollectionFirstNode) => { + const connectedNodeIsVl = connectedNode.data().componentInstance.isVl(); + if (connectedNodeIsVl) { + connectedVls.push(connectedNode); + } + }); + return connectedVls; + } + + /** + * Delete all VLs that have only two connected nodes (this function is called when deleting a node) + * @param connectedVls + */ + public handleConnectedVlsToDelete = (connectedVls: Cy.CollectionFirstNode[]) => { + _.forEach(connectedVls, (vlToDelete: Cy.CollectionNodes) => { + + if (vlToDelete.connectedEdges().length === 2) { // if vl connected only to 2 nodes need to delete the vl + this.eventListenerService.notifyObservers(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, vlToDelete.data().componentInstance.uniqueId); + } + }); + } + + /** + * This function will update nodes position. + * @param cy + * @param component + * @param nodesMoved - the node/multiple nodes now moved by the user + */ + public onNodesPositionChanged = (cy: Cy.Instance, component: TopologyTemplate, nodesMoved: Cy.CollectionNodes): void => { + + if (nodesMoved.length === 0) { + return; + } + + const isValidMove: boolean = this.generalGraphUtils.isGroupValidDrop(cy, nodesMoved); + if (isValidMove) { + + const instancesToUpdate: ComponentInstance[] = new Array(); + + _.each(nodesMoved, (node: Cy.CollectionFirstNode) => { // update all nodes new position + + // update position + const newPosition: Cy.Position = this.commonGraphUtils.getNodePosition(node); + node.data().componentInstance.updatePosition(newPosition.x, newPosition.y); + instancesToUpdate.push(node.data().componentInstance); + + }); + + if (instancesToUpdate.length > 0) { + this.generalGraphUtils.pushMultipleUpdateComponentInstancesRequestToQueue(instancesToUpdate); + } + } else { + // reset nodes position + nodesMoved.positions((i, node) => { + return { + x: +node.data().componentInstance.posX, + y: +node.data().componentInstance.posY + }; + }); + } + } + +} -- cgit 1.2.3-korg