diff options
author | Michael Lando <ml636r@att.com> | 2017-06-09 03:19:04 +0300 |
---|---|---|
committer | Michael Lando <ml636r@att.com> | 2017-06-09 03:19:04 +0300 |
commit | ed64b5edff15e702493df21aa3230b81593e6133 (patch) | |
tree | a4cb01fdaccc34930a8db403a3097c0d1e40914b /catalog-ui/app/scripts/directives/graphs-v2/composition-graph | |
parent | 280f8015d06af1f41a3ef12e8300801c7a5e0d54 (diff) |
[SDC-29] catalog 1707 rebase commit.
Change-Id: I43c3dc5cf44abf5da817649bc738938a3e8388c1
Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/app/scripts/directives/graphs-v2/composition-graph')
7 files changed, 0 insertions, 1666 deletions
diff --git a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.directive.ts b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.directive.ts deleted file mode 100644 index 708f1d091a..0000000000 --- a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.directive.ts +++ /dev/null @@ -1,555 +0,0 @@ -/// <reference path="../../../references"/> -module Sdc.Directives { - - import ComponentFactory = Sdc.Utils.ComponentFactory; - import LoaderService = Sdc.Services.LoaderService; - import GRAPH_EVENTS = Sdc.Utils.Constants.GRAPH_EVENTS; - - interface ICompositionGraphScope extends ng.IScope { - - component:Models.Components.Component; - isViewOnly:boolean; - // Link menu - create link menu - relationMenuDirectiveObj:Models.RelationMenuDirectiveObj; - isLinkMenuOpen:boolean; - createLinkFromMenu:(chosenMatch:Models.MatchBase, vl:Models.Components.Component)=>void; - - //modify link menu - for now only delete menu - relationMenuTimeout:ng.IPromise<any>; - linkMenuObject:Models.LinkMenu; - - //left palette functions callbacks - dropCallback(event:JQueryEventObject, ui:any):void; - beforeDropCallback(event:IDragDropEvent):void; - verifyDrop(event:JQueryEventObject, ui:any):void; - - //Links menus - deleteRelation(link:Cy.CollectionEdges):void; - hideRelationMenu(); - } - - export class CompositionGraph implements ng.IDirective { - private _cy:Cy.Instance; - private _currentlyCLickedNodePosition:Cy.Position; - private $document:JQuery = $(document); - private dragElement:JQuery; - private dragComponent: Sdc.Models.ComponentsInstances.ComponentInstance; - - constructor(private $q:ng.IQService, - private $filter:ng.IFilterService, - private $log:ng.ILogService, - private $timeout:ng.ITimeoutService, - private NodesFactory:Sdc.Utils.NodesFactory, - private CompositionGraphLinkUtils:Sdc.Graph.Utils.CompositionGraphLinkUtils, - private GeneralGraphUtils:Graph.Utils.CompositionGraphGeneralUtils, - private ComponentInstanceFactory:Utils.ComponentInstanceFactory, - private NodesGraphUtils:Sdc.Graph.Utils.CompositionGraphNodesUtils, - private eventListenerService:Services.EventListenerService, - private ComponentFactory:ComponentFactory, - private LoaderService:LoaderService, - private commonGraphUtils:Graph.Utils.CommonGraphUtils, - private matchCapabilitiesRequirementsUtils:Graph.Utils.MatchCapabilitiesRequirementsUtils) { - - } - - restrict = 'E'; - templateUrl = '/app/scripts/directives/graphs-v2/composition-graph/composition-graph.html'; - scope = { - component: '=', - isViewOnly: '=' - }; - - link = (scope:ICompositionGraphScope, el:JQuery) => { - this.loadGraph(scope, el); - - scope.$on('$destroy', () => { - this._cy.destroy(); - _.forEach(GRAPH_EVENTS, (event) => { - this.eventListenerService.unRegisterObserver(event); - }); - }); - - }; - - private loadGraph = (scope:ICompositionGraphScope, el:JQuery) => { - - - let graphEl = el.find('.sdc-composition-graph-wrapper'); - this.initGraph(graphEl, scope.isViewOnly); - this.initGraphNodes(scope.component.componentInstances, scope.isViewOnly); - this.commonGraphUtils.initGraphLinks(this._cy, scope.component.componentInstancesRelations); - this.commonGraphUtils.initUcpeChildren(this._cy); - this.initDropZone(scope); - this.registerCytoscapeGraphEvents(scope); - this.registerCustomEvents(scope, el); - this.initViewMode(scope.isViewOnly); - - }; - - private initGraph(graphEl:JQuery, isViewOnly:boolean) { - - this._cy = cytoscape({ - container: graphEl, - style: Sdc.Graph.Utils.ComponentIntanceNodesStyle.getCompositionGraphStyle(), - zoomingEnabled: false, - selectionType: 'single', - boxSelectionEnabled: true, - autolock: isViewOnly, - autoungrabify: isViewOnly - }); - } - - private initViewMode(isViewOnly:boolean) { - - if (isViewOnly) { - //remove event listeners - this._cy.off('drag'); - this._cy.off('handlemouseout'); - this._cy.off('handlemouseover'); - this._cy.edges().unselectify(); - } - }; - - private registerCustomEvents(scope:ICompositionGraphScope, el:JQuery) { - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, (component:Models.DisplayComponent) => { - this.$log.info(`composition-graph::registerEventServiceEvents:: palette hover on component: ${component.uniqueId}`); - - let nodesData = this.NodesGraphUtils.getAllNodesData(this._cy.nodes()); - let nodesLinks = this.GeneralGraphUtils.getAllCompositionCiLinks(this._cy); - - if (this.GeneralGraphUtils.componentRequirementsAndCapabilitiesCaching.containsKey(component.uniqueId)) { - let cacheComponent = this.GeneralGraphUtils.componentRequirementsAndCapabilitiesCaching.getValue(component.uniqueId); - let filteredNodesData = this.matchCapabilitiesRequirementsUtils.findByMatchingCapabilitiesToRequirements(cacheComponent, nodesData, nodesLinks); - - this.matchCapabilitiesRequirementsUtils.highlightMatchingComponents(filteredNodesData, this._cy); - this.matchCapabilitiesRequirementsUtils.fadeNonMachingComponents(filteredNodesData, nodesData, this._cy); - - return; - } - - component.component.updateRequirementsCapabilities() - .then((res) => { - component.component.capabilities = res.capabilities; - component.component.requirements = res.requirements; - - let filteredNodesData = this.matchCapabilitiesRequirementsUtils.findByMatchingCapabilitiesToRequirements(component.component, nodesData, nodesLinks); - this.matchCapabilitiesRequirementsUtils.fadeNonMachingComponents(filteredNodesData, nodesData, this._cy); - this.matchCapabilitiesRequirementsUtils.highlightMatchingComponents(filteredNodesData, this._cy) - }); - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT, () => { - this._cy.emit('hidehandles'); - this.matchCapabilitiesRequirementsUtils.resetFadedNodes(this._cy); - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_START, (dragElement, dragComponent) => { - - this.dragElement = dragElement; - this.dragComponent = this.ComponentInstanceFactory.createComponentInstanceFromComponent(dragComponent); - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_DRAG_ACTION, (event:IDragDropEvent) => { - this._onComponentDrag(event); - - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_COMPONENT_INSTANCE_NAME_CHANGED, (component:Models.ComponentsInstances.ComponentInstance) => { - - let selectedNode = this._cy.getElementById(component.uniqueId); - selectedNode.data().componentInstance.name = component.name; - selectedNode.data('displayName', selectedNode.data().getDisplayName()); - - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, (componentInstance:Models.ComponentsInstances.ComponentInstance) => { - let nodeToDelete = this._cy.getElementById(componentInstance.uniqueId); - this.NodesGraphUtils.deleteNode(this._cy, scope.component, nodeToDelete); - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_MULTIPLE_COMPONENTS, () => { - - this._cy.$('node:selected').each((i:number, node:Cy.CollectionNodes) => { - this.NodesGraphUtils.deleteNode(this._cy, scope.component, node); - }); - - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_DELETE_EDGE, (releaseLoading:boolean, linksToDelete:Cy.CollectionEdges) => { - this.CompositionGraphLinkUtils.deleteLink(this._cy, scope.component, releaseLoading, linksToDelete); - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_INSERT_NODE_TO_UCPE, (node:Cy.CollectionNodes, ucpe:Cy.CollectionNodes, updateExistingNode: boolean) => { - - this.commonGraphUtils.initUcpeChildData(node, ucpe); - //check if item is a VL, and if so, skip adding the binding to ucpe - if(!(node.data() instanceof Sdc.Models.Graph.CompositionCiNodeVl)){ - this.CompositionGraphLinkUtils.createVfToUcpeLink(scope.component, this._cy, ucpe.data(), node.data()); //create link from the node to the ucpe - } - - if(updateExistingNode){ - let vlsPendingDeletion:Cy.CollectionNodes = this.NodesGraphUtils.deleteNodeVLsUponMoveToOrFromUCPE(scope.component, node.cy(), node); //delete connected VLs that no longer have 2 links - this.CompositionGraphLinkUtils.deleteLinksWhenNodeMovedFromOrToUCPE(scope.component, node.cy(), node, vlsPendingDeletion); //delete all connected links if needed - this.GeneralGraphUtils.pushUpdateComponentInstanceActionToQueue(scope.component, true, node.data().componentInstance); //update componentInstance position - } - - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_REMOVE_NODE_FROM_UCPE, (node:Cy.CollectionNodes, ucpe:Cy.CollectionNodes) => { - this.commonGraphUtils.removeUcpeChildData(node); - let vlsPendingDeletion:Cy.CollectionNodes = this.NodesGraphUtils.deleteNodeVLsUponMoveToOrFromUCPE(scope.component, node.cy(), node); - this.CompositionGraphLinkUtils.deleteLinksWhenNodeMovedFromOrToUCPE(scope.component, node.cy(), node, vlsPendingDeletion); //delete all connected links if needed - this.GeneralGraphUtils.pushUpdateComponentInstanceActionToQueue(scope.component, true, node.data().componentInstance); //update componentInstance position - }); - - this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_VERSION_CHANGED, (component:Models.Components.Component) => { - scope.component = component; - this.loadGraph(scope, el); - }); - - - scope.createLinkFromMenu = (chosenMatch:Models.MatchBase, vl:Models.Components.Component):void => { - scope.isLinkMenuOpen = false; - - this.CompositionGraphLinkUtils.createLinkFromMenu(this._cy, chosenMatch, vl, scope.component); - }; - - scope.hideRelationMenu = () => { - this.commonGraphUtils.safeApply(scope, () => { - scope.linkMenuObject = null; - this.$timeout.cancel(scope.relationMenuTimeout); - }); - }; - - - scope.deleteRelation = (link:Cy.CollectionEdges) => { - scope.hideRelationMenu(); - - //if multiple edges selected, delete the VL itself so edges get deleted automatically - if (this._cy.$('edge:selected').length > 1) { - this.NodesGraphUtils.deleteNode(this._cy, scope.component, this._cy.$('node:selected')); - } else { - this.CompositionGraphLinkUtils.deleteLink(this._cy, scope.component, true, link); - } - }; - } - - - private registerCytoscapeGraphEvents(scope:ICompositionGraphScope) { - - this._cy.on('addedgemouseup', (event, data) => { - scope.relationMenuDirectiveObj = this.CompositionGraphLinkUtils.onLinkDrawn(this._cy, data.source, data.target); - if (scope.relationMenuDirectiveObj != null) { - scope.$apply(() => { - scope.isLinkMenuOpen = true; - }); - } - }); - this._cy.on('tapstart', 'node', (event:Cy.EventObject) => { - this._currentlyCLickedNodePosition = angular.copy(event.cyTarget[0].position()); //update node position on drag - if(event.cyTarget.data().isUcpe){ - this._cy.nodes('.ucpe-cp').unlock(); - event.cyTarget.style('opacity', 0.5); - } - }); - - this._cy.on('drag', 'node', (event:Cy.EventObject) => { - - if (event.cyTarget.data().isDraggable) { - event.cyTarget.style({'overlay-opacity': 0.24}); - if (this.GeneralGraphUtils.isValidDrop(this._cy, event.cyTarget)) { - event.cyTarget.style({'overlay-color': Utils.Constants.GraphColors.NODE_BACKGROUND_COLOR}); - } else { - event.cyTarget.style({'overlay-color': Utils.Constants.GraphColors.NODE_OVERLAPPING_BACKGROUND_COLOR}); - } - } - - if(event.cyTarget.data().isUcpe){ - let pos = event.cyTarget.position(); - - this._cy.nodes('[?isInsideGroup]').positions((i, node)=>{ - return { - x: pos.x + node.data("ucpeOffset").x, - y: pos.y + node.data("ucpeOffset").y - } - }); - } - }); - - - this._cy.on('handlemouseover', (event, payload) => { - - if (payload.node.grabbed()) { //no need to add opacity while we are dragging and hovering othe nodes - return; - } - - let nodesData = this.NodesGraphUtils.getAllNodesData(this._cy.nodes()); - let nodesLinks = this.GeneralGraphUtils.getAllCompositionCiLinks(this._cy); - - let linkableNodes = this.commonGraphUtils.getLinkableNodes(this._cy, payload.node); - let filteredNodesData = this.matchCapabilitiesRequirementsUtils.findByMatchingCapabilitiesToRequirements(payload.node.data().componentInstance, linkableNodes, nodesLinks); - this.matchCapabilitiesRequirementsUtils.highlightMatchingComponents(filteredNodesData, this._cy); - this.matchCapabilitiesRequirementsUtils.fadeNonMachingComponents(filteredNodesData, nodesData, this._cy, payload.node.data()); - - }); - - this._cy.on('handlemouseout', () => { - this._cy.emit('hidehandles'); - this.matchCapabilitiesRequirementsUtils.resetFadedNodes(this._cy); - }); - - - this._cy.on('tapend', (event:Cy.EventObject) => { - - if (event.cyTarget === this._cy) { //On Background clicked - if (this._cy.$('node:selected').length === 0) { //if the background click but not dragged - this.eventListenerService.notifyObservers(Sdc.Utils.Constants.GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED); - } - scope.hideRelationMenu(); - } - - else if (event.cyTarget.isEdge()) { //On Edge clicked - if (scope.isViewOnly) return; - this.CompositionGraphLinkUtils.handleLinkClick(this._cy, event); - this.openModifyLinkMenu(scope, this.CompositionGraphLinkUtils.getModifyLinkMenu(event.cyTarget[0], event), 6000); - } - - else { //On Node clicked - this._cy.nodes(':grabbed').style({'overlay-opacity': 0}); - - let isUcpe:boolean = event.cyTarget.data().isUcpe; - let newPosition = event.cyTarget[0].position(); - //node position changed (drop after drag event) - we need to update position - if (this._currentlyCLickedNodePosition.x !== newPosition.x || this._currentlyCLickedNodePosition.y !== newPosition.y) { - let nodesMoved:Cy.CollectionNodes = this._cy.$(':grabbed'); - if(isUcpe){ - nodesMoved = nodesMoved.add(this._cy.nodes('[?isInsideGroup]:free')); //'child' nodes will not be recognized as "grabbed" elements within cytoscape. manually add them to collection of nodes moved. - } - this.NodesGraphUtils.onNodesPositionChanged(this._cy, scope.component, nodesMoved); - } else { - this.$log.debug('composition-graph::onNodeSelectedEvent:: fired'); - scope.$apply(() => { - this.eventListenerService.notifyObservers(Sdc.Utils.Constants.GRAPH_EVENTS.ON_NODE_SELECTED, event.cyTarget.data().componentInstance); - }); - } - - if(isUcpe){ - this._cy.nodes('.ucpe-cp').lock(); - event.cyTarget.style('opacity', 1); - } - - } - }); - - this._cy.on('boxselect', 'node', (event:Cy.EventObject) => { - this.eventListenerService.notifyObservers(Utils.Constants.GRAPH_EVENTS.ON_NODE_SELECTED, event.cyTarget.data().componentInstance); - }); - } - - private openModifyLinkMenu = (scope:ICompositionGraphScope, linkMenuObject:Models.LinkMenu, timeOutInMilliseconds?:number) => { - - this.commonGraphUtils.safeApply(scope, () => { - scope.linkMenuObject = linkMenuObject; - }); - - scope.relationMenuTimeout = this.$timeout(() => { - scope.hideRelationMenu(); - }, timeOutInMilliseconds ? timeOutInMilliseconds : 6000); - }; - - private initGraphNodes(componentInstances:Models.ComponentsInstances.ComponentInstance[], isViewOnly:boolean) { - - if (!isViewOnly) { //Init nodes handle extension - enable dynamic links - setTimeout(()=> { - let handles = new CytoscapeEdgeEditation; - handles.init(this._cy, 18); - handles.registerHandle(Sdc.Graph.Utils.ComponentIntanceNodesStyle.getBasicNodeHanlde()); - handles.registerHandle(Sdc.Graph.Utils.ComponentIntanceNodesStyle.getBasicSmallNodeHandle()); - handles.registerHandle(Sdc.Graph.Utils.ComponentIntanceNodesStyle.getUcpeCpNodeHandle()); - }, 0); - } - - _.each(componentInstances, (instance) => { - let compositionGraphNode:Models.Graph.CompositionCiNodeBase = this.NodesFactory.createNode(instance); - this.commonGraphUtils.addComponentInstanceNodeToGraph(this._cy, compositionGraphNode); - }); - - - - } - - - private initDropZone(scope:ICompositionGraphScope) { - - if (scope.isViewOnly) { - return; - } - scope.dropCallback = (event:IDragDropEvent) => { - this.$log.debug(`composition-graph::dropCallback:: fired`); - this.addNode(event, scope); - }; - - scope.verifyDrop = (event:JQueryEventObject) => { - - if(this.dragElement.hasClass('red')){ - return false; - } - return true; - }; - - scope.beforeDropCallback = (event:IDragDropEvent): ng.IPromise<void> => { - let deferred: ng.IDeferred<void> = this.$q.defer<void>(); - if(this.dragElement.hasClass('red')){ - deferred.reject(); - } else { - deferred.resolve(); - } - - return deferred.promise; - } - } - - private _getNodeBBox(event:IDragDropEvent, position?:Cy.Position) { - let bbox = <Cy.BoundingBox>{}; - if (!position) { - position = this.commonGraphUtils.getCytoscapeNodePosition(this._cy, event); - } - let cushionWidth:number = 40; - let cushionHeight:number = 40; - - bbox.x1 = position.x - cushionWidth / 2; - bbox.y1 = position.y - cushionHeight / 2; - bbox.x2 = position.x + cushionWidth / 2; - bbox.y2 = position.y + cushionHeight / 2; - return bbox; - } - - private createComponentInstanceOnGraphFromComponent(fullComponent:Models.Components.Component, event:IDragDropEvent, scope:ICompositionGraphScope) { - - let componentInstanceToCreate:Models.ComponentsInstances.ComponentInstance = this.ComponentInstanceFactory.createComponentInstanceFromComponent(fullComponent); - let cytoscapePosition:Cy.Position = this.commonGraphUtils.getCytoscapeNodePosition(this._cy, event); - - componentInstanceToCreate.posX = cytoscapePosition.x; - componentInstanceToCreate.posY = cytoscapePosition.y; - - - let onFailedCreatingInstance:(error:any) => void = (error:any) => { - this.LoaderService.hideLoader('composition-graph'); - }; - - //on success - update node data - let onSuccessCreatingInstance = (createInstance:Models.ComponentsInstances.ComponentInstance):void => { - - this.LoaderService.hideLoader('composition-graph'); - - createInstance.name = this.$filter('resourceName')(createInstance.name); - createInstance.requirements = new Models.RequirementsGroup(fullComponent.requirements); - createInstance.capabilities = new Models.CapabilitiesGroup(fullComponent.capabilities); - createInstance.componentVersion = fullComponent.version; - createInstance.icon = fullComponent.icon; - createInstance.setInstanceRC(); - - let newNode:Models.Graph.CompositionCiNodeBase = this.NodesFactory.createNode(createInstance); - let cyNode:Cy.CollectionNodes = this.commonGraphUtils.addComponentInstanceNodeToGraph(this._cy, newNode); - - //check if node was dropped into a UCPE - let ucpe:Cy.CollectionElements = this.commonGraphUtils.isInUcpe(this._cy, cyNode.boundingbox()); - if (ucpe.length > 0) { - this.eventListenerService.notifyObservers(Utils.Constants.GRAPH_EVENTS.ON_INSERT_NODE_TO_UCPE, cyNode, ucpe, false); - } - - }; - - // Create the component instance on server - this.GeneralGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIAction(() => { - scope.component.createComponentInstance(componentInstanceToCreate).then(onSuccessCreatingInstance, onFailedCreatingInstance); - }); - } - - private _onComponentDrag(event:IDragDropEvent) { - - if(event.clientX < Sdc.Utils.Constants.GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET || event.clientY < Sdc.Utils.Constants.GraphUIObjects.DIAGRAM_HEADER_OFFSET){ //hovering over palette. Dont bother computing validity of drop - this.dragElement.removeClass('red'); - return; - } - - let offsetPosition = {x: event.clientX - Sdc.Utils.Constants.GraphUIObjects.DIAGRAM_PALETTE_WIDTH_OFFSET, y: event.clientY - Sdc.Utils.Constants.GraphUIObjects.DIAGRAM_HEADER_OFFSET} - let bbox = this._getNodeBBox(event, offsetPosition); - - if (this.GeneralGraphUtils.isPaletteDropValid(this._cy, bbox, this.dragComponent)) { - this.dragElement.removeClass('red'); - } else { - this.dragElement.addClass('red'); - } - } - - private addNode(event:IDragDropEvent, scope:ICompositionGraphScope) { - this.LoaderService.showLoader('composition-graph'); - - this.$log.debug('composition-graph::addNode:: fired'); - let draggedComponent:Models.Components.Component = event.dataTransfer.component; - - if (this.GeneralGraphUtils.componentRequirementsAndCapabilitiesCaching.containsKey(draggedComponent.uniqueId)) { - this.$log.debug('composition-graph::addNode:: capabilities found in cache, creating component'); - let fullComponent = this.GeneralGraphUtils.componentRequirementsAndCapabilitiesCaching.getValue(draggedComponent.uniqueId); - this.createComponentInstanceOnGraphFromComponent(fullComponent, event, scope); - return; - } - - this.$log.debug('composition-graph::addNode:: capabilities not found, requesting from server'); - this.ComponentFactory.getComponentFromServer(draggedComponent.getComponentSubType(), draggedComponent.uniqueId) - .then((fullComponent:Models.Components.Component) => { - this.createComponentInstanceOnGraphFromComponent(fullComponent, event, scope); - }); - } - - public static factory = ($q, - $filter, - $log, - $timeout, - NodesFactory, - LinksGraphUtils, - GeneralGraphUtils, - ComponentInstanceFactory, - NodesGraphUtils, - EventListenerService, - ComponentFactory, - LoaderService, - CommonGraphUtils, - MatchCapabilitiesRequirementsUtils) => { - return new CompositionGraph( - $q, - $filter, - $log, - $timeout, - NodesFactory, - LinksGraphUtils, - GeneralGraphUtils, - ComponentInstanceFactory, - NodesGraphUtils, - EventListenerService, - ComponentFactory, - LoaderService, - CommonGraphUtils, - MatchCapabilitiesRequirementsUtils); - } - } - - CompositionGraph.factory.$inject = [ - '$q', - '$filter', - '$log', - '$timeout', - 'NodesFactory', - 'CompositionGraphLinkUtils', - 'CompositionGraphGeneralUtils', - 'ComponentInstanceFactory', - 'CompositionGraphNodesUtils', - 'EventListenerService', - 'ComponentFactory', - 'LoaderService', - 'CommonGraphUtils', - 'MatchCapabilitiesRequirementsUtils' - ]; -}
\ No newline at end of file diff --git a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.html b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.html deleted file mode 100644 index 5f2c488341..0000000000 --- a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.html +++ /dev/null @@ -1,22 +0,0 @@ -<loader display="isLoading" loader-type="composition-graph"></loader> -<div class="sdc-composition-graph-wrapper" ng-class="{'view-only':isViewOnly}" - data-drop="true" - data-jqyoui-options="{accept: verifyDrop}" - data-jqyoui-droppable="{onDrop:'dropCallback', beforeDrop: 'beforeDropCallback'}"> -</div> - -<relation-menu relation-menu-directive-obj="relationMenuDirectiveObj" is-link-menu-open="isLinkMenuOpen" - create-relation="createLinkFromMenu" cancel="cancelRelationMenu()"></relation-menu> - - -<div class="w-sdc-canvas-menu" - data-ng-show="linkMenuObject" ng-style="{left: linkMenuObject.position.x, top: linkMenuObject.position.y}" - id="relationMenu"> - - <div class="w-sdc-canvas-menu-content hand" data-ng-click="deleteRelation(linkMenuObject.link)"> - <div class="w-sdc-canvas-menu-content-delete-button"></div> - <!--{{relationComponent.data.relation.relationships[0].relationship.type | relationName }}--> - Delete - </div> - -</div> diff --git a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.less b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.less deleted file mode 100644 index 7b999967b7..0000000000 --- a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.less +++ /dev/null @@ -1,14 +0,0 @@ -composition-graph { - display: block; - - height:100%; - width: 100%; - .sdc-composition-graph-wrapper{ - height:100%; - width: 100%; - } - - &.view-only{ - background-color:rgb(248, 248, 248); - } -}
\ No newline at end of file diff --git a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts deleted file mode 100644 index 495a243d75..0000000000 --- a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts +++ /dev/null @@ -1,243 +0,0 @@ -/// <reference path="../../../../references"/> -module Sdc.Graph.Utils { - - import Dictionary = Sdc.Utils.Dictionary; - - export class CompositionGraphGeneralUtils { - - public componentRequirementsAndCapabilitiesCaching = new Dictionary<string, Models.Components.Component>(); - protected static graphUtilsUpdateQueue: Sdc.Utils.Functions.QueueUtils; - - constructor(private $q: ng.IQService, - private LoaderService: Services.LoaderService, - private commonGraphUtils: Sdc.Graph.Utils.CommonGraphUtils, - private matchCapabilitiesRequirementsUtils: Graph.Utils.MatchCapabilitiesRequirementsUtils) { - CompositionGraphGeneralUtils.graphUtilsUpdateQueue = new Sdc.Utils.Functions.QueueUtils(this.$q); - } - - - /** - * Get the offset for the link creation Menu - * @param point - * @returns {Cy.Position} - */ - public calcMenuOffset: Function = (point: Cy.Position): Cy.Position => { - point.x = point.x + 60; - point.y = point.y + 105; - return point; - }; - - /** - * return the top left position of the link menu - * @param cy - * @param targetNodePosition - * @returns {Cy.Position} - */ - public getLinkMenuPosition = (cy: Cy.Instance, targetNodePosition: Cy.Position) => { - let menuPosition: Cy.Position = this.calcMenuOffset(targetNodePosition); //get the link mid point - if (document.body.scrollHeight < menuPosition.y + Sdc.Utils.Constants.GraphUIObjects.LINK_MENU_HEIGHT + $(document.getElementsByClassName('sdc-composition-graph-wrapper')).offset().top) { // if position menu is overflow bottom - menuPosition.y = document.body.scrollHeight - Sdc.Utils.Constants.GraphUIObjects.TOP_HEADER_HEIGHT - Sdc.Utils.Constants.GraphUIObjects.LINK_MENU_HEIGHT; - } - return menuPosition; - }; - - - /** - * will return true/false if two nodes overlapping - * - * @param graph node - */ - private isNodesOverlapping(node: Cy.CollectionFirstNode, draggedNode: Cy.CollectionFirstNode): boolean { - - let nodeBoundingBox: Cy.BoundingBox = node.renderedBoundingBox(); - let secondNodeBoundingBox: Cy.BoundingBox = draggedNode.renderedBoundingBox(); - - return this.isBBoxOverlapping(nodeBoundingBox, secondNodeBoundingBox); - } - - /** - * Checks whether the bounding boxes of two nodes are overlapping on any side - * @param nodeOneBBox - * @param nodeTwoBBox - * @returns {boolean} - */ - private isBBoxOverlapping(nodeOneBBox: Cy.BoundingBox, nodeTwoBBox: Cy.BoundingBox) { - return (((nodeOneBBox.x1 < nodeTwoBBox.x1 && nodeOneBBox.x2 > nodeTwoBBox.x1) || - (nodeOneBBox.x1 < nodeTwoBBox.x2 && nodeOneBBox.x2 > nodeTwoBBox.x2) || - (nodeTwoBBox.x1 < nodeOneBBox.x1 && nodeTwoBBox.x2 > nodeOneBBox.x2)) && - ((nodeOneBBox.y1 < nodeTwoBBox.y1 && nodeOneBBox.y2 > nodeTwoBBox.y1) || - (nodeOneBBox.y1 < nodeTwoBBox.y2 && nodeOneBBox.y2 > nodeTwoBBox.y2) || - (nodeTwoBBox.y1 < nodeOneBBox.y1 && nodeTwoBBox.y2 > nodeOneBBox.y2))) - } - - - /** - * Checks whether a specific component instance can be hosted on the UCPE instance - * @param cy - Cytoscape instance - * @param fromUcpeInstance - * @param toComponentInstance - * @returns {Models.MatchReqToCapability} - */ - public canBeHostedOn(cy: Cy.Instance, fromUcpeInstance: Models.ComponentsInstances.ComponentInstance, toComponentInstance: Models.ComponentsInstances.ComponentInstance): Models.MatchReqToCapability { - - let matches: Array<Models.MatchBase> = this.matchCapabilitiesRequirementsUtils.getMatchedRequirementsCapabilities(fromUcpeInstance, toComponentInstance, this.getAllCompositionCiLinks(cy)); - let hostedOnMatch: Models.MatchBase = _.find(matches, (match: Models.MatchReqToCapability) => { - return match.requirement.capability.toLowerCase() === 'tosca.capabilities.container'; - }); - - return <Models.MatchReqToCapability>hostedOnMatch; - }; - - - /** - * Checks whether node can be dropped into UCPE - * @param cy - * @param nodeToInsert - * @param ucpeNode - * @returns {boolean} - */ - private isValidDropInsideUCPE(cy: Cy.Instance, nodeToInsert: Models.ComponentsInstances.ComponentInstance, ucpeNode: Models.ComponentsInstances.ComponentInstance): boolean { - - let hostedOnMatch: Models.MatchReqToCapability = this.canBeHostedOn(cy, ucpeNode, nodeToInsert); - let result: boolean = !angular.isUndefined(hostedOnMatch) || nodeToInsert.isVl(); //group validation - return result; - - }; - - - /** - * For drops from palette, checks whether the node can be dropped. If node is being held over another node, check if capable of hosting - * @param cy - * @param pseudoNodeBBox - * @param paletteComponentInstance - * @returns {boolean} - */ - public isPaletteDropValid(cy: Cy.Instance, pseudoNodeBBox: Cy.BoundingBox, paletteComponentInstance:Sdc.Models.ComponentsInstances.ComponentInstance) { - - let componentIsUCPE:boolean = (paletteComponentInstance.capabilities && paletteComponentInstance.capabilities['tosca.capabilities.Container'] && paletteComponentInstance.name.toLowerCase().indexOf('ucpe') > -1); - - if(componentIsUCPE && cy.nodes('[?isUcpe]').length > 0) { //second UCPE not allowed - return false; - } - - let illegalOverlappingNodes = _.filter(cy.nodes("[isSdcElement]"), (graphNode: Cy.CollectionFirstNode) => { - - if(this.isBBoxOverlapping(pseudoNodeBBox, graphNode.renderedBoundingBox())){ - if (!componentIsUCPE && graphNode.data().isUcpe) { - return !this.isValidDropInsideUCPE(cy, paletteComponentInstance, graphNode.data().componentInstance); //if this is valid insert into ucpe, we return false - no illegal overlapping nodes - } - return true; - } - - return false; - }); - - return illegalOverlappingNodes.length === 0; - } - - /** - * will return true/false if a drop of a single node is valid - * - * @param graph node - */ - public isValidDrop(cy: Cy.Instance, draggedNode: Cy.CollectionFirstNode): boolean { - - let illegalOverlappingNodes = _.filter(cy.nodes("[isSdcElement]"), (graphNode: Cy.CollectionFirstNode) => { //all sdc nodes, removing child nodes (childe node allways collaps - - if (draggedNode.data().isUcpe && (graphNode.isChild() || graphNode.data().isInsideGroup)) { //ucpe cps always inside ucpe, no overlapping - return false; - } - if(draggedNode.data().isInsideGroup && (!draggedNode.active() || graphNode.data().isUcpe)) { - return false; - } - - if (!draggedNode.data().isUcpe && !(draggedNode.data() instanceof Sdc.Models.Graph.CompositionCiNodeUcpeCp) && graphNode.data().isUcpe) { //case we are dragging a node into UCPE - let isEntirelyInUCPE:boolean = this.commonGraphUtils.isFirstBoxContainsInSecondBox(draggedNode.renderedBoundingBox(), graphNode.renderedBoundingBox()); - if (isEntirelyInUCPE){ - if(this.isValidDropInsideUCPE(cy, draggedNode.data().componentInstance, graphNode.data().componentInstance)){ //if this is valid insert into ucpe, we return false - no illegal overlapping nodes - return false; - } - } - } - return graphNode.data().id !== draggedNode.data().id && this.isNodesOverlapping(draggedNode, graphNode); - - }); - // return false; - return illegalOverlappingNodes.length === 0; - }; - - /** - * will return true/false if the move of the nodes is valid (no node overlapping and verifying if insert into UCPE is valid) - * - * @param nodesArray - the selected drags nodes - */ - public isGroupValidDrop(cy: Cy.Instance, nodesArray: Cy.CollectionNodes): boolean { - var filterDraggedNodes = nodesArray.filter('[?isDraggable]'); - let isValidDrop = _.every(filterDraggedNodes, (node: Cy.CollectionFirstNode) => { - return this.isValidDrop(cy, node); - - }); - return isValidDrop; - }; - - /** - * get all links in diagram - * @param cy - * @returns {any[]|boolean[]} - */ - public getAllCompositionCiLinks = (cy: Cy.Instance): Array<Models.CompositionCiLinkBase> => { - return _.map(cy.edges("[isSdcElement]"), (edge: Cy.CollectionEdges) => { - return edge.data(); - }); - }; - - - /** - * Get Graph Utils server queue - * @returns {Sdc.Utils.Functions.QueueUtils} - */ - public getGraphUtilsServerUpdateQueue(): Sdc.Utils.Functions.QueueUtils { - return CompositionGraphGeneralUtils.graphUtilsUpdateQueue; - } - ; - - /** - * - * @param blockAction - true/false if this is a block action - * @param instances - * @param component - */ - public pushMultipleUpdateComponentInstancesRequestToQueue = (blockAction: boolean, instances: Array<Models.ComponentsInstances.ComponentInstance>, component: Models.Components.Component): void => { - if (blockAction) { - this.getGraphUtilsServerUpdateQueue().addBlockingUIAction( - () => component.updateMultipleComponentInstances(instances) - ); - } else { - this.getGraphUtilsServerUpdateQueue().addNonBlockingUIAction( - () => component.updateMultipleComponentInstances(instances), - () => this.LoaderService.hideLoader('composition-graph')); - } - }; - - /** - * this function will update component instance data - * @param blockAction - true/false if this is a block action - * @param updatedInstance - */ - public pushUpdateComponentInstanceActionToQueue = (component: Models.Components.Component, blockAction: boolean, updatedInstance: Models.ComponentsInstances.ComponentInstance): void => { - - if (blockAction) { - this.LoaderService.showLoader('composition-graph'); - this.getGraphUtilsServerUpdateQueue().addBlockingUIAction( - () => component.updateComponentInstance(updatedInstance) - ); - } else { - this.getGraphUtilsServerUpdateQueue().addNonBlockingUIAction( - () => component.updateComponentInstance(updatedInstance), - () => this.LoaderService.hideLoader('composition-graph')); - } - }; - } - - CompositionGraphGeneralUtils.$inject = ['$q', 'LoaderService', 'CommonGraphUtils', 'MatchCapabilitiesRequirementsUtils']; -}
\ No newline at end of file diff --git a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts deleted file mode 100644 index 602e6b6def..0000000000 --- a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts +++ /dev/null @@ -1,347 +0,0 @@ -/** - * Created by obarda on 6/28/2016. - */ -/// <reference path="../../../../references"/> -module Sdc.Graph.Utils { - - import ImageCreatorService = Sdc.Utils.ImageCreatorService; - import Module = Sdc.Models.Module; - export class CompositionGraphLinkUtils { - - private p2pVL:Models.Components.Component; - private mp2mpVL:Models.Components.Component; - - constructor(private linksFactory:Sdc.Utils.LinksFactory, - private loaderService:Services.LoaderService, - private generalGraphUtils:Sdc.Graph.Utils.CompositionGraphGeneralUtils, - private leftPaletteLoaderService:Services.Components.LeftPaletteLoaderService, - private componentInstanceFactory:Sdc.Utils.ComponentInstanceFactory, - private nodesFactory:Sdc.Utils.NodesFactory, - private commonGraphUtils: Sdc.Graph.Utils.CommonGraphUtils, - private matchCapabilitiesRequirementsUtils: Graph.Utils.MatchCapabilitiesRequirementsUtils) { - - this.initScopeVls(); - - } - - - /** - * Delete the link on server and then remove it from graph - * @param component - * @param releaseLoading - true/false release the loader when finished - * @param link - the link to delete - */ - public deleteLink = (cy:Cy.Instance, component:Models.Components.Component, releaseLoading:boolean, link:Cy.CollectionEdges) => { - - this.loaderService.showLoader('composition-graph'); - let onSuccessDeleteRelation = (response) => { - cy.remove(link); - }; - - if (!releaseLoading) { - this.generalGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIAction( - () => component.deleteRelation(link.data().relation).then(onSuccessDeleteRelation) - ); - } else { - this.generalGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIActionWithReleaseCallback( - () => component.deleteRelation(link.data().relation).then(onSuccessDeleteRelation), - () => this.loaderService.hideLoader('composition-graph')); - } - }; - - /** - * create the link on server and than draw it on graph - * @param link - the link to create - * @param cy - * @param component - */ - public createLink = (link:Models.CompositionCiLinkBase, cy:Cy.Instance, component:Models.Components.Component):void => { - - this.loaderService.showLoader('composition-graph'); - - let onSuccess:(response:Models.RelationshipModel) => void = (relation:Models.RelationshipModel) => { - link.setRelation(relation); - this.commonGraphUtils.insertLinkToGraph(cy, link); - }; - - link.updateLinkDirection(); - - this.generalGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIActionWithReleaseCallback( - () => component.createRelation(link.relation).then(onSuccess), - () => this.loaderService.hideLoader('composition-graph') - ); - }; - - - public initScopeVls = ():void => { - - let vls = this.leftPaletteLoaderService.getFullDataComponentList(Sdc.Utils.Constants.ResourceType.VL); - vls.forEach((item) => { - let key = _.find(Object.keys(item.capabilities), (key) => { - return _.includes(key.toLowerCase(), 'linkable'); - }); - let linkable = item.capabilities[key]; - if (linkable) { - if (linkable[0].maxOccurrences == '2') { - this.p2pVL = _.find(vls, (component:Models.Components.Component) => { - return component.uniqueId === item.uniqueId; - }); - - } else {//assuming unbounded occurrences - this.mp2mpVL = _.find(vls, (component:Models.Components.Component) => { - return component.uniqueId === item.uniqueId; - }); - } - } - }); - }; - - private setVLlinks = (match:Models.MatchReqToReq, vl:Models.ComponentsInstances.ComponentInstance):Array<Models.RelationshipModel> => { - - let relationship1 = new Models.Relationship(); - let relationship2 = new Models.Relationship(); - let newRelationshipModel1 = new Models.RelationshipModel(); - let newRelationshipModel2 = new Models.RelationshipModel(); - - let capability:Models.Capability = vl.capabilities.findValueByKey('linkable')[0]; - relationship1.setRelationProperties(capability, match.requirement); - relationship2.setRelationProperties(capability, match.secondRequirement); - - newRelationshipModel1.setRelationshipModelParams(match.fromNode, vl.uniqueId, [relationship1]); - newRelationshipModel2.setRelationshipModelParams(match.toNode, vl.uniqueId, [relationship2]); - - return [newRelationshipModel1, newRelationshipModel2]; - }; - - private createVlinks = (cy:Cy.Instance, component:Models.Components.Component, matchReqToReq:Models.MatchReqToReq, vl:Models.Components.Component):void => { - - let componentInstance:Models.ComponentsInstances.ComponentInstance = this.componentInstanceFactory.createComponentInstanceFromComponent(vl); - let fromNodePosition:Cy.Position = cy.getElementById(matchReqToReq.fromNode).relativePosition(); - let toNodePosition:Cy.Position = cy.getElementById(matchReqToReq.toNode).relativePosition(); - let location:Cy.Position = { - x: 0.5 * (fromNodePosition.x + toNodePosition.x), - y: 0.5 * (fromNodePosition.y + toNodePosition.y) - } - - componentInstance.posX = location.x; - componentInstance.posY = location.y; - - let onFailed:(error:any) => void = (error:any) => { - this.loaderService.hideLoader('composition-graph'); - console.info('onFailed', error); - }; - - let onSuccess = (response:Models.ComponentsInstances.ComponentInstance):void => { - - console.info('onSuccses', response); - response.requirements = new Models.RequirementsGroup(vl.requirements); - response.capabilities = new Models.CapabilitiesGroup(vl.capabilities); - response.componentVersion = vl.version; - response.setInstanceRC(); - - let newLinks = this.setVLlinks(matchReqToReq, response); - let newNode = this.nodesFactory.createNode(response); - - this.commonGraphUtils.addComponentInstanceNodeToGraph(cy, newNode); - - _.forEach(newLinks, (link) => { - let linkObg:Models.CompositionCiLinkBase = this.linksFactory.createGraphLink(cy, link, link.relationships[0]); - this.createLink(linkObg, cy, component); - }); - }; - component.createComponentInstance(componentInstance).then(onSuccess, onFailed); - }; - - private createSimpleLink = (match:Models.MatchReqToCapability, cy:Cy.Instance, component:Models.Components.Component):void => { - let newRelation:Models.RelationshipModel = match.matchToRelationModel(); - let linkObg:Models.CompositionCiLinkBase = this.linksFactory.createGraphLink(cy,newRelation, newRelation.relationships[0]); - this.createLink(linkObg, cy, component); - }; - - public createLinkFromMenu = (cy:Cy.Instance, chosenMatch:Models.MatchBase, vl:Models.Components.Component, component:Models.Components.Component):void => { - - if (chosenMatch) { - if (chosenMatch && chosenMatch instanceof Models.MatchReqToReq) { - this.createVlinks(cy, component, chosenMatch, vl); //TODO orit implement - } - if (chosenMatch && chosenMatch instanceof Models.MatchReqToCapability) { - this.createSimpleLink(chosenMatch, cy, component); - } - } - }; - - - /** - * Filters the matches for UCPE links so that shown requirements and capabilites are only related to the selected ucpe-cp - * @param fromNode - * @param toNode - * @param matchesArray - * @returns {Array<Models.MatchBase>} - */ - public filterUcpeLinks(fromNode: Models.Graph.CompositionCiNodeBase, toNode: Models.Graph.CompositionCiNodeBase, matchesArray: Array<Models.MatchBase>): any { - - let matchLink: Array<Models.MatchBase>; - - if (fromNode.isUcpePart) { - matchLink = _.filter(matchesArray, (match: Models.MatchBase) => { - return match.isOwner(fromNode.id); - }); - } - - if (toNode.isUcpePart) { - matchLink = _.filter(matchesArray, (match: Models.MatchBase) => { - return match.isOwner(toNode.id); - }); - } - return matchLink ? matchLink : matchesArray; - } - - - /** - * open the connect link menu if the link drawn is valid - match requirements & capabilities - * @param cy - * @param fromNode - * @param toNode - * @returns {any} - */ - public onLinkDrawn(cy:Cy.Instance, fromNode:Cy.CollectionFirstNode, toNode:Cy.CollectionFirstNode):Models.RelationMenuDirectiveObj { - - if(!this.commonGraphUtils.nodeLocationsCompatible(cy, fromNode, toNode)){ return null; } - let linkModel:Array<Models.CompositionCiLinkBase> = this.generalGraphUtils.getAllCompositionCiLinks(cy); - - let possibleRelations:Array<Models.MatchBase> = this.matchCapabilitiesRequirementsUtils.getMatchedRequirementsCapabilities(fromNode.data().componentInstance, - toNode.data().componentInstance, linkModel, this.mp2mpVL); //TODO orit - add p2p and mp2mp - - //filter relations found to limit to specific ucpe-cp - possibleRelations = this.filterUcpeLinks(fromNode.data(), toNode.data(), possibleRelations); - - //if found possibleRelations between the nodes we create relation menu directive and open the link menu - if (possibleRelations.length) { - let menuPosition = this.generalGraphUtils.getLinkMenuPosition(cy, toNode.renderedPoint()); - return new Models.RelationMenuDirectiveObj(fromNode.data(), toNode.data(), this.mp2mpVL, this.p2pVL, menuPosition, possibleRelations); - } - return null; - }; - - - /** - * when we drag instance in to UCPE or out of UCPE - get all links we need to delete - one node in ucpe and one node outside of ucpe - * @param node - the node we dragged into or out of the ucpe - */ - public deleteLinksWhenNodeMovedFromOrToUCPE(component:Models.Components.Component, cy:Cy.Instance, nodeMoved:Cy.CollectionNodes, vlsPendingDeletion?:Cy.CollectionNodes):void { - - - let linksToDelete:Cy.CollectionElements = cy.collection(); - _.forEach(nodeMoved.neighborhood('node'), (neighborNode)=>{ - - if(neighborNode.data().isUcpePart){ //existing connections to ucpe or ucpe-cp - we want to delete even though nodeLocationsCompatible will technically return true - linksToDelete = linksToDelete.add(nodeMoved.edgesWith(neighborNode)); // This will delete the ucpe-host-link, or the vl-ucpe-link if nodeMoved is vl - } else if(!this.commonGraphUtils.nodeLocationsCompatible(cy, nodeMoved, neighborNode)){ //connection to regular node or vl - check if locations are compatible - if(!vlsPendingDeletion || !vlsPendingDeletion.intersect(neighborNode).length){ //Check if this is a link to a VL pending deletion, to prevent double deletion of between the node moved and vl - linksToDelete = linksToDelete.add(nodeMoved.edgesWith(neighborNode)); - } - } - }); - - - - linksToDelete.each((i, link)=>{ - this.deleteLink(cy, component, false, link); - }); - - }; - - - /** - * Creates a hostedOn link between a VF and UCPE - * @param component - * @param cy - * @param ucpeNode - * @param vfNode - */ - public createVfToUcpeLink = (component: Models.Components.Component, cy:Cy.Instance, ucpeNode:Models.Graph.NodeUcpe, vfNode:Models.Graph.CompositionCiNodeVf):void => { - let hostedOnMatch:Models.MatchReqToCapability = this.generalGraphUtils.canBeHostedOn(cy, ucpeNode.componentInstance, vfNode.componentInstance); - /* create relation */ - let newRelation = new Models.RelationshipModel(); - newRelation.fromNode = ucpeNode.id; - newRelation.toNode = vfNode.id; - - let link:Models.CompositionCiLinkBase = this.linksFactory.createUcpeHostLink(newRelation); - link.relation = hostedOnMatch.matchToRelationModel(); - this.createLink(link, cy, component); - }; - - - /** - * Handles click event on links. - * If one edge selected: do nothing. - /*Two edges selected - always select all - /* Three or more edges: first click - select all, secondary click - select single. - * @param cy - * @param event - */ - public handleLinkClick(cy:Cy.Instance, event : Cy.EventObject) { - if(cy.$('edge:selected').length > 2 && event.cyTarget[0].selected()) { - cy.$(':selected').unselect(); - } else { - - let vl: Cy.CollectionNodes = event.cyTarget[0].target('.vl-node'); - let connectedEdges:Cy.CollectionEdges = vl.connectedEdges(); - if (vl.length && connectedEdges.length > 1) { - - setTimeout(() => { - vl.select(); - connectedEdges.select(); - }, 0); - } - } - - } - - - /** - * Calculates the position for the menu that modifies an existing link - * @param event - * @param elementWidth - * @param elementHeight - * @returns {Sdc.Models.Graph.Point} - */ - public calculateLinkMenuPosition(event, elementWidth, elementHeight): Sdc.Models.Graph.Point { - let point: Sdc.Models.Graph.Point = new Sdc.Models.Graph.Point(event.originalEvent.x,event.originalEvent.y); - if(event.originalEvent.view.screen.height-elementHeight<point.y){ - point.y = event.originalEvent.view.screen.height-elementHeight; - } - if(event.originalEvent.view.screen.width-elementWidth<point.x){ - point.x = event.originalEvent.view.screen.width-elementWidth; - } - return point; - }; - - - /** - * Gets the menu that is displayed when you click an existing link. - * @param link - * @param event - * @returns {Models.LinkMenu} - */ - public getModifyLinkMenu(link:Cy.CollectionFirstEdge, event:Cy.EventObject):Models.LinkMenu{ - let point:Sdc.Models.Graph.Point = this.calculateLinkMenuPosition(event,Sdc.Utils.Constants.GraphUIObjects.MENU_LINK_VL_WIDTH_OFFSET,Sdc.Utils.Constants.GraphUIObjects.MENU_LINK_VL_HEIGHT_OFFSET); - let menu:Models.LinkMenu = new Models.LinkMenu(point, true, link); - return menu; - }; - - } - - - - CompositionGraphLinkUtils.$inject = [ - 'LinksFactory', - 'LoaderService', - 'CompositionGraphGeneralUtils', - 'LeftPaletteLoaderService', - 'ComponentInstanceFactory', - 'NodesFactory', - 'CommonGraphUtils', - 'MatchCapabilitiesRequirementsUtils' - ]; -}
\ No newline at end of file diff --git a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts deleted file mode 100644 index 95c31d16b1..0000000000 --- a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts +++ /dev/null @@ -1,220 +0,0 @@ -/** - * Created by obarda on 11/9/2016. - */ - -/// <reference path="../../../../references"/> -module Sdc.Graph.Utils { - - export class CompositionGraphNodesUtils { - constructor(private NodesFactory:Sdc.Utils.NodesFactory, private $log:ng.ILogService, - private GeneralGraphUtils:Graph.Utils.CompositionGraphGeneralUtils, - private commonGraphUtils: Sdc.Graph.Utils.CommonGraphUtils, - private eventListenerService: Services.EventListenerService, - private loaderService:Services.LoaderService) { - - } - - /** - * 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(); - }) - }; - - /** - * 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:Models.Components.Component, nodeToDelete:Cy.CollectionNodes):void { - - this.loaderService.showLoader('composition-graph'); - let onSuccess:(response:Models.ComponentsInstances.ComponentInstance) => void = (response:Models.ComponentsInstances.ComponentInstance) => { - console.info('onSuccess', response); - - //if node to delete is a UCPE, remove all children (except UCPE-CPs) and remove their "hostedOn" links - if (nodeToDelete.data().isUcpe){ - _.each(cy.nodes('[?isInsideGroup]'), (node)=>{ - this.eventListenerService.notifyObservers(Sdc.Utils.Constants.GRAPH_EVENTS.ON_REMOVE_NODE_FROM_UCPE, node, nodeToDelete); - }); - } - - //check whether the node is connected to any VLs that only have one other connection. If so, delete that VL as well - if(!(nodeToDelete.data() instanceof Sdc.Models.Graph.CompositionCiNodeVl)){ - let connectedVls:Array<Cy.CollectionFirstNode> = this.getConnectedVlToNode(nodeToDelete); - this.handleConnectedVlsToDelete(connectedVls); - } - - //update UI - cy.remove(nodeToDelete); - - }; - - let onFailed:(response:any) => void = (response:any) => { - console.info('onFailed', response); - }; - - - this.GeneralGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIActionWithReleaseCallback( - () => component.deleteComponentInstance(nodeToDelete.data().componentInstance.uniqueId).then(onSuccess, onFailed), - () => this.loaderService.hideLoader('composition-graph') - ); - - }; - - - /** - * Finds all VLs connected to a single node - * @param node - * @returns {Array<Cy.CollectionFirstNode>} - */ - public getConnectedVlToNode = (node: Cy.CollectionNodes): Array<Cy.CollectionFirstNode> => { - let connectedVls: Array<Cy.CollectionFirstNode> = new Array<Cy.CollectionFirstNode>(); - _.forEach(node.connectedEdges().connectedNodes(), (node: Cy.CollectionFirstNode) => { - if (node.data() instanceof Models.Graph.CompositionCiNodeVl) { - connectedVls.push(node); - } - }); - return connectedVls; - }; - - - /** - * Delete all VLs that have only two connected nodes (this function is called when deleting a node) - * @param connectedVls - */ - public handleConnectedVlsToDelete = (connectedVls: Array<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(Sdc.Utils.Constants.GRAPH_EVENTS.ON_DELETE_COMPONENT_INSTANCE, vlToDelete.data().componentInstance); - } - }); - }; - - - /** - * This function is called when moving a node in or out of UCPE. - * Deletes all connected VLs that have less than 2 valid connections remaining after the move - * Returns the collection of vls that are in the process of deletion (async) to prevent duplicate calls while deletion is in progress - * @param component - * @param cy - * @param node - node that was moved in/out of ucpe - */ - public deleteNodeVLsUponMoveToOrFromUCPE = (component:Models.Components.Component, cy:Cy.Instance, node:Cy.CollectionNodes):Cy.CollectionNodes =>{ - if(node.data() instanceof Models.Graph.CompositionCiNodeVl){ return;} - - let connectedVLsToDelete:Cy.CollectionNodes = cy.collection(); - _.forEach(node.neighborhood('node'), (connectedNode) => { - - //Find all neighboring nodes that are VLs - if(connectedNode.data() instanceof Models.Graph.CompositionCiNodeVl){ - - //check VL's neighbors to see if it has 2 or more nodes whose location is compatible with VL (regardless of whether VL is in or out of UCPE) - let compatibleNodeCount = 0; - let vlNeighborhood = connectedNode.neighborhood('node'); - _.forEach(vlNeighborhood, (vlNeighborNode)=>{ - if(this.commonGraphUtils.nodeLocationsCompatible(cy, connectedNode, vlNeighborNode)) { - compatibleNodeCount ++; - } - }); - - if(compatibleNodeCount < 2) { - connectedVLsToDelete = connectedVLsToDelete.add(connectedNode); - } - } - }); - - connectedVLsToDelete.each((i, vlToDelete:Cy.CollectionNodes)=>{ - this.deleteNode(cy, component, vlToDelete); - }); - return connectedVLsToDelete; - }; - - /** - * This function will update nodes position. if the new position is into or out of ucpe, the node will trigger the ucpe events - * @param cy - * @param component - * @param nodesMoved - the node/multiple nodes now moved by the user - */ - public onNodesPositionChanged = (cy: Cy.Instance, component:Models.Components.Component, nodesMoved: Cy.CollectionNodes): void => { - - if (nodesMoved.length === 0) { - return; - } - - let isValidMove:boolean = this.GeneralGraphUtils.isGroupValidDrop(cy, nodesMoved); - if (isValidMove) { - - this.$log.debug(`composition-graph::ValidDrop:: updating node position`); - let instancesToUpdateInNonBlockingAction:Array<Models.ComponentsInstances.ComponentInstance> = new Array<Models.ComponentsInstances.ComponentInstance>(); - - _.each(nodesMoved, (node:Cy.CollectionFirstNode)=> { //update all nodes new position - - if(node.data().isUcpePart && !node.data().isUcpe){ return; }//No need to update UCPE-CPs - - //update position - let newPosition:Cy.Position = this.commonGraphUtils.getNodePosition(node); - node.data().componentInstance.updatePosition(newPosition.x, newPosition.y); - - //check if node moved to or from UCPE - let ucpe = this.commonGraphUtils.isInUcpe(node.cy(), node.boundingbox()); - if(node.data().isInsideGroup || ucpe.length) { - this.handleUcpeChildMove(node, ucpe, instancesToUpdateInNonBlockingAction); - } else { - instancesToUpdateInNonBlockingAction.push(node.data().componentInstance); - } - - }); - - if (instancesToUpdateInNonBlockingAction.length > 0) { - this.GeneralGraphUtils.pushMultipleUpdateComponentInstancesRequestToQueue(false, instancesToUpdateInNonBlockingAction, component); - } - } else { - this.$log.debug(`composition-graph::notValidDrop:: node return to latest position`); - //reset nodes position - nodesMoved.positions((i, node) => { - return { - x: +node.data().componentInstance.posX, - y: +node.data().componentInstance.posY - }; - }) - } - - this.GeneralGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIActionWithReleaseCallback(() => { - }, () => { - this.loaderService.hideLoader('composition-graph'); - }); - - }; - - /** - * Checks whether the node has been added or removed from UCPE and triggers appropriate events - * @param node - node moved - * @param ucpeContainer - UCPE container that the node has been moved to. When moving a node out of ucpe, param will be empty - * @param instancesToUpdateInNonBlockingAction - */ - public handleUcpeChildMove(node:Cy.CollectionFirstNode, ucpeContainer:Cy.CollectionElements, instancesToUpdateInNonBlockingAction:Array<Models.ComponentsInstances.ComponentInstance>){ - - if(node.data().isInsideGroup){ - if(ucpeContainer.length){ //moving node within UCPE. Simply update position - this.commonGraphUtils.updateUcpeChildPosition(<Cy.CollectionNodes>node, ucpeContainer); - instancesToUpdateInNonBlockingAction.push(node.data().componentInstance); - } else { //removing node from UCPE. Notify observers - this.eventListenerService.notifyObservers(Sdc.Utils.Constants.GRAPH_EVENTS.ON_REMOVE_NODE_FROM_UCPE, node, ucpeContainer); - } - } else if(!node.data().isInsideGroup && ucpeContainer.length && !node.data().isUcpePart){ //adding node to UCPE - this.eventListenerService.notifyObservers(Sdc.Utils.Constants.GRAPH_EVENTS.ON_INSERT_NODE_TO_UCPE, node, ucpeContainer, true); - } - } - - } - - - CompositionGraphNodesUtils.$inject = ['NodesFactory', '$log', 'CompositionGraphGeneralUtils', 'CommonGraphUtils', 'EventListenerService', 'LoaderService']; -}
\ No newline at end of file diff --git a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts deleted file mode 100644 index 5a401df317..0000000000 --- a/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts +++ /dev/null @@ -1,265 +0,0 @@ -/** - * Created by obarda on 1/1/2017. - */ -/// <reference path="../../../../references"/> -module Sdc.Graph.Utils { - - export class MatchCapabilitiesRequirementsUtils { - - constructor() { - } - - - - public static linkable(requirement1:Models.Requirement, requirement2:Models.Requirement, vlCapability:Models.Capability):boolean { - return MatchCapabilitiesRequirementsUtils.isMatch(requirement1, vlCapability) && MatchCapabilitiesRequirementsUtils.isMatch(requirement2, vlCapability); - }; - - - /** - * Shows + icon in corner of each node passed in - * @param filteredNodesData - * @param cy - */ - public highlightMatchingComponents(filteredNodesData, cy:Cy.Instance) { - _.each(filteredNodesData, (data:any) => { - let node = cy.getElementById(data.id); - cy.emit('showhandle', [node]); - }); - } - - /** - * Adds opacity to each node that cannot be linked to hovered node - * @param filteredNodesData - * @param nodesData - * @param cy - * @param hoveredNodeData - */ - public fadeNonMachingComponents(filteredNodesData, nodesData, cy:Cy.Instance, hoveredNodeData?) { - let fadeNodes = _.xorWith(nodesData, filteredNodesData, (node1, node2) => { - return node1.id === node2.id; - }); - if (hoveredNodeData) { - _.remove(fadeNodes, hoveredNodeData); - } - cy.batch(()=> { - _.each(fadeNodes, (node) => { - cy.getElementById(node.id).style({'background-image-opacity': 0.4}); - }); - }) - } - - /** - * Resets all nodes to regular opacity - * @param cy - */ - public resetFadedNodes(cy:Cy.Instance) { - cy.batch(()=> { - cy.nodes().style({'background-image-opacity': 1}); - }) - } - - // -------------------------------------------ALL FUNCTIONS NEED REFACTORING---------------------------------------------------------------// - - private static requirementFulfilled(fromNodeId:string, requirement:any, links:Array<Models.CompositionCiLinkBase>):boolean { - return _.some(links, { - 'relation': { - 'fromNode': fromNodeId, - 'relationships': [{ - 'requirementOwnerId': requirement.ownerId, - 'requirement': requirement.name, - 'relationship': { - 'type': requirement.relationship - } - } - ] - } - }); - }; - - private static isMatch(requirement:Models.Requirement, capability:Models.Capability):boolean { - if (capability.type === requirement.capability) { - if (requirement.node) { - if (_.includes(capability.capabilitySources, requirement.node)) { - return true; - } - } else { - return true; - } - } - return false; - }; - - private getFromToMatches(requirements1:Models.RequirementsGroup, - requirements2:Models.RequirementsGroup, - capabilities:Models.CapabilitiesGroup, - links:Array<Models.CompositionCiLinkBase>, - fromId:string, - toId:string, - vlCapability?:Models.Capability):Array<Models.MatchBase> { - let matches:Array<Models.MatchBase> = new Array<Models.MatchBase>(); - _.forEach(requirements1, (requirementValue:Array<Models.Requirement>, key) => { - _.forEach(requirementValue, (requirement:Models.Requirement) => { - if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromId, requirement, links)) { - _.forEach(capabilities, (capabilityValue:Array<Models.Capability>, key) => { - _.forEach(capabilityValue, (capability:Models.Capability) => { - if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) { - let match:Models.MatchReqToCapability = new Models.MatchReqToCapability(requirement, capability, true, fromId, toId); - matches.push(match); - } - }); - }); - if (vlCapability) { - _.forEach(requirements2, (requirement2Value:Array<Models.Requirement>, key) => { - _.forEach(requirement2Value, (requirement2:Models.Requirement) => { - if (!MatchCapabilitiesRequirementsUtils.requirementFulfilled(toId, requirement2, links) && MatchCapabilitiesRequirementsUtils.linkable(requirement, requirement2, vlCapability)) { - let match:Models.MatchReqToReq = new Models.MatchReqToReq(requirement, requirement2, true, fromId, toId); - matches.push(match); - } - }); - }); - } - } - }); - }); - return matches; - } - - private getToFromMatches(requirements:Models.RequirementsGroup, capabilities:Models.CapabilitiesGroup, links:Array<Models.CompositionCiLinkBase>, fromId:string, toId:string):Array<Models.MatchReqToCapability> { - let matches:Array<Models.MatchReqToCapability> = []; - _.forEach(requirements, (requirementValue:Array<Models.Requirement>, key) => { - _.forEach(requirementValue, (requirement:Models.Requirement) => { - if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(toId, requirement, links)) { - _.forEach(capabilities, (capabilityValue:Array<Models.Capability>, key) => { - _.forEach(capabilityValue, (capability:Models.Capability) => { - if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) { - let match:Models.MatchReqToCapability = new Models.MatchReqToCapability(requirement, capability, false, toId, fromId); - matches.push(match); - } - }); - }); - } - }); - }); - return matches; - } - - public getMatchedRequirementsCapabilities(fromComponentInstance:Models.ComponentsInstances.ComponentInstance, - toComponentInstance:Models.ComponentsInstances.ComponentInstance, - links:Array<Models.CompositionCiLinkBase>, - vl?:Models.Components.Component):Array<Models.MatchBase> {//TODO allow for VL array - let linkCapability; - if (vl) { - let linkCapabilities:Array<Models.Capability> = vl.capabilities.findValueByKey('linkable'); - if (linkCapabilities) { - linkCapability = linkCapabilities[0]; - } - } - let fromToMatches:Array<Models.MatchBase> = this.getFromToMatches(fromComponentInstance.requirements, - toComponentInstance.requirements, - toComponentInstance.capabilities, - links, - fromComponentInstance.uniqueId, - toComponentInstance.uniqueId, - linkCapability); - let toFromMatches:Array<Models.MatchReqToCapability> = this.getToFromMatches(toComponentInstance.requirements, - fromComponentInstance.capabilities, - links, - fromComponentInstance.uniqueId, - toComponentInstance.uniqueId); - - return fromToMatches.concat(toFromMatches); - } - - - - - - /** - * Step I: Check if capabilities of component match requirements of nodeDataArray - * 1. Get component capabilities and loop on each capability - * 2. Inside the loop, perform another loop on all nodeDataArray, and fetch the requirements for each one - * 3. Loop on the requirements, and verify match (see in code the rules) - * - * Step II: Check if requirements of component match capabilities of nodeDataArray - * 1. Get component requirements and loop on each requirement - * 2. - * - * @param component - this is the hovered resource of the left panel of composition screen - * @param nodeDataArray - Array of resource instances that are on the canvas - * @param links -getMatchedRequirementsCapabilities - * @param vl - - * @returns {any[]|T[]} - */ - public findByMatchingCapabilitiesToRequirements(component:Models.Components.Component, - nodeDataArray:Array<Models.Graph.CompositionCiNodeBase>, - links:Array<Models.CompositionCiLinkBase>, - vl?:Models.Components.Component):Array<any> {//TODO allow for VL array - let res = []; - - // STEP I - { - let capabilities:any = component.capabilities; - _.forEach(capabilities, (capabilityValue:Array<any>, capabilityKey)=> { - _.forEach(capabilityValue, (capability)=> { - _.forEach(nodeDataArray, (node:Models.Graph.CompositionCiNodeBase)=> { - if (node && node.componentInstance) { - let requirements:any = node.componentInstance.requirements; - let fromNodeId:string = node.componentInstance.uniqueId; - _.forEach(requirements, (requirementValue:Array<any>, requirementKey)=> { - _.forEach(requirementValue, (requirement)=> { - if (requirement.name !== "dependency" && MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability) - && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromNodeId, requirement, links)) { - res.push(node); - } - }); - }); - } - }); - }); - }); - } - - // STEP II - { - let requirements:any = component.requirements; - let fromNodeId:string = component.uniqueId; - let linkCapability:Array<Models.Capability> = vl ? vl.capabilities.findValueByKey('linkable') : undefined; - - _.forEach(requirements, (requirementValue:Array<any>, requirementKey)=> { - _.forEach(requirementValue, (requirement)=> { - if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.requirementFulfilled(fromNodeId, requirement, links)) { - _.forEach(nodeDataArray, (node:any)=> { - if (node && node.componentInstance && node.category !== 'groupCp') { - let capabilities:any = node.componentInstance.capabilities; - _.forEach(capabilities, (capabilityValue:Array<any>, capabilityKey)=> { - _.forEach(capabilityValue, (capability)=> { - if (MatchCapabilitiesRequirementsUtils.isMatch(requirement, capability)) { - res.push(node); - } - }); - }); - if (linkCapability) { - let linkRequirements = node.componentInstance.requirements; - _.forEach(linkRequirements, (value:Array<any>, key)=> { - _.forEach(value, (linkRequirement)=> { - if (!MatchCapabilitiesRequirementsUtils.requirementFulfilled(node.componentInstance.uniqueId, linkRequirement, links) - && MatchCapabilitiesRequirementsUtils.linkable(requirement, linkRequirement, linkCapability[0])) { - res.push(node); - } - }); - }); - } - } - }); - } - }); - }); - } - - return _.uniq(res); - }; - } - - MatchCapabilitiesRequirementsUtils.$inject = []; -}
\ No newline at end of file |