aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/directives/graphs-v2
diff options
context:
space:
mode:
authorMichael Lando <ml636r@att.com>2018-03-04 14:53:33 +0200
committerMichael Lando <ml636r@att.com>2018-03-07 13:19:05 +0000
commita5445100050e49e83f73424198d73cd72d672a4d (patch)
treecacf4df817df31be23e4e790d1dda857bdae061e /catalog-ui/src/app/directives/graphs-v2
parent51157f92c21976cba4914c378aaa3cba49826931 (diff)
Sync Integ to Master
Change-Id: I71e3acc26fa612127756ac04073a522b9cc6cd74 Issue-ID: SDC-977 Signed-off-by: Gitelman, Tal (tg851x) <tg851x@intl.att.com>
Diffstat (limited to 'catalog-ui/src/app/directives/graphs-v2')
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/common/common-graph-utils.ts251
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts22
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts225
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html33
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less24
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts1
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts41
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts28
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts80
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts55
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts3
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts3
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts1
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts97
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/palette/palette.html18
-rw-r--r--catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts1
16 files changed, 643 insertions, 240 deletions
diff --git a/catalog-ui/src/app/directives/graphs-v2/common/common-graph-utils.ts b/catalog-ui/src/app/directives/graphs-v2/common/common-graph-utils.ts
index 2a7fd74e53..81d41509e7 100644
--- a/catalog-ui/src/app/directives/graphs-v2/common/common-graph-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/common/common-graph-utils.ts
@@ -18,8 +18,11 @@
* ============LICENSE_END=========================================================
*/
+import * as _ from "lodash";
import {CommonNodeBase, CompositionCiLinkBase, RelationshipModel, Relationship, CompositionCiNodeBase, NodesFactory, LinksFactory} from "app/models";
import {GraphUIObjects} from "app/utils";
+import {CompositionCiServicePathLink} from "app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link";
+import {Requirement, Capability} from "app/models";
/**
* Created by obarda on 12/21/2016.
*/
@@ -56,11 +59,11 @@ export class CommonGraphUtils {
classes: compositionGraphNode.classes
});
- if(!node.data().isUcpe) { //ucpe should not have tooltip
- this.initNodeTooltip(node);
- }
- return node;
- };
+ if(!node.data().isUcpe) { //ucpe should not have tooltip
+ this.initNodeTooltip(node);
+ }
+ return node;
+ };
/**
* The function will create a component instance node by the componentInstance position.
@@ -135,33 +138,30 @@ export class CommonGraphUtils {
};
/**
- *
+ * Returns relation source and target nodes.
* @param nodes - all nodes in graph in order to find the edge connecting the two nodes
* @param fromNodeId
* @param toNodeId
- * @returns {boolean} true/false if the edge is certified (from node and to node are certified)
+ * @returns [source, target] array of source node and target node.
*/
- public isRelationCertified(nodes:Cy.CollectionNodes, fromNodeId:string, toNodeId:string):boolean {
- let resourceTemp = _.filter(nodes, function (node:Cy.CollectionFirst) {
- return node.data().id === fromNodeId || node.data().id === toNodeId;
- });
- let certified:boolean = true;
-
- _.forEach(resourceTemp, (item) => {
- certified = certified && item.data().certified;
- });
-
- return certified;
+ public getRelationNodes(nodes:Cy.CollectionNodes, fromNodeId:string, toNodeId:string) {
+ return [
+ _.find(nodes, (node:Cy.CollectionFirst) => node.data().id === fromNodeId),
+ _.find(nodes, (node:Cy.CollectionFirst) => node.data().id === toNodeId)
+ ];
}
/**
* Add link to graph - only draw the link
* @param cy
* @param link
+ * @param getRelationRequirementCapability
*/
- public insertLinkToGraph = (cy:Cy.Instance, link:CompositionCiLinkBase) => {
-
- if (!this.isRelationCertified(cy.nodes(), link.source, link.target)) {
+ public insertLinkToGraph = (cy:Cy.Instance, link:CompositionCiLinkBase, getRelationRequirementCapability:Function) => {
+ const relationNodes = this.getRelationNodes(cy.nodes(), link.source, link.target);
+ const sourceNode:CompositionCiNodeBase = relationNodes[0] && relationNodes[0].data();
+ const targetNode:CompositionCiNodeBase = relationNodes[1] && relationNodes[1].data();
+ if ((sourceNode && !sourceNode.certified) || (targetNode && !targetNode.certified)) {
link.classes = 'not-certified-link';
}
let linkElement = cy.add({
@@ -169,32 +169,85 @@ export class CommonGraphUtils {
data: link,
classes: link.classes
});
- this.initLinkTooltip(linkElement, link);
+ const getLinkRequirementCapability = () =>
+ getRelationRequirementCapability(link.relation.relationships[0], sourceNode.componentInstance, targetNode.componentInstance);
+ this.initLinkTooltip(linkElement, link.relation.relationships[0], getLinkRequirementCapability);
};
/**
+ * Add service path link to graph - only draw the link
+ * @param cy
+ * @param link
+ */
+ public insertServicePathLinkToGraph = (cy:Cy.Instance, link:CompositionCiServicePathLink) => {
+ let linkElement = cy.add({
+ group: 'edges',
+ data: link,
+ classes: link.classes
+ });
+ this.initServicePathTooltip(linkElement, link);
+ };
+
+ /**
+ * Returns function for the link tooltip content
+ * @param {Relationship} linkRelation
+ * @param {Requirement} requirement
+ * @param {Capability} capability
+ * @returns {() => string}
+ * @private
+ */
+ private _getLinkTooltipContent(linkRelation:Relationship, requirement?:Requirement, capability?:Capability):string {
+ return '<div class="line">' +
+ '<span class="req-cap-label">R: </span>' +
+ '<span>' + (requirement ? requirement.getTitle() : linkRelation.relation.requirement) + '</span>' +
+ '</div>' +
+ '<div class="line">' +
+ '<div class="sprite-new link-tooltip-arrow"></div>' +
+ '<span class="req-cap-label">C: </span>' +
+ '<span>' + (capability ? capability.getTitle() : linkRelation.relation.capability) + '</span>' +
+ '</div>';
+ }
+
+ /**
* This function will init qtip tooltip on the link
- * @params linkElement - the link we want the tooltip to apply on,
+ * @param linkElement - the link we want the tooltip to apply on,
+ * @param link
+ * @param getLinkRequirementCapability
* link - the link obj
*/
- public initLinkTooltip(linkElement:Cy.CollectionElements, link:CompositionCiLinkBase) {
+ public initLinkTooltip(linkElement:Cy.CollectionElements, link:Relationship, getLinkRequirementCapability:Function) {
+ const content = () => this._getLinkTooltipContent(link); // base tooltip content without owner names
+ const render = (event, api) => {
+ // on render (called once at first show), get the link requirement and capability and change to full tooltip content (with owner names)
+ getLinkRequirementCapability().then((linkReqCap) => {
+ const fullContent = () => this._getLinkTooltipContent(link, linkReqCap.requirement, linkReqCap.capability);
+ api.set('content.text', fullContent);
+ });
+ };
+ linkElement.qtip(this.prepareInitTooltipData({content, events: {render}}));
+ };
- let opts = {
- content: function () {
- return '<div class="line">' +
- '<span class="req-cap-label">R: </span>' +
- '<span>'+ link.relation.relationships[0].relation.requirement + '</span>' +
- '</div>' +
- '<div class="line">' +
- '<div class="sprite-new link-tooltip-arrow"></div>' +
- '<span class="req-cap-label">C: </span>' +
- '<span>' + link.relation.relationships[0].relation.capability + '</span>' +
- '</div>';
- },
+ /**
+ *
+ * @param linkElement
+ * @param link
+ */
+ public initServicePathTooltip(linkElement:Cy.CollectionElements, link:CompositionCiServicePathLink) {
+ let content = function () {
+ return '<div class="line">' +
+ '<div>'+link.pathName+'</div>' +
+ '</div>';
+ };
+ linkElement.qtip(this.prepareInitTooltipData({content}));
+ };
+
+ private prepareInitTooltipData(options?:Object) {
+ return _.merge({
position: {
my: 'top center',
at: 'bottom center',
- adjust: {x:0, y:0}
+ adjust: {x:0, y:0},
+ effect: false
},
style: {
classes: 'qtip-dark qtip-rounded qtip-custom link-qtip',
@@ -208,24 +261,24 @@ export class CommonGraphUtils {
delay: 1000
},
hide: {event: 'mouseout mousedown'},
- includeLabels: true
- };
-
- linkElement.qtip(opts);
- };
+ includeLabels: true,
+ events: {}
+ }, options);
+ }
/**
* go over the relations and draw links on the graph
* @param cy
* @param instancesRelations
+ * @param getRelationRequirementCapability - function to get requirement and capability of a relation
*/
- public initGraphLinks(cy:Cy.Instance, instancesRelations:Array<RelationshipModel>) {
+ public initGraphLinks(cy:Cy.Instance, instancesRelations:Array<RelationshipModel>, getRelationRequirementCapability:Function) {
if (instancesRelations) {
_.forEach(instancesRelations, (relationshipModel:RelationshipModel) => {
_.forEach(relationshipModel.relationships, (relationship:Relationship) => {
let linkToCreate = this.LinksFactory.createGraphLink(cy, relationshipModel, relationship);
- this.insertLinkToGraph(cy, linkToCreate);
+ this.insertLinkToGraph(cy, linkToCreate, getRelationRequirementCapability);
});
});
}
@@ -297,8 +350,8 @@ export class CommonGraphUtils {
public getCytoscapeNodePosition = (cy:Cy.Instance, event:IDragDropEvent):Cy.Position => {
let targetOffset = $(event.target).offset();
- let x = event.pageX - targetOffset.left;
- let y = event.pageY - targetOffset.top;
+ let x = (event.pageX - targetOffset.left) / cy.zoom();
+ let y = (event.pageY - targetOffset.top) / cy.zoom();
return this.HTMLCoordsToCytoscapeCoords(cy.extent(), {
x: x,
@@ -316,14 +369,14 @@ export class CommonGraphUtils {
return nodePosition;
}
- /**
- * Generic function that can be used for any html elements overlaid on canvas
- * Returns the html position of a node on canvas, including left palette and header offsets. Option to pass in additional offset to add to return position.
- * @param node
- * @param additionalOffset
- * @returns {Cy.Position}
-
- public getNodePositionWithOffset = (node:Cy.CollectionFirstNode, additionalOffset?:Cy.Position): Cy.Position => {
+ /**
+ * Generic function that can be used for any html elements overlaid on canvas
+ * Returns the html position of a node on canvas, including left palette and header offsets. Option to pass in additional offset to add to return position.
+ * @param node
+ * @param additionalOffset
+ * @returns {Cy.Position}
+
+ public getNodePositionWithOffset = (node:Cy.CollectionFirstNode, additionalOffset?:Cy.Position): Cy.Position => {
if(!additionalOffset) additionalOffset = {x: 0, y:0};
let nodePosition = node.renderedPosition();
@@ -334,13 +387,13 @@ export class CommonGraphUtils {
return posWithOffset;
};*/
- /**
- * return true/false if first node contains in second - this used in order to verify is node is entirely inside ucpe
- * @param firstBox
- * @param secondBox
- * @returns {boolean}
- */
- public isFirstBoxContainsInSecondBox(firstBox:Cy.BoundingBox, secondBox:Cy.BoundingBox) {
+ /**
+ * return true/false if first node contains in second - this used in order to verify is node is entirely inside ucpe
+ * @param firstBox
+ * @param secondBox
+ * @returns {boolean}
+ */
+ public isFirstBoxContainsInSecondBox(firstBox:Cy.BoundingBox, secondBox:Cy.BoundingBox) {
return firstBox.x1 > secondBox.x1 && firstBox.x2 < secondBox.x2 && firstBox.y1 > secondBox.y1 && firstBox.y2 < secondBox.y2;
@@ -385,50 +438,50 @@ export class CommonGraphUtils {
*/
public nodeLocationsCompatible(cy:Cy.Instance, node1:Cy.CollectionFirstNode, node2:Cy.CollectionFirstNode) {
- let ucpe = cy.nodes('[?isUcpe]');
- if(!ucpe.length){ return true; }
- if(node1.data().isUcpePart || node2.data().isUcpePart) { return true; }
+ let ucpe = cy.nodes('[?isUcpe]');
+ if(!ucpe.length){ return true; }
+ if(node1.data().isUcpePart || node2.data().isUcpePart) { return true; }
return (this.isFirstBoxContainsInSecondBox(node1.boundingbox(), ucpe.boundingbox()) == this.isFirstBoxContainsInSecondBox(node2.boundingbox(), ucpe.boundingbox()));
}
- /**
- * This function will init qtip tooltip on the node
- * @param node - the node we want the tooltip to apply on
- */
- public initNodeTooltip(node:Cy.CollectionNodes) {
-
- let opts = {
- content: function () {
- return this.data('name');
- },
- position: {
- my: 'top center',
- at: 'bottom center',
- adjust: {x:0, y:-5}
- },
- style: {
- classes: 'qtip-dark qtip-rounded qtip-custom',
- tip: {
- width: 16,
- height: 8
- }
- },
- show: {
- event: 'mouseover',
- delay: 1000
- },
- hide: {event: 'mouseout mousedown'},
- includeLabels: true
- };
-
- if (node.data().isUcpePart){ //fix tooltip positioning for UCPE-cps
- opts.position.adjust = {x:0, y:20};
- }
-
- node.qtip(opts);
+ /**
+ * This function will init qtip tooltip on the node
+ * @param node - the node we want the tooltip to apply on
+ */
+ public initNodeTooltip(node:Cy.CollectionNodes) {
+
+ let opts = {
+ content: function () {
+ return this.data('name');
+ },
+ position: {
+ my: 'top center',
+ at: 'bottom center',
+ adjust: {x:0, y:-5}
+ },
+ style: {
+ classes: 'qtip-dark qtip-rounded qtip-custom',
+ tip: {
+ width: 16,
+ height: 8
+ }
+ },
+ show: {
+ event: 'mouseover',
+ delay: 1000
+ },
+ hide: {event: 'mouseout mousedown'},
+ includeLabels: true
};
+
+ if (node.data().isUcpePart){ //fix tooltip positioning for UCPE-cps
+ opts.position.adjust = {x:0, y:20};
+ }
+
+ node.qtip(opts);
+ };
}
CommonGraphUtils.$inject = ['NodesFactory', 'LinksFactory'];
diff --git a/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts b/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts
index 36c75c55fc..596dcecc13 100644
--- a/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/common/style/component-instances-nodes-style.ts
@@ -176,6 +176,17 @@ export class ComponentInstanceNodesStyle {
}
},
{
+ selector: '.vl-link-1',
+ css: {
+ 'width': 3,
+ 'line-color': GraphColors.ACTIVE_LINK,
+ 'curve-style': 'unbundled-bezier',
+ 'target-arrow-color': '#3b7b9b',
+ 'target-arrow-shape': 'triangle',
+ 'control-point-step-size': 30
+ }
+ },
+ {
selector: '.ucpe-host-link',
css: {
'width': 0
@@ -196,6 +207,17 @@ export class ComponentInstanceNodesStyle {
},
{
+ selector: '.service-path-link',
+ css: {
+ 'width': 2,
+ 'line-color': GraphColors.SERVICE_PATH_LINK,
+ 'target-arrow-color': GraphColors.SERVICE_PATH_LINK,
+ 'target-arrow-shape': 'triangle',
+ 'curve-style': 'bezier',
+ 'control-point-step-size': 30
+ }
+ },
+ {
selector: '.not-certified',
css: {
'shape': 'rectangle',
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts
index cdb163bda1..2144ecfbfa 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.directive.ts
@@ -18,6 +18,7 @@
* ============LICENSE_END=========================================================
*/
+import * as _ from "lodash";
import {
Match,
LinkMenu,
@@ -28,13 +29,15 @@ import {
Relationship,
PropertyModel,
Component,
+ Service,
ConnectRelationModel,
CompositionCiNodeBase,
CompositionCiNodeVl,
ModalModel,
ButtonModel,
NodesFactory/*,
- AssetPopoverObj*/
+ AssetPopoverObj*/,
+ Point
} from "app/models";
import {ComponentInstanceFactory, ComponentFactory, GRAPH_EVENTS, GraphColors} from "app/utils";
import {EventListenerService, LoaderService} from "app/services";
@@ -60,13 +63,32 @@ import {ConnectionPropertiesViewComponent} from "../../../ng2/pages/connection-w
import {ComponentInstanceServiceNg2} from "../../../ng2/services/component-instance-services/component-instance.service";
import {EVENTS} from "../../../utils/constants";
import {PropertyBEModel} from "../../../models/properties-inputs/property-be-model";
+import {ComponentType} from "app/utils";
+import {ForwardingPath} from "app/models/forwarding-path";
+import {ServicePathGraphUtils} from "./utils/composition-graph-service-path-utils";
+import {CompositionCiServicePathLink} from "app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link";
+import { ZoneConfig, ZoneInstanceConfig, ZoneInstanceMode } from "app/models/graph/zones/zone-child";
+import { PoliciesService } from "app/ng2/services/policies.service";
+import { PaletteAnimationComponent } from "app/ng2/components/ui/palette-animation/palette-animation.component";
+import { CompositionGraphZoneUtils } from "./utils/composition-graph-zone-utils";
+import {LeftPaletteMetadataTypes} from "../../../models/components/displayComponent";
-interface ICompositionGraphScope extends ng.IScope {
+
+export interface ICompositionGraphScope extends ng.IScope {
component:Component;
isLoading: boolean;
isViewOnly: boolean;
withSidebar: boolean;
+
+ //zones
+ newZoneInstance;
+ zoneTagMode:string;
+ activeZoneInstance:ZoneInstanceConfig;
+ zones:any;
+ zoneInstanceModeChanged(newMode:ZoneInstanceMode, instance:ZoneInstanceConfig, zoneId:string);
+ clickOutsideZoneInstance():void;
+
// Link menu - create link menu
relationMenuDirectiveObj:ConnectRelationModel;
isLinkMenuOpen:boolean;
@@ -76,6 +98,7 @@ interface ICompositionGraphScope extends ng.IScope {
//modify link menu - for now only delete menu
relationMenuTimeout:ng.IPromise<any>;
linkMenuObject:LinkMenu;
+ isOnDrag: boolean;
//left palette functions callbacks
dropCallback(event:JQueryEventObject, ui:any):void;
@@ -95,7 +118,12 @@ interface ICompositionGraphScope extends ng.IScope {
highlightSearchMatches(searchTerm: string): void;
canvasMenuProps:any;
-
+
+ createOrUpdateServicePath(data: any):void;
+ deletePathsOnCy():void;
+ drawPathOnCy(data: ForwardingPath):void;
+ selectedPathId: string;
+
/*//asset popover menu
assetPopoverObj:AssetPopoverObj;
assetPopoverOpen:boolean;
@@ -124,10 +152,13 @@ export class CompositionGraph implements ng.IDirective {
private commonGraphUtils:CommonGraphUtils,
private matchCapabilitiesRequirementsUtils:MatchCapabilitiesRequirementsUtils,
private CompositionGraphPaletteUtils:CompositionGraphPaletteUtils,
+ private compositionGraphZoneUtils:CompositionGraphZoneUtils,
private ComponentServiceNg2: ComponentServiceNg2,
private ModalServiceNg2: ModalService,
private ConnectionWizardServiceNg2: ConnectionWizardService,
- private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2) {
+ private ComponentInstanceServiceNg2: ComponentInstanceServiceNg2,
+ private servicePathGraphUtils: ServicePathGraphUtils,
+ private policiesService:PoliciesService) {
}
@@ -140,7 +171,6 @@ export class CompositionGraph implements ng.IDirective {
};
link = (scope:ICompositionGraphScope, el:JQuery) => {
-
this.loadGraph(scope, el);
if(scope.component.componentInstances && scope.component.componentInstancesRelations) {
@@ -164,15 +194,16 @@ export class CompositionGraph implements ng.IDirective {
private loadGraphData = (scope:ICompositionGraphScope) => {
this.initGraphNodes(scope.component.componentInstances, scope.isViewOnly);
- this.commonGraphUtils.initGraphLinks(this._cy, scope.component.componentInstancesRelations);
+ this.commonGraphUtils.initGraphLinks(this._cy, scope.component.componentInstancesRelations, scope.component.getRelationRequirementCapability.bind(scope.component));
this.commonGraphUtils.initUcpeChildren(this._cy);
+ this.compositionGraphZoneUtils.initPolicyInstances(scope.zones.policy, scope.component.policies);
}
private loadGraph = (scope:ICompositionGraphScope, el:JQuery) => {
-
let graphEl = el.find('.sdc-composition-graph-wrapper');
this.initGraph(graphEl, scope.isViewOnly);
this.initDropZone(scope);
+ this.initZones(scope);
this.registerCytoscapeGraphEvents(scope);
this.registerCustomEvents(scope, el);
this.initViewMode(scope.isViewOnly);
@@ -210,6 +241,12 @@ export class CompositionGraph implements ng.IDirective {
private registerCustomEvents(scope:ICompositionGraphScope, el:JQuery) {
this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, (leftPaletteComponent:LeftPaletteComponent) => {
+ if(scope.isOnDrag ||
+ leftPaletteComponent.categoryType === LeftPaletteMetadataTypes.Group ||
+ leftPaletteComponent.categoryType === LeftPaletteMetadataTypes.Policy) {
+ return;
+ }
+
this.$log.info(`composition-graph::registerEventServiceEvents:: palette hover on component: ${leftPaletteComponent.uniqueId}`);
let nodesData = this.NodesGraphUtils.getAllNodesData(this._cy.nodes());
@@ -240,6 +277,33 @@ export class CompositionGraph implements ng.IDirective {
});
});
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ADD_COMPONENT_INSTANCE_ZONE_START, (component:Component, paletteComponent:LeftPaletteComponent, startPosition:Point) => {
+ this.LoaderService.showLoader('composition-graph');
+
+ let zoneType:string = LeftPaletteMetadataTypes[paletteComponent.categoryType].toLowerCase();
+ scope.zones[zoneType].showZone = true;
+ if(scope.minifyZone) scope.minifyZone = false;
+
+ this.policiesService.createPolicyInstance(component.componentType, component.uniqueId, paletteComponent.type).subscribe((newInstance)=>{
+
+ this.LoaderService.hideLoader('composition-graph');
+ scope.newZoneInstance = newInstance;
+ this.compositionGraphZoneUtils.showAnimationToZone(startPosition, zoneType);
+ }, (error) => {
+ this.LoaderService.hideLoader('composition-graph');
+ });
+ });
+
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_FINISH_ANIMATION_ZONE, () => {
+ if(scope.newZoneInstance){
+ this.compositionGraphZoneUtils.addInstanceToZone(scope.zones['policy'], scope.newZoneInstance);
+ }
+ })
+
+ this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_ZONE_SIZE_CHANGE, () => {
+ scope.minifyZone = true;
+ })
+
this.eventListenerService.registerObserverCallback(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT, () => {
this._cy.emit('hidehandles');
this.matchCapabilitiesRequirementsUtils.resetFadedNodes(this._cy);
@@ -362,17 +426,11 @@ export class CompositionGraph implements ng.IDirective {
.updateInstanceCapabilityProperties(
scope.component,
this.ConnectionWizardServiceNg2.selectedMatch.toNode,
- this.ConnectionWizardServiceNg2.selectedMatch.capability.type,
- this.ConnectionWizardServiceNg2.selectedMatch.capability.name,
+ this.ConnectionWizardServiceNg2.selectedMatch.capability,
capabilityPropertiesBE
)
.subscribe((response) => {
console.log("Update resource instance capability properties response: ", response);
- response.forEach((resProperty) => {
- this.ConnectionWizardServiceNg2.selectedMatch.capabilityProperties.find((property) => {
- return property.uniqueId == resProperty.uniqueId;
- }).value = resProperty.value;
- });
this.ConnectionWizardServiceNg2.changedCapabilityProperties = [];
resolve(capabilityPropertiesBE);
});
@@ -400,6 +458,16 @@ export class CompositionGraph implements ng.IDirective {
});
};
+ scope.createOrUpdateServicePath = (data:any) => {
+ this.servicePathGraphUtils.createOrUpdateServicePath(scope, data);
+ };
+ scope.deletePathsOnCy = () => {
+ this.servicePathGraphUtils.deletePathsFromGraph(this._cy, <Service> scope.component);
+ };
+ scope.drawPathOnCy = (data: ForwardingPath) => {
+ this.servicePathGraphUtils.drawPath(this._cy, data, <Service> scope.component);
+ };
+
scope.viewRelation = (link:Cy.CollectionEdges) => {
scope.hideRelationMenu();
@@ -408,41 +476,9 @@ export class CompositionGraph implements ng.IDirective {
const targetNode:CompositionCiNodeBase = link.target().data();
const relationship:Relationship = linkData.relation.relationships[0];
- let capability:Capability;
- _.some(_.values(targetNode.componentInstance.capabilities), (capGroup) => {
- //item.uniqueId + item.ownerId + item.name === (selectedReqOrCapModel.uniqueId + selectedReqOrCapModel.ownerId + selectedReqOrCapModel.name)
- capability = _.find<Capability>(_.values<Capability>(capGroup), (cap:Capability) => (
- cap.uniqueId === relationship.relation.capabilityUid &&
- cap.ownerId === relationship.relation.capabilityOwnerId &&
- cap.name === relationship.relation.capability
- ));
- return capability;
- });
- let requirement:Requirement;
- _.some(_.values(sourceNode.componentInstance.requirements), (reqGroup) => {
- requirement = _.find<Requirement>(_.values<Requirement>(reqGroup), (req:Requirement) => (
- req.uniqueId === relationship.relation.requirementUid &&
- req.ownerId === relationship.relation.requirementOwnerId &&
- req.name === relationship.relation.requirement
- ));
- return requirement;
- });
-
- new Promise<{capability:Capability, requirement:Requirement}>((resolve, reject) => {
- if (capability && requirement) {
- resolve({capability, requirement});
- }
- else {
- scope.component.fetchRelation(relationship.relation.id).then((fetchedRelation) => {
- resolve({
- capability: fetchedRelation.relationships[0].capability,
- requirement: fetchedRelation.relationships[0].requirement
- });
- }, reject);
- }
- }).then((objReqCap) => {
- capability = objReqCap.capability;
- requirement = objReqCap.requirement;
+ scope.component.getRelationRequirementCapability(relationship, sourceNode.componentInstance, targetNode.componentInstance).then((objReqCap) => {
+ const capability = objReqCap.capability;
+ const requirement = objReqCap.requirement;
this.ConnectionWizardServiceNg2.currentComponent = scope.component;
this.ConnectionWizardServiceNg2.connectRelationModel = new ConnectRelationModel(sourceNode, targetNode, []);
@@ -459,11 +495,19 @@ export class CompositionGraph implements ng.IDirective {
this.ModalServiceNg2.addDynamicContentToModal(modalInstance, ConnectionPropertiesViewComponent);
modalInstance.instance.open();
- this.ComponentInstanceServiceNg2.getInstanceCapabilityProperties(scope.component, linkData.target, capability.type, capability.name)
- .subscribe((response: Array<PropertyModel>) => {
- this.ConnectionWizardServiceNg2.selectedMatch.capabilityProperties = response;
- this.ModalServiceNg2.addDynamicContentToModal(modalInstance, ConnectionPropertiesViewComponent);
- }, (error) => {});
+ new Promise((resolve) => {
+ if (!this.ConnectionWizardServiceNg2.selectedMatch.capability.properties) {
+ this.ComponentInstanceServiceNg2.getInstanceCapabilityProperties(scope.component, linkData.target, capability)
+ .subscribe(() => {
+ resolve();
+ }, (error) => {});
+ } else {
+ resolve();
+ }
+ }).then(() => {
+ this.ModalServiceNg2.addDynamicContentToModal(modalInstance, ConnectionPropertiesViewComponent);
+ })
+
}, (error) => {});
};
@@ -504,7 +548,7 @@ export class CompositionGraph implements ng.IDirective {
this.ConnectionWizardServiceNg2.currentComponent = scope.component;
//TODO: init with the selected values
this.ConnectionWizardServiceNg2.selectedMatch = null;
-
+
let steps:Array<StepModel> = [];
let fromNodeName:string = scope.relationMenuDirectiveObj.fromNode.componentInstance.name;
let toNodeName:string = scope.relationMenuDirectiveObj.toNode.componentInstance.name;
@@ -523,6 +567,7 @@ export class CompositionGraph implements ng.IDirective {
}
});
this._cy.on('tapstart', 'node', (event:Cy.EventObject) => {
+ scope.isOnDrag = true;
this._currentlyCLickedNodePosition = angular.copy(event.cyTarget[0].position()); //update node position on drag
if (event.cyTarget.data().isUcpe) {
this._cy.nodes('.ucpe-cp').unlock();
@@ -592,7 +637,7 @@ export class CompositionGraph implements ng.IDirective {
this._cy.on('tapend', (event:Cy.EventObject) => {
-
+ scope.isOnDrag = false;
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(GRAPH_EVENTS.ON_GRAPH_BACKGROUND_CLICKED);
@@ -603,6 +648,9 @@ export class CompositionGraph implements ng.IDirective {
else if (event.cyTarget.isEdge()) { //On Edge clicked
if (scope.isViewOnly) return;
this.CompositionGraphLinkUtils.handleLinkClick(this._cy, event);
+ if (event.cyTarget.data().type === CompositionCiServicePathLink.LINK_TYPE) {
+ return;
+ }
this.openModifyLinkMenu(scope, this.CompositionGraphLinkUtils.getModifyLinkMenu(event.cyTarget[0], event), 6000);
}
@@ -640,13 +688,6 @@ export class CompositionGraph implements ng.IDirective {
});
}
- /*
- private showNodePopoverMenu = (scope:ICompositionGraphScope, node:Cy.CollectionNodes) => {
-
- scope.assetPopoverObj = this.NodesGraphUtils.createAssetPopover(this._cy, node, scope.isViewOnly);
- scope.assetPopoverOpen = true;
-
- };*/
private openModifyLinkMenu = (scope:ICompositionGraphScope, linkMenuObject:LinkMenu, timeOutInMilliseconds?:number) => {
scope.hideRelationMenu();
this.$timeout(() => {
@@ -732,6 +773,49 @@ export class CompositionGraph implements ng.IDirective {
}
}
+
+ private initZones = (scope:ICompositionGraphScope):void => {
+ scope.zones = this.compositionGraphZoneUtils.createCompositionZones();
+
+ scope.zoneInstanceModeChanged = (newMode:ZoneInstanceMode, instance:ZoneInstanceConfig, zoneId:string):void => {
+ if(scope.zoneTagMode) { //we're in tag mode.
+ if(instance == scope.activeZoneInstance && newMode == ZoneInstanceMode.TAG){ //we want to toggle tag mode off.
+ scope.unsetActiveZoneInstance();
+ }
+ } else {
+ scope.setZoneInstanceMode(newMode, instance, zoneId);
+ }
+ };
+
+ scope.setZoneInstanceMode = (newMode:ZoneInstanceMode, instance:ZoneInstanceConfig, zoneId:string):void => {
+ instance.mode = newMode;
+ switch(newMode){
+ case ZoneInstanceMode.TAG: {
+ scope.zoneTagMode = zoneId + "-tagging";
+ }
+ case ZoneInstanceMode.SELECTED: { //case TAG flows into here as well
+ scope.activeZoneInstance = instance;
+ break;
+ }
+ }
+ };
+
+ scope.unsetActiveZoneInstance = ():void => {
+ scope.activeZoneInstance.mode = ZoneInstanceMode.NONE;
+ scope.activeZoneInstance = null;
+ scope.zoneTagMode = null;
+ };
+
+ scope.clickOutsideZoneInstance = ():void => {
+ if(!scope.zoneTagMode)
+ scope.unsetActiveZoneInstance();
+ };
+
+ };
+
+
+
+
public static factory = ($q,
$log,
$timeout,
@@ -746,10 +830,13 @@ export class CompositionGraph implements ng.IDirective {
CommonGraphUtils,
MatchCapabilitiesRequirementsUtils,
CompositionGraphPaletteUtils,
+ CompositionGraphZoneUtils,
ComponentServiceNg2,
ModalService,
ConnectionWizardService,
- ComponentInstanceServiceNg2) => {
+ ComponentInstanceServiceNg2,
+ ServicePathGraphUtils,
+ PoliciesService) => {
return new CompositionGraph(
$q,
$log,
@@ -765,10 +852,13 @@ export class CompositionGraph implements ng.IDirective {
CommonGraphUtils,
MatchCapabilitiesRequirementsUtils,
CompositionGraphPaletteUtils,
+ CompositionGraphZoneUtils,
ComponentServiceNg2,
ModalService,
ConnectionWizardService,
- ComponentInstanceServiceNg2);
+ ComponentInstanceServiceNg2,
+ ServicePathGraphUtils,
+ PoliciesService);
}
}
@@ -787,8 +877,11 @@ CompositionGraph.factory.$inject = [
'CommonGraphUtils',
'MatchCapabilitiesRequirementsUtils',
'CompositionGraphPaletteUtils',
+ 'CompositionGraphZoneUtils',
'ComponentServiceNg2',
'ModalServiceNg2',
'ConnectionWizardServiceNg2',
- 'ComponentInstanceServiceNg2'
+ 'ComponentInstanceServiceNg2',
+ 'ServicePathGraphUtils',
+ 'PoliciesServiceNg2'
];
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html
index bbf2d6bbb2..487e4cb65a 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.html
@@ -1,5 +1,5 @@
<loader display="isLoading" loader-type="composition-graph"></loader>
-<div class="sdc-composition-graph-wrapper" ng-class="{'view-only':isViewOnly}"
+<div class="sdc-composition-graph-wrapper {{zoneTagMode}}" ng-class="{'view-only':isViewOnly}"
data-drop="true"
data-jqyoui-options="{accept: verifyDrop}"
data-jqyoui-droppable="{onDrop:'dropCallback', beforeDrop: 'beforeDropCallback'}">
@@ -11,10 +11,37 @@
<menu-list-ng2 [props]="canvasMenuProps"></menu-list-ng2>
<div class="w-sdc-search-menu" data-ng-class="{'with-sidebar': withSidebar}">
- <ng2-search-with-autocomplete [search-placeholder]="'Type to search'" [auto-complete-values]="componentInstanceNames" (search-changed)="getAutoCompleteValues($event)" (search-button-clicked)="highlightSearchMatches($event)"
- [search-bar-class]="'composition-search'"></ng2-search-with-autocomplete>
+
+ <ng2-service-path-selector
+ ng-if="component.isService()"
+ [service]="component"
+ [draw-path]="drawPathOnCy"
+ [delete-paths]="deletePathsOnCy"
+ [selected-path-id]="selectedPathId">
+ </ng2-service-path-selector>
+ <ng2-service-path
+ ng-if="component.isService()"
+ [service]="component"
+ [on-create]="createOrUpdateServicePath">
+ </ng2-service-path>
+ <ng2-search-with-autocomplete
+ [search-placeholder]="'Type to search'"
+ [auto-complete-values]="componentInstanceNames"
+ (search-changed)="getAutoCompleteValues($event)"
+ (search-button-clicked)="highlightSearchMatches($event)"
+ [search-bar-class]="'composition-search'">
+ </ng2-search-with-autocomplete>
<div class="zoom-icons sprite-new canvas-fit-all" data-ng-click="zoomAll()"></div>
<div class="zoom-icons sprite-new zoom-plus" data-ng-click="zoom(true)"></div>
<div class="zoom-icons sprite-new zoom-minus" data-ng-click="zoom(false)"></div>
</div>
<!--<asset-popover ng-if="assetPopoverOpen" asset-popover-obj="assetPopoverObj" delete-asset="deleteNode(assetPopoverObj.nodeId)"></asset-popover>-->
+<div class="sdc-canvas-zones__wrapper {{zoneTagMode}}" data-ng-class="{'with-sidebar': withSidebar}">
+ <ng2-zone-container data-ng-repeat="zoneConfig in zones" [title]="zoneConfig.title" [class]="zoneConfig.type" [count]="zoneConfig.instances.length" [show-zone] = "zoneConfig.showZone" [minify-zone] = "minifyZone">
+ <ng2-zone-instance
+ data-ng-repeat="instance in zoneConfig.instances" clicked-outside="{onClickedOutside: 'clickOutsideZoneInstance()', clickedOutsideEnable: 'activeZoneInstance == instance'}"
+ [config]="instance" [default-icon-text]="zoneConfig.defaultIconText" [is-active]="activeZoneInstance == instance" [active-instance-mode]="activeZoneInstance && activeZoneInstance.mode"
+ (mode-change)="zoneInstanceModeChanged($event.newMode, $event.instance, zoneConfig.type)">
+ </ng2-zone-instance>
+ </ng2-zone-container>
+</div>
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less
index 56c8b5529d..5a6a104670 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/composition-graph.less
@@ -11,4 +11,28 @@ composition-graph {
.view-only{
background-color:rgb(248, 248, 248);
}
+
+ .sdc-canvas-zones__wrapper {
+ position: absolute;
+ bottom: 10px;
+ right: 12px;
+ display:flex;
+ transition: right 0.2s;
+
+ &.with-sidebar {
+ right:310px;
+ }
+
+ ng2-zone-container {
+ display:flex;
+ margin-left: 10px;
+ }
+ }
+
+ .group-tagging {
+ cursor: url("/assets/styles/images/canvas-tagging-icons/adding_group.svg"), pointer;
+ }
+ .policy-tagging {
+ cursor: url("/assets/styles/images/canvas-tagging-icons/adding_policy.svg"), pointer;
+ }
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
index da7d48e6ae..73e03e954d 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts
@@ -18,6 +18,7 @@
* ============LICENSE_END=========================================================
*/
+import * as _ from "lodash";
import {ComponentInstance, Component, Match, CompositionCiLinkBase, CompositionCiNodeUcpeCp} from "app/models";
import {QueueUtils, Dictionary, GraphUIObjects} from "app/utils";
import {LoaderService} from "app/services";
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts
index 89c5e14602..705367c5f7 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts
@@ -21,6 +21,7 @@
/**
* Created by obarda on 6/28/2016.
*/
+import * as _ from "lodash";
import {GraphUIObjects} from "app/utils";
import {LoaderService} from "app/services";
import {
@@ -39,6 +40,7 @@ import {
import {CommonGraphUtils} from "../../common/common-graph-utils";
import {CompositionGraphGeneralUtils} from "./composition-graph-general-utils";
import {MatchCapabilitiesRequirementsUtils} from "./match-capability-requierment-utils";
+import {CompositionCiServicePathLink} from "../../../../models/graph/graph-links/composition-graph-links/composition-ci-service-path-link";
export class CompositionGraphLinkUtils {
@@ -86,7 +88,7 @@ export class CompositionGraphLinkUtils {
let onSuccess:(response:RelationshipModel) => void = (relation:RelationshipModel) => {
link.setRelation(relation);
- this.commonGraphUtils.insertLinkToGraph(cy, link);
+ this.commonGraphUtils.insertLinkToGraph(cy, link, component.getRelationRequirementCapability.bind(component));
};
link.updateLinkDirection();
@@ -212,6 +214,28 @@ export class CompositionGraphLinkUtils {
this.createLink(link, cy, component);
};
+ private handlePathLink(cy:Cy.Instance, event:Cy.EventObject) {
+ let linkData = event.cyTarget.data();
+ let selectedPathId = linkData.pathId;
+ let pathEdges = cy.collection(`[pathId='${selectedPathId}']`);
+ if (pathEdges.length > 1) {
+ setTimeout(() => {
+ pathEdges.select();
+ }, 0);
+ }
+ }
+
+ private handleVLLink(event:Cy.EventObject) {
+ let vl:Cy.CollectionNodes = event.cyTarget[0].target('.vl-node');
+ let connectedEdges:Cy.CollectionEdges = vl.connectedEdges(`[type!="${CompositionCiServicePathLink.LINK_TYPE}"]`);
+ if (vl.length && connectedEdges.length > 1) {
+ setTimeout(() => {
+ vl.select();
+ connectedEdges.select();
+ }, 0);
+ }
+ }
+
/**
* Handles click event on links.
@@ -224,18 +248,13 @@ export class CompositionGraphLinkUtils {
if (cy.$('edge:selected').length > 1 && 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);
+ if (event.cyTarget[0].data().type === CompositionCiServicePathLink.LINK_TYPE) {
+ this.handlePathLink(cy, event);
+ }
+ else {
+ this.handleVLLink(event);
}
}
-
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts
index 449d551cc0..fb1e6650bd 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts
@@ -18,11 +18,15 @@
* ============LICENSE_END=========================================================
*/
-import {Component, NodesFactory, ComponentInstance, CompositionCiNodeVl,IAppMenu,AssetPopoverObj} from "app/models";
+import * as _ from "lodash";
+import {Component, NodesFactory, ComponentInstance, CompositionCiNodeVl,IAppMenu,AssetPopoverObj, Service} from "app/models";
import {EventListenerService, LoaderService} from "app/services";
import {GRAPH_EVENTS,ModalsHandler,GraphUIObjects} from "app/utils";
import {CompositionGraphGeneralUtils} from "./composition-graph-general-utils";
import {CommonGraphUtils} from "../../common/common-graph-utils";
+import {CompositionCiServicePathLink} from "app/models/graph/graph-links/composition-graph-links/composition-ci-service-path-link";
+import {ServiceGenericResponse} from "app/ng2/services/responses/service-generic-response";
+import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service';
/**
* Created by obarda on 11/9/2016.
*/
@@ -31,9 +35,10 @@ export class CompositionGraphNodesUtils {
private GeneralGraphUtils:CompositionGraphGeneralUtils,
private commonGraphUtils:CommonGraphUtils,
private eventListenerService:EventListenerService,
- private loaderService:LoaderService /*,
- private sdcMenu: IAppMenu,
- private ModalsHandler: ModalsHandler*/) {
+ private loaderService:LoaderService,
+ private serviceService:ServiceServiceNg2,
+ /*private sdcMenu: IAppMenu,
+ private ModalsHandler: ModalsHandler*/) {
}
@@ -88,9 +93,20 @@ export class CompositionGraphNodesUtils {
this.handleConnectedVlsToDelete(connectedVls);
}
+ // check whether there is a service path going through this node, and if so clean it from the graph.
+ let nodeId = nodeToDelete.data().id;
+ let 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((response:ServiceGenericResponse) => {
+ (<Service>component).forwardingPaths = response.forwardingPaths;
+ });
+
//update UI
cy.remove(nodeToDelete);
-
};
let onFailed:(response:any) => void = (response:any) => {
@@ -297,5 +313,5 @@ export class CompositionGraphNodesUtils {
}
- CompositionGraphNodesUtils.$inject = ['NodesFactory', '$log', 'CompositionGraphGeneralUtils', 'CommonGraphUtils', 'EventListenerService', 'LoaderService' /*, 'sdcMenu', 'ModalsHandler'*/]
+ CompositionGraphNodesUtils.$inject = ['NodesFactory', '$log', 'CompositionGraphGeneralUtils', 'CommonGraphUtils', 'EventListenerService', 'LoaderService', 'ServiceServiceNg2' /*, 'sdcMenu', 'ModalsHandler'*/]
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts
new file mode 100644
index 0000000000..ef047d7dd3
--- /dev/null
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-service-path-utils.ts
@@ -0,0 +1,80 @@
+/*-
+ * ============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 * as _ from "lodash";
+import {LoaderService} from "app/services";
+import {CompositionGraphGeneralUtils} from "./composition-graph-general-utils";
+import {ICompositionGraphScope} from "../composition-graph.directive";
+import {ServiceServiceNg2} from 'app/ng2/services/component-services/service.service';
+import {Service} from "../../../../models/components/service";
+import {ForwardingPath} from "app/models/forwarding-path";
+import {ForwardingPathLink} from "app/models/forwarding-path-link";
+import {CompositionCiServicePathLink} from "../../../../models/graph/graph-links/composition-graph-links/composition-ci-service-path-link";
+import {CommonGraphUtils} from "app/directives/graphs-v2/common/common-graph-utils";
+
+export class ServicePathGraphUtils {
+
+ constructor(
+ private loaderService:LoaderService,
+ private generalGraphUtils:CompositionGraphGeneralUtils,
+ private serviceService:ServiceServiceNg2,
+ private commonGraphUtils:CommonGraphUtils
+ ) {}
+
+ public deletePathsFromGraph(cy: Cy.Instance, service:Service){
+ cy.remove(`[type="${CompositionCiServicePathLink.LINK_TYPE}"]`);
+ }
+
+ public drawPath(cy: Cy.Instance, forwardingPath: ForwardingPath, service:Service) {
+ let pathElements = forwardingPath.pathElements.listToscaDataDefinition;
+
+ _.forEach(pathElements, (link: ForwardingPathLink) => {
+ let data:CompositionCiServicePathLink = new CompositionCiServicePathLink(link);
+ data.source = data.forwardingPathLink.fromNode;
+ data.target = data.forwardingPathLink.toNode;
+ data.pathId = forwardingPath.uniqueId;
+ data.pathName = forwardingPath.name;
+ this.commonGraphUtils.insertServicePathLinkToGraph(cy, data);
+ });
+ }
+
+ public createOrUpdateServicePath = (scope:ICompositionGraphScope, path: any): void => {
+ let service = <Service>scope.component;
+ this.loaderService.showLoader('composition-graph');
+
+ let onSuccess: (response: ForwardingPath) => void = (response: ForwardingPath) => {
+
+ service.forwardingPaths[response.uniqueId] = response;
+ scope.selectedPathId = response.uniqueId;
+ };
+
+ this.generalGraphUtils.getGraphUtilsServerUpdateQueue().addBlockingUIActionWithReleaseCallback(
+ () => this.serviceService.createOrUpdateServicePath(service, path).subscribe(onSuccess),
+ () => this.loaderService.hideLoader('composition-graph')
+ );
+ };
+}
+
+ServicePathGraphUtils.$inject = [
+ 'LoaderService',
+ 'CompositionGraphGeneralUtils',
+ 'ServiceServiceNg2',
+ 'CommonGraphUtils'
+];
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts
new file mode 100644
index 0000000000..28f2dc85d2
--- /dev/null
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/composition-graph-zone-utils.ts
@@ -0,0 +1,55 @@
+import { PolicyInstance } from "app/models/graph/zones/policy-instance";
+import { ZoneConfig, ZoneInstanceConfig } from "app/models/graph/zones/zone-child";
+import { DynamicComponentService } from "app/ng2/services/dynamic-component.service";
+import { PaletteAnimationComponent } from "app/ng2/components/ui/palette-animation/palette-animation.component";
+import { Point } from "../../../../models";
+
+export class CompositionGraphZoneUtils {
+
+ constructor(private dynamicComponentService: DynamicComponentService) {}
+
+ public createCompositionZones(){
+ let zones = {
+ 'policy': new ZoneConfig('Policies', 'P', 'policy', false),
+ 'group': new ZoneConfig('Groups', 'G', 'group', false)
+ };
+ return zones;
+ }
+
+ public initPolicyInstances(policyZone:ZoneConfig, policies:Array<PolicyInstance>) {
+ if(policies && policies.length){
+ policyZone.showZone = true;
+ }
+ _.forEach(policies, (policy:PolicyInstance) => {
+ policyZone.instances.push(new ZoneInstanceConfig(policy));
+ });
+ }
+
+ public addInstanceToZone(zone:ZoneConfig, instance:PolicyInstance){
+ zone.instances.push(new ZoneInstanceConfig(instance));
+ };
+
+ private findZoneCoordinates(zoneType):Point{
+ let point:Point = new Point(0,0);
+ let zone = angular.element(document.querySelector('.' + zoneType + '-zone'));
+ let wrapperZone = zone.offsetParent();
+ point.x = zone.prop('offsetLeft') + wrapperZone.prop('offsetLeft');
+ point.y = zone.prop('offsetTop') + wrapperZone.prop('offsetTop');
+ return point;
+ }
+
+ public showAnimationToZone = (startPoint:Point, zoneType:string) => {
+
+ let paletteToZoneAnimation = this.dynamicComponentService.createDynamicComponent(PaletteAnimationComponent);
+ paletteToZoneAnimation.instance.from = startPoint;
+ paletteToZoneAnimation.instance.to = this.findZoneCoordinates(zoneType);
+ paletteToZoneAnimation.instance.iconName = zoneType;
+ paletteToZoneAnimation.instance.runAnimation();
+ }
+
+
+}
+
+CompositionGraphZoneUtils.$inject = [
+ 'DynamicComponentService'
+]; \ No newline at end of file
diff --git a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts
index 6a02381902..3a05ce901f 100644
--- a/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts
@@ -18,6 +18,7 @@
* ============LICENSE_END=========================================================
*/
+import * as _ from "lodash";
import {
Requirement, CompositionCiLinkBase, CapabilitiesGroup, RequirementsGroup, Match,
CompositionCiNodeBase, Component, Capability
@@ -142,7 +143,7 @@ export class MatchCapabilitiesRequirementsUtils {
let requirementArray:Array<Requirement> = [];
_.forEach(_.flatten(_.values(requirements)), (requirement:Requirement)=> {
- if (requirement.name !== "dependency" && !MatchCapabilitiesRequirementsUtils.isRequirementFulfilled(fromNodeId, requirement, links)) {
+ if (requirement.name !== 'dependency' && requirement.parentName !== 'dependency' && !MatchCapabilitiesRequirementsUtils.isRequirementFulfilled(fromNodeId, requirement, links)) {
requirementArray.push(requirement);
}
});
diff --git a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts
index 127f43b734..c542e9fc95 100644
--- a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts
@@ -18,6 +18,7 @@
* ============LICENSE_END=========================================================
*/
+import * as _ from "lodash";
import { Component, Module, NodesFactory, ComponentInstance } from "app/models";
import { ComponentInstanceFactory } from "app/utils";
import { DeploymentGraphGeneralUtils } from "./deployment-utils/deployment-graph-general-utils";
@@ -133,7 +134,7 @@ export class DeploymentGraph implements ng.IDirective {
});
this.initGraphNodes(this._cy, scope.component); //creating instances nodes
- this.commonGraphUtils.initGraphLinks(this._cy, scope.component.componentInstancesRelations);
+ this.commonGraphUtils.initGraphLinks(this._cy, scope.component.componentInstancesRelations, scope.component.getRelationRequirementCapability.bind(scope.component));
this._cy.collapseAll();
this.registerGraphEvents();
diff --git a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts
index e481b1d268..3a90115179 100644
--- a/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts
@@ -18,6 +18,7 @@
* ============LICENSE_END=========================================================
*/
+import * as _ from "lodash";
import {Module} from "app/models";
/**
* Created by obarda on 12/21/2016.
diff --git a/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts b/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts
index 8abf968c82..9b9235248e 100644
--- a/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/palette/palette.directive.ts
@@ -7,9 +7,9 @@
* 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.
@@ -17,7 +17,8 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-import {Component, IAppMenu, LeftPanelModel, NodesFactory, LeftPaletteComponent, CompositionCiNodeBase, ComponentInstance} from "app/models";
+import * as _ from "lodash";
+import {Component, IAppMenu, LeftPanelModel, NodesFactory, LeftPaletteComponent, CompositionCiNodeBase, ComponentInstance, Point} from "app/models";
import {CompositionGraphGeneralUtils} from "../composition-graph/utils/composition-graph-general-utils";
import {EventListenerService} from "app/services";
import {ResourceType, GRAPH_EVENTS, EVENTS, ComponentInstanceFactory, ModalsHandler} from "app/utils";
@@ -25,6 +26,8 @@ import 'sdc-angular-dragdrop';
import {LeftPaletteLoaderService} from "../../../services/components/utils/composition-left-palette-service";
import {Resource} from "app/models/components/resource";
import {ComponentType} from "app/utils/constants";
+import {LeftPaletteMetadataTypes} from "../../../models/components/displayComponent";
+
interface IPaletteScope {
components:Array<LeftPaletteComponent>;
@@ -39,10 +42,15 @@ interface IPaletteScope {
ui:any
}
+ addInstanceClick: ()=>void; // added code
+ onPopupMouseOver: ()=>void // added code
+ onPopupMouseOut: ()=>void // added code
+
sectionClick:(section:string)=>void;
searchComponents:(searchText:string)=>void;
- onMouseOver:(displayComponent:LeftPaletteComponent)=>void;
+ onMouseOver:(displayComponent:LeftPaletteComponent, elem: HTMLElement)=>void;
onMouseOut:(displayComponent:LeftPaletteComponent)=>void;
+
dragStartCallback:(event:JQueryEventObject, ui, displayComponent:LeftPaletteComponent)=>void;
dragStopCallback:()=>void;
onDragCallback:(event:JQueryEventObject) => void;
@@ -65,8 +73,8 @@ export class Palette implements ng.IDirective {
private CompositionGraphGeneralUtils:CompositionGraphGeneralUtils,
private EventListenerService:EventListenerService,
private sdcMenu:IAppMenu,
- private ModalsHandler:ModalsHandler) {
-
+ private ModalsHandler:ModalsHandler
+ ) {
}
private fetchingComponentFromServer:boolean = false;
@@ -84,7 +92,6 @@ export class Palette implements ng.IDirective {
this.nodeHtmlSubstitute = $('<div class="node-substitute"><span></span><img /></div>');
el.append(this.nodeHtmlSubstitute);
this.registerEventListenerForLeftPalette(scope);
- // this.LeftPaletteLoaderService.loadLeftPanel(scope.currentComponent.componentType);
this.initComponents(scope);
this.initEvents(scope);
@@ -96,31 +103,15 @@ export class Palette implements ng.IDirective {
});
};
- private getUpdateLeftPaletteEventName = (component:Component):string => {
- switch (component.componentType) {
- case ComponentType.SERVICE:
- return EVENTS.SERVICE_LEFT_PALETTE_UPDATE_EVENT;
- case ComponentType.RESOURCE:
- if((<Resource>component).resourceType == ResourceType.PNF){
- return EVENTS.RESOURCE_PNF_LEFT_PALETTE_UPDATE_EVENT;
- }else{
- return EVENTS.RESOURCE_LEFT_PALETTE_UPDATE_EVENT;
- }
- default:
- console.log('ERROR: Component type '+ component.componentType + ' is not exists');
- }
- };
private registerEventListenerForLeftPalette = (scope:IPaletteScope):void => {
- let updateEventName:string = this.getUpdateLeftPaletteEventName(scope.currentComponent);
- this.EventListenerService.registerObserverCallback(updateEventName, () => {
+ this.EventListenerService.registerObserverCallback(EVENTS.LEFT_PALETTE_UPDATE_EVENT, () => {
this.updateLeftPanelDisplay(scope);
});
};
private unRegisterEventListenerForLeftPalette = (scope:IPaletteScope):void => {
- let updateEventName:string = this.getUpdateLeftPaletteEventName(scope.currentComponent);
- this.EventListenerService.unRegisterObserver(updateEventName);
+ this.EventListenerService.unRegisterObserver(EVENTS.LEFT_PALETTE_UPDATE_EVENT);
};
private leftPanelResourceFilter(resourcesNotAbstract:Array<LeftPaletteComponent>, resourceFilterTypes:Array<string>):Array<LeftPaletteComponent> {
@@ -132,7 +123,7 @@ export class Palette implements ng.IDirective {
private initLeftPanel(leftPanelComponents:Array<LeftPaletteComponent>, resourceFilterTypes:Array<string>):LeftPanelModel {
let leftPanelModel = new LeftPanelModel();
-
+
if (resourceFilterTypes && resourceFilterTypes.length) {
leftPanelComponents = this.leftPanelResourceFilter(leftPanelComponents, resourceFilterTypes);
}
@@ -151,10 +142,7 @@ export class Palette implements ng.IDirective {
private initEvents(scope:IPaletteScope) {
- /**
- *
- * @param section
- */
+
scope.sectionClick = (section:string) => {
if (section === scope.expandedSection) {
scope.expandedSection = '';
@@ -163,20 +151,37 @@ export class Palette implements ng.IDirective {
scope.expandedSection = section;
};
- scope.onMouseOver = (displayComponent:LeftPaletteComponent) => {
- if (scope.isOnDrag) {
- return;
+ scope.onMouseOver = (displayComponent:LeftPaletteComponent, sectionElem: HTMLElement) => {
+ if (this.isGroupOrPolicy(displayComponent)) {
+ this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_SHOW_POPUP_PANEL, scope.currentComponent, displayComponent, sectionElem);
+ } else {
+ if (scope.isOnDrag) {
+ return;
+ }
+ scope.isOnDrag = true;
+ this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, displayComponent);
+ this.$log.debug('palette::onMouseOver:: fired');
}
- scope.isOnDrag = true;
- this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_IN, displayComponent);
- this.$log.debug('palette::onMouseOver:: fired');
};
- scope.onMouseOut = () => {
- scope.isOnDrag = false;
- this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT);
+ scope.onMouseOut = (displayComponent:LeftPaletteComponent) => {
+ if(this.isGroupOrPolicy(displayComponent)) {
+ this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HIDE_POPUP_PANEL);
+ } else {
+ scope.isOnDrag = false;
+ this.EventListenerService.notifyObservers(GRAPH_EVENTS.ON_PALETTE_COMPONENT_HOVER_OUT);
+ }
+ };
+ }
+
+ private isGroupOrPolicy(component:LeftPaletteComponent): boolean {
+ if(component &&
+ (component.categoryType === LeftPaletteMetadataTypes.Group ||
+ component.categoryType === LeftPaletteMetadataTypes.Policy)) {
+ return true;
}
+ return false;
}
private initComponents(scope:IPaletteScope) {
@@ -193,10 +198,10 @@ export class Palette implements ng.IDirective {
let entityType:string = scope.currentComponent.componentType.toLowerCase();
let resourceFilterTypes:Array<string> = this.sdcConfig.resourceTypesFilter[entityType];
scope.components = this.LeftPaletteLoaderService.getLeftPanelComponentsForDisplay(scope.currentComponent);
- //remove the container component from the list
+ //remove the container component from the list
let componentTempToDisplay = angular.copy(scope.components);
- componentTempToDisplay = _.remove(componentTempToDisplay, function (component) {
- return component.component.invariantUUID !== scope.currentComponent.invariantUUID;
+ componentTempToDisplay = _.remove(componentTempToDisplay, function (leftPalettecomponent) {
+ return leftPalettecomponent.invariantUUID !== scope.currentComponent.invariantUUID;
});
scope.model = this.initLeftPanel(componentTempToDisplay, resourceFilterTypes);
scope.displaySortedCategories = angular.copy(scope.model.sortedCategories);
@@ -224,7 +229,7 @@ export class Palette implements ng.IDirective {
private initDragEvents(scope:IPaletteScope) {
scope.dragStartCallback = (event:IDragDropEvent, ui, displayComponent:LeftPaletteComponent):void => {
- if (scope.isLoading || !scope.isDragable || scope.isViewOnly) {
+ if (scope.isLoading || !scope.isDragable || scope.isViewOnly || this.isGroupOrPolicy(displayComponent)) {
return;
}
@@ -302,7 +307,8 @@ export class Palette implements ng.IDirective {
CompositionGraphGeneralUtils,
EventListenerService,
sdcMenu,
- ModalsHandler) => {
+ ModalsHandler
+ ) => {
return new Palette($log,
LeftPaletteLoaderService,
sdcConfig,
@@ -312,7 +318,8 @@ export class Palette implements ng.IDirective {
CompositionGraphGeneralUtils,
EventListenerService,
sdcMenu,
- ModalsHandler);
+ ModalsHandler
+ );
};
}
diff --git a/catalog-ui/src/app/directives/graphs-v2/palette/palette.html b/catalog-ui/src/app/directives/graphs-v2/palette/palette.html
index 7f9bfd1e0d..a8139e3140 100644
--- a/catalog-ui/src/app/directives/graphs-v2/palette/palette.html
+++ b/catalog-ui/src/app/directives/graphs-v2/palette/palette.html
@@ -24,9 +24,9 @@
</div>
<div class="i-sdc-designer-leftbar-section-content-item"
data-ng-class="{'default-pointer': isViewOnly}"
- data-ng-mouseover="!isViewOnly && onMouseOver(component)"
- data-ng-mouseleave="!isViewOnly && onMouseOut()"
- data-drag="{{!isViewOnly}}"
+ data-ng-mouseover="!isViewOnly && onMouseOver(component, $event.currentTarget)"
+ data-ng-mouseleave="!isViewOnly && onMouseOut(component)"
+ data-drag="!isViewOnly"
data-jqyoui-options="{revert: 'invalid', helper:setElementTemplate, appendTo:'body', cursorAt: {left:38, top: 38}, cursor:'move'}"
jqyoui-draggable="{index:{{$index}},animate:true,onStart:'dragStartCallback(component)',onStop:'dragStopCallback()', onDrag:'onDragCallback()'}"
data-ng-repeat="component in components | orderBy: 'displayName' track by $index"
@@ -40,14 +40,16 @@
</div>
</div>
<div class="i-sdc-designer-leftbar-section-content-item-info">
- <span class="i-sdc-designer-leftbar-section-content-item-info-title"
- uib-tooltip="{{component.displayName}}" tooltip-class="uib-custom-tooltip"
- tooltip-placement="bottom" tooltip-popup-delay="700">
- {{component.displayName}}</span>
+ <span class="i-sdc-designer-leftbar-section-content-item-info-title"
+ uib-tooltip="{{component.displayName}}" tooltip-class="uib-custom-tooltip"
+ tooltip-placement="bottom" tooltip-popup-delay="700">
+ {{component.displayName}}</span>
<div class="i-sdc-designer-leftbar-section-content-item-info-text">
V.{{component.version}}
</div>
- <div class="i-sdc-designer-leftbar-section-content-item-info-text"> Type:
+ <div class="i-sdc-designer-leftbar-section-content-item-info-text"
+ uib-tooltip="{{component.type}}" tooltip-class="uib-custom-tooltip"
+ tooltip-placement="top" tooltip-popup-delay="700"> Type:
{{component.componentSubType}}
</div>
</div>
diff --git a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts b/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts
index f73e855c0e..78a269ead1 100644
--- a/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts
+++ b/catalog-ui/src/app/directives/graphs-v2/relation-menu/relation-menu.ts
@@ -18,6 +18,7 @@
* ============LICENSE_END=========================================================
*/
'use strict'
+import * as _ from "lodash";
import {Match, ConnectRelationModel} from "app/models";
import {Component} from "../../../models/components/component";