summaryrefslogtreecommitdiffstats
path: root/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2017-02-19 10:28:42 +0200
committerMichael Lando <ml636r@att.com>2017-02-19 10:51:01 +0200
commit451a3400b76511393c62a444f588a4ed15f4a549 (patch)
treee4f5873a863d1d3e55618eab48b83262f874719d /catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
parent5abfe4e1fb5fae4bbd5fbc340519f52075aff3ff (diff)
Initial OpenECOMP SDC commit
Change-Id: I0924d5a6ae9cdc161ae17c68d3689a30d10f407b Signed-off-by: Michael Lando <ml636r@att.com>
Diffstat (limited to 'catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts')
-rw-r--r--catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts243
1 files changed, 243 insertions, 0 deletions
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
new file mode 100644
index 0000000000..495a243d75
--- /dev/null
+++ b/catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
@@ -0,0 +1,243 @@
+/// <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