2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 import React, {Component} from 'react';
22 import Modal from 'react-bootstrap/lib/Modal';
23 import Grid from 'react-bootstrap/lib/Grid';
24 import FormGroup from 'react-bootstrap/lib/FormGroup';
25 import FormControl from 'react-bootstrap/lib/FormControl';
26 import ControlLabel from 'react-bootstrap/lib/ControlLabel';
27 import Button from 'react-bootstrap/lib/Button';
28 import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
29 import Spinner from 'utils/SpinnerContainer.jsx';
30 import Row from 'react-bootstrap/lib/Row';
31 import Col from 'react-bootstrap/lib/Col';
32 import Panel from 'react-bootstrap/lib/Panel';
33 import Tooltip from 'react-bootstrap/lib/Tooltip';
34 import FilterTypes from 'generic-components/filter/components/FilterTypes.jsx';
35 import BootstrapSwitchButton from 'bootstrap-switch-button-react';
36 import {GeneralCommonFunctions} from 'utils/GeneralCommonFunctions.js';
37 import * as d3 from "d3";
38 import 'd3-selection-multi';
41 let EDGERULES = GlobalExtConstants.EDGERULES;
42 let OXM = GlobalExtConstants.OXM;
43 let INVLIST = GlobalExtConstants.INVLIST;
44 let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
45 let APERTURE_SERVICE = JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
48 let properties = null;
49 let traverseRulesDsl = [];
52 'NODESERVER': INVLIST.NODESERVER,
53 'PROXY': INVLIST.PROXY,
54 'PREFIX': INVLIST.PREFIX,
55 'VERSION': INVLIST.VERSION,
56 'USESTUBS': INVLIST.useStubs
58 class PathFilterDslBuilder extends Component {
60 console.log('PathFilter props>>>>',props);
62 APERTURE_SERVICE=JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
63 this.state = {edgeRules : null,
78 autoZoomEnabled: true,
79 aggregateObjects: false,
81 filterTypeDisplay: 'Filter Type',
82 selectedfilterType:[],
84 closePathNodeModal:true,
85 submitPathNodeModal:false,
88 showPathFilterDslBuilder:false,
93 showEditNodeModal:false,
94 enableRealTime: JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'ENABLE_ANALYSIS'))
98 componentDidMount () {
99 console.log('Path Filter componentDidMount',JSON.stringify(this.props));
100 //this.buildSQLStatementsFromSchema();
101 this.processEdgeRules(EDGERULES);
103 componentDidUpdate (nextProps) {
104 console.log('Path Filter componentDidUpdate>>>>>>>',nextProps);
105 if(this.state.isInitialize){
106 this.props=nextProps;
107 console.log('this.props>>>>>>>>>>>>>',this.props);
108 this.setState({submitPathNodeModal:this.props.submitPathNodeModal,
109 closePathNodeModal:this.props.closePathNodeModal,
110 parentNodeType:this.props.nodeType,
111 parentAttrDetails:this.props.attrDetails,
112 showPathFilterDslBuilder:this.props.showPathFilterDslBuilder,
113 dslPath:this.props.dslPath,
114 dslPathTree:this.props.dslPathTree,
115 isInitialize: false},()=>{
116 if(this.props.dslPathTree){
117 this.build(this.props.nodeType,null,this.props.attrDetails,this.props.dslPathTree);
119 //this.initialize(this.props.nodeName);
120 this.setState({showNodeModal: true,isInitialize:false},()=>{this.populateEdgeRules(this.props.nodeName,this.state.edgeRules)});
124 console.log('this.state under Update>>>>>',this.state);
126 componentWillReceiveProps(nextProps) {
127 console.log('path Filter componentWillReceiveProps>>>>');
130 var nodeDetails = [];
132 console.log('initializing');
133 var id = GeneralCommonFunctions.generateID();
134 var nodeTypes = GeneralCommonFunctions.getNodeTypes();
135 for (var i = 0; i < nodeTypes.length; i++) {
136 node = nodeTypes[i] + id;
137 if(this.props.nodeName === nodeTypes[i]){
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]);
148 let nodesSorted = nodeDetails.sort(function (filter1, filter2) {
149 if (filter1.nodeType < filter2.nodeType) {
151 } else if (filter1.nodeType > filter2.nodeType) {
157 console.log('Node Types List' + JSON.stringify(nodesSorted));
158 nodeDetails = nodesSorted;
160 nodeDetails: nodeDetails,
165 initialLoadWhileClose= ()=>{
166 this.setState({showNodeModal: true,isInitialize:false},()=>{this.populateEdgeRules(this.props.nodeName,this.state.edgeRules)});
168 processEdgeRules = (data) => {
170 edgeRules: data.rules
173 closeNodeModal = () =>{
175 showNodeModal: false,
181 var nodeDetails = this.state.nodeDetails;
182 if (e.target.checked) {
183 nodeDetails[e.target.value].isSelected = true;
184 this.selectAll(e.target.value);
186 nodeDetails[e.target.value].isSelected = false;
187 this.deselectAll(e.target.value);
189 // update the state with the new array of traverse to nodes
190 this.setState({ nodeDetails: nodeDetails });
193 var nodeDetails = this.state.nodeDetails;
194 if (e.target.checked) {
195 nodeDetails[e.target.value].isSelected = true;
196 this.selectAll(e.target.value);
198 for (var key in nodeDetails) {
199 if(key != e.target.value && nodeDetails[key].isSelected ){
200 nodeDetails[key].isSelected = false;
201 this.deselectAll(key);
204 // update the state with the new array of traverse to nodes
205 this.setState({ nodeDetails: nodeDetails });
207 onAutoZoomCheckbox(e) {
209 if (e.target.checked) {
214 this.setState({ autoZoomEnabled: cbValue });
217 onAttributeCheckbox(e){//delete
218 let splitVal = e.target.value.split("|");
219 let nodeKey = splitVal[0];
220 let attrValue = splitVal[1];
221 let nodeDetails = this.state.nodeDetails;
222 let node = nodeDetails[nodeKey];
223 let attribute = null;
224 if(!node.attrDetails){
225 node.attrDetails = [];
227 if(!node.attrDetails[attrValue]){
228 node.attrDetails[attrValue] = {};
229 node.attrDetails[attrValue].isSelected = true;
230 node.attrDetails[attrValue].filterValue = [];
231 node.attrDetails[attrValue].filterType = [];
234 // check if the check box is checked or unchecked
235 if (e.target.checked) {
236 // add the value of the checkbox to nodes array
237 node.attrDetails[attrValue].isSelected = true;
238 node.attrDetails[attrValue].filterType[0]='EQ';
240 // or remove the value from the unchecked checkbox from the array
241 node.attrDetails[attrValue].isSelected = false;
242 node.attrDetails[attrValue].filterType = [''];
243 node.attrDetails[attrValue].filterValue = [''];
245 nodeDetails[nodeKey] = node;
246 // update the state with the new array of traverse to nodes
247 this.setState({ nodeDetails: nodeDetails });
249 onFilterValueChange(e, nodeKey, attrKey, indx){
250 let nodeDetails = this.state.nodeDetails;
251 let node = nodeDetails[nodeKey];
252 if(!node.attrDetails){
253 node.attrDetails = [];
255 if(!node.attrDetails[attrKey]){
256 node.attrDetails[attrKey] = {};
257 node.attrDetails[attrKey].isSelected = true;
258 node.attrDetails[attrKey].filterValue = [];
259 node.attrDetails[attrKey].filterType = [];
261 // add the value of the checkbox to nodes array
262 //node.attrDetails[attrKey].filterValue.push(e.target.value);
263 let filterValArr=node.attrDetails[attrKey].filterValue;
264 filterValArr[indx]=e.target.value;
265 node.attrDetails[attrKey].filterValue=filterValArr;
266 nodeDetails[nodeKey] = node;
267 // update the state with the new array of traverse to nodes
268 this.setState({ nodeDetails: nodeDetails });
270 submitPathNodeModal= () =>{
271 console.log('PathFinder submitPathNodeModal>>>>>',this.props);
272 this.props.submitPathNodeModal(this.state.dslQuery,this.props.nodeType,this.state.dslQueryTree,this.props.isEditEnable,this.props.pathFilterIndex);
274 submitNodeModal = () =>{
275 if(this.state.selectedNode){
276 var treeData=this.state.dslQueryTree;
277 var updatedTreeData='';
278 var d = this.state.selectedNode;
279 for(var node in this.state.nodeDetails){
280 if(this.state.nodeDetails[node].isSelected){
283 name: this.state.nodeDetails[node].nodeType,
288 Object.assign(newNodeObj.details, this.state.nodeDetails[node]);
289 var newNode = d3.hierarchy(newNodeObj);
290 newNode.depth = d.depth + 1;
291 newNode.height = d.height - 1;
297 if(newNodeObj.details){
298 var selectedAttributeCount = 0;
299 for (var key in newNodeObj.details.attrDetails){
300 if (newNodeObj.details.attrDetails[key].isSelected){
301 selectedAttributeCount++;
303 if(selectedAttributeCount === Object.keys(newNodeObj.details.attrDetails).length){
304 newNodeObj.details.includeInOutput = true;
308 console.log('submit node newNodeObj>>>>>',newNodeObj);
309 treeData=(updatedTreeData==='')?treeData:updatedTreeData;
310 updatedTreeData=this.handlingTreeDataWhileAddRemove(treeData,newNodeObj,d.data.id,d.data.name);
311 d.children.push(newNode);
312 this.setState({ nodeDetails: [] });
316 showNodeModal: false,
319 dslQueryTree:updatedTreeData
320 }, ()=>{this.update(this, d)});
323 var attrDetails = null;
324 for (var key in this.state.nodeDetails) {
325 if(this.state.nodeDetails[key].isSelected){
326 nodeType = this.state.nodeDetails[key].nodeType;
327 attrDetails = this.state.nodeDetails[key].attrDetails;
330 this.build(nodeType, null, attrDetails);
331 this.setState({ nodeDetails: [], showNodeModal: false, traverseToNodes: [], selectedNode: null });
334 handlingTreeDataWhileAddRemove = (treeData,addObject,id,name)=>{
336 if(treeData.children && treeData.children.length>0){
337 for(var y=0;y<treeData.children.length;y++){
338 if(treeData.children[y].id=== id && treeData.children[y].name===name){
339 treeData.children.splice(y,1);
341 treeData.children[y]=this.handlingTreeDataWhileAddRemove(treeData.children[y],'',id,name);
346 if(treeData.id === id && treeData.name===name){
347 if(!treeData.children){
348 treeData.children=[];
350 treeData.children.push(addObject);
351 }else if(treeData.children && treeData.children.length>0){
352 for(var y=0;y<treeData.children.length;y++){
353 if(treeData.children[y].id=== id && treeData.children[y].name===name){
354 if(!treeData.children[y].children){
355 treeData.children[y].children=[];
357 treeData.children[y].children.push(addObject);
359 treeData.children[y]=this.handlingTreeDataWhileAddRemove(treeData.children[y],addObject,id,name);
367 populateEdgeRules = (nodeType) => {
368 let nodeDetails=GeneralCommonFunctions.populateEdgeRules(nodeType,this.state.edgeRules);
370 nodeDetails: nodeDetails
375 closeEditDSLModal = () => {
376 console.log("closing DSL edit modal");
377 this.setState({ showEditModal: false });
379 submitEditNodeModal = () =>{
380 this.update(this, this.state.selectedNode);
381 this.setState({showEditNodeModal: false});
383 closeEditNodeModal = () =>{
385 showEditNodeModal: false,
390 this.setState({ editModel: e.target.value });
393 update = (base, source, isInit) => {
395 // Assigns the x and y position for the nodes
396 var treeData = base.state.treemap(base.state.root);
398 var DSL = GeneralCommonFunctions.populatePathDSL(treeData,true,false,this.state.enableRealTime);
399 console.log(JSON.stringify("DSL :" + DSL));
401 this.setState({ dslQuery: DSL });
403 // Compute the new tree layout.
404 var nodes = treeData.descendants(),
405 links = treeData.descendants().slice(1);
407 var list1 = d3.selectAll(".fa")
409 .style("display","block");
411 // Normalize for fixed-depth.
412 nodes.forEach(function(d){ d.y = d.depth * 100});
414 // ****************** Nodes section ***************************
416 // Update the nodes...
417 var node = base.state.g.selectAll('g.node')
418 .data(nodes, function(d) {return d.id });
420 // Enter any new modes at the parent's previous position.
421 var nodeEnter = node.enter().append('g')
422 .attr('class', 'node')
423 .attr("transform", function(d) {
424 return "translate(" + source.y0 + "," + source.x0 + ")";
426 // .on('click', click)
427 .on('dblclick', doubleClick);
429 // Add Circle for the nodes
430 nodeEnter.append('circle')
431 .attr('class', 'node')
433 .style("fill", function(d) {
434 return d.data.details && d.data.details.includeInOutput ? "lightsteelblue" : "#fff";
436 nodeEnter.append("svg:foreignObject")
441 .append("xhtml:span")
442 .attr("class", function (d) {
444 if(!INVLIST.IS_ONAP){
445 icon = 'icon-datanetwork-serverL';
447 icon = 'browse-fa fa fa-server';
449 if(d.data.details && d.data.details.parentContainer){
450 var iconKey = ((d.data.details.parentContainer).replace(/-/g, '')).toUpperCase();
451 if(INVLIST.INVENTORYLIST[iconKey] && INVLIST.INVENTORYLIST[iconKey].icon){
452 return INVLIST.INVENTORYLIST[iconKey].icon;
460 .style("font-size", function (d) {
461 if (!INVLIST.IS_ONAP){
467 .attr("id", function (d) {return "nodeIcon" + d.id})
468 .style("color", '#387dff')
469 .style("display", "block")
470 .style("padding-top",function(d){
471 if (!INVLIST.IS_ONAP){
478 nodeEnter.append("svg:foreignObject")
483 .on('click', function (d) {
484 if(d.data.details.isRootNode){
486 base.state.svg.selectAll("*").remove();
487 base.setState({init: true, dslQuery: '',dslQueryTree:''});
489 let dslQueryTree=base.state.dslQueryTree;
490 for(var i = 0; d.parent.children && i < d.parent.children.length; i++){
491 if (d.parent.children.length > 1 && d.data.name === d.parent.children[i].data.name){
492 d.parent.children.splice(i, 1);
493 dslQueryTree=base.handlingTreeDataWhileAddRemove(dslQueryTree,'',d.data.id,d.data.name);
494 base.setState({dslQueryTree:dslQueryTree});
495 }else if (d.parent.children.length === 1 && d.data.name === d.parent.children[i].data.name){
496 d.parent.children = null;
499 base.update(base, d);
502 .append("xhtml:span")
503 .attr("class", "fa fa-minus")
504 .style("padding-top", "1px")
505 .style("font-size", function (d){ return "5px";})
506 .attr("id", function (d) {return "nodeDelete" + d.id})
507 .style("color", '#387dff')
508 .style("display", function (d) {return "block";});
509 nodeEnter.append("svg:foreignObject")
514 .on('click', function (d) { add(d)})
515 .append("xhtml:span")
516 .attr("class", "fa fa-plus")
517 .style("font-size", function (d){ return "5px";})
518 .style("padding-top", "1px")
519 .attr("id", function (d) {return "nodeAdd" + d.id})
520 .style("color", '#387dff');
521 nodeEnter.append("svg:foreignObject")
526 .on('click', function (d) { edit(d)})
527 .append("xhtml:span")
528 .attr("class", "fa fa-pencil-square")
529 .style("padding-top", "1px")
530 .style("font-size", function (d){ return "5px";})
531 .attr("id", function (d) {return "nodeEdit" + d.id})
532 .style("color", '#387dff');
533 // Add labels for the nodes
534 nodeEnter.append('text')
536 .attr("x", function(d) {
537 return d.children ? -13 : 13;
539 .attr("text-anchor", function(d) {
540 return d.children ? "end" : "start";
542 .text(function(d) { return d.data.name; });
545 var nodeUpdate = nodeEnter.merge(node);
546 var postNodeDrawnCallBack = function (d){
547 if(!isInit && base.state.autoZoomEnabled || d.data.details.isRootNode){
548 base.state.zoomFit();
551 // Transition to the proper position for the node
552 nodeUpdate.transition()
553 .duration(base.state.duration)
554 .attr("transform", function(d) {
555 return "translate(" + d.y + "," + d.x + ")"
556 }).on("end", postNodeDrawnCallBack);
558 // Update the node attributes and style
559 nodeUpdate.select('circle.node')
561 .style("fill", function(d) {
562 return d.data.details && d.data.details.includeInOutput ? "lightsteelblue" : "#fff";
564 .attr('cursor', 'pointer');
567 // Remove any exiting nodes
568 var nodeExit = node.exit().transition()
569 .duration(base.state.duration)
570 .attr("transform", function(d) {
571 return "translate(" + source.y + "," + source.x + ")";
575 // On exit reduce the node circles size to 0
576 nodeExit.select('circle')
579 // On exit reduce the opacity of text labels
580 nodeExit.select('text')
581 .style('fill-opacity', 1e-6);
583 // ****************** links section ***************************
585 // Update the links...
586 var link = base.state.g.selectAll('path.link')
587 .data(links, function(d) { return d.id; });
589 // Enter any new links at the parent's previous position.
590 var linkEnter = link.enter().insert('path', "g")
591 .attr("class", "link")
592 .attr('d', function(d){
593 var o = {x: source.x0, y: source.y0}
594 return diagonal(o, o)
598 var linkUpdate = linkEnter.merge(link);
600 // Transition back to the parent element position
601 linkUpdate.transition()
602 .duration(base.state.duration)
603 .attr('d', function(d){ return diagonal(d, d.parent) });
605 // Remove any exiting links
606 var linkExit = link.exit().transition()
607 .duration(base.state.duration)
608 .attr('d', function(d) {
609 var o = {x: source.x, y: source.y}
610 return diagonal(o, o)
614 // Store the old positions for transition.
615 nodes.forEach(function(d){
620 // Creates a curved (diagonal) path from parent to the child nodes
621 function diagonal(s, d) {
622 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;
625 base.state.svg.on("dblclick.zoom", null);
626 // Toggle children on click.
628 base.populateEdgeRules(d.data.name,base.state.edgeRules);
631 d.data.children = [];
640 console.log("object editing: " + d);
641 var nodeDetails = base.state.nodeDetails;
642 //set up node details to have the node to edit
643 nodeDetails[0] = d.data.details;
646 showEditNodeModal: true
649 function doubleClick(d) {
653 selectAll = (nodeKey) =>{//delete
654 var nodeDetails = this.state.nodeDetails;
655 for (var key in nodeDetails[nodeKey].attrDetails) {
656 nodeDetails[nodeKey].attrDetails[key].isSelected = true;
658 this.setState({nodeDetails: nodeDetails});
660 deselectAll = (nodeKey) =>{//delete
661 var nodeDetails = this.state.nodeDetails;
662 for (var key in nodeDetails[nodeKey].attrDetails) {
663 nodeDetails[nodeKey].attrDetails[key].isSelected = false;
665 this.setState({nodeDetails: nodeDetails});
667 build = (type, propID, attrDetails,preBuiltTree) =>{
668 console.log('build>>>>>>>>',type);
676 if(!preBuiltTree && type && (propID || attrDetails)){
684 treeData.details.includeInOutput = true;
685 treeData.details.isSelected = true;
686 treeData.details.isRootNode = true;
687 treeData.details.nodeType = nodeType;
689 treeData.details.attrDetails = attrDetails;
691 treeData.details.attrDetails = {};
694 let propIds = (propID) ? propID.split(';') : '';
695 let propertyValue = '';
696 for(var i in propIds){
697 let propValue = propIds[i].split(':');
698 console.log(propValue[0] + '....' + propValue[1]);
699 treeData.details.attrDetails[propValue[0]] = {};
700 treeData.details.attrDetails[propValue[0]].filterValue=[];
701 treeData.details.attrDetails[propValue[0]].filterValue.push(atob(propValue[1]).replace('<pre>','').replace('</pre>',''));
702 treeData.details.attrDetails[propValue[0]].attributeName = propValue[0];
703 treeData.details.attrDetails[propValue[0]].isSelected = true;
706 }else if (preBuiltTree){
707 treeData = preBuiltTree;
710 // append the svg object to the body of the page
711 // appends a 'group' element to 'svg'
712 // moves the 'group' element to the top left margin
713 var svg = d3.select("#PathDSLBuilder");
714 // Set the dimensions and margins of the diagram
715 var margin = {top: 20, right: 120, bottom: 20, left: 120},
716 width = +svg.attr("width") - margin.right - margin.left,
717 height = +svg.attr("height") - margin.top - margin.bottom;
719 var g = svg.append("g")
720 .attr("transform", "translate("
721 + margin.left + "," + margin.top + ")");
726 // declares a tree layout and assigns the size
727 var treemap = d3.tree().size([height - 200, width]);
728 // Assigns parent, children, height, depth
729 root = d3.hierarchy(treeData, function(d) { return d.children; });
730 root.x0 = height / 2;
734 function zoom_actions(){
735 g.attr("transform", d3.event.transform)
737 //add zoom capabilities
738 var zoom_handler = d3.zoom()
739 .on("zoom", zoom_actions);
744 var bounds = g.node().getBBox();
745 var parent = g.node().parentElement;
746 var fullWidth = parent.clientWidth || parent.parentNode.clientWidth,
747 fullHeight = parent.clientHeight || parent.parentNode.clientHeight;
748 var width = bounds.width,
749 height = bounds.height;
750 var midX = bounds.x + width / 2,
751 midY = bounds.y + height / 2;
752 if (width == 0 || height == 0) return; // nothing to fit
753 var scale = Math.min((0.95 / Math.max(width / fullWidth, height / fullHeight)), 2);
754 var translate = [fullWidth / 2 - scale * midX, fullHeight / 2 - scale * midY];
756 var transform = d3.zoomIdentity
757 .translate(80, translate[1])
759 svg.transition().duration(350)
760 .call(zoom_handler.transform, transform);
765 svg.call(zoom_handler)
766 .call(zoom_handler.transform, d3.zoomIdentity.translate(80, -500).scale(2));
775 dslQueryTree: treeData
776 }, ()=>{this.update(this, root, true);})
778 // Collapse the node and all it's children
779 function collapse(d) {
781 d.children.forEach(collapse)
788 onTargetMenuOfFilterTypes=(listname,id)=>{
789 console.log(listname+'onTargetMenuOfFilterTypes',id);
790 let keysOfArray=id.split('#');
791 let nodekey=keysOfArray[0];
792 let attrKey=keysOfArray[1];
793 let indx=parseInt(keysOfArray[2]);
794 let nodeDetails = this.state.nodeDetails;
795 let node = nodeDetails[nodekey];
796 if(!node.attrDetails){
797 node.attrDetails = [];
799 if(!node.attrDetails[attrKey]){
800 node.attrDetails[attrKey] = {};
801 node.attrDetails[attrKey].isSelected = true;
802 node.attrDetails[attrKey].filterValue = [];
803 node.attrDetails[attrKey].filterType = [];
805 let filterTypes=node.attrDetails[attrKey].filterType;
806 filterTypes[indx]=listname;
807 node.attrDetails[attrKey].filterType=filterTypes;
809 nodeDetails[nodekey] = node;
810 // update the state with the new array of traverse to nodes
811 this.setState({ nodeDetails: nodeDetails });
813 filterTags = (key,property,state) =>{
816 state=true;//always enable, in future if wants to disable remove this line
817 if(APERTURE_SERVICE && this.state.enableRealTime){
818 let nodeDetails = this.state.nodeDetails;
819 let node = nodeDetails[key];
820 filterTags= Object.keys(Object.keys(node.attrDetails[property].filterType)).map((indx) =>{
821 let selectedFilter=(node.attrDetails[property].filterType[indx]!=='')?node.attrDetails[property].filterType[indx]:this.state.filterTypeDisplay;
822 return <div style={{margin:'0px 0px 0px 5px'}}>
824 <FilterTypes param={this.state}
825 selectedFilter={selectedFilter}
826 id={key+'#'+property+'#'+indx}
827 onMenuSelect={this.onTargetMenuOfFilterTypes}
832 filters= <Col md={4} className='removeLeftPadding'>{filterTags}</Col>;
836 addOrTemplate=(nodeKey,attrKey,indx)=>{
837 let nodeDetails = this.state.nodeDetails;
838 let node = nodeDetails[nodeKey];
839 node.attrDetails[attrKey].filterValue.push('');
840 node.attrDetails[attrKey].filterType.push('EQ');
841 nodeDetails[nodeKey] = node;
842 // update the state with the new array of traverse to nodes
843 this.setState({ nodeDetails: nodeDetails });
845 deleteOrTemplate=(nodeKey,attrKey,index)=>{
846 let nodeDetails = this.state.nodeDetails;
847 let node = nodeDetails[nodeKey];
848 let filterValuesArray=node.attrDetails[attrKey].filterValue;
849 let filterTypeArray=node.attrDetails[attrKey].filterType;
850 filterValuesArray.splice(index,1);
851 filterTypeArray.splice(index,1);
852 node.attrDetails[attrKey].filterValue=filterValuesArray;
853 node.attrDetails[attrKey].filterType=filterTypeArray;
854 nodeDetails[nodeKey] = node;
855 this.setState({ nodeDetails: nodeDetails });
859 <div id='pathFilterDSLModel'>
860 <div className="addPadding">
861 <div className={'row ' + (!this.state.init ? 'show' : 'hidden')}>
862 <div className="checkbox" style={{float:'left',width:'70%'}}>
864 <input type="checkbox" checked={this.state.autoZoomEnabled} onChange={this.onAutoZoomCheckbox.bind(this)}/>
868 <div style={{float:'right'}}>
869 <Button onClick={this.props.closePathNodeModal}>Close</Button>
870 <Button onClick={this.submitPathNodeModal} disabled={(this.state.dslQuery === '')}>Submit</Button>
873 <div className={'row ' + (!this.state.init ? 'show' : 'hidden')}>
874 <div style={{fontWeight:'bold'}}>
875 <span>DSL PATH Query :</span> {this.state.dslQuery}
878 <div className={'row ' + ((this.state.dslQuery != '') ? 'hidden' : 'show')}>
879 <div style={{float:'left'}}>
880 <button className='btn btn-primary' type='button' onClick={this.initialLoadWhileClose}>Start Building (+)</button>
882 <div style={{float:'right'}}>
883 <Button onClick={this.props.closePathNodeModal}>Close</Button>
884 <Button onClick={this.submitPathNodeModal} disabled={(this.state.dslQuery === '')}>Submit</Button>
888 <svg id='PathDSLBuilder' width='1800' height='800'></svg>
889 <div className='static-modal' id='customDslPathBuilderModel'>
890 <Modal show={this.state.showNodeModal} onHide={this.closeNodeModal}>
892 <Modal.Title>Modify Dsl Path Query</Modal.Title>
896 {Object.keys(this.state.nodeDetails).sort().map((key, node) => (
897 <div className="dsl-panel">
901 <div className={'checkbox ' + (!this.state.init ? 'show' : 'hidden')}>
903 <input type="checkbox" checked={this.state.nodeDetails[key].isSelected} value={key} onChange={this.onNodeCheckbox.bind(this)} />
904 {this.state.nodeDetails[key].nodeType}
907 <div className="pull-right">Options</div>
910 <div className={'form-check ' + (this.state.init ? 'show' : 'hidden')}>
911 <label className="form-check-label">
912 <input className="form-check-input" type="radio" value={key} checked={this.state.nodeDetails[key].isSelected} onChange={this.onNodeRadio.bind(this)} />
913 {" " + this.state.nodeDetails[key].nodeType}
916 <div className="pull-right">Options</div>
922 <Panel.Body className='cardwrap'>
923 <Grid fluid={true} className='addPaddingTop'>
924 <Row className='show-grid addPaddingTop'>
925 <Col md={(this.state.enableRealTime)?4:6}>
926 <strong>PROPERTIES</strong>
928 {this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
929 <strong>Filter Types</strong>
931 <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
932 <strong>Filter By (Optional)</strong>
935 {Object.keys(this.state.nodeDetails[key].attrDetails).sort().map((attrKey, attr) => {
937 <Row className='show-grid'>
938 <Col md={(this.state.enableRealTime)?4:6}>
939 <div className="checkbox">
945 {this.filterTags(key,attrKey,this.state.nodeDetails[key].attrDetails[attrKey].isSelected)}
946 <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
947 {Object.keys(this.state.nodeDetails[key].attrDetails[attrKey].filterValue).map((indx) =>{
950 {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
951 placeholder={"Enter " + attrKey }
952 className='inputFilter'
953 onBlur={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
956 {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
957 onChange={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
958 placeholder={"Enter " + attrKey }
959 className='inputFilter'
960 value={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]}
963 {indx == 0 && <button
964 className={(this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='')?'btn btn-primary':'btn btn-secondary'}
965 style={{padding:'2px',margin:'0px 0px 7px 3px'}}
966 disabled={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]===''}
968 onClick={e => {this.addOrTemplate(key,attrKey,indx)}}>+</button>}
970 style={{padding:'2px',margin:'0px 0px 7px 3px'}}
972 className='btn btn-danger'
974 onClick={e => {this.deleteOrTemplate(key,attrKey,indx)}}>x</button>}
993 <Button onClick={this.closeNodeModal}>Close</Button>
994 <Button onClick={this.submitNodeModal}>Submit</Button>
998 <div className='static-modal' id='editNodeModel'>
999 <Modal show={this.state.showEditNodeModal} onHide={this.closeEditNodeModal}>
1001 <Modal.Title>Modify Node</Modal.Title>
1005 <div className="dsl-panel">
1010 <label>{this.state.selectedNode
1011 && this.state.selectedNode.data
1012 && this.state.selectedNode.data.details ?
1013 this.state.selectedNode.data.details.nodeType
1020 <Panel.Body className='cardwrap'>
1021 <Grid fluid={true} className='addPaddingTop'>
1022 <Row className='show-grid addPaddingTop'>
1023 <Col md={(this.state.enableRealTime)?4:6}>
1024 <strong>Include in Output</strong>
1026 {this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
1027 <strong>Filter Types</strong>
1029 <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
1030 <strong>Filter By (Optional)</strong>
1033 {this.state.selectedNode
1034 && this.state.selectedNode.data
1035 && this.state.selectedNode.data.details
1036 && this.state.nodeDetails[0]
1037 && Object.keys(this.state.nodeDetails[0].attrDetails).sort().map((attrKey, attr) => {
1039 <Row className='show-grid'>
1040 <Col md={(this.state.enableRealTime)?4:6}>
1041 <div className="checkbox">
1047 {this.filterTags(0,attrKey, this.state.nodeDetails[0].attrDetails[attrKey].isSelected)}
1048 <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
1049 {Object.keys(this.state.nodeDetails[0].attrDetails[attrKey].filterValue).map((indx) =>{
1053 {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
1054 placeholder={"Enter " + attrKey }
1055 className='inputFilter'
1056 onBlur={(e)=>{this.onFilterValueChange(e, 0, attrKey, indx);}}
1059 {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
1060 onChange={(e)=>{this.onFilterValueChange(e, 0, attrKey,indx);}}
1061 placeholder={"Enter " + attrKey }
1062 className='inputFilter'
1063 value={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]}
1066 {indx == 0 && <button
1067 className={(this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]!=='')?'btn btn-primary':'btn btn-secondary'}
1068 style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1069 disabled={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]===''}
1071 onClick={e => {this.addOrTemplate(0 ,attrKey,indx)}}>+</button>}
1072 {indx > 0 && <button
1073 style={{padding:'2px',margin:'0px 0px 7px 3px'}}
1075 className='btn btn-danger'
1077 onClick={e => {this.deleteOrTemplate(0 ,attrKey,indx)}}>x</button>}
1095 <Button onClick={this.closeEditNodeModal}>Close</Button>
1096 <Button onClick={this.submitEditNodeModal}>Submit</Button>
1105 export default PathFilterDslBuilder;