1e034fade0043776fcf914910fa94e4a1c06f995
[aai/sparky-fe.git] / src / app / byoq / CustomDslBuilder.jsx
1 /*
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2021 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *       http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 import React, {Component} from 'react';
22 import commonApi from 'utils/CommonAPIService.js';
23 import {GeneralCommonFunctions} from 'utils/GeneralCommonFunctions.js';
24 import Modal from 'react-bootstrap/lib/Modal';
25 import Grid from 'react-bootstrap/lib/Grid';
26 import FormGroup from 'react-bootstrap/lib/FormGroup';
27 import FormControl from 'react-bootstrap/lib/FormControl';
28 import ControlLabel from 'react-bootstrap/lib/ControlLabel';
29 import Button from 'react-bootstrap/lib/Button';
30 import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
31 import Spinner from 'utils/SpinnerContainer.jsx';
32 import Row from 'react-bootstrap/lib/Row';
33 import Col from 'react-bootstrap/lib/Col';
34 import Panel from 'react-bootstrap/lib/Panel';
35 import Tooltip from 'react-bootstrap/lib/Tooltip';
36 import FilterTypes from 'generic-components/filter/components/FilterTypes.jsx';
37 import PathFilterDslBuilder from './PathFilterDslBuilder.jsx';
38 import CustomDSLSaveLoad from 'app/byoq/CustomDSLSaveLoad.jsx';
39 import BootstrapSwitchButton from 'bootstrap-switch-button-react';
40 import * as d3 from "d3";
41 import 'd3-selection-multi';
42
43
44 let EDGERULES = GlobalExtConstants.EDGERULES;
45 let OXM = GlobalExtConstants.OXM;
46 let INVLIST = GlobalExtConstants.INVLIST;
47 let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
48 let APERTURE_SERVICE = JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
49
50
51 let nodeTypes = [];
52 let properties = null;
53 let traverseRulesDsl = [];
54
55 const settings = {
56         'NODESERVER': INVLIST.NODESERVER,
57         'PROXY': INVLIST.PROXY,
58         'PREFIX': INVLIST.PREFIX,
59         'VERSION': INVLIST.VERSION,
60     'APERTURE': INVLIST.APERTURE,
61     'USESTUBS': INVLIST.useStubs
62 };
63 class CustomDslBuilder extends Component {
64         constructor(props) {
65                 console.log('props>>>>',props);
66         super(props);
67         this.saveLoadComponent = React.createRef();
68         APERTURE_SERVICE=JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
69                 this.state = {edgeRules : null,
70                               connectableNodes:[],
71                               showNodeModal: false,
72                               enableModalFeedback: false,
73                               showEditNodeModal: false,
74                               treemap: null,
75                               root: null,
76                               svg: null,
77                               duration: null,
78                               g: null,
79                               selectedNode: null,
80                               traverseToNodes:[],
81                               traverseToNodeAttributes: [],
82                               nodeDetails: [],
83                               dslQuery: '',
84                               editModel:'',
85                               showEditModal: false,
86                               zoomFit: null,
87                               autoZoomEnabled: true,
88                               aggregateObjects: false,
89                               init: true,
90                               filterTypeDisplay: 'Filter Type',
91                       selectedfilterType:[],
92                       oxmMapping: null,
93                       initialRootEdit: true,
94                               showPathFilterDslBuilder: false,
95                       pathFilterNodeType: '',
96                       pathFilterNodeName:'',
97                       pathFIlterAttrDetails: [],
98                       dslPathBuilder:'',
99                       dslPathTree:'',
100                       loadedQueries: [],
101                       queryDescription: '',
102                       queryName: '',
103                       category:'',
104                       queryId:'',
105                       treeLoadErrMsg: '',
106                       isEditEnable:false,
107                       pathFilterIndex:0,
108                       isDataSteward: sessionStorage.getItem(ENVIRONMENT + 'roles') && sessionStorage.getItem(ENVIRONMENT + 'roles').indexOf('data_steward_ui_view') > -1,
109                       isPublicChecked: sessionStorage.getItem(ENVIRONMENT + 'roles') && sessionStorage.getItem(ENVIRONMENT + 'roles').indexOf('data_steward_ui_view') > -1,
110                       enableRealTime: JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'ENABLE_ANALYSIS'))
111                     }
112             this.baseState=this.state;
113   }
114   componentDidMount () {
115     console.log('componentDidMount',JSON.stringify(this.props));
116     //this.buildSQLStatementsFromSchema();
117     this.processEdgeRules(EDGERULES);
118     if(this.props.match.params.type && this.props.match.params.propId) {
119         this.build(this.props.match.params.type, this.props.match.params.propId);
120     }
121   }
122   initialize = () =>{
123     this.setState({enableModalFeedback: true}, function () {
124                                                   //console.log("EnableModalFeedback: " + this.state.enableModalFeedback);
125                                                   setTimeout(() => {this.postSpinner()},1);
126                                               });
127   }
128
129   postSpinner = () => {
130
131     var nodeDetails = [];
132     var node = null;
133     console.log('initializing');
134     var id = GeneralCommonFunctions.generateID();
135     var nodeTypes = GeneralCommonFunctions.getNodeTypes();
136     for (var i = 0; i < nodeTypes.length; i++) {
137             node = nodeTypes[i] + id;
138             var attributes = GeneralCommonFunctions.getFilteringOptions(nodeTypes[i]);
139             if(!nodeDetails[node] && Object.keys(attributes).length > 0){
140                 nodeDetails[node] = {};
141                 nodeDetails[node].nodeType = nodeTypes[i];
142                 nodeDetails[node].isSelected = false;
143                 nodeDetails[node].attrDetails = attributes;
144                 nodeDetails[node].parentContainer = GeneralCommonFunctions.populateContainer(nodeTypes[i]);
145             }
146     }
147     let nodesSorted = nodeDetails.sort(function (filter1, filter2) {
148         if (filter1.nodeType < filter2.nodeType) {
149                 return -1;
150         } else if (filter1.nodeType > filter2.nodeType) {
151                 return 1;
152         } else {
153                 return 0;
154         }
155     });
156     //console.log('Node Types List' + JSON.stringify(nodesSorted));
157     nodeDetails = nodesSorted;
158     this.setState({nodeDetails: nodeDetails, showNodeModal: true, enableModalFeedback: false});
159   }
160   processEdgeRules = (data) => {
161         this.setState({
162                 edgeRules: data.rules
163         },()=>{this.baseState=this.state});
164   }
165   closeNodeModal = () =>{
166     this.setState({
167         showNodeModal: false,
168         enableModalFeedback: false,
169         traverseToNodes: [],
170         selectedNode: null
171     });
172   }
173   closeEditNodeModal = () =>{
174     this.setState({
175         showEditNodeModal: false,
176         selectedNode: null,
177         showPathFilterDslBuilder: false
178     });
179   }
180   closePathNodeModal = () =>{
181     console.log('closePathNodeModal>>>>>>>');
182     this.setState({
183         showPathFilterDslBuilder: false,
184         pathFilterNodeType: '',
185         pathFilterNodeName:'',
186         pathFIlterAttrDetails: []
187     });
188   }
189   submitPathNodeModal = (dslQuery,nodetype,dslQueryTree,isEditEnable,pathFilterIndex) =>{
190     console.log('CustomDSLBuilder  submitPathNodeModel>>>>>dslQuery ###',dslQuery);
191     console.log(isEditEnable+'<<submitPathNodeModal this.state.nodeDetails>>>>',this.state.nodeDetails)  
192     var nodeDetails = this.state.nodeDetails;
193     if(!nodeDetails[nodetype].dslPath){
194         nodeDetails[nodetype].dslPath=[];
195         nodeDetails[nodetype].dslPathTree=[];
196     }
197     if(isEditEnable){        
198         nodeDetails[nodetype].dslPath[pathFilterIndex]=dslQuery;
199         nodeDetails[nodetype].dslPathTree[pathFilterIndex]=dslQueryTree;
200         console.log('nodeDetails on edit>>>>>>>>>',nodeDetails);
201     }else{        
202         nodeDetails[nodetype].dslPath.push(dslQuery);
203         nodeDetails[nodetype].dslPathTree.push(dslQueryTree);
204     }    
205     this.setState({ nodeDetails: nodeDetails },()=>{this.closePathNodeModal()});    
206   }
207  editPathNodeModal = (key,path,tree,indx) =>{
208     console.log('editPathNodeModal>>>>>>>>>###',indx);
209     let attrDetails=this.state.nodeDetails[key].attrDetails; 
210     let nodeType=this.state.nodeDetails[key].nodeType;
211     this.setState({showPathFilterDslBuilder: true,pathFilterNodeType: key,pathFilterNodeName:nodeType,pathFIlterAttrDetails: '',dslPathBuilder: path,dslPathTree:tree,isEditEnable:true,pathFilterIndex:indx}); 
212  }
213  deletePathNodeModal = (key,path,tree,index) =>{
214     console.log(index+'<<deletePathNodeModal>>>>>',key);
215     var nodeDetails = this.state.nodeDetails;
216     nodeDetails[key].dslPath.splice(index,1);
217     nodeDetails[key].dslPathTree.splice(index,1);
218     this.setState({ nodeDetails: nodeDetails });
219  }
220   onNodeCheckbox(e) {
221       var nodeDetails = this.state.nodeDetails;
222       if (e.target.checked) {
223         nodeDetails[e.target.value].isSelected = true;
224         this.selectAll(e.target.value);
225       }else {
226         nodeDetails[e.target.value].isSelected = false;
227         this.deselectAll(e.target.value);
228       }
229       // update the state with the new array of traverse to nodes
230       this.setState({ nodeDetails: nodeDetails });
231   }
232   onNodeRadio(e) {
233       var nodeDetails = this.state.nodeDetails;
234       if (e.target.checked) {
235         nodeDetails[e.target.value].isSelected = true;
236         this.selectAll(e.target.value);
237       }
238       for (var key in nodeDetails) {
239           if(key != e.target.value && nodeDetails[key].isSelected ){
240             nodeDetails[key].isSelected = false;
241             this.deselectAll(key);
242           }
243       }
244       // update the state with the new array of traverse to nodes
245       this.setState({ nodeDetails: nodeDetails });
246   }
247   onAutoZoomCheckbox(e) {
248       var cbValue = false;
249       if (e.target.checked) {
250         cbValue = true;
251       }else {
252         cbValue = false;
253       }
254       this.setState({ autoZoomEnabled: cbValue });
255   }
256   onAggregateCheckbox(e) {
257       var cbValue = false;
258       if (e.target.checked) {
259         cbValue = true;
260       }else {
261         cbValue = false;
262       }
263       this.setState({ aggregateObjects: cbValue });
264   }
265   onAttributeCheckbox(e){
266         let splitVal = e.target.value.split("|");
267         let nodeKey = splitVal[0];
268         let attrValue = splitVal[1];
269         let nodeDetails = this.state.nodeDetails;
270         let node = nodeDetails[nodeKey];
271         let attribute = null;
272         if(!node.attrDetails){
273             node.attrDetails = [];
274         }
275         if(!node.attrDetails[attrValue]){
276             node.attrDetails[attrValue] = {};
277             node.attrDetails[attrValue].isSelected = true;
278             node.attrDetails[attrValue].filterValue = [];
279             node.attrDetails[attrValue].filterType = [];
280             node.attrDetails[attrValue].dslPath = [];
281             node.attrDetails[attrValue].dslPathTree = [];
282         }
283
284         // check if the check box is checked or unchecked
285         if (e.target.checked) {
286           // add the value of the checkbox to nodes array
287           node.attrDetails[attrValue].isSelected = true;
288           node.attrDetails[attrValue].filterType[0]='EQ';
289         } else {
290           // or remove the value from the unchecked checkbox from the array
291           node.attrDetails[attrValue].isSelected = false;
292           //node.attrDetails[attrValue].filterType = [''];
293           //node.attrDetails[attrValue].filterValue = [''];
294         }
295         nodeDetails[nodeKey] = node;
296         // update the state with the new array of traverse to nodes
297         this.setState({ nodeDetails: nodeDetails });
298   }
299   onFilterValueChange(e, nodeKey, attrKey, indx){
300         let nodeDetails = this.state.nodeDetails;
301         let node = nodeDetails[nodeKey];
302         if(!node.attrDetails){
303             node.attrDetails = [];
304         }
305         if(!node.attrDetails[attrKey]){
306             node.attrDetails[attrKey] = {};
307             node.attrDetails[attrKey].isSelected = true;
308             node.attrDetails[attrKey].filterValue = [];
309             node.attrDetails[attrKey].filterType = [];
310             node.attrDetails[attrValue].dslPath = [];
311             node.attrDetails[attrValue].dslPathTree = [];
312         }
313         // add the value of the checkbox to nodes array
314         //node.attrDetails[attrKey].filterValue.push(e.target.value);
315         let filterValArr=node.attrDetails[attrKey].filterValue;
316         filterValArr[indx]=e.target.value;
317         node.attrDetails[attrKey].filterValue=filterValArr;
318         nodeDetails[nodeKey] = node;
319         // update the state with the new array of traverse to nodes
320         this.setState({ nodeDetails: nodeDetails });
321   }
322   submitNodeModal = () =>{
323     if(this.state.selectedNode){
324         var d = this.state.selectedNode;
325         for(var node in this.state.nodeDetails){
326             if(this.state.nodeDetails[node].isSelected){
327                 var newNodeObj = {
328                                 type: 'node',
329                             name: this.state.nodeDetails[node].nodeType,
330                             details: {}
331                           };
332                  //Creates new Node
333                  Object.assign(newNodeObj.details, this.state.nodeDetails[node]);
334                  var newNode = d3.hierarchy(newNodeObj);
335                  newNode.depth = d.depth + 1;
336                  newNode.height = d.height - 1;
337                  newNode.parent = d;
338                  newNode.id = node;
339                  if(!d.children){
340                     d.children = [];
341                  }
342                 if(newNodeObj.details){
343                    var selectedAttributeCount = 0;
344                    for (var key in newNodeObj.details.attrDetails){
345                         if (newNodeObj.details.attrDetails[key].isSelected){
346                             selectedAttributeCount++;
347                         }
348                         if(selectedAttributeCount === Object.keys(newNodeObj.details.attrDetails).length){
349                            newNodeObj.details.includeInOutput = true;
350                         }
351                    }
352                 }
353                  d.children.push(newNode);
354                  this.setState({ nodeDetails: [] });
355         }
356       }
357       this.update(this, d);
358       this.setState({
359                 showNodeModal: false,
360                 enableModalFeedback: false,
361                 traverseToNodes: [],
362                 selectedNode: null
363        });
364     }else{
365         var nodeType = "";
366         var attrDetails = null;
367         var dslPath =[];
368         var dslPathTree=[];
369         for (var key in this.state.nodeDetails) {
370             if(this.state.nodeDetails[key].isSelected){
371               nodeType = this.state.nodeDetails[key].nodeType;
372               attrDetails = this.state.nodeDetails[key].attrDetails;
373               dslPath =this.state.nodeDetails[key].dslPath;
374               dslPathTree=this.state.nodeDetails[key].dslPathTree;
375             }
376         }
377        this.build(nodeType, null, attrDetails,null,dslPath,dslPathTree);
378        this.setState({ nodeDetails: [], showNodeModal: false, enableModalFeedback:false, traverseToNodes: [], selectedNode: null });
379     }
380   }
381   submitEditNodeModal  = () =>{
382     this.update(this, this.state.selectedNode);
383     this.setState({showEditNodeModal: false,showPathFilterDslBuilder:false});
384   }
385   populateEdgeRules = (nodeType) => {
386         let  nodeDetails=GeneralCommonFunctions.populateEdgeRules(nodeType,this.state.edgeRules);
387             this.setState({
388                 nodeDetails: nodeDetails
389         });
390   }
391  
392   buildOXMAttributesAndReturn = (nodeType) =>{
393     var oxmArray = [];
394     var result = JSON.parse(OXM);
395     var arrayOfTypes = result['xml-bindings']['java-types'][0]['java-type'];
396     for (var i = 0; i < arrayOfTypes.length; i++) {
397         var propertiesDsl = [];
398         for (var j = 0; j < arrayOfTypes[i]['java-attributes'][0]['xml-element'].length; j++) {
399             let property =  arrayOfTypes[i]['java-attributes'][0]['xml-element'][j]['$']['name'];
400             let type = arrayOfTypes[i]['java-attributes'][0]['xml-element'][j]['$']['type'];
401             if (type === 'java.lang.String' || type === 'java.lang.Boolean') {
402                 propertiesDsl[property] = {};
403                 propertiesDsl[property].isSelected = false;
404                 propertiesDsl[property].attributeName = property;
405                 propertiesDsl[property].filterValue = [''];
406                 propertiesDsl[property].filterType = [''];
407                 propertiesDsl[property].dslPath = [];
408                 propertiesDsl[property].dslPathTree = [];
409             }
410         }
411         let sortedPropertiesDsl = propertiesDsl.sort(function (filter1, filter2) {
412                 if (filter1.attributeName < filter2.attributeName) {
413                         return -1;
414                 } else if (filter1.attributeName > filter2.attributeName) {
415                         return 1;
416                 } else {
417                         return 0;
418                 }
419         });
420         oxmArray[GeneralCommonFunctions.camelToDash(arrayOfTypes[i]['xml-root-element'][0]['$']['name'])] = sortedPropertiesDsl;
421     }
422     this.setState({oxmMapping: oxmArray});
423     return oxmArray[nodeType];
424   }
425
426   runDSL = () => {
427     console.log("running DSL");
428     let paramToPassThrough = '';
429     if(this.state.aggregateObjects){
430         paramToPassThrough = '/customDsl/built-aggregate/' + btoa('<pre>' + this.state.dslQuery + '</pre>');
431     }else{
432         paramToPassThrough = '/customDsl/built/' + btoa('<pre>' + this.state.dslQuery + '</pre>');
433     }
434     this.props.history.push(paramToPassThrough);
435   }
436   submitEditAndRunDSL = () =>{
437     this.setState({ dslQuery: this.state.editModel }, () => this.runDSL());
438   }
439   showEditDSLModal = () => {
440     console.log("enabling DSL edit modal");
441     this.setState({ editModel: this.state.dslQuery, showEditModal: true });
442   }
443   closeEditDSLModal = () => {
444     console.log("closing DSL edit modal");
445     this.setState({ showEditModal: false });
446   }
447   bindEdits = (e) => {
448     this.setState({ editModel: e.target.value });
449   }
450   populateDSL = (tree, isInit) =>{
451         var DSL = '';
452         var treeArray = '';
453         var treeArrayLength = 0;
454         if(isInit){
455             treeArray = tree;
456             treeArrayLength = 1;
457         }else{
458             treeArray = tree.children;
459             treeArrayLength = tree.children.length;
460         }
461         for(var k = 0; treeArray && k < treeArrayLength; k++){
462             if(k === 0 && treeArrayLength > 1){
463                 DSL += '[';
464             }
465             var node = '';
466             if(isInit){
467                 node = tree;
468             }else{
469                 node = treeArray[k];
470             }
471             if(node.data){
472                 console.log('Node data while rendering DSl path>>',JSON.stringify(node.data));
473                 DSL += node.data.name;
474                 let propState=false;
475                 if(node.data.details){
476                     var tempAttributeString = '';
477                     var selectedAttributeCount = 0;
478                     for (var key in node.data.details.attrDetails){
479                         if (node.data.details.attrDetails[key].isSelected){
480                             selectedAttributeCount++;
481                             let aliasWithProp=node.data.details.attrDetails[key].attributeName;
482                             if(node.data.details.attrDetails[key].alias){
483                                 aliasWithProp= aliasWithProp+'\' as \''+node.data.details.attrDetails[key].alias;
484                             }
485                             if(selectedAttributeCount === 1){
486                                 tempAttributeString += '{\'' + aliasWithProp +'\'';
487                                 propState=true;
488                             }else{
489                                 tempAttributeString += ',\'' + aliasWithProp + '\'';
490                             }
491                         }
492                     }
493                     if(selectedAttributeCount === Object.keys(node.data.details.attrDetails).length){
494                         DSL+= '*';
495                     }
496                     if((selectedAttributeCount < Object.keys(node.data.details.attrDetails).length) && propState){
497                         DSL += tempAttributeString + '}';
498                     }                    
499                     for (var key in node.data.details.attrDetails){
500                         if(node.data.details.attrDetails[key].filterValue && node.data.details.attrDetails[key].filterValue[0] !==''){
501                             DSL += '(\'' + node.data.details.attrDetails[key].attributeName + '\',';
502                             let dslValues='';
503                             for(var indx=0; indx<node.data.details.attrDetails[key].filterValue.length; indx++){                            
504                                 dslValues=(indx>0) ? dslValues+',':dslValues;
505                                 if(this.state.enableRealTime && node.data.details.attrDetails[key].filterType && node.data.details.attrDetails[key].filterType[indx]){
506                                     dslValues += node.data.details.attrDetails[key].filterType[indx]+'(\''+ node.data.details.attrDetails[key].filterValue[indx] + '\')';                                    
507                                 }else{
508                                     dslValues +='\''+node.data.details.attrDetails[key].filterValue[indx] + '\'';                                    
509                                 }                      
510                                 if(node.data.details.attrDetails[key].filterValue.length-1 ===  indx){
511                                     dslValues +=')';
512                                 }
513                             }                        
514                             DSL += dslValues;
515                         }
516                     }
517                     if(node.data.details.dslPath && node.data.details.dslPath.length>0){
518                         for(var n in node.data.details.dslPath){
519                             DSL += node.data.details.dslPath[n];
520                         }                        
521                     }
522                 }
523             }
524             if(node.children){
525                 DSL+= '>' + this.populateDSL(node);
526             }
527             if(k !==  treeArrayLength - 1){
528                 DSL += ',';
529             }
530             if(k === treeArrayLength - 1 && treeArrayLength > 1){
531                 DSL += ']';
532             }
533         }
534         return DSL;
535   }
536   update = (base, source, isInit) => {
537
538         // Assigns the x and y position for the nodes
539         var treeData = base.state.treemap(base.state.root);
540
541         var DSL = base.populateDSL(treeData, true);
542         console.log(JSON.stringify("DSL :" + DSL));
543
544         this.setState({ dslQuery: DSL });
545
546         // Compute the new tree layout.
547         var nodes = treeData.descendants(),
548             links = treeData.descendants().slice(1);
549
550         var list1 = d3.selectAll(".fa")
551             .filter(".fa-plus")
552             .style("display", "block");
553
554         // Normalize for fixed-depth.
555         nodes.forEach(function(d){ d.y = d.depth * 100});
556         // ****************** Nodes section ***************************
557
558         // Update the nodes...
559         var node = base.state.g.selectAll('g.node')
560             .data(nodes, function(d) {return d.id });
561
562         // Enter any new modes at the parent's previous position.
563         var nodeEnter = node.enter().append('g')
564             .attr('class', 'node')
565             .attr("transform", function(d) {
566               return "translate(" + source.y0 + "," + source.x0 + ")";
567           })
568          // .on('click', click)
569           .on('dblclick', doubleClick);
570
571         // Add Circle for the nodes
572         nodeEnter.append('circle')
573             .attr('class', 'node')
574             .attr('r', 1e-6)
575             .style("fill", "lightsteelblue");
576         nodeEnter.append("svg:foreignObject")
577                 .attr("width", 20)
578                 .attr("height", 25)
579                 .attr("y", -14)
580                 .attr("x", -10)
581             .append("xhtml:span")
582                      .attr("class", function (d) {
583                                     let icon = '';
584                                     if(!INVLIST.IS_ONAP){
585                                         icon = 'icon-datanetwork-serverL';
586                                     }else{
587                                         icon = 'browse-fa fa fa-server';
588                                     }
589                                     if(d.data.details && d.data.details.parentContainer){
590                                         var iconKey = ((d.data.details.parentContainer).replace(/-/g, '')).toUpperCase();
591                                         if(INVLIST.INVENTORYLIST[iconKey] && INVLIST.INVENTORYLIST[iconKey].icon){
592                                             return INVLIST.INVENTORYLIST[iconKey].icon;
593                                         }else{
594                                             return icon;
595                                         }
596                                     }else{
597                                         return icon;
598                                     }
599                       })
600                  .style("font-size", function (d) {
601                                      if (!INVLIST.IS_ONAP){
602                                         return "20px";
603                                      } else {
604                                         return "16px";
605                                      }
606                  })
607                  .attr("id", function (d) {return "nodeIcon" + d.id})
608                  .style("color", '#387dff')
609                  .style("display", "block")
610                  .style("padding-top",function(d){
611                                       if (!INVLIST.IS_ONAP){
612                                         return "0px";
613                                       } else {
614                                         return "8px";
615                                       }
616                  });
617
618         nodeEnter.append("svg:foreignObject")
619                 .attr("width", 6)
620                 .attr("height", 6)
621                 .attr("y", 10)
622                 .attr("x", -10)
623                 .on('click', function (d) {
624                     if(d.data.details.isRootNode){
625                         d = null;
626                         base.resetBuilder();
627                     }else{
628                         for(var i = 0; d.parent.children && i < d.parent.children.length; i++){
629                             if (d.parent.children.length > 1 && d.data.name === d.parent.children[i].data.name){
630                                 d.parent.children.splice(i, 1);
631                             }else if (d.parent.children.length === 1 && d.data.name === d.parent.children[i].data.name){
632                                 d.parent.children = null;
633                             }
634                         }
635                         base.update(base, d);
636                     }
637                 })
638             .append("xhtml:span")
639                      .attr("class", "fa fa-minus")
640                      .style("padding-top", "1px")
641                  .style("font-size", function (d){ return "5px";})
642                  .attr("id", function (d) {return "nodeDelete" + d.data.id})
643                  .style("color", '#387dff')
644                  .style("display", function (d) {return "block";});
645         nodeEnter.append("svg:foreignObject")
646                          .attr("width", 6)
647                          .attr("height", 6)
648                          .attr("y", 10)
649                          .attr("x", 5)
650                          .on('click', function (d) { base.setState({enableModalFeedback: true}, function () {setTimeout(() => {add(d)},1);})})
651                      .append("xhtml:span")
652                               .attr("class", "fa fa-plus")
653                               .style("padding-top", "1px")
654                           .style("font-size", function (d){ return "5px";})
655                           .attr("id", function (d) {return "nodeAdd" + d.data.id})
656                           .style("color", '#387dff');
657         nodeEnter.append("svg:foreignObject")
658                                  .attr("width", 6)
659                                  .attr("height", 6)
660                                  .attr("y", -17)
661                                  .attr("x", -10)
662                                  .on('click', function (d) { edit(d)})
663                              .append("xhtml:span")
664                                       .attr("class", "fa fa-pencil-square")
665                                       .style("padding-top", "1px")
666                                   .style("font-size", function (d){ return "5px";})
667                                   .attr("id", function (d) {return "nodeEdit" + d.data.id})
668                                   .style("color", '#387dff');
669         // Add labels for the nodes
670         nodeEnter.append("svg:foreignObject")
671                   .attr("width", 60)
672                   .attr("height", 40)
673                   .attr("y", -10)
674                   .attr("x", -75)
675                   .append("xhtml:span")
676                   .append('text')
677                     .attr("dy", ".35em")
678                     .attr("x", function(d) {
679                         return d.children ? -13 : 13;
680                     })
681                     .text(function(d) { return d.data.name; })
682                     .style("float","right")
683                     .style("color", '#000000');
684
685         // UPDATE
686         var nodeUpdate = nodeEnter.merge(node);
687         var postNodeDrawnCallBack = function (d){
688           if(!isInit && base.state.autoZoomEnabled || d.data.details.isRootNode){
689              base.state.zoomFit();
690           }
691         }
692         // Transition to the proper position for the node
693         nodeUpdate.transition()
694           .duration(base.state.duration)
695           .attr("transform", function(d) {
696               return "translate(" + d.y + "," + d.x + ")"
697            }).on("end", postNodeDrawnCallBack);
698
699         // Update the node attributes and style
700         nodeUpdate.select('circle.node')
701           .attr('r', 11)
702           .style("fill", "lightsteelblue")
703           .attr('cursor', 'pointer');
704
705
706         // Remove any exiting nodes
707         var nodeExit = node.exit().transition()
708             .duration(base.state.duration)
709             .attr("transform", function(d) {
710                 return "translate(" + source.y + "," + source.x + ")";
711             })
712             .remove();
713
714         // On exit reduce the node circles size to 0
715         nodeExit.select('circle')
716           .attr('r', 1e-6);
717
718         // On exit reduce the opacity of text labels
719         nodeExit.select('text')
720           .style('fill-opacity', 1e-6);
721
722         // ****************** links section ***************************
723
724         // Update the links...
725         var link = base.state.g.selectAll('path.link')
726             .data(links, function(d) { return d.id; });
727
728         // Enter any new links at the parent's previous position.
729         var linkEnter = link.enter().insert('path', "g")
730             .attr("class", "link")
731             .attr('d', function(d){
732               var o = {x: source.x0, y: source.y0}
733               return diagonal(o, o)
734             });
735
736         // UPDATE
737         var linkUpdate = linkEnter.merge(link);
738
739         // Transition back to the parent element position
740         linkUpdate.transition()
741             .duration(base.state.duration)
742             .attr('d', function(d){ return diagonal(d, d.parent) });
743
744         // Remove any exiting links
745         var linkExit = link.exit().transition()
746             .duration(base.state.duration)
747             .attr('d', function(d) {
748               var o = {x: source.x, y: source.y}
749               return diagonal(o, o)
750             })
751             .remove();
752
753         // Store the old positions for transition.
754         nodes.forEach(function(d){
755           d.x0 = d.x;
756           d.y0 = d.y;
757         });
758
759         // Creates a curved (diagonal) path from parent to the child nodes
760         function diagonal(s, d) {
761           var path = 'M ' + s.y + ' ' + s.x + ' C ' + ((s.y + d.y) / 2) + ' ' + s.x + ' ' +  (s.y + d.y) / 2 + ' ' + d.x + ' ' + d.y + ' ' + d.x;
762           return path
763         }
764         base.state.svg.on("dblclick.zoom", null);
765         // Toggle children on click.
766         function add(d){
767             base.populateEdgeRules(d.data.name,base.state.edgeRules);
768             if(!d.children){
769               d.children = [];
770               d.data.children = [];
771             }
772             base.setState({
773               selectedNode: d,
774               showNodeModal: true,
775               enableModalFeedback: false
776             });
777
778         }
779         function edit(d){
780             console.log("object editing: " + d);
781             var nodeDetails = base.state.nodeDetails;
782             //set up node details to have the node to edit
783             if(d.data.details.isRootNode && base.props.match.params.type){
784                 var attributes = GeneralCommonFunctions.getFilteringOptions(d.data.details.nodeType);
785                 if(Object.keys(attributes).length > 0){
786                     nodeDetails[0] = {};
787                     nodeDetails[0].isRootNode = true;
788                     nodeDetails[0].nodeType = base.props.match.params.type;
789                     nodeDetails[0].isSelected = true;
790                     nodeDetails[0].attrDetails = attributes;
791                     if(base.state.initialRootEdit){
792                         for (var key in nodeDetails[0].attrDetails) {
793                             nodeDetails[0].attrDetails[key].isSelected = true;
794                         }
795                     }
796                     nodeDetails[0].parentContainer = GeneralCommonFunctions.populateContainer(base.props.match.params.type);
797                     for (var key in d.data.details.attrDetails) {
798                         nodeDetails[0].attrDetails[key] = d.data.details.attrDetails[key];
799                         if(base.state.initialRootEdit){
800                             nodeDetails[0].attrDetails[key].filterType = [];
801                             nodeDetails[0].attrDetails[key].filterType.push('EQ');
802                         }
803                     }
804                 }
805                 d.data.details = nodeDetails[0];
806                 base.setState({
807                   initialRootEdit: false
808                 });
809             }else{
810                 nodeDetails[0] = d.data.details;
811             }
812             base.setState({
813               selectedNode: d,
814               showEditNodeModal: true,
815               showPathFilterDslBuilder: false
816             });
817         }
818         function doubleClick(d) {
819             edit(d);
820         }
821       }
822   selectAll = (nodeKey) =>{
823     var nodeDetails = this.state.nodeDetails;
824     for (var key in nodeDetails[nodeKey].attrDetails) {
825         nodeDetails[nodeKey].attrDetails[key].isSelected = true;
826     }
827     this.setState({nodeDetails: nodeDetails});
828   }
829   deselectAll = (nodeKey) =>{
830     var nodeDetails = this.state.nodeDetails;
831     for (var key in nodeDetails[nodeKey].attrDetails) {
832         nodeDetails[nodeKey].attrDetails[key].isSelected = false;
833     }
834     this.setState({nodeDetails: nodeDetails});
835   }
836   build = (type, propID, attrDetails, preBuiltTree,dslPath,dslPathTree) =>{
837     var selected = null;
838     var treeData;
839     if(!preBuiltTree && type && (propID || attrDetails)){
840         let nodeType =  type;
841         treeData = {
842             "name": nodeType,
843             "id": nodeType,
844             "children": [],
845             "details":{},
846             "dslPath":[],
847             "dslPathTree":[]
848         }
849         treeData.details.includeInOutput = true;
850         treeData.details.isSelected = true;
851         treeData.details.isRootNode = true;
852         treeData.details.nodeType = nodeType;
853         if(attrDetails){
854             treeData.details.attrDetails = attrDetails;
855         } else{
856             treeData.details.attrDetails = {};
857         }        
858         if(dslPath && dslPath.length>0 && dslPathTree && dslPathTree.length>0){
859             treeData.details.dslPath=dslPath;
860             treeData.details.dslPathTree=dslPathTree;
861         }
862         if(propID){
863             let propIds = (propID) ? propID.split(';') : '';
864             let propertyValue = '';
865             for(var i  in propIds){
866                 let propValue = propIds[i].split(':');
867                 console.log(propValue[0] + '....' + propValue[1]);
868                 treeData.details.attrDetails[propValue[0]] = {};
869                 treeData.details.attrDetails[propValue[0]].filterValue=[];
870                 treeData.details.attrDetails[propValue[0]].filterValue.push(atob(propValue[1]).replace('<pre>','').replace('</pre>',''));
871                 treeData.details.attrDetails[propValue[0]].attributeName = propValue[0];
872                 treeData.details.attrDetails[propValue[0]].isSelected = true;
873             }
874         }
875     }else if (preBuiltTree){
876         treeData = preBuiltTree;
877         if(treeData.details && treeData.details.dslPathTree && treeData.details.dslPathTree.length>0){
878             for(var x=0;x<treeData.details.dslPathTree.length;x++){
879                 treeData.details.dslPath.push(GeneralCommonFunctions.populatePathDSL(treeData.details.dslPathTree[x],true,true,this.state.enableRealTime));
880             }
881         }
882         if(treeData.children && treeData.children.length>0){
883             for(var x=0;x<treeData.children.length;x++){               
884                treeData.children[x]=this.updateDslPathValueOnExtract(treeData.children[x]);
885             }
886         }
887     }
888
889     // append the svg object to the body of the page
890     // appends a 'group' element to 'svg'
891     // moves the 'group' element to the top left margin
892     var svg = d3.select("#DSLBuilder");
893     // Set the dimensions and margins of the diagram
894
895     var margin = {top: 20, right: 120, bottom: 20, left: 120},
896            width = +svg.attr("width") - margin.right - margin.left,
897            height = +svg.attr("height") - margin.top - margin.bottom;
898
899     var g = svg.append("g")
900         .attr("transform", "translate("
901               + margin.left + "," + margin.top + ")");
902
903     var duration = 750,
904         root;
905
906     // declares a tree layout and assigns the size
907     var treemap = d3.tree().size([height - 200, width]);
908
909     // Assigns parent, children, height, depth
910     root = d3.hierarchy(treeData, function(d) { return d.children; });
911     root.x0 = height / 2;
912     root.y0 = 0;
913
914     //Zoom functions
915     function zoom_actions(){
916         g.attr("transform", d3.event.transform)
917     }
918     //add zoom capabilities
919     var zoom_handler = d3.zoom()
920         .on("zoom", zoom_actions);
921
922     zoom_handler(svg);
923
924     function zoomFit() {
925       var bounds = g.node().getBBox();
926       var parent = g.node().parentElement;
927       if(bounds && parent){
928         var fullWidth = parent.clientWidth || parent.parentNode.clientWidth,
929             fullHeight = parent.clientHeight || parent.parentNode.clientHeight;
930         var width = bounds.width,
931             height = bounds.height;
932         var midX = bounds.x + width / 2,
933             midY = bounds.y + height / 2;
934         if (width == 0 || height == 0) return; // nothing to fit
935         var scale = Math.min((0.95 / Math.max(width / fullWidth, height / fullHeight)), 4);
936         var translate = [fullWidth / 2 - scale * midX, fullHeight / 2 - scale * midY];
937
938         var transform = d3.zoomIdentity
939             .translate(300, translate[1])
940             .scale(scale);
941         svg.transition().duration(350)
942           .call(zoom_handler.transform, transform);
943      }
944
945     }
946
947     //Set Default zoom
948     svg.call(zoom_handler)
949     .call(zoom_handler.transform, d3.zoomIdentity.translate(80, -1000).scale(4));
950     this.setState({
951             init: false,
952                 svg: svg,
953                 g: g,
954                 treemap: treemap,
955                 root: root,
956                 duration: duration,
957                 zoomFit: zoomFit
958         }, ()=>{this.update(this, root, true);})
959
960     // Collapse the node and all it's children
961     function collapse(d) {
962       if(d.children) {
963         d.children.forEach(collapse)
964         d.children = null
965       }
966     }
967   }
968   
969   updateDslPathValueOnExtract=(treeDataChildren)=>{                   
970     if(treeDataChildren.details && treeDataChildren.details.dslPathTree && treeDataChildren.details.dslPathTree.length>0){
971         for(var x=0;x<treeDataChildren.details.dslPathTree.length;x++){
972             let dsl=GeneralCommonFunctions.populatePathDSL(treeDataChildren.details.dslPathTree[x],true,true,this.state.enableRealTime);
973             treeDataChildren.details.dslPath.push(dsl);         
974         }
975     }
976     if(treeDataChildren && treeDataChildren.children && treeDataChildren.children.length>0){
977         for(var x=0;x<treeDataChildren.children.length;x++){
978             treeDataChildren.children[x]=this.updateDslPathValueOnExtract(treeDataChildren.children[x]);
979         }
980     } 
981     return treeDataChildren;   
982   }
983   onTargetMenuOfFilterTypes=(listname,id)=>{
984     console.log(listname+'onTargetMenuOfFilterTypes',id);
985     let keysOfArray=id.split('#');
986     let nodekey=keysOfArray[0];
987     let attrKey=keysOfArray[1];
988     let indx=parseInt(keysOfArray[2]);
989     let nodeDetails = this.state.nodeDetails;
990     let node = nodeDetails[nodekey];
991     if(!node.attrDetails){
992         node.attrDetails = [];
993     }
994     if(!node.attrDetails[attrKey]){
995         node.attrDetails[attrKey] = {};
996         node.attrDetails[attrKey].isSelected = true;
997         node.attrDetails[attrKey].filterValue = [];
998         node.attrDetails[attrKey].filterType = [];   
999     }else{
1000         let filterTypes=node.attrDetails[attrKey].filterType;
1001         filterTypes[indx]=listname;
1002         node.attrDetails[attrKey].filterType=filterTypes;
1003     }    
1004     nodeDetails[nodekey] = node;
1005     // update the state with the new array of traverse to nodes
1006     this.setState({ nodeDetails: nodeDetails });
1007   };
1008   filterTags = (key,property,state) =>{
1009     let filterTags ='';
1010     let filters='';
1011     state=true;//always enable, in future if wants to disable remove this line
1012     if(APERTURE_SERVICE && this.state.enableRealTime){
1013         let nodeDetails = this.state.nodeDetails;
1014         let node = nodeDetails[key];
1015         filterTags= Object.keys(Object.keys(node.attrDetails[property].filterType)).map((indx) =>{
1016                     let selectedFilter=(node.attrDetails[property].filterType[indx]!=='')?node.attrDetails[property].filterType[indx]:this.state.filterTypeDisplay;
1017                     return <div style={{margin:'0px 0px 0px 5px'}}>
1018                         <label>                                       
1019                             <FilterTypes param={this.state}
1020                             selectedFilter={selectedFilter}
1021                             id={key+'#'+property+'#'+indx}
1022                             onMenuSelect={this.onTargetMenuOfFilterTypes} 
1023                             state={!state}/>
1024                         </label>
1025                         </div>                        
1026                     });
1027         filters= <Col md={4} className='removeLeftPadding'>{filterTags}</Col>;                
1028     }
1029     return filters;
1030   };
1031   addOrTemplate=(nodeKey,attrKey,indx)=>{
1032     let nodeDetails = this.state.nodeDetails;
1033     let node = nodeDetails[nodeKey];
1034     node.attrDetails[attrKey].filterValue.push('');
1035     node.attrDetails[attrKey].filterType.push('EQ');
1036     nodeDetails[nodeKey] = node;
1037     // update the state with the new array of traverse to nodes
1038     this.setState({ nodeDetails: nodeDetails });    
1039   };
1040   deleteOrTemplate=(nodeKey,attrKey,index)=>{
1041     let nodeDetails = this.state.nodeDetails;
1042     let node = nodeDetails[nodeKey];
1043     let filterValuesArray=node.attrDetails[attrKey].filterValue;
1044     let filterTypeArray=node.attrDetails[attrKey].filterType;
1045     filterValuesArray.splice(index,1);
1046     filterTypeArray.splice(index,1);
1047     node.attrDetails[attrKey].filterValue=filterValuesArray;
1048     node.attrDetails[attrKey].filterType=filterTypeArray;
1049     nodeDetails[nodeKey] = node;
1050     this.setState({ nodeDetails: nodeDetails });
1051   }
1052   toggleRealTimeAnalysisCallback=(checked)=>{
1053     console.log('toggleRealTimeAnalysisCallback>>>>',checked);
1054     sessionStorage.setItem(ENVIRONMENT + 'ENABLE_ANALYSIS', !checked);
1055     this.baseState.enableRealTime=!checked;
1056     this.baseState.init= true;
1057     this.setState({...this.baseState},()=>{document.getElementById("DSLBuilder").innerHTML='';});
1058   }
1059   renderPathFilterBuilder=(key,dslPath,dslPathTree)=>{
1060     console.log('renderPathFilterBuilder>>>>',key);
1061     let attrDetails=this.state.nodeDetails[key].attrDetails; 
1062     let nodeType=this.state.nodeDetails[key].nodeType; 
1063     this.setState({showPathFilterDslBuilder: true,pathFilterNodeType: key,pathFilterNodeName:nodeType,pathFIlterAttrDetails: attrDetails,dslPathBuilder: dslPath,dslPathTree:dslPathTree,isEditEnable:false});
1064   }
1065   /* Load Functions */
1066   getAndPopulateTreeFromDSL = (dslQuery) =>{
1067       var treeObject = [];
1068       var payload = {dsl: dslQuery};
1069       settings['ISAPERTURE'] = true;
1070       commonApi(settings, 'dsl/convert-query-to-tree', 'PUT', payload, 'ConvertQueryToTree')
1071                                         .then(res => {
1072                                                 console.log('res:' + res.data, 'load');
1073                                                 if(res.status === 200 || res.status === 404){
1074                                                     if(res.data.status && (res.data.status !== 200 && res.data.status !== 201 && res.data.status !== 404)){
1075                                                         this.triggerError(res.data, 'treeLoad');
1076                                                     }else{
1077                                                         treeObject = res.data;
1078                                                         this.setState({
1079                                                enableTreeLoadBusyFeedback:false,
1080                                                treeLoadErrMsg: null
1081                                                });
1082                                             console.log("TREE OBJECT: " + JSON.stringify(treeObject));
1083                                             //clear the svg
1084                                             if(this.state.svg){
1085                                               this.state.svg.selectAll("*").remove();
1086                                             }
1087                                             //set the init state
1088                                             this.setState({init: true, dslQuery: '', initialRootEdit: false, nodeDetails: [], selectedNode: null });
1089                                             var initNode = this.extractNodeDetails(treeObject.children[0], true);
1090                                             if(!this.state.treeLoadErrMsg || this.state.treeLoadErrMsg === ''){
1091                                                 console.log(JSON.stringify(initNode));
1092                                                 this.build(null, null, null, initNode);
1093                                                 setTimeout(() => { this.state.zoomFit() }, 600);
1094                                                 //scroll to the hidden static modal since svg offsetTop doesnt work for DSLBuilder id
1095                                                 GeneralCommonFunctions.scrollTo('customDslBuilderModel');
1096                                             }else{
1097                                                 this.triggerError(null, 'invalidQuery');
1098                                             }
1099                                         }
1100                                     }else{
1101                                       this.triggerError(res.data, 'treeLoad');
1102                                     }
1103                                         }, error=>{
1104                                             if(error.response.status === 404){
1105                                                 this.setState({enableTreeLoadBusyFeedback:false});
1106                                             }else{
1107                                                 this.triggerError(error.response.data, 'treeLoad');
1108                                             }
1109                                         }).catch(error => {
1110                                             this.triggerError(error, 'treeLoad');
1111                                 })
1112
1113   };
1114   resetBuilder = () => {
1115         if(this.state.svg){
1116                 this.state.svg.selectAll("*").remove();
1117             }
1118         this.setState({
1119                     init: true,
1120                     dslQuery: '',
1121                     queryName:'',
1122                     queryDescription:'',
1123                     initialRootEdit: false,
1124                     nodeDetails: [],
1125                     selectedNode: null,
1126                         treeLoadErrMsg: '',
1127                         enableTreeLoadBusyFeedback: false,
1128                         aggregateObjects: false
1129                     });
1130   }
1131   triggerError = (error, type) => {
1132     console.error('[CustomDslBuilder.jsx] error : ', JSON.stringify(error));
1133         let errMsg = '';
1134         if(error && error.status && error.message){
1135             errMsg += "Error Occurred: " + error.status + ' - ' +error.message;
1136         }else{
1137             errMsg += "Error Occurred: " + JSON.stringify(error);
1138         }
1139         console.log(errMsg);
1140         if(type === 'treeLoad' || type === 'invalidQuery'){
1141             this.resetBuilder();
1142             var errorMessage = errMsg;
1143             if(type === 'invalidQuery'){
1144                  errorMessage = 'The loaded query uses DSL syntax not supported by the DSL Builder,'
1145                             + ' please only load queries compatible with the builder. For more'
1146                             + ' information on this error, please contact an administrator.';
1147             }
1148         this.setState({treeLoadErrMsg: errorMessage});
1149         GeneralCommonFunctions.scrollTo('treeLoadErrorMessage');
1150     }else{
1151         console.log('[CustomDslBuilder.jsx] :: triggerError invoked with invalid type : ' + type);
1152     }
1153   }
1154   validLoadableDSL = (dslQuery) => {
1155     var valid = false;
1156     dslQuery = dslQuery.replace(/\s/g, '');
1157     valid = dslQuery.indexOf(']>') === -1 && !(new RegExp("LIMIT[0-9]+$").test(dslQuery));
1158     return valid;
1159   }
1160   loadCallback = (name, description, category, dslQuery, isAggregate, type, queryId, id, templateDetails, makeCall) =>{
1161     var decodedDslQuery = atob(dslQuery).replace('<pre>','').replace('</pre>','');
1162     if(this.validLoadableDSL(decodedDslQuery)){
1163         if(name !== '' && description !== ''){
1164           this.setState({
1165                 queryName:name,
1166                 queryDescription:description,
1167                 category:category,
1168                 isPublicChecked: type === 'public',
1169                 queryId: queryId,
1170                 treeLoadErrMsg: null,
1171                 aggregateObjects: isAggregate === "true"
1172           });
1173           console.log("DSL Query Loaded: "+ decodedDslQuery);
1174           console.log("DSL Query Name: "+ name);
1175           console.log("DSL Query Description: "+ description);
1176           console.log("DSL Query ID: "+ queryId);
1177           console.log("DSL Query Category: "+ category);
1178           console.log("DSL Query isAggregate: "+ isAggregate);
1179           console.log("DSL Query type: "+ type);
1180           var treeObject = this.getAndPopulateTreeFromDSL(decodedDslQuery);
1181         }
1182     }else{
1183         this.triggerError(null, "invalidQuery");
1184     }
1185   }
1186   extractNodeDetails = (node, isRoot) =>{
1187     let nodeType =  node['node-type'];
1188     let nodeData = {
1189         "name": nodeType,
1190         "id": nodeType,
1191         "children": [],
1192         "details":{}
1193     }
1194     nodeData.details.includeInOutput = node.store;
1195     nodeData.details.isSelected = true;
1196     nodeData.details.isRootNode = isRoot;
1197     nodeData.details.nodeType = nodeType;
1198     var attributes = GeneralCommonFunctions.getFilteringOptions(nodeType);
1199     nodeData.details.attrDetails = attributes;
1200     nodeData.details.parentContainer = GeneralCommonFunctions.populateContainer(nodeType);
1201     if(node.store && !node['requested-props']){
1202         for(var key in nodeData.details.attrDetails){
1203             nodeData.details.attrDetails[key].isSelected = true;
1204         }
1205     }else if (node.store && node['requested-props']){
1206          for(var key in node['requested-props']){
1207             nodeData.details.attrDetails[key].isSelected = true;
1208             nodeData.details.attrDetails[key].alias=node['requested-props'][key];
1209          }
1210     }
1211     var isValid = true;
1212     for (var x in node['node-filter']){
1213         if(isValid){
1214             for (var y in node['node-filter'][x]) {
1215                 if(isValid){
1216                     var attrKey = node['node-filter'][x][y]['key'];
1217                     var filter = node['node-filter'][x][y]['filter'];
1218                     //If aperture is not turned on and query loaded uses anything besides EQ throw error
1219                     if(!APERTURE_SERVICE && filter !== 'EQ'){
1220                         this.triggerError(null, "invalidQuery");
1221                         isValid = false;
1222                     }
1223                     if(!nodeData.details.attrDetails[attrKey]){
1224                         nodeData.details.attrDetails[attrKey] = {};
1225                     }
1226                     if(nodeData.details.attrDetails[attrKey].filterType.length > 0 && nodeData.details.attrDetails[attrKey].filterType[0] === ''){
1227                         nodeData.details.attrDetails[attrKey].filterType = [];
1228                     }
1229                     if(nodeData.details.attrDetails[attrKey].filterValue.length > 0 && nodeData.details.attrDetails[attrKey].filterValue[0] === ''){
1230                         nodeData.details.attrDetails[attrKey].filterValue = [];
1231                     }
1232                     //if a filter had no values associated to it throw a not supported error
1233                     if(node['node-filter'][x][y]['value'][0]){
1234                         for (var i in node['node-filter'][x][y]['value']){
1235                             nodeData.details.attrDetails[attrKey].filterType.push(filter);
1236                             nodeData.details.attrDetails[attrKey].filterValue.push(node['node-filter'][x][y]['value'][i]);
1237                         }
1238                         if(!nodeData.details.attrDetails[attrKey].attributeName){
1239                             nodeData.details.attrDetails[attrKey].attributeName = attrKey;
1240                         }
1241                     }else{
1242                         this.triggerError(null, "invalidQuery");
1243                         isValid = false;
1244                     }
1245                 }
1246             }
1247         }
1248     }
1249     var initWhereNode = null;
1250     if(node['where-filter'].length > 0){
1251         for(var index in node['where-filter']){
1252             initWhereNode = this.extractNodeDetails(node['where-filter'][index].children[0], true);
1253         }
1254     }
1255     if(initWhereNode){
1256         nodeData.details.dslPath=[];
1257         nodeData.details.dslPathTree=[];
1258         nodeData.details.dslPathTree.push(initWhereNode);
1259     }
1260     if(node.children.length > 0){
1261         for(var i = 0; i < node.children.length; i++){
1262             nodeData.children[i] = this.extractNodeDetails(node.children[i], false);
1263         }
1264     }
1265     return nodeData;
1266   }
1267
1268   setQueriesState = (savedQueries) =>{
1269     this.setState({
1270         loadedQueries: savedQueries
1271     });
1272   };
1273   /* End Load Functions */
1274   render(){ 
1275     var toggelRealtimeAnalysis = '';
1276         if(APERTURE_SERVICE){           
1277                   toggelRealtimeAnalysis = <div className='toggleSwitch'><BootstrapSwitchButton
1278                                                                         checked={!this.state.enableRealTime}
1279                                                                         onlabel='Real Time'
1280                                                                         onstyle='danger'
1281                                                                         offlabel='Analysis'
1282                                                                         offstyle='success'
1283                                                                         style='w-100 mx-3'
1284                                                                         onChange={(checked) => {
1285                                                                                 this.toggleRealTimeAnalysisCallback(checked);
1286                                                                         }}
1287                                                                 /></div>             
1288         }
1289         return(
1290         <div>
1291             {toggelRealtimeAnalysis}
1292                <div className="addPadding">
1293                 <div className='row container-fluid my-4'>
1294                         <div className='col-lg-9'>
1295                                 <header className='jumbotron'>
1296                                     <h1 className='display-2'>Visual Query Builder for <strong>B</strong>uild <strong>Y</strong>our <strong>O</strong>wn <strong>Q</strong>uery</h1>
1297                                     <p className='lead'>
1298                                         Visually build your own query, you can click the + icon to add objects to your query,
1299                                         - icon to remove objects from your query, or the pencil icon/double click to edit attributes.
1300                                         Single click and drag in the view to pan, use scrollwheel or pinch to zoom. <br/>
1301                                     </p>
1302                         </header>
1303                         </div>
1304                 </div>
1305                 <div className={'addPaddingTop alert alert-danger ' +(this.state.treeLoadErrMsg && this.state.treeLoadErrMsg !== '' ? 'show' : 'hidden')} id="treeLoadErrorMessage" role="alert">
1306                   An error occurred in loading the query. Please see details {this.state.treeLoadErrMsg}
1307                 </div>
1308                 <CustomDSLSaveLoad loadCallback={this.loadCallback} setQueriesState={this.setQueriesState} ref={this.saveLoadComponent} isDataSteward={this.state.isDataSteward} isDSLBuilder={true}/>
1309                 <div className={'row ' + (this.state.init ? 'show' : 'hidden')}>
1310                     <button className='btn btn-primary' type='button' onClick={this.initialize.bind(this)}>Start Building (+)</button>
1311                 </div>
1312                 <div className={'row ' + (!this.state.init ? 'show' : 'hidden')}>
1313                     <button className='btn btn-primary' type='button' onClick={this.runDSL}>Run Query</button>
1314                     <button className='btn btn-outline-secondary' type='button' onClick={this.showEditDSLModal}>Manual Edit & Run</button>
1315                     <div className={'checkbox ' + (GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
1316                        <label>
1317                          <input type="checkbox" checked={this.state.aggregateObjects} onChange={this.onAggregateCheckbox.bind(this)} />
1318                          Aggregate Objects
1319                        </label>
1320                        <label>
1321                          <input type="checkbox" checked={this.state.autoZoomEnabled} onChange={this.onAutoZoomCheckbox.bind(this)} />
1322                          Auto Zoom Enabled
1323                        </label>
1324                     </div>
1325                 </div>
1326
1327                 <div className='static-modal' id='customDslBuilderModel'>
1328                         <Modal show={this.state.showNodeModal} onHide={this.closeNodeModal}>
1329                                 <Modal.Header>
1330                                         <Modal.Title>Modify Query</Modal.Title>
1331                                 </Modal.Header>
1332                                     <Modal.Body>
1333                               <form>
1334                                    {Object.keys(this.state.nodeDetails).sort().map((key, node) => (
1335                                         <div className="dsl-panel">
1336                                            <Panel>
1337                                              <Panel.Heading>
1338                                                <Panel.Title>
1339                                                  <div className={'checkbox ' + (!this.state.init ? 'show' : 'hidden')}>
1340                                                     <label>
1341                                                       <input type="checkbox" checked={this.state.nodeDetails[key].isSelected} value={key} onChange={this.onNodeCheckbox.bind(this)} />
1342                                                       {this.state.nodeDetails[key].nodeType}
1343                                                     </label>
1344                                                     <Panel.Toggle>
1345                                                       <div className="pull-right">Options</div>
1346                                                     </Panel.Toggle>
1347                                                  </div>
1348                                                  <div className={(this.state.init ? 'show' : 'hidden')}>
1349                                                     <label>
1350                                                       <input type="radio" value={key} checked={this.state.nodeDetails[key].isSelected} onChange={this.onNodeRadio.bind(this)} />
1351                                                       {" " + this.state.nodeDetails[key].nodeType}
1352                                                     </label>
1353                                                     <Panel.Toggle>
1354                                                       <div className="pull-right">Options</div>
1355                                                     </Panel.Toggle>
1356                                                  </div>
1357                                                </Panel.Title>
1358                                              </Panel.Heading>
1359                                              <Panel.Collapse>
1360                                                <Panel.Body className='cardwrap'>
1361                                                  <div>
1362                                                     <div style={{float:'right'}}>
1363                                                         <button type='button' className='btn btn-primary pull-right' onClick={()=>this.renderPathFilterBuilder(key)}>Build Path Filter</button>
1364                                                     </div>
1365                                                  </div>
1366                                                  {this.state.nodeDetails[key].dslPath && this.state.nodeDetails[key].dslPath.length>0 &&
1367                                                   <Grid fluid={true} className='addPaddingTop'>
1368                                                     <Row className='show-grid addPaddingTop'>
1369                                                         <Col md={10}>
1370                                                         <strong>DSL PATH Filter</strong>
1371                                                         </Col>
1372                                                         <Col md={2} className='removeLeftPadding'>
1373                                                             <strong>Action</strong>
1374                                                         </Col>
1375                                                     </Row>
1376                                                   </Grid>}
1377                                                   <Grid fluid={true}>
1378                                                  {this.state.nodeDetails[key].dslPath && Object.keys(this.state.nodeDetails[key].dslPath).map((indx) => {
1379                                                     return(
1380                                                         <Row className='show-grid'>
1381                                                             <Col md={9}>
1382                                                                 <div style={{float:'left',width:'100%',margin:'10px 0px'}}>
1383                                                                     {this.state.nodeDetails[key].dslPath[indx]}
1384                                                                 </div>
1385                                                             </Col>
1386                                                             <Col md={3}>
1387                                                                      <button
1388                                                                         className='btn btn-primary'
1389                                                                         style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1390                                                                         type='button'
1391                                                                         onClick={e => {this.editPathNodeModal(key,this.state.nodeDetails[key].dslPath[indx],this.state.nodeDetails[key].dslPathTree[indx],indx)}}>Edit</button>
1392                                                                     <button
1393                                                                         className='btn btn-primary'
1394                                                                         style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1395                                                                         type='button'
1396                                                                         onClick={e => {this.deletePathNodeModal(key,this.state.nodeDetails[key].dslPath[indx],this.state.nodeDetails[key].dslPathTree[indx],indx)}}>Delete</button>
1397                                                             </Col>
1398                                                         </Row>
1399                                                     )
1400                                                  })}
1401                                                  </Grid>
1402                                                  <div style={{float:'left'}} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
1403                                                         <button type='button' className='btn btn-outline-primary pull-right' onClick={()=>this.deselectAll(key)}>Deselect All</button>
1404                                                         <button type='button' className='btn btn-primary pull-right' onClick={()=>this.selectAll(key)}>Select All</button>
1405                                                 </div>
1406                                                  <Grid fluid={true} className='addPaddingTop'>
1407                                                     <Row className='show-grid addPaddingTop'>
1408                                                        <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
1409                                                          <strong>Include in Output</strong>
1410                                                        </Col>
1411                                                        {APERTURE_SERVICE && this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
1412                                                          <strong>Filter Types</strong>
1413                                                        </Col>}
1414                                                        <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
1415                                                           <strong>Filter By (Optional)</strong>
1416                                                        </Col>
1417                                                     </Row>
1418                                                  {Object.keys(this.state.nodeDetails[key].attrDetails).sort().map((attrKey, attr) => {
1419                                                     return(
1420                                                            <Row className='show-grid'>
1421                                                               <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
1422                                                                <div className="checkbox">
1423                                                                    <label>
1424                                                                      <input type="checkbox" checked={this.state.nodeDetails[key].attrDetails
1425                                                                      && this.state.nodeDetails[key].attrDetails[attrKey]
1426                                                                      && this.state.nodeDetails[key].attrDetails[attrKey].isSelected }
1427                                                                      value={key + "|" + attrKey} onChange={this.onAttributeCheckbox.bind(this)} />
1428                                                                      {attrKey}
1429                                                                    </label>
1430                                                                 </div>
1431                                                               </Col>
1432                                                               {this.filterTags(key,attrKey,this.state.nodeDetails[key].attrDetails[attrKey].isSelected)}
1433                                                               <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
1434                                                               {Object.keys(this.state.nodeDetails[key].attrDetails[attrKey].filterValue).map((indx) =>{
1435                                                                 return(
1436                                                                     <div>
1437                                                                         {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
1438                                                                             placeholder={"Enter " + attrKey }
1439                                                                             className='inputFilter'
1440                                                                             onBlur={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
1441                                                                             />
1442                                                                         }
1443                                                                         {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
1444                                                                             onChange={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
1445                                                                             placeholder={"Enter " + attrKey }
1446                                                                             className='inputFilter'
1447                                                                             value={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]}
1448                                                                             />
1449                                                                         }
1450                                                                         {indx == 0 && <button
1451                                                                             className={(this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='')?'btn btn-primary':'btn btn-secondary'}
1452                                                                             style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1453                                                                             disabled={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]===''}
1454                                                                             type='button'
1455                                                                             onClick={e => {this.addOrTemplate(key,attrKey,indx)}}>+</button>}
1456                                                                         {indx > 0 && <button
1457                                                                             style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1458                                                                             id={'delete-'+indx}
1459                                                                             className='btn btn-danger'
1460                                                                             type='button'
1461                                                                             onClick={e => {this.deleteOrTemplate(key,attrKey,indx)}}>x</button>}
1462
1463                                                                     </div>
1464                                                                 )
1465                                                               })}
1466
1467                                                               </Col>
1468                                                            </Row>
1469                                                     );
1470                                                   }
1471                                                  )}
1472                                                  </Grid>
1473                                                </Panel.Body>
1474                                              </Panel.Collapse>
1475                                            </Panel>
1476                                         </div>
1477                                    ))}
1478                                  </form>
1479                                  <div className={this.state.showPathFilterDslBuilder ? 'show' : 'hidden'}>
1480                                     <Modal show={this.state.showPathFilterDslBuilder} onHide={!this.state.showPathFilterDslBuilder} style={{width:'100%'}}>
1481                                         <Modal.Header>
1482                                             <Modal.Title>Build DSL Path</Modal.Title>
1483                                         </Modal.Header>
1484                                         <Modal.Body style={{overflow:'scroll'}}>
1485                                             <PathFilterDslBuilder  nodeType={this.state.pathFilterNodeType}
1486                                                                 nodeName={this.state.pathFilterNodeName}
1487                                                                 attrDetails={this.state.pathFIlterAttrDetails}
1488                                                                 closePathNodeModal={this.closePathNodeModal}
1489                                                                 submitPathNodeModal={this.submitPathNodeModal}
1490                                                                 showPathFilterDslBuilder={this.state.showPathFilterDslBuilder}
1491                                                                 dslPath={this.state.dslPathBuilder}
1492                                                                 dslPathTree={this.state.dslPathTree}
1493                                                                 isEditEnable={this.state.isEditEnable}
1494                                                                 pathFilterIndex={this.state.pathFilterIndex}/>
1495                                         </Modal.Body>
1496                                     </Modal>
1497                                 </div>
1498                                     </Modal.Body>
1499                                     <Modal.Footer>
1500                                         <Button onClick={this.closeNodeModal}>Close</Button>
1501                                         <Button onClick={this.submitNodeModal}>Submit</Button>
1502                                     </Modal.Footer>
1503                         </Modal>
1504                 </div>
1505                 <div className='static-modal' id='editNodeModel'>
1506                         <Modal show={this.state.showEditNodeModal} onHide={this.closeEditNodeModal}>
1507                                 <Modal.Header>
1508                                         <Modal.Title>Modify Node</Modal.Title>
1509                                 </Modal.Header>
1510                                 <Modal.Body>
1511                           <form>
1512                             <div className="dsl-panel">
1513                                <Panel>
1514                                  <Panel.Heading>
1515                                    <Panel.Title>
1516                                      <div>
1517                                         <label>{this.state.selectedNode
1518                                                 && this.state.selectedNode.data
1519                                                 && this.state.selectedNode.data.details ?
1520                                                 this.state.selectedNode.data.details.nodeType
1521                                                 : ""
1522                                                }
1523                                         </label>
1524                                      </div>
1525                                    </Panel.Title>
1526                                  </Panel.Heading>
1527                                  <Panel.Body className='cardwrap'>                                
1528                                     <Grid fluid={true} className='addPaddingTop'>
1529                                     <Row className='show-grid addPaddingTop'>
1530                                         <div style={{float:'right'}}>
1531                                             <button type='button' className='btn btn-primary pull-right' onClick={()=>this.renderPathFilterBuilder(0)}>Build Path Filter</button>
1532                                         </div>
1533                                     </Row>
1534                                     {this.state.selectedNode
1535                                         && this.state.selectedNode.data
1536                                         && this.state.selectedNode.data.details
1537                                         && this.state.nodeDetails[0]
1538                                         && this.state.nodeDetails[0].dslPath && this.state.nodeDetails[0].dslPath.length>0 && 
1539                                     <Row className='show-grid addPaddingTop'>
1540                                         <Col md={10}>
1541                                         <strong>DSL PATH Filter</strong>
1542                                         </Col>                                                
1543                                         <Col md={2} className='removeLeftPadding'>
1544                                             <strong>Action</strong>
1545                                         </Col>
1546                                     </Row>}
1547                                     </Grid>                                                                                                                                 
1548                                     {this.state.selectedNode
1549                                         && this.state.selectedNode.data
1550                                         && this.state.selectedNode.data.details
1551                                         && this.state.nodeDetails[0]
1552                                         && this.state.nodeDetails[0].dslPath && Object.keys(this.state.nodeDetails[0].dslPath).map((indx) => {
1553                                     return(
1554                                         <Row className='show-grid'>
1555                                             <Col md={9}>
1556                                                 <div style={{float:'left',width:'100%',margin:'10px 0px'}}>
1557                                                     {this.state.nodeDetails[0].dslPath[indx]}
1558                                                 </div>
1559                                             </Col>
1560                                             <Col md={3}>
1561                                                         <button 
1562                                                         className='btn btn-primary'
1563                                                         style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1564                                                         type='button' 
1565                                                         onClick={e => {this.editPathNodeModal(0,this.state.nodeDetails[0].dslPath[indx],this.state.nodeDetails[0].dslPathTree[indx],indx)}}>Edit</button>
1566                                                     <button 
1567                                                         className='btn btn-primary'
1568                                                         style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1569                                                         type='button' 
1570                                                         onClick={e => {this.deletePathNodeModal(0,this.state.nodeDetails[0].dslPath[indx],this.state.nodeDetails[0].dslPathTree[indx],indx)}}>Delete</button>
1571                                             </Col>
1572                                         </Row>
1573                                     )
1574                                     })}
1575                                     <div style={{float:'left'}} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
1576                                         <button type='button' className='btn btn-outline-primary pull-right' onClick={()=>this.deselectAll(0)}>Deselect All</button>
1577                                         <button type='button' className='btn btn-primary pull-right' onClick={()=>this.selectAll(0)}>Select All</button>
1578                                     </div>
1579                                    <Grid fluid={true} className='addPaddingTop'>
1580                                       <Row className='show-grid addPaddingTop'>
1581                                          <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
1582                                            <strong>Include in Output</strong>
1583                                          </Col>
1584                                          {this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
1585                                            <strong>Filter Types</strong>
1586                                          </Col>}
1587                                          <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
1588                                             <strong>Filter By (Optional)</strong>
1589                                          </Col>
1590                                       </Row>
1591                                    {this.state.selectedNode
1592                                         && this.state.selectedNode.data
1593                                         && this.state.selectedNode.data.details
1594                                         && this.state.nodeDetails[0]
1595                                         && Object.keys(this.state.nodeDetails[0].attrDetails).sort().map((attrKey, attr) => {
1596                                       return(
1597                                              <Row className='show-grid'>
1598                                                 <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
1599                                                  <div className="checkbox">
1600                                                      <label>
1601                                                        <input type="checkbox" checked={this.state.nodeDetails[0].attrDetails
1602                                                        && this.state.nodeDetails[0].attrDetails[attrKey]
1603                                                        && this.state.nodeDetails[0].attrDetails[attrKey].isSelected }
1604                                                        value={0 + "|" + attrKey} onChange={this.onAttributeCheckbox.bind(this)} />
1605                                                        {attrKey}
1606                                                      </label>
1607                                                   </div>
1608                                                 </Col>
1609                                                 {this.filterTags(0,attrKey, this.state.nodeDetails[0].attrDetails[attrKey].isSelected)}
1610                                                 <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
1611                                                 {Object.keys(this.state.nodeDetails[0].attrDetails[attrKey].filterValue).map((indx) =>{
1612                                                   return(
1613                                                       <div>
1614                                                           
1615                                                           {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
1616                                                               placeholder={"Enter " + attrKey }
1617                                                               className='inputFilter'
1618                                                               onBlur={(e)=>{this.onFilterValueChange(e, 0, attrKey, indx);}}
1619                                                               />
1620                                                           }
1621                                                           {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
1622                                                               onChange={(e)=>{this.onFilterValueChange(e, 0, attrKey,indx);}}
1623                                                               placeholder={"Enter " + attrKey }
1624                                                               className='inputFilter'
1625                                                               value={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]}
1626                                                               />
1627                                                           }
1628                                                           {indx == 0 && <button
1629                                                               className={(this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]!=='')?'btn btn-primary':'btn btn-secondary'}
1630                                                               style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1631                                                               disabled={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]===''}
1632                                                               type='button'
1633                                                               onClick={e => {this.addOrTemplate(0 ,attrKey,indx)}}>+</button>}
1634                                                           {indx > 0 && <button
1635                                                               style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1636                                                               id={'delete-'+indx}
1637                                                               className='btn btn-danger'
1638                                                               type='button'
1639                                                               onClick={e => {this.deleteOrTemplate(0 ,attrKey,indx)}}>x</button>}
1640
1641                                                       </div>
1642                                                   )
1643                                                 })}
1644
1645                                                 </Col>
1646                                              </Row>
1647                                       );
1648                                     }
1649                                    )}
1650                                    </Grid>
1651                                  </Panel.Body>
1652                                </Panel>
1653                             </div>
1654                           </form>                          
1655                           <div className={(this.state.showPathFilterDslBuilder && this.state.showEditNodeModal) ? 'show' : 'hidden'}>
1656                                 <Modal show={this.state.showPathFilterDslBuilder} onHide={!this.state.showPathFilterDslBuilder} style={{width:'100%'}}>
1657                                     <Modal.Header>
1658                                         <Modal.Title>Build DSL Path</Modal.Title>
1659                                     </Modal.Header>
1660                                     <Modal.Body style={{overflow:'scroll'}}>
1661                                         <PathFilterDslBuilder  nodeType={this.state.pathFilterNodeType}
1662                                                             nodeName={this.state.pathFilterNodeName}
1663                                                             attrDetails={this.state.pathFIlterAttrDetails}
1664                                                             closePathNodeModal={this.closePathNodeModal}
1665                                                             submitPathNodeModal={this.submitPathNodeModal}
1666                                                             showPathFilterDslBuilder={this.state.showPathFilterDslBuilder}
1667                                                             dslPath={this.state.dslPathBuilder}
1668                                                             dslPathTree={this.state.dslPathTree}
1669                                                             isEditEnable={this.state.isEditEnable}
1670                                                             pathFilterIndex={this.state.pathFilterIndex}/>
1671                                     </Modal.Body>
1672                                 </Modal> 
1673                            </div> 
1674                                 </Modal.Body>
1675                                 <Modal.Footer>
1676                                         <Button onClick={this.closeEditNodeModal}>Close</Button>
1677                                         <Button onClick={this.submitEditNodeModal}>Submit</Button>
1678                                 </Modal.Footer>
1679                         </Modal>
1680                 </div>
1681                 <div className='static-modal'>
1682                         <Modal show={this.state.showEditModal} onHide={this.closeEditDSLModal}>
1683                                 <Modal.Header>
1684                                         <Modal.Title>Edit DSL Query</Modal.Title>
1685                                 </Modal.Header>
1686                                 <Modal.Body>
1687                             <form>
1688                                 <FormGroup controlId="dslQuery">
1689                                       <ControlLabel>DSL Query</ControlLabel>
1690                                       <FormControl onChange={this.bindEdits.bind(this)} value={this.state.editModel} componentClass="textarea" placeholder="Enter DSL Query" />
1691                                  </FormGroup>
1692                             </form>
1693                                 </Modal.Body>
1694                                 <Modal.Footer>
1695                                         <Button onClick={this.closeEditDSLModal}>Close</Button>
1696                                         <Button onClick={this.submitEditAndRunDSL}>Submit</Button>
1697                                 </Modal.Footer>
1698                         </Modal>
1699                 </div>
1700                 <div>
1701                     <div className={'card-header ' + (this.state.queryName && this.state.queryName !== '' ? 'show' : 'hidden')}>
1702                         <div>
1703                                 <h3>{this.state.queryName}</h3>
1704                         </div>
1705                     </div>
1706                     <div className={'card-header ' + (this.state.queryDescription && this.state.queryDescription !== ''  ? 'show' : 'hidden')}>
1707                         <div>
1708                                 <h4>{this.state.queryDescription}</h4>
1709                         </div>
1710                     </div>
1711                     <div className={'card-header ' + (this.state.dslQuery && this.state.dslQuery !== ''  ? 'show' : 'hidden')}>
1712                         <div>
1713                                 <h4><strong>DSL Query: </strong><span className='pre-wrap-text'>{this.state.dslQuery}</span></h4>
1714                         </div>
1715                     </div>
1716                 </div>
1717                 {this.state.enableModalFeedback && <Spinner loading={true}><span height="100%" width="100%"></span></Spinner>}
1718                 <svg id='DSLBuilder' width='1800' height='800'></svg>
1719            </div>
1720         </div>
1721         );
1722   }
1723 }
1724
1725 export default CustomDslBuilder;