summaryrefslogtreecommitdiffstats
path: root/src/app/byoq
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/byoq')
-rw-r--r--src/app/byoq/CustomDSLSaveLoad.jsx842
-rw-r--r--src/app/byoq/CustomDsl.jsx4710
-rw-r--r--src/app/byoq/CustomDslBuilder.jsx1725
-rw-r--r--src/app/byoq/PathFilterDslBuilder.jsx1105
4 files changed, 8382 insertions, 0 deletions
diff --git a/src/app/byoq/CustomDSLSaveLoad.jsx b/src/app/byoq/CustomDSLSaveLoad.jsx
new file mode 100644
index 0000000..e106e4a
--- /dev/null
+++ b/src/app/byoq/CustomDSLSaveLoad.jsx
@@ -0,0 +1,842 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import React, { Component } from 'react';
+
+import commonApi from 'utils/CommonAPIService.js';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+import Spinner from 'utils/SpinnerContainer.jsx';
+import Grid from 'react-bootstrap/lib/Grid';
+import Row from 'react-bootstrap/lib/Row';
+import Col from 'react-bootstrap/lib/Col';
+import Button from 'react-bootstrap/lib/Button';
+import Modal from 'react-bootstrap/lib/Modal';
+import Tabs from 'react-bootstrap/lib/Tabs';
+import Tab from 'react-bootstrap/lib/Tab';
+import Pagination from 'react-js-pagination';
+import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
+import Tooltip from 'react-bootstrap/lib/Tooltip';
+import Panel from 'react-bootstrap/lib/Panel';
+import {GeneralCommonFunctions} from 'utils/GeneralCommonFunctions.js';
+import Alert from 'react-bootstrap/lib/Alert';
+import MultiSelectDropDown from 'generic-components/MultiSelectDropDown.jsx';
+let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
+let APERTURE_SERVICE = JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+
+let INVLIST = GlobalExtConstants.INVLIST;
+
+const settings = {
+ 'NODESERVER': INVLIST.NODESERVER,
+ 'PROXY': INVLIST.PROXY,
+ 'PREFIX': INVLIST.PREFIX,
+ 'VERSION': INVLIST.VERSION,
+ 'USESTUBS': INVLIST.useStubs,
+ 'TABULAR': INVLIST.TABULAR,
+ 'APERTURE': INVLIST.APERTURE,
+ 'TABULARVERSION': INVLIST.TABULARVERSION
+};
+
+/**
+ * This class is used to handle any saving or loading of dsl queries
+ */
+
+class CustomDSLSaveLoad extends Component {
+
+ constructor(props) {
+ console.log(props);
+ super(props);
+ APERTURE_SERVICE=JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+ this.state = {
+ enablePublicQueriesBusyFeedback: false,
+ enableCommunityQueriesBusyFeedback: false,
+ enablePersonalQueriesBusyFeedback: false,
+ enableDeleteBusyFeedback: false,
+ loadedPublicQueries: [],
+ loadedCommunityQueries: [],
+ loadedPersonalQueries: [],
+ filteredPublicEntries: [],
+ filteredCommunityEntries: [],
+ filteredPersonalEntries: [],
+ initialFilteredPublicEntries: [],
+ initialFilteredCommunityEntries: [],
+ initialFilteredPersonalEntries:[],
+ totalPublicResults: 0,
+ totalCommunityResults: 0,
+ totalPersonalResults: 0,
+ queriesPublicErrMsg: false,
+ queriesCommunityErrMsg: false,
+ queriesPersonalErrMsg: false,
+ deleteErrMsg: false,
+ deleteSuccessfulMsg: false,
+ focusedEntryName: '',
+ focusedEntryType: false,
+ showDeleteModal: false,
+ filterPublicCriteria: '',
+ filterCommunityCriteria: '',
+ filterPersonalCriteria: '',
+ displayValue:'Category',
+ selectedOption:{"public":[],"community":[],"personal":[]},
+ filterText:'',
+ activeType:'public',
+ queryId:'',
+ loadQueryList:[],
+ publicLoadQueryList:[],
+ personalLoadQueryList:[],
+ communityLoadQueryList:[],
+ loadQueryLimit:parseInt(sessionStorage.getItem(ENVIRONMENT + 'LOADTEMPLATE_MAX_COUNT')),
+ loadQueryFlag:true,
+ selectedCount:0
+ };
+ settings['ISAPERTURE']=APERTURE_SERVICE;
+ }
+ componentDidMount = () => {
+ this.setState({enablePersonalQueriesBusyFeedback:true,enablePublicQueriesBusyFeedback:true,enableCommunityQueriesBusyFeedback:true});
+ this.getQueries();
+ };
+ componentWillUnmount = () => {};
+
+ filterPublicList = (event) =>{
+ this.filterPublicListWithCategory(event.target.value);
+ }
+ filterPublicListWithCategory = (value) =>{
+ var updatedList = this.state.loadedPublicQueries;
+ updatedList = Object.keys(updatedList).filter(key => {
+ return JSON.stringify(updatedList[key]).toLowerCase().search(value.toLowerCase()) !== -1;
+ }).reduce( (res, key) => Object.assign(res, { [key]: updatedList[key] }), {} );
+ let filterList=this.filterUpdatedList(updatedList, "public");
+ console.log('filterPublicListWithCategory filterList>>>>>',filterList);
+ this.setState({filteredPublicEntries: filterList, totalPublicResults: Object.keys(filterList).length, filterPublicCriteria: value,filterText: value.toLowerCase()});
+ }
+ filterCommunityList = (event) =>{
+ this.filterCommunityListWithCategory(event.target.value);
+ }
+ filterCommunityListWithCategory = (value) =>{
+ var updatedList = this.state.loadedCommunityQueries;
+ updatedList = Object.keys(updatedList).filter(key => {
+ return JSON.stringify(updatedList[key]).toLowerCase().search(value.toLowerCase()) !== -1;
+ }).reduce( (res, key) => Object.assign(res, { [key]: updatedList[key] }), {} );
+ let filterList=this.filterUpdatedList(updatedList, "community");
+ console.log('filterCommunityListWithCategory filterList>>>>>',filterList);
+ this.setState({filteredCommunityEntries: filterList, totalCommunityResults: Object.keys(filterList).length, filterCommunityCriteria: value,filterText: value.toLowerCase()});
+ }
+ filterPersonalList = (event) =>{
+ this.filterPersonalListWithCategory(event.target.value);
+ }
+ filterPersonalListWithCategory =(value) =>{
+ var updatedList = this.state.loadedPersonalQueries;
+ updatedList = Object.keys(updatedList).filter(key => {
+ return JSON.stringify(updatedList[key]).toLowerCase().search(value.toLowerCase()) !== -1;
+ }).reduce( (res, key) => Object.assign(res, { [key]: updatedList[key] }), {} );
+ let filterList=this.filterUpdatedList(updatedList, "personal");
+ console.log('filterPersonalListWithCategory filterList>>>>>',filterList);
+ this.setState({filteredPersonalEntries: filterList, totalPersonalResults: Object.keys(filterList).length, filterPersonalCriteria: value,filterText: value.toLowerCase()});
+ }
+ filterUpdatedList = (updatedList, type) =>{
+ let selectedCategory = this.state.selectedOption[type];
+ let filterList = [];
+ let selectedOption = [];
+ if(selectedCategory.length > 0){
+ selectedOption = Object.keys(selectedCategory).map((index)=>{
+ return selectedCategory[index].value;
+ });
+ Object.keys(updatedList).map((key) => {
+ Object.keys(updatedList[key]).map((entry) => {
+ if(entry === 'category' && selectedOption.indexOf(updatedList[key][entry]) !==-1){
+ filterList[key]=updatedList[key];
+ }
+ })
+ });
+ }else{
+ filterList=updatedList;
+ }
+ return filterList;
+ }
+ processQueryResponse = (res) => {
+ var formattedList = [];
+ for(var i = 0; i < res.length; i++){
+ var newQueryObj = {};
+ var requiredFieldCount = 0;
+ if(res[i]){
+ newQueryObj.isSelect=false;
+ newQueryObj.id = res[i].id;
+ newQueryObj['is_aggregate'] = false;
+ newQueryObj['is_public'] = false;
+ newQueryObj['community_shared'] = false;
+ newQueryObj['template_details'] = [];
+ for(var j = 0; j < res[i].cols.length; j++){
+ if(res[i].cols[j].name){
+ if(res[i].cols[j].name === 'query_name'){
+ requiredFieldCount++;
+ newQueryObj.name = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'creator'){
+ requiredFieldCount++;
+ newQueryObj.creator = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'dsl'){
+ requiredFieldCount++;
+ newQueryObj.dsl = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'description'){
+ newQueryObj.description = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'is_aggregate'){
+ newQueryObj['is_aggregate'] = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'is_public'){
+ newQueryObj['is_public'] = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'community_shared'){
+ newQueryObj['community_shared'] = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'template_details'){
+ newQueryObj['template_details'] = res[i].cols[j].value;
+ }
+ if(res[i].cols[j].name === 'category'){
+ newQueryObj['category'] = res[i].cols[j].value;
+ }
+ }
+ }
+ newQueryObj.version = res[i].version;
+ }
+ if(requiredFieldCount === 3){
+ formattedList[res[i].id] = newQueryObj;
+ }else{
+ console.log('Issue occurred on query list processing for the following element: ' + JSON.stringify(newQueryObj));
+ }
+ }
+ return formattedList;
+ }
+
+ getPublicQueries = () => {
+ settings['ISTABULAR'] = true;
+ return new Promise((resolve, reject) => {
+ commonApi(settings, 'queries/is_public=true', 'GET', null, 'BYOQPublicQueries', GlobalExtConstants.OVERRIDE_DOMAIN)
+ .then(res => {
+ console.log('res:' + res.data, 'load');
+ if(res.status === 200 || res.status === 404){
+ if(res.data.status && (res.data.status !== 200 && res.data.status !== 201 && res.data.status !== 404)){
+ this.triggerError(res.data);
+ }else{
+ var list = this.processQueryResponse(res.data);
+ this.setState({
+ enablePublicQueriesBusyFeedback:false,
+ filteredPublicEntries: list,
+ initialFilteredPublicEntries: list,
+ totalPublicResults: Object.keys(list).length,
+ loadedPublicQueries: list
+ });
+ this.runPublicFilter();
+ resolve(list);
+ }
+ }else{
+ this.triggerError(res.data, 'public_load');
+ }
+ resolve([]);
+ }, error=>{
+ if(error.response.status === 404){
+ this.setState({
+ enablePublicQueriesBusyFeedback:false,
+ filteredPublicEntries: [],
+ totalPublicResults: 0,
+ initialFilteredPublicEntries:[],
+ loadedPublicQueries: []
+ });
+ }else{
+ this.triggerError(error.response.data, 'public_load');
+ }
+ resolve([]);
+ }).catch(error => {
+ this.triggerError(error, 'public_load');
+ resolve([]);
+ })
+ })
+ }
+ getCommunityQueries = () => {
+ settings['ISTABULAR'] = true;
+ return new Promise((resolve, reject) => {
+ commonApi(settings, 'queries/community_shared=true', 'GET', null, 'BYOQCommunityQueries', GlobalExtConstants.OVERRIDE_DOMAIN)
+ .then(res => {
+ console.log('res:' + res.data, 'load');
+ if(res.status === 200 || res.status === 404){
+ if(res.data.status && (res.data.status !== 200 && res.data.status !== 201 && res.data.status !== 404)){
+ this.triggerError(res.data);
+ }else{
+ var list = this.processQueryResponse(res.data);
+ this.setState({
+ enableCommunityQueriesBusyFeedback:false,
+ filteredCommunityEntries: list,
+ initialFilteredCommunityEntries: list,
+ totalCommunityResults: Object.keys(list).length,
+ loadedCommunityQueries: list
+ });
+ this.runCommunityFilter();
+ resolve(list);
+ }
+ }else{
+ this.triggerError(res.data, 'community_load');
+ }
+ resolve([]);
+ }, error=>{
+ if(error.response.status === 404){
+ this.setState({
+ enableCommunityQueriesBusyFeedback:false,
+ filteredCommunityEntries: [],
+ totalCommunityResults: 0,
+ initialFilteredCommunityEntries:[],
+ loadedCommunityQueries: []
+ });
+ }else{
+ this.triggerError(error.response.data, 'community_load');
+ }
+ resolve([]);
+ }).catch(error => {
+ this.triggerError(error, 'community_load');
+ resolve([]);
+ })
+ })
+ }
+ getPrivateQueries = () => {
+ settings['ISTABULAR'] = true;
+ let query='queries/is_public=false';
+ if(sessionStorage.getItem(GlobalExtConstants.ENVIRONMENT + 'userId')){
+ query+='&creator=' + sessionStorage.getItem(GlobalExtConstants.ENVIRONMENT + 'userId');
+ }
+ return new Promise((resolve, reject) => {
+ commonApi(settings, 'queries/is_public=false&creator=' + sessionStorage.getItem(GlobalExtConstants.ENVIRONMENT + 'userId'), 'GET', null, 'BYOQPersonalQueries', GlobalExtConstants.OVERRIDE_DOMAIN)
+ .then(res => {
+ console.log('res:' + res.data, 'load');
+ if(res.status === 200 || res.status === 404){
+ if(res.data.status && (res.data.status !== 200 && res.data.status !== 201 && res.data.status !== 404)){
+ this.triggerError(res.data);
+ }else{
+ var list = this.processQueryResponse(res.data);
+ this.setState({
+ enablePersonalQueriesBusyFeedback:false,
+ filteredPersonalEntries: list,
+ initialFilteredPersonalEntries: list,
+ totalPersonalResults: Object.keys(list).length,
+ loadedPersonalQueries: list
+ });
+ this.runPersonalFilter();
+ resolve(list);
+ }
+ }else{
+ this.triggerError(res.data, 'personal_load');
+ }
+ resolve([]);
+ }, error=>{
+ if(error.response.status === 404){
+ this.setState({
+ enablePersonalQueriesBusyFeedback:false,
+ filteredPersonalEntries: [],
+ initialFilteredPersonalEntries: [],
+ totalPersonalResults: 0,
+ loadedPersonalQueries: []
+ });
+ }else{
+ this.triggerError(error.response.data, 'personal_load');
+ }
+ resolve([]);
+ }).catch(error => {
+ this.triggerError(error, 'personal_load');
+ resolve([]);
+ })
+ })
+ }
+ getQueries = () =>{
+ var state = this;
+ this.getCommunityQueries();
+ Promise.all([
+ this.getPublicQueries(),
+ this.getPrivateQueries()
+ ])
+ .then(function (responses) {
+ var result = Object.assign({}, responses[0], responses[1]);
+ state.props.setQueriesState(result);
+ state.setState({loadQueryList:[],publicLoadQueryList:[],personalLoadQueryList:[],communityLoadQueryList:[],selectedCount:0});
+ }).catch(function (error) {
+ console.log(error);
+ });
+ };
+ triggerError = (error, type) => {
+ console.error('[CustomDslSaveLoad.jsx] error : ', JSON.stringify(error));
+ let errMsg = '';
+ if(error.status && error.message){
+ errMsg += "Error Occurred: " + error.status + ' - ' +error.message;
+ }else{
+ errMsg += "Error Occurred: " + JSON.stringify(error);
+ }
+ console.log(errMsg);
+ if(type === 'public_load'){
+ this.setState({queriesPublicErrMsg:errMsg,
+ enablePublicQueriesBusyFeedback:false,
+ filteredPublicEntries: [],
+ totalPublicResults: 0,
+ loadedPublicQueries: []});
+ var result = Object.assign({}, [], this.state.loadedPersonalQueries);
+ this.props.setQueriesState(result);
+ }else if(type === 'personal_load'){
+ this.setState({queriesPersonalErrMsg:errMsg,
+ enablePersonalQueriesBusyFeedback:false,
+ filteredPersonalEntries: [],
+ totalPersonalResults: 0,
+ loadedPersonalQueries: []});
+ var result = Object.assign({}, this.state.loadedPublicQueries, []);
+ this.props.setQueriesState(result);
+ }else if(type === 'community_load'){
+ this.setState({queriesCommunityErrMsg:errMsg,
+ enableCommunityQueriesBusyFeedback:false,
+ filteredCommunityEntries: [],
+ totalCommunityResults: 0,
+ loadedCommunityQueries: []});
+ var result = Object.assign({}, this.state.loadedCommunityQueries, []);
+ this.props.setQueriesState(result);
+ }else if (type === 'delete'){
+ this.setState({deleteErrMsg: errMsg + " - Failed to delete query : " + this.state.focusedEntryName, enableDeleteBusyFeedback:false});
+ GeneralCommonFunctions.scrollTo("deleteError");
+ }else{
+ console.log('[CustomDslSaveLoad.jsx] :: triggerError invoked with invalid type : ' + type);
+ }
+ }
+
+ runPublicFilter = () =>{
+ var updatedList = this.state.loadedPublicQueries;
+ updatedList = Object.keys(updatedList).filter(key => {
+ return JSON.stringify(updatedList[key]).toLowerCase().search(this.state.filterPublicCriteria.toLowerCase()) !== -1;
+ }).reduce( (res, key) => Object.assign(res, { [key]: updatedList[key] }), {} );
+ this.setState({filteredPublicEntries: updatedList, totalPublicResults: Object.keys(updatedList).length},()=>{if(this.state.selectedOption["public"].length>0){this.filterPublicListWithCategory(this.state.filterPublicCriteria)}});
+ }
+ runCommunityFilter = () =>{
+ var updatedList = this.state.loadedCommunityQueries;
+ updatedList = Object.keys(updatedList).filter(key => {
+ return JSON.stringify(updatedList[key]).toLowerCase().search(this.state.filterCommunityCriteria.toLowerCase()) !== -1;
+ }).reduce( (res, key) => Object.assign(res, { [key]: updatedList[key] }), {} );
+ this.setState({filteredCommunityEntries: updatedList, totalCommunityResults: Object.keys(updatedList).length},()=>{if(this.state.selectedOption["community"].length>0){this.filterCommunityListWithCategory(this.state.filterCommunityCriteria)}});
+ }
+ runPersonalFilter = () =>{
+ var updatedList = this.state.loadedPersonalQueries;
+ updatedList = Object.keys(updatedList).filter(key => {
+ return JSON.stringify(updatedList[key]).toLowerCase().search(this.state.filterPersonalCriteria.toLowerCase()) !== -1;
+ }).reduce( (res, key) => Object.assign(res, { [key]: updatedList[key] }), {} );
+ this.setState({filteredPersonalEntries: updatedList, totalPersonalResults: Object.keys(updatedList).length},()=>{if(this.state.selectedOption["personal"].length>0){this.filterPersonalListWithCategory(this.state.filterPersonalCriteria)}});
+ }
+
+ addElement = (element) =>{
+ var updatedList = this.state.loadedPublicQueries;
+ updatedList[element.id] = element[0];
+ this.setState({loadedPublicQueries: updatedList});
+ this.props.setQueriesState(updatedList);
+ this.runPublicFilter();
+ }
+
+ submitDelete = () =>{
+ var loadedQueries = [];
+ if(this.state.focusedEntryType === "personal"){
+ loadedQueries = this.state.loadedPersonalQueries;
+ }else{
+ loadedQueries = this.state.loadedPublicQueries;
+ }
+ this.setState({enableDeleteBusyFeedback:true});
+ settings['ISTABULAR'] = true;
+ commonApi(settings, 'queries/' + encodeURIComponent(this.state.queryId), 'DELETE', '{\"id\":\"'
+ + encodeURIComponent(this.state.queryId) + '\"}', 'BYOQDeleteQuery', GlobalExtConstants.OVERRIDE_DOMAIN, null,
+ [{
+ "name":"If-Match",
+ "value": loadedQueries[this.state.queryId].version
+ }])
+ .then(res => {
+ console.log('res:' + res.data);
+ if(res.status === 200){
+ if(res.data.status && (res.data.status !== 200 && res.data.status !== 201)){
+ this.triggerError(res.data, 'delete');
+ }else{
+ var updatedList = loadedQueries;
+ //remove the entry from the list
+ updatedList = Object.keys(updatedList).filter(key => {
+ return key !== this.state.queryId;
+ }).reduce( (res, key) => Object.assign(res, { [key]: updatedList[key] }), {} );
+ this.setState({showDeleteModal:false,
+ focusedEntryName: '',
+ enableDeleteBusyFeedback:false,
+ deleteSuccessfulMsg: "Successfully deleted query : " + this.state.focusedEntryName});
+ GeneralCommonFunctions.scrollTo("deleteSuccess");
+ if(this.state.focusedEntryType === "personal"){
+ this.getCommunityQueries();
+ this.setState({loadedPersonalQueries: updatedList});
+ var result = Object.assign({}, this.state.loadedPublicQueries, updatedList);
+ this.props.setQueriesState(result);
+ }else{
+ this.setState({loadedPublicQueries: updatedList});
+ var result = Object.assign({}, updatedList, this.state.loadedPersonalQueries);
+ this.props.setQueriesState(result);
+ }
+ this.runPublicFilter();
+ this.runCommunityFilter();
+ this.runPersonalFilter();
+ }
+ }else{
+ this.triggerError(res.data, 'delete');
+ }
+ }, error=>{
+ this.triggerError(error.response.data, 'delete');
+ }).catch(error => {
+ this.triggerError(error, 'delete');
+ });
+ };
+
+ openDeleteModal = (id,name, isPublic) =>{
+ var focusedEntryType = "public";
+ if(isPublic === "true"){
+ focusedEntryType = "public";
+ }else{
+ focusedEntryType = "personal";
+ }
+ this.setState({showDeleteModal:true, focusedEntryName: name, focusedEntryType: focusedEntryType, deleteSuccessfulMsg:false, deleteErrMsg:false, queryId:id});
+ };
+
+ closeDeleteModal = () =>{
+ this.setState({showDeleteModal:false, focusedEntryName: '', focusedEntryType: false, deleteSuccessfulMsg:false, deleteErrMsg:false, queryId:''});
+ };
+
+ loadQuery = (e) =>{
+ this.loadQueryData(e.target.value,0);
+ };
+ loadQueryData=(queryTemp, id)=>{
+ let splitString = queryTemp.split('||');
+ let name = splitString[0];
+ let description = splitString[1];
+ let category=(splitString[2] !== 'undefined')? splitString[2]:'';
+ let dsl = splitString[3];
+ let isAggregate = splitString[4];
+ let type = splitString[5];
+ let queryId = splitString[6];
+ let isCommunityShared = splitString[7];
+ let templateDetails = splitString[8];
+ this.props.loadCallback(name, description, category, dsl, isAggregate, type, queryId, isCommunityShared, id, templateDetails, false);
+ };
+ loadBulkCallback =() =>{
+ this.props.loadBulkCallback(this.state.loadQueryList);
+ }
+ loadAndRunQuery = (e) =>{
+ let splitString = (e.target.value).split('||');
+ let dsl = splitString[0];
+ let isAggregate = splitString[1];
+ this.props.loadCallback('', '', '', dsl, isAggregate, null, '', null, 0, [], true);
+ };
+ onMultiSelectPublicDropdownSelect = (selectedOption) =>{
+ console.log('onMultiSelectPublicDropdownSelect selectedList',selectedOption);
+ var tempSelection = this.state.selectedOption;
+ tempSelection["public"] = selectedOption;
+ this.setState({selectedOption:tempSelection},()=>{this.filterPublicListWithCategory(this.state.filterPublicCriteria)});
+ };
+ onMultiSelectCommunityDropdownSelect = (selectedOption) =>{
+ console.log('onMultiSelectCommunityDropdownSelect selectedList',selectedOption);
+ var tempSelection = this.state.selectedOption;
+ tempSelection["community"] = selectedOption;
+ this.setState({selectedOption:tempSelection},()=>{this.filterCommunityListWithCategory(this.state.filterCommunityCriteria)});
+ };
+ onMultiSelectPersonalDropdownSelect = (selectedOption) =>{
+ console.log('onMultiSelectPersonalDropdownSelect selectedList',selectedOption);
+ var tempSelection = this.state.selectedOption;
+ tempSelection["personal"] = selectedOption;
+ this.setState({selectedOption:tempSelection},()=>{this.filterPersonalListWithCategory(this.state.filterPersonalCriteria)});
+ };
+ prepareMultiOptions = (type) => {
+ //this.setState({activeType:type});
+ let filteredEntries=[];
+ if(type==='public'){
+ filteredEntries=this.state.initialFilteredPublicEntries;
+ }else if(type==='community'){
+ filteredEntries=this.state.initialFilteredCommunityEntries;
+ }else{
+ filteredEntries=this.state.initialFilteredPersonalEntries;
+ }
+ let dupArray=[];
+ let multiOption=Object.keys(filteredEntries).map((entry, idx) => {
+ let obj ={};
+ if(filteredEntries[entry]['category'] && dupArray.indexOf(filteredEntries[entry]['category']) === -1){
+ obj['value']=filteredEntries[entry]['category'];
+ obj['label']= filteredEntries[entry]['category'];
+ dupArray.push(filteredEntries[entry]['category']);
+ }else{
+ obj='';
+ }
+ return obj;
+ });
+ let filterMultiOption = multiOption.filter((entry) => {
+ if(entry !== '') return entry;
+ });
+ console.log('filterMultiOption>>>>>',filterMultiOption);
+ return filterMultiOption;
+ };
+ editSavedQuery = (e) =>{
+ let splitString = (e.target.value).split('||');
+ let name = splitString[0];
+ let description = splitString[1];
+ let category = (splitString[2] !== 'undefined')? splitString[2]:'';
+ let dsl = atob(splitString[3]).replace('<pre>','').replace('</pre>','');
+ let isAggregate = splitString[4];
+ let type = splitString[5];
+ let queryId= splitString[6];
+ let isCommunityShared = splitString[7];
+ let templateDetails = splitString[8];
+ this.props.editCallback(name, description, category, dsl, isAggregate, type, queryId, isCommunityShared, templateDetails);
+ };
+ loadAllQueries = () =>{
+ console.log('this.state.loadQueryList>>>>',this.state.loadQueryList);
+ let loadQueryList=this.state.loadQueryList;
+ for(var l=0;l<loadQueryList.length;l++){
+ this.loadQueryData(loadQueryList[l],l);
+ }
+ };
+ onSelectCheckbox=(e) =>{
+ let splitString = (e.target.value).split('||');
+ let type = splitString[5];
+ let queryId=splitString[6];
+ let queryList='';
+ let loadQuery='';
+ if(type =='public'){
+ queryList=this.state.filteredPublicEntries;
+ loadQuery= this.state.publicLoadQueryList;
+ }else if (type == 'personal'){
+ queryList=this.state.filteredPersonalEntries;
+ loadQuery= this.state.personalLoadQueryList;
+ }else{
+ queryList=this.state.filteredCommunityEntries;
+ loadQuery= this.state.communityLoadQueryList;
+ }
+ let flag= true;
+ if (e.target.checked) {
+ if(loadQuery.length<10){
+ loadQuery.push(e.target.value);
+ queryList[queryId].isSelect=true;
+ }
+ }else{
+ let index=loadQuery.indexOf(e.target.value);
+ loadQuery.splice(index,1);
+ queryList[queryId].isSelect=false;
+ }
+ flag=(loadQuery.length<=10)?true:false;
+ if(type=='public'){
+ this.setState({loadQueryList:loadQuery,publicLoadQueryList:loadQuery,personalLoadQueryList:[],communityLoadQueryList:[],filteredPublicEntries:queryList,loadQueryFlag:flag,selectedCount:loadQuery.length});
+ }else if(type=='personal'){
+ this.setState({loadQueryList:loadQuery,personalLoadQueryList:loadQuery,publicLoadQueryList:[],communityLoadQueryList:[],filteredPersonalEntries:queryList,loadQueryFlag:flag,selectedCount:loadQuery.length});
+ } else{
+ this.setState({loadQueryList:loadQuery,communityLoadQueryList:loadQuery,publicLoadQueryList:[],personalLoadQueryList:[],filteredCommunityEntries:queryList,loadQueryFlag:flag,selectedCount:loadQuery.length});
+ }
+ }
+ render() {
+ let savedQueryCard = (type, totalCount, filterList, filteredEntries) =>{
+ let onMultiSelectDropdownSelect= (type==='public') ? this.onMultiSelectPublicDropdownSelect : (type==='community') ? this.onMultiSelectCommunityDropdownSelect : this.onMultiSelectPersonalDropdownSelect;
+ return <div className='card d3-model-card'>
+ <div className={'card-header ' + (this.props.isSavedQueryFlow ? 'show' : 'hidden')}>
+ <div>
+ <h3>Find A Query</h3>
+ </div>
+ </div>
+ <div className='card-header'>
+ <div>
+ <div style={{width:'82%',float:'left'}}>
+ <h5>Total Saved Queries: <strong>{totalCount}</strong></h5>
+ </div>
+ <div className={(this.props.isSavedQueryFlow ? 'show' : 'hidden')}>
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>{'Enabled for up to '+this.state.loadQueryLimit+' Queries'}</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <button className='btn btn-outline-primary' type='button' onClick={()=>this.loadBulkCallback()} disabled={!(this.state.loadQueryList.length<=10 && this.state.loadQueryList.length>0)}>Load Selected Queries</button>
+ </span>
+ </OverlayTrigger>
+ </div>
+ </div>
+ <div>
+ <form>
+ <div className='alignFormTwinElements'>
+ <fieldset className="form-group">
+ <input type="text" className="form-control form-control-lg" placeholder="Search" onChange={filterList}/>
+ </fieldset>
+ </div>
+ <div className='alignFormTwinElements'>
+ <fieldset className="form-group">
+ <MultiSelectDropDown
+ options={this.prepareMultiOptions(type)}
+ displayValue={this.state.displayValue}
+ triggerSelect={onMultiSelectDropdownSelect}
+ />
+ </fieldset>
+ </div>
+ </form>
+ </div>
+ </div>
+ <div className='card-content model-card-content'>
+ <table className="table table-hover table-striped">
+ <thead>
+ <tr>
+ <th scope='col' className={(this.props.isSavedQueryFlow ? 'show' : 'hidden')}>Select</th>
+ <th scope="col">Name</th>
+ <th scope="col">Description</th>
+ <th scope="col">Category</th>
+ <th scope="col">Creator</th>
+ <th scope="col">Aggregate</th>
+ <th scope="col" className={((type === 'personal') ? '' : 'hidden')}>Shared</th>
+ <th scope="col">Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+ {Object.keys(filteredEntries).sort(function(a, b) {
+ var compareA = a.toUpperCase();
+ var compareB = b.toUpperCase();
+ if(compareA < compareB) return -1;
+ if(compareA > compareB) return 1;
+ return 0;
+ }).map((entry, idx) => {
+ return (
+ <tr>
+ <td className={(this.props.isSavedQueryFlow ? '' : 'hidden')}>
+ <div className="checkbox">
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>{(this.state.selectedCount===this.state.loadQueryLimit)?'Reached Maximun Template Count '+this.state.loadQueryLimit:(this.state.loadQueryLimit-this.state.selectedCount)+' More Selectable'}</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <label>
+ <input type="checkbox" checked={filteredEntries[entry].isSelect} onChange={this.onSelectCheckbox.bind(this)} value={filteredEntries[entry].name + '||' + filteredEntries[entry].description + '||' + filteredEntries[entry].category + '||' + filteredEntries[entry].dsl + '||' + filteredEntries[entry]['is_aggregate'] + '||' + type + '||' + entry + '||' + filteredEntries[entry]['community_shared'] + '||' + filteredEntries[entry]['template_details']} disabled={!filteredEntries[entry].isSelect && !this.state.loadQueryFlag}/>
+ </label>
+ </span>
+ </OverlayTrigger>
+ </div>
+ </td>
+ <td><strong>{filteredEntries[entry].name}</strong></td>
+ <td>{filteredEntries[entry].description}</td>
+ <td width='15%'>{(filteredEntries[entry].category)?filteredEntries[entry].category:''}</td>
+ <td>{filteredEntries[entry].creator}</td>
+ <td>{filteredEntries[entry]['is_aggregate']}</td>
+ <td className={((type === 'personal') ? '' : 'hidden')}>{filteredEntries[entry]['community_shared']}</td>
+ <td className="actionsRow">
+ <div>
+ <button className={'btn btn-primary ' + (!this.props.isDSLBuilder ? '' : 'hidden')} type='button' value={filteredEntries[entry].dsl + "||" + filteredEntries[entry]['is_aggregate']} onClick={this.loadAndRunQuery}>Run</button>
+ <button className='btn btn-outline-secondary' type='button' value={filteredEntries[entry].name + '||' + filteredEntries[entry].description + '||' + filteredEntries[entry].category + '||' + filteredEntries[entry].dsl + '||' + filteredEntries[entry]['is_aggregate'] + '||' + type + '||' + entry + '||' + filteredEntries[entry]['community_shared'] + '||' + filteredEntries[entry]['template_details'] } onClick={this.loadQuery}>Load</button>
+ <button className={'btn btn-outline-secondary ' + ((this.props.isDataSteward || type === 'personal') && type !== 'community' && !this.props.isDSLBuilder ? '' : 'hidden')} type='button' value={filteredEntries[entry].name + '||' + filteredEntries[entry].description + '||' + filteredEntries[entry].category + '||' + filteredEntries[entry].dsl + '||' + filteredEntries[entry]['is_aggregate'] + '||' + type +'||' + entry + '||' + filteredEntries[entry]['community_shared'] + '||' + filteredEntries[entry]['template_details']} onClick={this.editSavedQuery}>Edit</button>
+ <button className={'btn btn-outline-secondary ' + ((this.props.isDataSteward || type === 'personal') && type !== 'community' && !this.props.isDSLBuilder ? '' : 'hidden')} type='button' onClick={(e) => this.openDeleteModal(entry,filteredEntries[entry].name, filteredEntries[entry]['is_public'])}>Delete</button>
+ </div>
+ </td>
+ </tr>
+ );
+ })}
+ </tbody>
+ </table>
+ </div>
+ </div>};
+ let savedQueryMessaging = (type, loadedQueries, queryErrMsg) => { return <Col>
+ <Alert className={!queryErrMsg ? 'show' : 'hidden'} bsStyle="warning">
+ {type === 'public' && <h3>No Saved Public Queries Loaded</h3>}
+ {type === 'community' && <h3>No Saved Community Shared Queries Loaded</h3>}
+ {type === 'personal' && <h3>No Saved Personal Queries Loaded</h3>}
+ </Alert>
+ <Alert bsStyle="danger" className={queryErrMsg ? 'show' : 'hidden'} onDismiss={() => {
+ if(type==='public'){
+ this.setState({queriesPublicErrMsg: false});
+ }else if (type === 'community'){
+ this.setState({queriesCommunityErrMsg: false});
+ }else{
+ this.setState({queriesPersonalErrMsg: false});
+ }}}>
+ <h3>An error occurred</h3>
+ <p>
+ {queryErrMsg}
+ </p>
+ </Alert>
+ </Col>
+ }
+ let savedQueryTabs = () => { return <Tabs defaultActiveKey={'1'} id="multipleTabularView">
+ <Tab eventKey={'1'} title={'Public'}>
+ <Spinner loading={this.state.enablePublicQueriesBusyFeedback}>
+ {Object.keys(this.state.loadedPublicQueries).length <= 0 && (<div>{savedQueryMessaging('public', this.state.loadedPublicQueries, this.state.queriesPublicErrMsg)}</div>)}
+ {Object.keys(this.state.loadedPublicQueries).length > 0 && (<div>{savedQueryCard('public', this.state.totalPublicResults, this.filterPublicList, this.state.filteredPublicEntries)}</div>)}
+ </Spinner>
+ </Tab>
+ <Tab eventKey={'2'} title={'Community'}>
+ <Spinner loading={this.state.enableCommunityQueriesBusyFeedback}>
+ {Object.keys(this.state.loadedCommunityQueries).length <= 0 && (<div>{savedQueryMessaging('community', this.state.loadedCommunityQueries, this.state.queriesCommunityErrMsg)}</div>)}
+ {Object.keys(this.state.loadedCommunityQueries).length > 0 && (<div>{savedQueryCard('community', this.state.totalCommunityResults, this.filterCommunityList, this.state.filteredCommunityEntries)}</div>)}
+ </Spinner>
+ </Tab>
+ <Tab eventKey={'3'} title={'My Personal Queries'}>
+ <Spinner loading={this.state.enablePersonalQueriesBusyFeedback}>
+ {Object.keys(this.state.loadedPersonalQueries).length <= 0 &&(<div>{savedQueryMessaging('personal', this.state.loadedPersonalQueries, this.state.queriesPersonalErrMsg)}</div>)}
+ {Object.keys(this.state.loadedPersonalQueries).length > 0 && (<div>{savedQueryCard('personal', this.state.totalPersonalResults, this.filterPersonalList, this.state.filteredPersonalEntries)}</div>)}
+ </Spinner>
+ </Tab>
+ </Tabs>
+ };
+ if (!GlobalExtConstants.INVLIST.IS_ONAP){
+ return (<div>
+ <div className='static-modal'>
+ <Modal show={this.state.showDeleteModal} onHide={this.closeDeleteModal} dialogClassName="modal-override">
+ <Spinner loading={this.state.enableDeleteBusyFeedback}>
+ <Modal.Header>
+ <Modal.Title>Delete DSL Query</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Alert id="deleteError" className={this.state.deleteErrMsg ? 'show' : 'hidden'} bsStyle="danger" onDismiss={() => this.setState({deleteErrMsg: false})}>
+ <h3>An error occurred</h3>
+ <p>
+ {this.state.deleteErrMsg}
+ </p>
+ </Alert>
+ <p>Are you sure you want to delete the following query?: {this.state.focusedEntryName}</p>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeDeleteModal}>Cancel</Button>
+ <Button onClick={this.submitDelete}>Delete</Button>
+ </Modal.Footer>
+ </Spinner>
+ </Modal>
+ </div>
+
+ <Row>
+ <Col className={this.props.isSavedQueryFlow ? 'col-lg-10' : 'col-lg-12'}>
+ <Alert id="deleteSuccess" bsStyle="success" className={this.state.deleteSuccessfulMsg ? 'show' : 'hidden'} onDismiss={() => this.setState({deleteSuccessfulMsg: false})}>
+ <h3>Delete Successful</h3>
+ <p>
+ {this.state.deleteSuccessfulMsg}
+ </p>
+ </Alert>
+ {!this.props.isSavedQueryFlow && (<Panel>
+ <Panel.Heading>
+ <Panel.Title toggle>
+ <div className="checkbox">
+ <h2>Saved Queries</h2>
+ </div>
+ </Panel.Title>
+ </Panel.Heading>
+ <Panel.Collapse>
+ <Panel.Body className='cardwrap'>
+ {savedQueryTabs()}
+ </Panel.Body>
+ </Panel.Collapse>
+ </Panel>)}
+ {this.props.isSavedQueryFlow && savedQueryTabs()}
+ </Col>
+ </Row>
+ </div>);
+ }else{
+ return (<span></span>);
+ }
+ }
+}
+
+export default CustomDSLSaveLoad;
diff --git a/src/app/byoq/CustomDsl.jsx b/src/app/byoq/CustomDsl.jsx
new file mode 100644
index 0000000..61650ba
--- /dev/null
+++ b/src/app/byoq/CustomDsl.jsx
@@ -0,0 +1,4710 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+import React, {Component} from 'react';
+import PanelGroup from 'react-bootstrap/lib/PanelGroup';
+import Panel from 'react-bootstrap/lib/Panel';
+import Modal from 'react-bootstrap/lib/Modal';
+import Grid from 'react-bootstrap/lib/Grid';
+import Button from 'react-bootstrap/lib/Button';
+import ModelGallery from 'app/model/modelSearch/components/ModelGallery.jsx';
+import Autosuggest from 'react-autosuggest';
+import DatePicker from 'react-datepicker';
+import moment from "moment";
+import DslHints from 'app/assets/configuration/dsl_hints.json';
+import DslDetailedHelp from 'app/assets/configuration/dsl_detailedHelp.json';
+import {ExportExcel} from 'utils/ExportExcel.js';
+import commonApi from 'utils/CommonAPIService.js';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+import {GeneralCommonFunctions} from 'utils/GeneralCommonFunctions.js';
+import Spinner from 'utils/SpinnerContainer.jsx';
+import OutputToggle from 'generic-components/OutputToggle.jsx';
+import Pagination from 'react-js-pagination';
+import Col from 'react-bootstrap/lib/Col';
+import Row from 'react-bootstrap/lib/Row';
+import OverlayTrigger from 'react-bootstrap/lib/OverlayTrigger';
+import Tooltip from 'react-bootstrap/lib/Tooltip';
+import OutputVisualization, {Visualization} from 'generic-components/OutputVisualization.jsx';
+import ModelCard from 'app/model/modelSearch/components/ModelCard.jsx';
+import CustomDSLSaveLoad from 'app/byoq/CustomDSLSaveLoad.jsx';
+import FormGroup from 'react-bootstrap/lib/FormGroup';
+import FormControl from 'react-bootstrap/lib/FormControl';
+import ControlLabel from 'react-bootstrap/lib/ControlLabel';
+import InfoToggle from 'generic-components/InfoToggle.jsx';
+import Alert from 'react-bootstrap/lib/Alert';
+import Tabs from 'react-bootstrap/lib/Tabs';
+import Tab from 'react-bootstrap/lib/Tab';
+import BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, {textFilter,customFilter} from 'react-bootstrap-table2-filter';
+import FilterTypes from 'generic-components/filter/components/FilterTypes.jsx';
+import DownloadRangeModel from 'generic-components/DownloadRangeModel.jsx';
+import SelectFilter from 'generic-components/filter/components/SelectFilter.jsx';
+import Toggle from 'react-toggle';
+import "react-toggle/style.css";
+import BootstrapSwitchButton from 'bootstrap-switch-button-react';
+
+let PAGINATION_CONSTANT = GlobalExtConstants.PAGINATION_CONSTANT;
+let EDGERULES = GlobalExtConstants.EDGERULES;
+let OXM = GlobalExtConstants.OXM;
+let INVLIST = GlobalExtConstants.INVLIST;
+let generateExcels = ExportExcel.generateExcels;
+let DOWNLOAD_ALL = GlobalExtConstants.DOWNLOAD_ALL;
+let DOWNLOAD_TOOLTIP = GlobalExtConstants.DOWNLOAD_TOOLTIP;
+let filterTypeList = GlobalExtConstants.FILTER_TYPES;
+let TABULAR_FILTER_TYPE = GlobalExtConstants.TABULAR_FILTER_TYPE;
+let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
+let EMAIL_EXT = GlobalExtConstants.EMAIL_EXT;
+let APERTURE_SERVICE = JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+let buildAttrList = ExportExcel.buildAttrList;
+
+let dslHints = null;
+let nodeTypes = [];
+let properties = null;
+let traverseRulesDsl = [];
+let inputValue = '';
+let testData = null;
+
+var settings = {
+ 'NODESERVER': INVLIST.NODESERVER,
+ 'PROXY': INVLIST.PROXY,
+ 'PREFIX': INVLIST.PREFIX,
+ 'VERSION': INVLIST.VERSION,
+ 'USESTUBS': INVLIST.useStubs,
+ 'APERTURE': INVLIST.APERTURE,
+ 'TABULAR': INVLIST.TABULAR,
+ 'TABULARVERSION': INVLIST.TABULARVERSION
+};
+class AttributeFilter extends Component {
+
+ constructor(props) {
+ super(props);
+ this.filter = this.filter.bind(this);
+ this.getValue = this.getValue.bind(this);
+ this.props = props;
+ this.state = {
+ filterText: '',
+ isPageChange: this.props.isPageChange,
+ columnValue : ''
+ };
+ }
+ getValue = () => {
+ return this.input.value;
+ }
+ setPlaceHolder = () => {
+ let filterText = '';
+ filterText = 'Enter ' + this.props.column.text;
+ return filterText;
+ }
+ filter = () => {
+ let txt=this.props.column.text;
+ let obj = {};
+ obj[txt] = this.getValue();
+ var columnFilter = this.props.columnFilter;
+ for(var i=0;i<columnFilter.length;i++){
+ if(columnFilter[i][txt] != undefined){
+ columnFilter[i][txt] = this.getValue();
+ this.props.handleOnFilter(columnFilter,this.getValue());
+ this.props.onFilter(this.getValue());
+ }
+ }
+ }
+ render() {
+ return (
+ <div>
+
+ <input
+ key="input"
+ ref={ node => this.input = node }
+ type="text"
+ placeholder={this.setPlaceHolder()}
+ onChange={this.filter}
+ />
+
+ </div>
+ )
+ }
+ }
+
+class CustomDsl extends Component {
+ nodeResults = '';
+ typeOfCall = true;
+ downloadTooltip = DOWNLOAD_TOOLTIP;
+ downloadAllTooltip = 'Downloads First ' + DOWNLOAD_ALL + ' Results';
+ downloadRangeTooltip= 'Download Results By Custom Range Selection';
+ downloadBulkTooltip= 'Download Results Of All Loaded Queries';
+ historyStackString = '';
+ dslObject={};
+ dslObjectList=[];
+ nodeTypeArray=[];
+ nodeTypeArrayList=[];
+ edgesArray=[];
+ relationsArray=[];
+ tempDslQuery='';
+ tempDslQueryList=[];
+ templateError=[];
+ templateErrorList={};
+ baseState='';
+ propertiesDsl = [];
+ tableFilterAliasColumns={};
+ constructor(props) {
+ console.log('CustomDsl:Constuctor props>>>>',props);
+ super(props);
+ APERTURE_SERVICE=JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+ console.log('APERTURE_SERVICE: ' + APERTURE_SERVICE);
+ TABULAR_FILTER_TYPE=(APERTURE_SERVICE && JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'ENABLE_ANALYSIS')))?'CONTAINS':'=';
+ this.saveLoadComponent = React.createRef();
+ this.saveLoadComponentDsl = React.createRef();
+ this.state = {
+ nodeTypes: [],
+ hintHtml: {},
+ header: null,
+ multipleNodes: '',
+ isLoading: false,
+ nodes: [],
+ simpleQueries: [],
+ traversalQueries: [],
+ unionQueries: [],
+ negationQueries: [],
+ topologyQueries: [],
+ limitQueries: [],
+ advancedQueries: [],
+ showModal: false,
+ query: '',
+ value: '',
+ valuePreviousState: '',
+ suggestions: [],
+ edgeRules: [],
+ previousNodeTypeDsl: '',
+ selected: [],
+ nodeTypeDsl: '',
+ model: null,
+ showPagination: false,
+ showResults: false,
+ activePage: 1,
+ aggregateActivePage: 1,
+ totalResults: 0,
+ errorResults: false,
+ errorMessage: '',
+ noResults: true,
+ validInput: false,
+ isInitialLoad: true,
+ prevQuery : '',
+ showHistoryModal:false,
+ startDate: moment(),
+ res: null,
+ visualAddition: false,
+ nodeDisplay: '',
+ showNodeModal: false,
+ focusedNode: {},
+ historyType: 'dsl',
+ focusedNodeUri: 0,
+ viewName: localStorage.getItem(GlobalExtConstants.ENVIRONMENT + '_' + sessionStorage.getItem(GlobalExtConstants.ENVIRONMENT + 'userId') + '_viewPreference') || 'CardLayout',
+ focusedNodeType: '',
+ historyParams: '' ,
+ showModelOptions:false,
+ enableCalendar: true,
+ resetColumnFilters: true,
+ isPageNumberChange: false,
+ loadedQueries: [],
+ queryDescription: '',
+ queryName: '',
+ category:'',
+ saveSuccessfulMsg: false,
+ saveErrorMsg: false,
+ enableSaveBusyFeedback: false,
+ isAggregate: false,
+ isAggregatePreviousState: false,
+ isAggregateChecked: false,
+ isCommunitySharedPreviousState: false,
+ isCommunitySharedChecked: false,
+ associatedNodesEnabled: false,
+ associatedNodesEnabledPreviuosState: false,
+ aggregatePaths: [],
+ aggregatePathAttrs: [],
+ aggregateParentGroup: [],
+ aggregateObjects: [],
+ tabularAggregateColumns: [],
+ tabularAggregateData: [],
+ aggregateAttrList: [],
+ aggregateNodes: [],
+ allAggregateNodes: [],
+ allres: null,
+ allAggregatePaths: [],
+ allAggregatePathAttrs: [],
+ allAggregateObjects: [],
+ allAggregateParentGroup: [],
+ allTabularAggregateColumns: [],
+ allTabularAggregateData: [],
+ allAggregateAttrList: [],
+ reRender: false,
+ columnFilter: [],
+ filterTemplateEntries: [],
+ filterTemplateHeader: [],
+ filterTemplateError: false,
+ filterTemplateEntriesList:[],
+ filterTemplateHeaderList:[],
+ filterTemplateErrorList:[],
+ nodeTypeOfDslTemplateList:[],
+ valueList:[],
+ templateQueryList:[],
+ editModel: {},
+ showEditModal: false,
+ templateQuery: '',
+ isDSLFlow: props.viewName === 'BYOQ',
+ isSavedQueryFlow: props.viewName === 'Saved Queries',
+ filterTypeDisplay: {'default':'Filter Type'},
+ filterTypeDisplayList: [],
+ disableFilter: true,
+ totalPages: 0,
+ pageRange: 1,
+ showDownloadResultsModal: false,
+ errorDownloadResults:false,
+ downloadErrorMsg: '',
+ enableModelBusyFeedback:false,
+ downloadCount:DOWNLOAD_ALL,
+ addAndTemplateState:false,
+ nodeTypeOfDslTemplate:[],
+ filterDisplay:'Select Property',
+ queryId:'',
+ queryNameList: [],
+ queryDescriptionList: [],
+ categoryList: [],
+ isPublicCheckedList: [],
+ isCommunitySharedList: [],
+ queryIdList: [],
+ isAggregateCheckedList:[],
+ associatedNodesEnabledList: [],
+ associatedNodesEnabledPreviuosStateList: [],
+ enableTreeLoadBusyFeedback: false,
+ treeLoadErrMsg: null,
+ isDataSteward: sessionStorage.getItem(ENVIRONMENT + 'roles') && sessionStorage.getItem(ENVIRONMENT + 'roles').indexOf('data_steward_ui_view') > -1,
+ isPublicChecked: sessionStorage.getItem(ENVIRONMENT + 'roles') && sessionStorage.getItem(ENVIRONMENT + 'roles').indexOf('data_steward_ui_view') > -1,
+ defaultViewName: localStorage.getItem(GlobalExtConstants.ENVIRONMENT + '_' + sessionStorage.getItem(GlobalExtConstants.ENVIRONMENT + 'userId') + '_viewPreference') || 'CardLayout',
+ isTypeahead: true,
+ enableRealTime: JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'ENABLE_ANALYSIS')),
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:'',
+ isMergedTabsChecked:false,
+ isGenerateEmailChecked: false,
+ emailTriggerMsg:'',
+ dslConfigArray: [],
+ staticTemplateFilters: [],
+ staticTemplateFiltersList: [],
+ tableAggregateAliasColumns:{}
+ }
+ }
+ componentWillMount = () => {
+ console.log('CustomDsl:componentWillMount',JSON.stringify(this.props));
+ if(!this.props.location.historyStackString){
+ this.props.location.historyStackString = this.props.location.pathname + ',,Origin||';
+ }else{
+ this.historyStackString = this.props.location.historyStackString;
+ }
+ dslHints = Object.values(DslHints);
+ this.setState( {hintHtml: dslHints});
+ this.processHelp( DslDetailedHelp );
+ console.log('how many nodes? ' + this.state.nodes.length);
+ this.processEdgeRules(EDGERULES);
+ nodeTypes = this.buildNodeList();
+ this.setState({
+ nodeTypes: nodeTypes},
+ function () {
+ console.log('nodeTypes: ' + this.state.nodeTypes.length) ;
+ this.baseState=this.state;
+ this.buildDynamicByoq('','','init');
+ }
+ );
+
+ }
+ buildDynamicByoq=(queryParam, makeCall, loadType)=> {
+ let query = '';
+ let shouldRun = makeCall;
+ if(queryParam){
+ query = queryParam;
+ }else if(this.props.match.params.type === 'built' || this.props.match.params.type === 'built-aggregate'){
+ query = atob(this.props.match.params.propId).replace('<pre>','').replace('</pre>','');
+ shouldRun = true;
+ }else{
+ shouldRun = true;
+ let nodeType = (this.props.match.params.type) ? this.props.match.params.type : '';
+ let propIds = (this.props.match.params.propId) ? this.props.match.params.propId.split(';') : '';
+ let propertyValue = '';
+ for(var i in propIds){
+ let propValue = propIds[i].split(':');
+ console.log(propValue[0] + '....' + propValue[1]);
+ let atobPropValue = atob(propValue[1]).replace('<pre>','').replace('</pre>','');
+ if(propertyValue == ''){
+ propertyValue ='(\'' + propValue[0] +'\',\''+ atobPropValue + '\')';
+ }else{
+ propertyValue = propertyValue + '(\'' + propValue[0] +'\',\''+ atobPropValue + '\')';
+ }
+ }
+ console.log('propertyValue>>>>>',propertyValue);
+ let relArray = (this.props.match.params.relArray) ? this.props.match.params.relArray.split('&') : '';
+ let relativeStr = '';
+ let str = '';
+ if(relArray.length>0){
+ for(var n in relArray){
+ relativeStr = relativeStr + relArray[n] + '*'
+ }
+ str = relativeStr.replace(/\*/g, '*,').slice(0, -1);
+ }
+ let relativeAttachStr = (str === '') ? '' : '>[' + str + ']';
+ //encPropValue = (nodeType === '') ? '': atob(propValue[1]);
+ query = (nodeType === '') ? '' : nodeType + '*' + propertyValue + relativeAttachStr;
+ if(loadType ==='init'){
+ console.log('this.baseState>>>>>',this.baseState)
+ this.baseState.value=query;
+ }
+ }
+ console.log('query>>>',query);
+ console.log('this.props.match.params.type>>>',this.props.match.params.type);
+ if(query != ''){
+ this.nodeResults = '';
+ this.typeOfCall = true;
+ let isInitialLoad = this.state.isInitialLoad;
+ this.setState( {value: query,validInput: true,isInitialLoad: false},() => { if(shouldRun){this.formQueryString(false, isInitialLoad,false)}});
+ }
+}
+ getNodeTypes = () =>{
+ var result = JSON.parse(OXM);
+ var arrayOfTypes = result['xml-bindings']['java-types'][0]['java-type'];
+ var nodeTypeArray = [];
+ for(var j = 0; j < arrayOfTypes.length; j++){
+ if(arrayOfTypes[j]['xml-root-element'] && arrayOfTypes[j]['xml-root-element'][0]
+ && arrayOfTypes[j]['xml-root-element'][0]['$'] && arrayOfTypes[j]['xml-root-element'][0]['$']['name']){
+ nodeTypeArray.push((arrayOfTypes[j]['xml-root-element'][0]['$']['name']).toLowerCase());
+ }
+ }
+ return nodeTypeArray;
+ }
+
+ getNodeTypeFromURI = (uri) => {
+ var nodeTypeArray = this.getNodeTypes();
+ var tokenizedUri = uri.split("/");
+ var nodeType = "";
+ var found = false;
+ for (var i = tokenizedUri.length - 1; i >= 0 && !found; i--){
+ if(nodeTypeArray.indexOf(tokenizedUri[i]) > -1){
+ nodeType = tokenizedUri[i];
+ found = true;
+ }
+ }
+ return nodeType;
+ }
+
+ getAttributesFromNodeType = (nt) => {
+ var result = JSON.parse(OXM);
+ var arrayOfTypes = result['xml-bindings']['java-types'][0]['java-type'];
+ var foundIndex = -1;
+ var attributesArray = [];
+ var nodeType = nt.replace(/-/g,'');
+ for (var i = 0; i < arrayOfTypes.length && foundIndex === -1; i++) {
+ if(arrayOfTypes[i]['$'] && arrayOfTypes[i]['$']['name'] && arrayOfTypes[i]['$']['name'].toLowerCase() === nodeType){
+ foundIndex = i;
+ }
+ }
+ for (var j = 0; j < arrayOfTypes[foundIndex]['java-attributes'][0]['xml-element'].length; j++) {
+ let property = arrayOfTypes[foundIndex]['java-attributes'][0]['xml-element'][j]['$']['name'];
+ let type = arrayOfTypes[foundIndex]['java-attributes'][0]['xml-element'][j]['$']['type'];
+ if (type === 'java.lang.String' || type === 'java.lang.Boolean') {
+ attributesArray.push(property);
+ }
+ }
+ return attributesArray;
+ }
+
+ getAttributesFromPath = (path,tableAggregateAliasColumns) => {
+ var nodeParseArray = path.split('>');
+ console.log(nodeParseArray);
+ var attributeArray = [];
+ var aggregatePaths = this.state.aggregatePathAttrs;
+ if(!this.typeOfCall){
+ aggregatePaths = this.state.allAggregatePathAttrs;
+ }
+ for(var i = 0; i < nodeParseArray.length; i++){
+ var nodeKey = nodeParseArray[i].trim();
+ let tableColumnsBuilt = ExportExcel.buildAttrList(nodeKey,[],'required');
+ for(var j = 0; j < aggregatePaths[nodeKey].length; j++){
+ let desc=tableColumnsBuilt.map((a) =>
+ {
+ if(a.value.toLowerCase()==aggregatePaths[nodeKey][j].toLowerCase())
+ return a.description;
+ else
+ return '';
+ }).filter(function (el) {
+ return el != '';
+ });
+ if(desc.length===0){
+ desc.push('');
+ }
+ if(Object.keys(tableAggregateAliasColumns).length !== 0 && tableAggregateAliasColumns[nodeKey] && tableAggregateAliasColumns[nodeKey][0][aggregatePaths[nodeKey][j]]){
+ attributeArray.push(nodeKey + '|' + tableAggregateAliasColumns[nodeKey][0][aggregatePaths[nodeKey][j]] +'|'+ desc[0]);
+ }else{
+ attributeArray.push(nodeKey + '|' + aggregatePaths[nodeKey][j] + '|' + desc[0]);
+ }
+ }
+ }
+ return attributeArray;
+ }
+
+ buildNodeList = () => {
+ var result = JSON.parse(OXM);
+ var arrayOfTypes = result['xml-bindings']['java-types'][0]['java-type'];
+ let nodeList = [];
+
+ for (var i = 0; i < arrayOfTypes.length; i++) {
+ var hasProperties = false;
+ if (arrayOfTypes[i]['java-attributes']) {
+ let elementLength = 0;
+ if (arrayOfTypes[i]['java-attributes'][0]['xml-element']) {
+ elementLength = arrayOfTypes[i]['java-attributes'][0]['xml-element'].length;
+ }
+ for (var j = 0; j < elementLength; j++) {
+ let property = JSON.stringify(arrayOfTypes[i]['java-attributes'][0]['xml-element'][j]['xml-properties']);
+ if (property) { //add to the list
+ hasProperties = true;
+ }
+ }
+ if (hasProperties) {
+ let node = arrayOfTypes[i]['xml-root-element'][0]['$']['name'];
+ nodeList.push(node);
+ }
+ }
+ }
+ nodeList.sort();
+ return nodeList;
+ }
+
+ processHelp(data) {
+ //console.log('Data' + JSON.stringify(data));
+ this.setState( {simpleQueries: data.simple } );
+ console.log('Value' + JSON.stringify(this.state.simpleQueries));
+ this.setState( {traversalQueries: data.traversal} );
+ this.setState( {unionQueries: data.union} );
+ this.setState( {negationQueries: data.negation} );
+ this.setState( {topologyQueries: data.topology} );
+ this.setState( {limitQueries: data.limit} );
+ this.setState( {advancedQueries: data.advanced} );
+ }
+
+ processEdgeRules = (data) => {
+ var ruleArr = [];
+ this.setState({
+ edgeRules: data.rules
+ });
+ ruleArr = data.rules;
+ // console.log("Rule"+JSON.stringify(ruleArr));
+ // new = data.Rules;
+ }
+
+ hint = () => { // open modal
+ console.log('hint >> showModal');
+ this.setState({
+ showModal:true
+ });
+ this.hints = this.state.html;
+ }
+
+ onAddItem = (event) => {
+ event.preventDefault();
+ GeneralCommonFunctions.scrollTo("outputBlock");
+ this.nodeResults = '';
+ this.typeOfCall = true;
+ this.setState({ viewName: this.state.defaultViewName, aggregateActivePage: 1, activePage: 1, nodes: [], aggregateNodes: [],errorResults:false},function () { this.formQueryString(false,false,false); }.bind(this));
+ };
+
+ formQueryString = (bypassCall, isInitialLoad, aggregateForGraph) =>{
+ console.log('formQueryString>>>>>>this.state.value :',this.state.value);
+ var DSLQuery = this.state.value;
+ DSLQuery.trim();
+ console.log('DSLQuery.trim().length: ' + DSLQuery.trim().length);
+ let resp = '';
+ if (DSLQuery.trim() !== '' || (this.props.match.params.type && DSLQuery.trim() !== '')){
+ console.log('validInput.DSLQuery: ' + DSLQuery);
+ this.setState({
+ validInput: true,isInitialLoad: isInitialLoad
+ });
+ const payload = {dsl: DSLQuery};
+ let format = 'simple';
+ if((this.state.isAggregateChecked || (isInitialLoad && this.props.match.params.type === 'built-aggregate')) && !aggregateForGraph){
+ format = 'aggregate';
+ this.setState({isAggregateChecked: true});
+ }
+ let queryStr = '';
+ if(this.typeOfCall){
+ if(format === 'aggregate' || aggregateForGraph){
+ this.setState({isAggregate: true});
+ queryStr = 'dsl?format=' + format + '&resultIndex=' + this.state.aggregateActivePage + '&resultSize=' + PAGINATION_CONSTANT.RESULTS_PER_PAGE;
+ }else{
+ this.setState({isAggregate: false});
+ queryStr = 'dsl?format=' + format + '&resultIndex='
+ + this.state.activePage + '&resultSize=' + PAGINATION_CONSTANT.RESULTS_PER_PAGE;
+ }
+ }else{
+ let pagerange=this.state.pageRange.toString();
+ pagerange=pagerange.split('-');
+ if(pagerange.length > 1){
+ queryStr = 'dsl?format=' + format + '&resultIndex='+ parseInt(pagerange[0]) +'&resultSize=' + PAGINATION_CONSTANT.RESULTS_PER_PAGE + '&resultRangeEnd=' + parseInt(pagerange[1]);
+ }else{
+ queryStr = 'dsl?format=' + format + '&resultIndex='+ 1 +'&resultSize=' + parseInt(pagerange);
+ }
+
+ }
+ const path = queryStr;
+ this.state.header = DSLQuery;
+ console.log('DSLQuery: ' + DSLQuery);
+ console.log('payload: ' + JSON.stringify(payload));
+ console.log('path: ' + path);
+ if(aggregateForGraph){
+ this.setState({isLoading: true, prevQuery:DSLQuery});
+ } else if(this.typeOfCall){
+ if(this.state.prevQuery !== DSLQuery){
+ this.setState({isLoading: true,
+ totalResults: 0,
+ prevQuery:DSLQuery
+ });
+ }else{
+ this.setState({isLoading: true, nodes: [], aggregateNodes: [], prevQuery:DSLQuery});
+ }
+ }
+ if(!bypassCall){
+ resp = this.getNodes(settings, path, payload, aggregateForGraph);
+ }
+ }else { // write a msg
+ console.log('validInput: ' + false);
+ this.setState({
+ validInput: false,
+ isInitialLoad: isInitialLoad
+ });
+ GeneralCommonFunctions.scrollTo('dslInputError');
+ }
+ console.log('Response: ' + resp);
+ }
+
+ onSuggestionSelected = (event, { suggestion }) => {
+ event.preventDefault();
+
+ let item = suggestion;
+ console.log('onSuggestionSelected.item: ' + item);
+ console.log('onSuggestionSelected.inputValue: ' + inputValue);
+
+ this.setState({
+ selected: [...this.state.selected, item],
+ value: inputValue + item
+ },
+ function () {
+ console.log('onSuggestionSelected.selected: ' + this.state.selected);
+ console.log('onSuggestionSelected.value: ' + this.state.value);
+ });
+ //if (!item.includes('(')) {
+ if (item.indexOf('(') === -1) { // not found
+ this.setState({previousNodeTypeDsl: item},
+ function () {
+ this.setState({
+ nodeTypeDsl: item
+ });
+ console.log('onSuggestionSelected.previousNodeTypeDsl: ' + this.state.previousNodeTypeDsl);
+ console.log('onSuggestionSelected.nodeTypeDsl: ' + this.state.nodeTypeDsl);
+ }
+ );
+ }
+ }
+
+ storeInputReference = autosuggest => {
+ if (autosuggest !== null) {
+ this.input = autosuggest.input;
+ }
+ };
+
+ clear = () => {
+ this.setState({
+ value: '',
+ previousNodeTypeDsl: '',
+ header: ''
+ });
+ }
+
+ openSaveModal = () =>{
+ this.setState({
+ showSaveModal: true,
+ saveSuccessfulMsg: false,
+ treeLoadErrMsg: false,
+ isPublicChecked:this.state.isDataSteward,
+ isCommunitySharedChecked: false,
+ isEditModal:false,
+ enableTreeLoadBusyFeedback: true,
+ dslConfigurableFiltersArray: []
+ });
+ this.getTreeFromDSL(this.state.value).then(tree => {
+ this.setState({enableTreeLoadBusyFeedback: false, dslConfigArray: this.getConfigArrayFromDSLTree(tree, [], [])});
+ });
+ };
+
+ handleTypeaheadChange = (event) =>{
+ this.setState({isTypeahead: event.target.checked});
+ }
+
+ closeSaveModal = () =>{
+ //Set previous loaded state
+ if(this.state.isEditModal){
+ this.setState({
+ value: this.state.valuePreviousState,
+ isAggregateChecked: this.state.isAggregateCheckedPreviousState,
+ isCommunitySharedChecked: this.state.isCommunitySharedCheckedPreviousState,
+ associatedNodesEnabled: this.state.associatedNodesEnabledPreviousState,
+ enableTreeLoadBusyFeedback: false
+ });
+ }
+
+ this.setState({
+ showSaveModal: false,
+ queryDescription: '',
+ queryName: '',
+ category:'',
+ enableSaveBusyFeedback: false,
+ showQueryExistsWarning: false,
+ saveFailureMsg: false,
+ isEditModal:false
+ });
+ };
+
+ submitSave = (bypassDupeCheck) =>{
+ let existQueryName=false;
+ let queryId='';
+ Object.keys(this.state.loadedQueries).map((key) =>{
+ if(this.state.loadedQueries[key].name === this.state.queryName){
+ existQueryName=true;
+ if(this.state.showQueryExistsWarning){
+ queryId=key;
+ }
+ }
+ });
+ if(!bypassDupeCheck && existQueryName){
+ this.setState({showQueryExistsWarning:true});
+ }else{
+ var aggregateString = "false";
+ if(this.state.isAggregateChecked){
+ aggregateString = "true";
+ }
+ var queryParam=(this.state.queryId==='')?queryId:this.state.queryId;
+ var body = {
+ "cols": [
+ {
+ "name": "query_name",
+ "value": this.state.queryName
+ },
+ {
+ "name": "creator",
+ "value": sessionStorage.getItem(ENVIRONMENT + 'userId')
+ },
+ {
+ "name": "description",
+ "value": this.state.queryDescription
+ },
+ {
+ "name": "is_aggregate",
+ "value": aggregateString
+ },
+ {
+ "name": "community_shared",
+ "value": "" + this.state.isCommunitySharedChecked
+ },
+ {
+ "name": "is_public",
+ "value": "" + this.state.isPublicChecked
+ },
+ {
+ "name": "template_details",
+ "value": JSON.stringify(this.state.staticTemplateFilters)
+ },
+ {
+ "name": "dsl",
+ "value": btoa('<pre>' + this.state.value + '</pre>')
+ }
+ ]
+ }
+ if(this.state.category && this.state.category !=''){
+ let catObj={"name": "category","value": this.state.category}
+ body['cols'].push(catObj);
+ }
+ let localVersion='';
+ if(this.state.showQueryExistsWarning){
+ if(bypassDupeCheck && this.state.loadedQueries[queryParam] && this.state.loadedQueries[queryParam].version ){
+ localVersion = this.state.loadedQueries[queryParam].version;;
+ body.version = localVersion;
+
+ }
+ }else{
+ if(bypassDupeCheck && this.state.loadedQueries[this.state.queryId] && this.state.loadedQueries[this.state.queryId].version ){
+ localVersion = this.state.loadedQueries[this.state.queryId].version;;
+ body.version = localVersion;
+ }
+ }
+
+ this.setState({showQueryExistsWarning:false, enableSaveBusyFeedback:true});
+ settings['ISTABULAR'] = true;
+ let localQuery='queries';
+ let localHeader=null;
+ if(queryParam !==''){
+ localQuery += '/'+encodeURIComponent(queryParam);
+ localHeader= [{
+ "name":"If-Match",
+ "value": localVersion
+ }];
+ }
+ commonApi(settings, localQuery, 'PUT', body, 'BYOQSaveInfo', GlobalExtConstants.OVERRIDE_DOMAIN,null,localHeader)
+ .then(res => {
+ console.log('res:' + res.data);
+ if(res.status === 201){
+ if(res.data.status && (res.data.status !== 200 && res.data.status !== 201)){
+ this.triggerSaveError(res.data);
+ }else{
+ if(this.state.isEditModal && this.state.isDSLFlow){
+ this.setState({
+ value: this.state.valuePreviousState,
+ isAggregateChecked: this.state.isAggregateCheckedPreviousState,
+ isCommunitySharedChecked: this.state.isCommunitySharedCheckedPreviousState,
+ associatedNodesEnabled: this.state.associatedNodesEnabledPreviousState,
+ });
+ }
+
+ let jumpToId = "saveSuccess";
+ if (this.state.isSavedQueryFlow && this.state.isEditModal){
+ jumpToId = "saveSuccessEdit";
+ }
+ else if(this.state.isSavedQueryFlow && !this.state.isEditModal){
+ jumpToId = "saveSuccessTemplate";
+ }
+
+ this.setState({
+ saveSuccessfulMsg: "The following query was successfully saved: " + this.state.queryName,
+ showSaveModal: false,
+ enableSaveBusyFeedback:false,
+ });
+
+ GeneralCommonFunctions.scrollTo(jumpToId);
+ if(this.state.isSavedQueryFlow){
+ this.saveLoadComponent.current.getQueries();
+ }else {
+ this.saveLoadComponentDsl.current.getQueries();
+ }
+ }
+ }else{
+ this.triggerSaveError(res.data);
+ }
+ }, error=>{
+ this.triggerSaveError(error.response.data);
+ }).catch(error => {
+ this.triggerSaveError(error);
+ });
+ }
+ };
+
+ triggerSaveError = (error) => {
+ console.error('[CustomDsl.jsx] error : ', JSON.stringify(error));
+ let errMsg = '';
+ if(error.status && error.message){
+ errMsg += "Error Occurred: " + error.status + ' - ' +error.message;
+ }else{
+ errMsg += "Error Occurred: " + JSON.stringify(error);
+ }
+ console.log(errMsg);
+ this.setState({saveFailureMsg: errMsg + " - Failed to save query : " + this.state.queryName, enableSaveBusyFeedback:false});
+ GeneralCommonFunctions.scrollTo("saveFailure");
+ }
+
+ handleQueryDescriptionChange = (e) => {
+ this.setState({queryDescription: e.target.value});
+ };
+ handleQueryNameChange = (e) => {
+ this.setState({queryName: e.target.value});
+ };
+ handleQueryChange = (e) => {
+ this.setState({value: e.target.value});
+ };
+ handleCategoryChange = (e) =>{
+ this.setState({category: e.target.value});
+ };
+
+ setQueriesState = (savedQueries) =>{
+ this.setState({
+ loadedQueries: savedQueries
+ });
+ };
+
+ getNodes(settings, path, payload, graphCall) {
+ this.setState({isLoading: true});
+ settings['ISTABULAR'] = false;
+ if(this.state.enableRealTime && APERTURE_SERVICE){
+ settings['ISAPERTURE'] = this.state.enableRealTime;
+ }else{
+ Object.keys(settings).forEach((key)=>{
+ if(key==='ISAPERTURE'){
+ delete settings[key];
+ }
+ })
+ }
+ console.dir('CustomDSL:settings:' + JSON.stringify(settings));
+ console.log('CustomDSL:path:' + path);
+ console.dir('CustomDSL:payload:' + JSON.stringify(payload));
+ commonApi(settings, path, 'PUT', payload, 'BYOQDefault', null, null, [{
+ "name":"X-DslApiVersion",
+ "value": "V2"
+ }])
+ .then(res => {
+ console.log('CustomDSL: Response',Object.keys(res.data));
+ if(!graphCall && this.typeOfCall){
+ this.setState({aggregatePaths: [],
+ aggregateParentGroup: [],
+ aggregateObjects: []});
+ }
+ if(this.state.isAggregate){
+ if(graphCall){
+ if(res.data.results.length > 0 && this.state.visualAddition){
+ Visualization.chart('currentStateAggregate', [], [], res.data, this);
+ this.setState({isLoading: false, nodes: res.data.results, res: res});
+ }
+ }else{
+ this.processAggregateData(res);
+ }
+ }else{
+ this.processData(res);
+ if(this.state.nodes.length > 0 && this.state.visualAddition){
+ Visualization.chart('currentState', [], [], this.state.res.data, this);
+ }
+ }
+ }, error=>{
+ if(this.typeOfCall){
+ this.triggerError(error);
+ }else{
+ let errMsg = this.renderErrorMsg(error);
+ this.setState({ isLoading: false,errorDownloadResults:true,downloadErrorMsg:errMsg,enableModelBusyFeedback:false});
+ }
+ }).catch(error => {
+ if(this.typeOfCall){
+ this.triggerError(error);
+ }else{
+ let errMsg = this.renderErrorMsg(error);
+ this.setState({ isLoading: false,errorDownloadResults:true,downloadErrorMsg:errMsg,enableModelBusyFeedback:false});
+ }
+ });
+ //this.input.focus();
+ }
+
+ triggerError = (error) => {
+ console.error('[CustomDsl.jsx] triggerError error : ', JSON.stringify(error));
+ //this.processData('');
+ this.setState({isLoading: false,
+ totalResults: 0,
+ showPagination: false,
+ showResults: false,
+ isInitialLoad: false,
+ noResults: true,
+ errorResults: true
+ });
+ this.downloadAllTooltip = 'Downloads First ' + DOWNLOAD_ALL + ' Results';
+ let errMsg = this.renderErrorMsg(error);
+ this.setState({errorMessage:errMsg});
+ console.log(error.config);
+ this.input.focus();
+ }
+ renderErrorMsg = (error) =>{
+ let errMsg='';
+ if (error.response) {
+ // The request was made and the server responded with a status code
+ // that falls out of the range of 2xx
+ console.log('[CustomDsl.jsx] error :', error.response);
+ if(error.response.status){
+ errMsg += " Code: " + error.response.status;
+ }
+ if(error.response.data){
+ errMsg += " - " + JSON.stringify(error.response.data);
+ }
+ } else if (error.request) {
+ // The request was made but no response was received
+ // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
+ // http.ClientRequest in node.js
+ console.log(error.request);
+ errMsg += " - Request was made but no response received";
+ } else {
+ // Something happened in setting up the request that triggered an Error
+ console.log('Error', error.message);
+ errMsg += " - Unknown error occurred " + error.message;
+ }
+ return errMsg;
+ }
+ formAliasFilterPropertes = () =>{
+ let tableAggregateAliasColumns={};
+ this.tableFilterAliasColumns={};
+ let dslQuery = this.state.value;
+ var limitPattern = /limit[\s]\d+|limit\d+/ig
+ var limitkey = dslQuery.match(limitPattern);
+ if(limitkey){
+ dslQuery = dslQuery.replace(limitkey[limitkey.length-1],'').trim();
+ }
+ dslQuery = this.alterDslQueryByRemoveSpaces(dslQuery);
+ //New adding
+ this.dslObject={};
+ this.nodeTypeArray=[];
+ //create placeholders for NodeTypes with Propand Propvalues
+ this.tempDslQuery=this.formTempDslQuery(dslQuery);
+ //Preparing Json Object to render into Placeholder
+ this.contructDslNodes(dslQuery,'node',false,false,false,false);
+ ;
+ let aliasRegex=/\'(\s)as(\s)\'|\'as\'/ig;
+ Object.keys(this.dslObject).map((nodekey)=>{
+ let nodeprops=this.dslObject[nodekey][0]['props'];
+ if(nodeprops){
+ let nodeTypeProp = nodeprops[0].slice(1,-1).split(',');
+ let objAlias = {};
+ let filterObjAlias={};
+ for(var s=0;s<nodeTypeProp.length;s++){
+ let nodeTypePropes=nodeTypeProp[s].match(aliasRegex);
+ let alias='';
+ let nprop='';
+ if(nodeTypePropes){
+ let nodeTypeSplit=nodeTypeProp[s].split(aliasRegex);
+ nprop=nodeTypeSplit[0].replace(/\'/g,'');
+ alias=nodeTypeSplit[nodeTypeSplit.length-1].replace(/\'/g,'');
+ objAlias[nprop]=alias;
+ filterObjAlias[alias]=nprop;
+ }
+ }
+ let nodeNo=parseInt(nodekey.substr(nodekey.length-2,nodekey.length-1).replace(/\-/g,''));
+ let keyact=isNaN(nodeNo);
+ let actKey=nodekey.split('-');
+ if(!keyact){
+ actKey.splice(actKey.length-1,1);
+ nodekey=actKey.join('-')+nodeNo;
+ }
+ if(!tableAggregateAliasColumns[nodekey]){
+ tableAggregateAliasColumns[nodekey]=[];
+ tableAggregateAliasColumns[nodekey].push(objAlias);
+
+ }
+ if(!this.tableFilterAliasColumns[nodekey]){
+ this.tableFilterAliasColumns[nodekey]=[];
+ this.tableFilterAliasColumns[nodekey].push(filterObjAlias);
+ }
+ }
+ });
+ return tableAggregateAliasColumns;
+ }
+ processAggregateData = (resp) =>{
+ console.log('CustomDSL:processAggregateData Response data: ' + JSON.stringify(resp.data));
+ var downloadCount = DOWNLOAD_ALL;
+ var uniqueNodePaths = [];
+ var uniqueNodeAttributes = [];
+ var groupingByStart = [];
+ var aggregateObjectArray = [];
+ if (resp.data && resp.data.results) {
+ for(var i = 0; i < resp.data.results.length; i++){
+ var fullPath = "";
+ var nodePath = "";
+ var nodeTypesForPath = [];
+ var startNodeKey = "";
+ var aggregateObject = {};
+ //Make sure everything is in an array, so pushing single element into the array
+ if(!Array.isArray(resp.data.results[i])){
+ var tempObj = Object.assign({}, resp.data.results[i]);
+ resp.data.results[i] = [];
+ resp.data.results[i].push(tempObj);
+ }
+ for(var j = 0; j < resp.data.results[i].length; j++){
+ var objectIndex = 0;
+ for(var key in resp.data.results[i][j]){
+ var nodeType = this.getNodeTypeFromURI(key);
+ if (objectIndex === 0){
+ startNodeKey = key;
+ }
+ objectIndex++;
+ var nodeTypeLabel = '';
+ if(nodeTypesForPath[nodeType] >= 1){
+ nodeTypeLabel = nodeType + nodeTypesForPath[nodeType];
+ nodeTypesForPath[nodeType] = nodeTypesForPath[nodeType]++;
+ }else if (nodeTypesForPath[nodeType] === 0){
+ nodeTypeLabel = nodeType + 1;
+ nodeTypesForPath[nodeType] = 1;
+ }else{
+ nodeTypeLabel = nodeType;
+ nodeTypesForPath[nodeType] = 0;
+ }
+ if(!uniqueNodeAttributes[nodeTypeLabel]){
+ uniqueNodeAttributes[nodeTypeLabel] = [];
+ }
+ for(var propKey in resp.data.results[i][j][key].properties){
+ if(uniqueNodeAttributes[nodeTypeLabel].indexOf(propKey) === -1){
+ uniqueNodeAttributes[nodeTypeLabel].push(propKey);
+ }
+ Object.defineProperty(resp.data.results[i][j][key].properties, nodeTypeLabel + '|' + propKey, Object.getOwnPropertyDescriptor(resp.data.results[i][j][key].properties, propKey));
+ delete resp.data.results[i][j][key].properties[propKey];
+ }
+ fullPath += key + ' > ';
+ nodePath += nodeTypeLabel + ' > ';
+ }
+ aggregateObject = Object.assign({}, aggregateObject, resp.data.results[i][j][startNodeKey].properties);
+ }
+ nodePath = nodePath.substring(0, nodePath.length - 3);
+ if(!aggregateObjectArray[nodePath]){
+ aggregateObjectArray[nodePath] = [];
+ }
+ aggregateObjectArray[nodePath].push(aggregateObject);
+ resp.data.results[i].fullPath = fullPath.substring(0, fullPath.length - 3);
+ resp.data.results[i].nodePath = nodePath;
+ if(!groupingByStart[startNodeKey]){
+ groupingByStart[startNodeKey] = [];
+ groupingByStart[startNodeKey].push(resp.data.results[i]);
+ }else{
+ groupingByStart[startNodeKey].push(resp.data.results[i]);
+ }
+ if(uniqueNodePaths.indexOf(resp.data.results[i].nodePath) === -1){
+ uniqueNodePaths.push(resp.data.results[i].nodePath);
+ }
+ console.log('Grouping by Start: ' + JSON.stringify(groupingByStart));
+ console.log('Unique Paths: ' + JSON.stringify(uniqueNodePaths));
+ }
+ if(this.typeOfCall){
+ let totalResults = (resp.headers) ? parseInt(resp.headers['total-results']) : 0;
+ console.log('totalResults>>>>>>>>>>>>>>>>>>>>>',totalResults);
+ if(totalResults > DOWNLOAD_ALL){
+ this.downloadAllTooltip = DOWNLOAD_ALL + ' results out of '+ totalResults +' results will be downloaded, Please filter results further to obtain full report';
+ }else{
+ this.downloadAllTooltip = (totalResults === 1) ?'Downloads ' + totalResults + ' Results' : 'Downloads all ' + totalResults + ' Results' ;
+ downloadCount= totalResults;
+ }
+ this.setState({
+ aggregateNodes: resp.data.results,
+ res: resp,
+ aggregatePaths: uniqueNodePaths,
+ aggregatePathAttrs: uniqueNodeAttributes,
+ aggregateObjects: aggregateObjectArray,
+ aggregateParentGroup: groupingByStart,
+ isLoading: false,
+ totalResults: totalResults,
+ showResults: totalResults > 0 ? true : false,
+ showPagination: totalResults > 0 ? true : false,
+ isInitialLoad: false,
+ noResults: totalResults > 0 ? false : true,
+ errorResults: false,
+ downloadCount: downloadCount,
+ },function(){this.formatAggregateIntoTabular();});
+ this.multipleNodes = this.state.aggregateNodes.length > 1;
+ //this.setState({ viewName: "CardLayout" }); commented not to defaulting to CardView
+ }else{
+ console.log('else condition>>>>');
+ if(resp.data && resp.data.results) {
+ this.nodeResults = resp.data.results;
+ let totalResults = 0;
+ let totalPages = 0;
+ totalResults = parseInt(resp.headers['total-results']);
+ totalPages = parseInt(resp.headers['total-pages']);
+ this.setState({
+ allAggregateNodes: resp.data.results,
+ allres: resp,
+ allAggregatePathAttrs: uniqueNodeAttributes,
+ allAggregatePaths: uniqueNodePaths,
+ allAggregateObjects: aggregateObjectArray,
+ allAggregateParentGroup: groupingByStart,
+ totalPages:totalPages,
+ totalResults:totalResults,
+ errorDownloadResults:false,
+ downloadErrorMsg:''
+ },function(){this.formatAggregateIntoTabular();});
+ }else{
+ this.downloadAllTooltip = 'Downloads First ' + DOWNLOAD_ALL + ' Results';
+ }
+ this.setState({isLoading: false});
+ }
+ }
+ GeneralCommonFunctions.scrollTo("outputBlock");
+ }
+
+ formatAggregateIntoTabular = () =>{
+ let tableColumnsList = [];
+ let tableDataList = [];
+ let columnFilter = [];
+ var aggregatePaths = [];
+ var aggregateObjects = [];
+ let tableAggregateAliasColumns=this.formAliasFilterPropertes();
+
+ if(this.typeOfCall){
+ aggregatePaths = this.state.aggregatePaths;
+ aggregateObjects = this.state.aggregateObjects;
+ }else{
+ aggregatePaths = this.state.allAggregatePaths;
+ aggregateObjects = this.state.allAggregateObjects;
+ }
+ for(var p = 0; p < aggregatePaths.length; p++){
+ var types = [aggregatePaths[p]];
+ var type = types[0];
+ var attributeList = this.getAttributesFromPath(type,tableAggregateAliasColumns);
+ var downloadAllCalled = false;
+ tableColumnsList[type] = [];
+ tableColumnsList[type].push({dataField: 'id', text: 'id', hidden: true });
+ tableDataList[type] = aggregateObjects[type];
+ for(var attrIndex = 0; attrIndex < attributeList.length; attrIndex++){
+ let col=attributeList[attrIndex].split('|').splice(0,2).join('|');
+ let desc=attributeList[attrIndex].split('|')[2];
+ if(!columnFilter[attrIndex] || (columnFilter[attrIndex] && columnFilter[attrIndex][attributeList[attrIndex]] === undefined)){
+ let obj = {};
+ obj[col] = '';
+ obj['description']=desc
+ columnFilter.push(obj);
+ }
+ if(!this.typeOfCall){
+ tableColumnsList[type].push({name: col,
+ dataField: col,
+ text: col,
+ hidden: false,
+ headerAttrs: {title:desc},
+ filter: textFilter({getFilter: (f) => { this.setState({filterEnable: true})}})
+ });
+ }else{
+ tableColumnsList[type].push({name: col,
+ dataField: col,
+ text: col,
+ hidden: false,
+ headerAttrs: { title:desc},
+ filter : customFilter(),
+ filterRenderer : (onFilter, column) => <AttributeFilter handleOnFilter= {this.handleOnFilter} onFilter={ onFilter } column={ column } isPageChange={this.state.isPageNumberChange} nodeType={type} columnFilter={columnFilter}/>
+ });
+ }
+ }
+ if(this.typeOfCall){
+ this.setState({tabularAggregateColumns: tableColumnsList, tabularAggregateData: tableDataList, aggregateAttrList: attributeList,tableAggregateAliasColumns:tableAggregateAliasColumns});
+ }else{
+ this.setState({allTabularAggregateColumns: tableColumnsList, allTabularAggregateData: tableDataList, allAggregateAttrList: attributeList,tableAggregateAliasColumns:tableAggregateAliasColumns}, function(){if(!downloadAllCalled){downloadAllCalled = true;this.downloadAllAggregate();}});
+ }
+ }
+ }
+
+ downloadAggregate = () =>{
+ this.typeOfCall = true;
+ ExportExcel.generateExcelFromTabularViewMultiTabs( this.state.tabularAggregateData, this.state.tabularAggregateColumns, 'AggregateObjects.xlsx');
+ }
+
+ downloadAllAggregate = (pageRange,rangeState) =>{
+ console.log('downloadAllAggregate>>>>>>>>>>>*',pageRange);
+ if(pageRange){
+ this.typeOfCall=false;
+ let rangeModelState=(rangeState)? rangeState: false;
+ this.setState(
+ { pageRange: pageRange,isLoading: true,showDownloadResultsModal:rangeModelState,enableModelBusyFeedback:true},
+ function () { this.formQueryString(false,false,false); }.bind(this)
+ );
+ }else{
+ this.setState(
+ {errorDownloadResults: false, showDownloadResultsModal: false, downloadErrorMsg:'', isLoading: false, enableModelBusyFeedback:false},
+ function (){
+ ExportExcel.generateExcelFromTabularViewMultiTabs( this.state.allTabularAggregateData, this.state.allTabularAggregateColumns, 'AggregateObjects.xlsx');
+ this.typeOfCall = true;
+ }.bind(this)
+ );
+ }
+ }
+ openDownloadRange = () =>{
+ this.setState({
+ showDownloadResultsModal: true,
+ errorDownloadResults: false,
+ downloadErrorMsg:''});
+ }
+ closeDownloadResults = () =>{
+ this.setState({
+ showDownloadResultsModal: false,
+ enableModelBusyFeedback: false
+ });
+ }
+ processData = (resp) => {
+ console.log('Response data: ' + JSON.stringify(resp.data));
+ this.tableFilterAliasColumns=this.formAliasFilterPropertes();
+ if(this.typeOfCall){
+ if (resp.data && resp.data.results) {
+ //this.nodes = data.results;setDefaultViewName
+ this.setState({
+ nodes: resp.data.results,
+ res: resp
+ });
+ this.multipleNodes = this.state.nodes.length > 1;
+ //this.setState({ viewName: "CardLayout" });
+ }
+ let totalResults = 0;
+ let downloadCount = DOWNLOAD_ALL;
+ if(resp.headers) {
+ totalResults = parseInt(resp.headers['total-results']);
+ if(totalResults > DOWNLOAD_ALL){
+ this.downloadAllTooltip = DOWNLOAD_ALL + ' results out of '+ totalResults +' results will be downloaded, Please filter results further to obtain full report';
+ }else{
+ this.downloadAllTooltip = (totalResults === 1) ?'Downloads ' + totalResults + ' Results' : 'Downloads all ' + totalResults + ' Results' ;
+ downloadCount= totalResults;
+ }
+ this.setState({isLoading: false,
+ totalResults: totalResults,
+ totalPages: parseInt(resp.headers['total-pages']),
+ showPagination: resp.headers['total-results'] > 0 ? true : false,
+ showResults: resp.headers['total-results'] > 0 ? true : false,
+ isInitialLoad: false,
+ noResults: resp.headers['total-results'] && resp.headers['total-results'] > 0 ? false : true,
+ errorResults: !resp.headers['total-results'],
+ downloadCount: downloadCount
+ });
+ }
+ }else{
+ if(resp.data && resp.data.results) {
+ this.nodeResults = resp.data.results;
+ let totalResults = 0;
+ let totalPages = 0;
+ if(resp.headers) {
+ totalResults = parseInt(resp.headers['total-results']);
+ totalPages = parseInt(resp.headers['total-pages']);
+ }
+ this.setState({totalPages:totalPages,errorDownloadResults:false,downloadErrorMsg:''},() => {this.getAllExcels()});
+ }else{
+ this.nodeResults = '';
+ this.setState({ isLoading: false,errorDownloadResults:true,downloadErrorMsg:error+'',enableModelBusyFeedback:false});
+ }
+ }
+ GeneralCommonFunctions.scrollTo("outputBlock");
+ }
+
+ close = () => {
+ this.setState({
+ showModal: false
+ });
+ }
+
+ onClick = (event) => {
+ console.log('onClick');
+ }
+
+ onTextAreaChange = (event) => {
+ this.setState({value: event.target.value});
+ }
+
+ onChange = (event, { newValue }) => {
+ console.log('onChange.newValue: ' + newValue);
+ let term = null;
+ this.setState({
+ value: newValue},
+ function () {
+ console.log('onChange.selected: ' + this.state.selected);
+ console.log('onChange.state value set: ' + this.state.value);
+ if (this.state.value.slice(-1) === '(' || this.state.value.slice(-1) === '>') {
+ //this.onSuggestionsFetchRequested(term);
+ term = this.getValue(this.state.value); // this returns term, array of props or rules
+ if (term) {
+ console.log('onChange.term: ' + term.toString());
+ }
+ console.log('onChange.setting suggestions');
+ this.setState({
+ suggestions: term
+ });
+ }else if(this.state.value === ''){
+ inputValue='';
+ }
+ }
+ );
+ // if term exists && term length > 0 - try to load suggestions
+ //if(term && term.length > 0){
+ //properties = term.map(property => {
+ //return <div key={property}>{property}<br/></div>;
+ //});
+ //}
+ }
+
+ getValue = (term) => {
+ inputValue = '';
+ let isStartNode = (term.split('>')).length <= 1;
+ console.log('getValue.term is: ' + term);
+
+ let toArray = term.split(' ');
+ //console.log('Value' + JSON.stringify(toArray[toArray.length - 1]));
+ if (toArray && toArray.length > 1) {
+ //this.model = term;
+ console.log('getValue.toArray: ' + toArray.length);
+ this.setState({
+ model: term
+ });
+ term = toArray[toArray.length - 1];
+
+ }
+ for (var i = 0; i < toArray.length - 1; i++) {
+ inputValue = inputValue + ' ' + toArray[i];
+ }
+ console.log('getValue.inputValue toArray: ' + inputValue);
+ //console.log(term.slice(-1));
+ if (term.slice(-1) === '(') {
+ console.log('getValue.detected ( property search');
+ var nodeVal = term.slice(0, -1);
+ nodeVal = nodeVal.trim();
+ console.log('getValue.property.nodeVal: ' + nodeVal);
+ var val = [];
+ val = this.state.nodeTypes.filter(v => v.toLowerCase().indexOf(nodeVal.toLowerCase()) > -1);
+ console.log('getValue.val.length: ' + val.length);
+ if (val.length === 0) {
+ nodeVal = this.state.previousNodeTypeDsl;
+ inputValue = inputValue + term.slice(0, -1);
+ }else {
+ inputValue = inputValue + ' ' + nodeVal;
+ }
+ console.log('getValue.inputValue property: ' + inputValue);
+ if (nodeVal) {
+ this.propertiesDsl=this.populateColumnOptions(nodeVal, isStartNode);
+ this.setState({nodeTypeDsl: nodeVal,previousNodeTypeDsl:nodeVal});
+ }
+ term = this.propertiesDsl;
+ } else if (term.slice(-1) === '>') {
+ console.log('getValue.detected > edgerule search');
+ var nodeVal = this.state.previousNodeTypeDsl;
+ nodeVal = nodeVal.trim();
+ console.log('getValue.edgerule.nodeVal: ' + nodeVal);
+ var val = [];
+
+ inputValue = term;
+
+ this.populateEdgeRules(nodeVal);
+ term = traverseRulesDsl;
+ }
+ else {
+ //console.log('getValue.nodeTypes: ' + this.state.nodeTypes);
+ term = (term === '' ? this.state.nodeTypes : this.state.nodeTypes.filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)).slice(0, 10);
+ }
+ //console.log('getValue.term: ' + term);
+ return term;
+ }
+
+ camelToDash = (str) => {
+ console.log('camelToDash.str: ' + str);
+ return (str.replace(/\W+/g, '-')
+ .replace(/([a-z\d])([A-Z])/g, '$1-$2')).toLowerCase();
+ }
+
+
+ populateColumnOptions = (nodeType, isStartNode) =>{
+ console.log('populateColumnOptions>>>>>nodeType',nodeType);
+ let propertiesDsl = [];
+ var result = JSON.parse(OXM);
+ var arrayOfTypes = result['xml-bindings']['java-types'][0]['java-type'];
+ //console.dir(arrayOfTypes);
+ var foundIndex = -1;
+ var searchParam = nodeType;
+ //if(['PSERVER', 'COMPLEX', 'CLOUDREGION', 'NETWORKPROFILE', 'VIRTUALDATACENTER'].indexOf(this.nodeType.toUpperCase()) === -1){
+ //searchParam = this.nodeType.substring(0, this.nodeType.length - 1);
+ //}
+ //console.log('nodeType:' + nodeType);
+ if (nodeType.substr(nodeType.length - 3) === 'ies') {
+ searchParam = nodeType.substring(0, nodeType.length - 3) + 'y';
+ }
+
+ if (nodeType.toUpperCase() === 'LINESOFBUSINESS') {
+ searchParam = 'lineOfBusiness';
+ }
+ //console.log('searchParam:' + searchParam);
+ for (var i = 0; i < arrayOfTypes.length && foundIndex === -1; i++) {
+ if (arrayOfTypes[i]['xml-root-element'][0]['$']['name'] === this.camelToDash(searchParam)) {
+ foundIndex = i;
+ }
+ }
+ for (var j = 0; j < arrayOfTypes[foundIndex]['java-attributes'][0]['xml-element'].length; j++) {
+ let property = arrayOfTypes[foundIndex]['java-attributes'][0]['xml-element'][j]['$']['name'];
+ //console.log('array' + JSON.stringify(property));
+ let type = arrayOfTypes[foundIndex]['java-attributes'][0]['xml-element'][j]['$']['type'];
+ //console.log('type: ' + type);
+ if (type === 'java.lang.String' || type === 'java.lang.Boolean' || type ==='java.lang.Integer' || type ==='java.lang.Long') {
+ let value = '';
+ if(isStartNode !== undefined){
+ value = '(\'' + property + '\',\'Value\')';
+ }else{
+ value= property;
+ }
+ propertiesDsl.push(value);
+ }
+ }
+ //console.log('propertiesDsl: ' + propertiesDsl);
+ let sortedPropertiesDsl = propertiesDsl.sort(function (filter1, filter2) {
+ if (filter1 < filter2) {
+ return -1;
+ } else if (filter1 > filter2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ //console.log('sortedPropertiesDsl: ' + sortedPropertiesDsl);
+ if(isStartNode !== undefined){
+ propertiesDsl = sortedPropertiesDsl;
+ //console.log('FilterList' + JSON.stringify(propertiesDsl));
+ }
+ return propertiesDsl;
+
+ }
+ componentWillReceiveProps(nextProps) {
+ console.log('nextProps......', nextProps);
+ //console.log('this.props.....', this.props);
+
+ var relArray = false;
+ if(this.props.match.params.relArray){
+ if(nextProps.match.params.relArray){
+ if(nextProps.match.params.relArray !== this.props.match.params.relArray){
+ relArray = true;
+ }
+ }
+ }else{
+ relArray = false;
+ }
+ console.log('relArray>>>>',relArray);
+ this.setState({
+ isDSLFlow: this.props.viewName === 'BYOQ',
+ isSavedQueryFlow: this.props.viewName === 'Saved Queries',
+ showNodeModal:false
+ },()=>{if (nextProps.match.params.type && nextProps.match.params.propId &&
+ (nextProps.match.params.type !== this.props.match.params.type ||
+ nextProps.match.params.propId !== this.props.match.params.propId || relArray)) {
+ this.props = nextProps;
+ this.buildDynamicByoq();
+ }});
+ }
+ populateEdgeRules = (nodeType) => {
+ traverseRulesDsl = [];
+ console.log('populateEdgeRules.nodeType: ' + nodeType);
+ for (var i = 0; i < this.state.edgeRules.length; i++) {
+ var ruleObj = this.state.edgeRules[i];
+ if (ruleObj.from === nodeType) {
+ console.log('from: ' + ruleObj.to);
+ traverseRulesDsl.push(ruleObj.to);
+ }
+ if (ruleObj.to === nodeType) {
+ console.log('to: ' + ruleObj.from);
+ traverseRulesDsl.push(ruleObj.from);
+ }
+ }
+ let traverseRulesDslSorted = traverseRulesDsl.sort(function (filter1, filter2) {
+ if (filter1 < filter2) {
+ return -1;
+ } else if (filter1 > filter2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ console.log('EdgeRulesList' + JSON.stringify(traverseRulesDslSorted));
+ traverseRulesDsl = traverseRulesDslSorted;
+ }
+
+ // Autosuggest will call this function every time you need to update suggestions.
+ // You already implemented this logic above, so just use it.
+ onSuggestionsFetchRequested = ({ value }) => {
+ this.setState({
+ suggestions: this.getSuggestions(value)
+ });
+ };
+ getAllExcels = (pageRange,rangeState) =>{
+ console.log('getAllExcels>>>>>>>>>>>*',pageRange);
+ if(pageRange){
+ this.typeOfCall=false;
+ let rangeModelState=(rangeState)? rangeState: false;
+ this.setState(
+ { pageRange: pageRange,isLoading: true,showDownloadResultsModal:rangeModelState,enableModelBusyFeedback:true},
+ function () { this.formQueryString(false,false,false); }.bind(this)
+ );
+ }else{
+
+ this.setState(
+ {errorDownloadResults: false, showDownloadResultsModal: false, downloadErrorMsg:'', isLoading: false, enableModelBusyFeedback:false},
+ function () { generateExcels(this.nodeResults,this.state.prevQuery);this.nodeResults='';this.typeOfCall = true;}.bind(this)
+ );
+ }
+ }
+
+ getTreeFromDSL = (dslQuery) =>{
+ var treeObject = [];
+ var payload = {dsl: dslQuery};
+ settings['ISAPERTURE'] = true;
+ return commonApi(settings, 'dsl/convert-query-to-tree', 'PUT', payload, 'ConvertQueryToTree')
+ .then(res => {
+ console.log('res:' + res.data, 'load');
+ if(res.status === 200 || res.status === 404){
+ if(res.data.status && (res.data.status !== 200 && res.data.status !== 201 && res.data.status !== 404)){
+ this.triggerTreeError(res.data, 'treeLoad');
+ return {};
+ }else{
+ treeObject = res.data;
+ this.setState({
+ treeLoadErrMsg: null
+ });
+ console.log("TREE OBJECT: " + JSON.stringify(treeObject));
+ //set the init state
+ var initNode = GeneralCommonFunctions.extractNodeDetails(treeObject.children[0], true, this.triggerTreeError, APERTURE_SERVICE);
+ if(!this.state.treeLoadErrMsg || this.state.treeLoadErrMsg === ''){
+ console.log(JSON.stringify(initNode));
+ return initNode;
+ }else{
+ this.triggerTreeError(null, 'treeLoad');
+ return {};
+ }
+ }
+ }else{
+ this.triggerTreeError(res.data, 'treeLoad');
+ return {};
+ }
+ }, error=>{
+ if(error.response.status === 404){
+ this.setState({enableTreeLoadBusyFeedback:false});
+ return {};
+ }else{
+ this.triggerTreeError(error.response.data, 'treeLoad');
+ return {};
+ }
+ }).catch(error => {
+ this.triggerTreeError(error, 'treeLoad');
+ return {};
+ })
+ }
+ triggerTreeError = (error, type) => {
+ console.error('[CustomDsl.jsx] error : ', JSON.stringify(error));
+ let errMsg = '';
+ if(error && error.status && error.message){
+ errMsg += "Error Occurred: " + error.status + ' - ' +error.message;
+ }else{
+ errMsg += "Error Occurred: " + JSON.stringify(error);
+ }
+ console.log(errMsg);
+ if(type === 'treeLoad' || type === 'invalidQuery'){
+ var errorMessage = errMsg;
+ this.setState({treeLoadErrMsg: errorMessage, enableTreeLoadBusyFeedback: false});
+ }else{
+ console.log('[CustomDsl.jsx] :: triggerError invoked with invalid type : ' + type);
+ }
+ }
+ getConfigArrayFromDSLTree = (node, configArray, keyArray) =>{
+
+ var tempKey = node.name;
+ var nodeKey;
+ if(keyArray[tempKey]){
+ nodeKey = tempKey + '-' + keyArray[tempKey];
+ keyArray[tempKey] = keyArray[tempKey]++;
+ }else{
+ nodeKey = tempKey;
+ keyArray[tempKey] = 1;
+ }
+ if(node.details && node.details.attrDetails){
+ for (var attr in node.details.attrDetails){
+ if(node.details.attrDetails[attr].filterType && node.details.attrDetails[attr].filterType.length > 0
+ && node.details.attrDetails[attr].filterType[0] !== ""){
+ if(!configArray[nodeKey]){
+ configArray[nodeKey] = {};
+ configArray[nodeKey].filters = [];
+ }
+ configArray[nodeKey].filters.push(attr);
+ }
+ }
+ }
+ if(node.children && node.children.length > 0){
+ for(var i = 0; i < node.children.length; i++){
+ configArray = this.getConfigArrayFromDSLTree(node.children[i], configArray, keyArray);
+ }
+ }
+ return configArray;
+ }
+ handlePageChange = (pageNumber) => {
+ console.log('[CustomDsl.jsx] HandelPageChange active page is', pageNumber);
+ this.typeOfCall = true;
+ if(this.state.isAggregateChecked){
+ this.setState(
+ { aggregateActivePage: pageNumber, isLoading: true, nodes: [], aggregateNodes: [],resetColumnFilters: false, isPageNumberChange: true},
+ function () { this.formQueryString(false,false,false); }.bind(this)
+ );
+ }else{
+ this.setState(
+ { activePage: pageNumber, isLoading: true, nodes: [], aggregateNodes: [],resetColumnFilters: false, isPageNumberChange: true},
+ function () { this.formQueryString(false,false,false); }.bind(this)
+ );
+ }
+ }
+ // Autosuggest will call this function every time you need to clear suggestions.
+ onSuggestionsClearRequested = () => {
+ this.setState({
+ suggestions: []
+ });
+ };
+
+// https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions#Using_Special_Characters
+ escapeRegexCharacters(str) {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+ }
+
+ getSuggestions = (value) => {
+ console.log('getSuggestions.value: ' + value);
+ const escapedValue = this.escapeRegexCharacters(value.trim());
+ const regex = new RegExp('^' + escapedValue, 'i');
+ return nodeTypes.filter(nodeType => regex.test(nodeType));
+ }
+
+
+// When suggestion is clicked, Autosuggest needs to populate the input
+// based on the clicked suggestion. Teach Autosuggest how to calculate the
+// input value for every given suggestion.
+ getSuggestionValue = suggestion => suggestion;
+
+// Use your imagination to render suggestions.
+ renderSuggestion = suggestion => (
+ <div>
+ {suggestion}
+ </div>
+ );
+
+ onSuggestionsUpdateRequested =( { value }) => {
+ console.log('onSuggestionsUpdateRequested.value: ' + value);
+ this.setState({
+ suggestions: getSuggestions(value)
+ });
+ }
+
+ shouldRenderSuggestions = () => {
+ return true;
+ }
+ openHistory = (nodeDisplay, nodeUri, nodeType) => { // open modal from Card
+ console.log('history >> showModal',nodeDisplay);
+ let historyNodeUri = (nodeUri)?nodeUri.replace('/aperture/','/'):nodeUri;
+ let paramToPassThrough = '';
+ if(nodeType){
+ this.setState({
+ nodeDisplay: nodeDisplay,
+ showHistoryModal: true,
+ showModelOptions:true,
+ enableCalendar:true,
+ historyType:(this.state.historyType === 'dsl') ? 'nodeState' : this.state.historyType,
+ focusedNodeUri: historyNodeUri,
+ focusedNodeType: nodeType
+ });
+ }else{
+ this.setState({
+ showHistoryModal:true,
+ showModelOptions:false,
+ enableCalendar:true,
+ historyType : 'dsl',
+ focusedNodeUri: this.state.value,
+ focusedNodeType: nodeType
+ });
+ }
+ }
+ closeHistory = () => {
+ this.setState({
+ showHistoryModal: false,
+ enableCalendar:true,
+ historyType :'nodeState'
+ });
+ }
+ submitHistory = () => {
+ console.log("submitting history");
+ let paramToPassThrough = '';
+ if(this.state.focusedNodeType){
+ paramToPassThrough = '/history/' + this.state.historyType +'/' + this.state.focusedNodeType + '/' + btoa(this.state.focusedNodeUri);
+ }else{
+ paramToPassThrough = '/historyQuery/' + this.state.historyType + '/' + btoa(this.state.value);
+ }
+ let epochStartTime = (this.state.startDate).unix();
+ this.props.history.push(paramToPassThrough + '/' + epochStartTime * 1000);
+ }
+ handleDateChange = (newDate) =>{
+ this.setState({ startDate: moment(+newDate) });
+ console.log('[CustomDsl.jsx] handleDateChange date is ', this.state.startDate);
+ console.log('[CustomDsl.jsx] handleDateChange date is in millis ', +this.state.startDate);
+ }
+
+ setViewName(event) {
+ console.log(event.currentTarget.value);
+ if(this.state.isAggregate && event.currentTarget.value === 'VisualLayout'){
+ this.formQueryString(false, false, true);
+ }
+ this.setState({
+ viewName: event.currentTarget.value
+ });
+ }
+
+ setDefaultViewName=(event)=>{
+ let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
+ let layout = event.target.value;
+
+ if(sessionStorage.getItem(ENVIRONMENT + 'userId')) {
+ if (event.target.checked) {
+ localStorage.setItem(ENVIRONMENT + '_' + sessionStorage.getItem(ENVIRONMENT + 'userId') + '_viewPreference', layout);
+ } else {
+ localStorage.removeItem(ENVIRONMENT + '_' + sessionStorage.getItem(ENVIRONMENT + 'userId') + '_viewPreference');
+ }
+ }
+
+ this.setState({
+ defaultViewName: event.target.value
+ });
+ this.baseState.viewName=event.target.value;
+ this.baseState.defaultViewName=event.target.value;
+ }
+ openNodeModal(nodeDisplay, nodeUri, nodeType){ // open modal
+ console.log('customdsl >> showModal');
+ nodeDisplay = "Node Details of " + nodeUri;
+ let node = null;
+ let found = false;
+ for(var j = 0; j < this.state.nodes.length && !found; j++){
+ if(this.state.nodes[j].url === nodeUri){
+ node = this.state.nodes[j];
+ found = true;
+ }
+ }
+ if(nodeDisplay && found){
+ this.setState({
+ nodeDisplay: nodeDisplay,
+ focusedNode: node,
+ showNodeModal:true
+ });
+ }else{
+ this.setState({
+ showNodeModal:true
+ });
+ }
+ }
+
+ closeNodeModal = () => {
+ this.setState({
+ showNodeModal: false
+ });
+ }
+
+ componentDidUpdate(prevProps, prevState, snapshot) {
+ if((this.state.isAggregate || this.state.aggregateNodes.length > 0 || this.state.nodes.length > 0) && !this.state.visualAddition){
+ //Visualization.chart('currentState', [], [], this.state.res.data, this);
+ this.setState({
+ visualAddition: true
+ });
+ }
+ }
+ setHistoryType(event) {
+ console.log(event.target.value);
+ let enableCalendar = false;
+ if(event.target.value === 'nodeLifeCycle'){
+ enableCalendar = false;
+ }else{
+ enableCalendar = true;
+ }
+ this.setState({
+ historyType: event.target.value,
+ enableCalendar: enableCalendar
+ });
+ console.log(this.state.enableCalendar);
+ }
+ loadBulkCallback=(loadQueryList)=>{
+ console.log('Start:Load bulk Callback>>>>>>');
+ let filterEntriesList=[];
+ let filterTemplateHeaderList=[];
+ let filterTemplateErrorList=[];
+ let nodeTypeOfDslTemplateList=[];
+ let templateQueryList=[];
+ let valueList=[];
+ this.dslObjectList=[];
+ this.nodeTypeArrayList=[];
+ this.tempDslQueryList=[];
+ this.templateErrorList={};
+ let isAggregateCheckedList=[];
+ let associatedNodesEnabledList=[];
+ let queryNameList=[];
+ let queryDescriptionList=[];
+ let categoryList=[];
+ let isPublicCheckedList=[];
+ let queryIdList=[];
+ let filterTypeDisplayList=[];
+ let isCommunitySharedList = [];
+ let staticTemplateFiltersList=[];
+ for(var idx=0;idx<loadQueryList.length;idx++){
+ let splitString = loadQueryList[idx].split('||');
+ let name = splitString[0];
+ let description = splitString[1];
+ let category=(splitString[2] !== 'undefined')? splitString[2]:'';
+ let dsl = splitString[3];
+ let isAggregate = splitString[4];
+ let type = splitString[5];
+ let queryId = splitString[6];
+ let isCommunityShared = splitString[7];
+ let templateDetails = splitString[8];
+ if(name !== '' && description !== '' && this.state.isSavedQueryFlow){
+ var staticTemplateFilters = templateDetails;
+ if(staticTemplateFilters.length > 0){
+ staticTemplateFilters = JSON.parse(staticTemplateFilters);
+ }else{
+ staticTemplateFilters = [];
+ }
+ staticTemplateFiltersList.push(staticTemplateFilters);
+ queryNameList.push(name);
+ queryIdList.push(queryId);
+ queryDescriptionList.push(description);
+ isPublicCheckedList.push(type === 'public');
+ categoryList.push(category);
+ isCommunitySharedList.push(isCommunityShared);
+ }
+ associatedNodesEnabledList.push(false);
+ if(isAggregate === "true"){
+ isAggregateCheckedList.push(true);
+ }else{
+ isAggregateCheckedList.push(false);
+ }
+ filterTypeDisplayList.push({'default':'Filter Type'});
+ this.setState({
+ queryNameList:queryNameList,
+ queryDescriptionList:queryDescriptionList,
+ categoryList:categoryList,
+ isPublicCheckedList: isPublicCheckedList,
+ queryIdList: queryIdList,
+ filterTemplateEntries:[],
+ filterTemplateError: false,
+ isTypeahead: false,
+ isAggregateCheckedList: isAggregateCheckedList,
+ associatedNodesEnabledList: associatedNodesEnabledList,
+ filterTypeDisplayList: filterTypeDisplayList,
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:'',
+ emailTriggerMsg:'',
+ isMergedTabsChecked: false,
+ staticTemplateFiltersList: staticTemplateFiltersList
+ });
+
+ if(this.state.isSavedQueryFlow){
+
+ dsl=atob(dsl).replace('<pre>','').replace('</pre>','');
+ this.dslObject={};
+ this.nodeTypeArray=[];
+
+ var limitPattern = /limit[\s]\d+|limit\d+/ig;
+ var limitkey = dsl.match(limitPattern);
+ if(limitkey){
+ dsl = dsl.replace(limitkey[limitkey.length-1],'').trim();
+ }
+ dsl = this.alterDslQueryByRemoveSpaces(dsl);
+ //create placeholders for NodeTypes with Propand Propvalues
+ this.tempDslQuery=this.formTempDslQuery(dsl);
+ this.tempDslQueryList.push(this.tempDslQuery);
+ //Preparinga Json Object to render into Placeholder
+ this.contructDslNodes(dsl,'node',false,false,false,false);
+ //Query to replace placeholders with JSON Object values depends on Flow either SavedQuery or TableFilters
+ let query=this.formTemplateQuery('savedQuery',idx,true);
+ query=query.replace(/\'(as)\'/g,'\' as \'').replace(/\(\'\s(as)\s\'\)/g,'(\'as\')');
+ if(limitkey){
+ query+=' '+limitkey[limitkey.length-1];
+ }
+ let filterEntries=[];
+ let filterTemplateHeader={};
+ var errorOccurred=false;
+ Object.keys(this.dslObject).map((key)=>{
+ filterEntries.push(this.dslObject[key]['filterEntries'][0]);
+ filterTemplateHeader[key]= {}
+ filterTemplateHeader[key]=this.dslObject[key]['filterTemplateHeader'][key];
+ if(!errorOccurred){
+ errorOccurred=this.dslObject[key]['errorOccurred'];
+ }
+ });
+ filterEntriesList.push(filterEntries);
+ filterTemplateHeaderList.push(filterTemplateHeader);
+ filterTemplateErrorList.push(errorOccurred);
+ nodeTypeOfDslTemplateList.push(this.nodeTypeArray);
+ templateQueryList.push(query);
+ valueList.push(dsl);
+ this.dslObjectList.push(this.dslObject);
+
+ }
+ }
+ this.setState({ valueList: valueList,
+ templateQueryList: templateQueryList,
+ filterTemplateEntriesList: filterEntriesList,
+ filterTemplateHeaderList:filterTemplateHeaderList,
+ filterTemplateErrorList: filterTemplateErrorList,
+ nodeTypeOfDslTemplateList:nodeTypeOfDslTemplateList,
+ isAggregateCheckedList: isAggregateCheckedList,
+ associatedNodesEnabledList: associatedNodesEnabledList,
+ isInitialLoad:false
+ },()=>{GeneralCommonFunctions.scrollTo('templateList');});
+ }
+ loadCallback = (name, description, category, dslQuery, isAggregate, type, queryId, isCommunityShared, id, templateDetails, makeCall) =>{
+ let filterEntriesList=[];
+ let filterTemplateHeaderList=[];
+ let filterTemplateErrorList=[];
+ let nodeTypeOfDslTemplateList=[];
+ let templateQueryList=[];
+ let valueList=[];
+ this.dslObjectList=[];
+ this.nodeTypeArrayList=[];
+ this.tempDslQueryList=[];
+ this.templateErrorList={};
+ let isAggregateCheckedList=[];
+ let associatedNodesEnabledList=[];
+ let queryNameList=[];
+ let queryDescriptionList=[];
+ let categoryList=[];
+ let isPublicCheckedList=[];
+ let queryIdList=[];
+ let filterTypeDisplayList=[];
+ let isCommunitySharedList=[];
+ let staticTemplateFiltersList=[];
+ let idx=parseInt(id);
+ if(isNaN(idx)){
+ idx=0;
+ }
+ if(name !== '' && description !== '' && this.state.isSavedQueryFlow){
+ queryNameList.push(name);
+ queryIdList.push(queryId);
+ queryDescriptionList.push(description);
+ isPublicCheckedList.push(type === 'public');
+ var staticTemplateFilters = templateDetails;
+ if(staticTemplateFilters.length > 0){
+ staticTemplateFilters = JSON.parse(staticTemplateFilters);
+ }else{
+ staticTemplateFilters = [];
+ }
+ staticTemplateFiltersList.push(staticTemplateFilters);
+ categoryList.push(category);
+ isCommunitySharedList.push(isCommunityShared);
+ this.setState({
+ queryNameList:queryNameList,
+ queryDescriptionList:queryDescriptionList,
+ categoryList:categoryList,
+ isPublicCheckedList: isPublicCheckedList,
+ isCommunitySharedChecked: isCommunityShared === "true",
+ queryIdList: queryIdList,
+ isCommunitySharedList:isCommunitySharedList,
+ staticTemplateFiltersList: staticTemplateFiltersList,
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:'',
+ emailTriggerMsg:'',
+ isMergedTabsChecked: false,
+ isGenerateEmailChecked: false
+ });
+ }
+ //reset any filter template forms
+ this.setState({ filterTemplateEntries: [], filterTemplateError: false, isTypeahead: false});
+ associatedNodesEnabledList.push(false);
+ let associatedNodesEnable=false;
+ let isAggregateChecked=false;
+ if(isAggregate === "true"){
+ isAggregateCheckedList.push(true);
+ isAggregateChecked=true;
+ }else{
+ isAggregateCheckedList.push(false);
+ }
+ this.setState({ isAggregateCheckedList: isAggregateCheckedList, associatedNodesEnabledList: associatedNodesEnabledList,isAggregateChecked:isAggregateChecked,associatedNodesEnabled:associatedNodesEnable});
+ if(this.state.isSavedQueryFlow && !makeCall){
+ this.loadTemplateForm(atob(dslQuery).replace('<pre>','').replace('</pre>',''),idx);
+ }else{
+ this.setState({viewName: this.state.defaultViewName,
+ activePage: 1,
+ aggregateActivePage: 1});
+ this.buildDynamicByoq(atob(dslQuery).replace('<pre>','').replace('</pre>',''), makeCall);
+ }
+ if(this.state.isDSLFlow){
+ GeneralCommonFunctions.scrollTo("jumbotron");
+ }else if(this.state.isSavedQueryFlow){
+ GeneralCommonFunctions.scrollTo("templateList");
+ }
+ }
+
+ editCallback = (name, description, category, dsl, isAggregateStr, type, queryId, isCommunityShared, templateDetails) =>{
+ //Save stated of loaded queries
+ this.state.valuePreviousState = this.state.value;
+ this.state.isAggregateCheckedPreviousState = this.state.isAggregateChecked;
+ this.state.isCommunitySharedCheckedPreviousState = this.state.isCommunitySharedChecked;
+ this.state.associatedNodesEnabledPreviousState = this.state.associatedNodesEnabled;
+
+ let isAggregateChecked = false;
+ let isCommunitySharedChecked = false;
+ let associatedNodesEnabled = false;
+
+ if(isAggregateStr === 'true'){
+ isAggregateChecked = true;
+ associatedNodesEnabled = true;
+ }
+
+ if(isCommunityShared === 'true'){
+ isCommunitySharedChecked = true;
+ }
+
+ var staticTemplateFilters = templateDetails;
+ if(staticTemplateFilters.length > 0){
+ staticTemplateFilters = JSON.parse(staticTemplateFilters);
+ }else{
+ staticTemplateFilters = [];
+ }
+ this.getTreeFromDSL(dsl).then(tree => {
+ this.setState({
+ enableTreeLoadBusyFeedback: false,
+ dslConfigArray: this.getConfigArrayFromDSLTree(tree, [], []),
+ showSaveModal: true,
+ saveSuccessfulMsg: false,
+ isPublicChecked: type === 'public',
+ isEditModal:true,
+ queryName:name,
+ queryDescription:description,
+ category:category,
+ isAggregateChecked: isAggregateChecked,
+ isCommunitySharedChecked: isCommunitySharedChecked,
+ associatedNodesEnabled: associatedNodesEnabled,
+ value: dsl,
+ queryId: queryId,
+ staticTemplateFilters: staticTemplateFilters
+ });
+ });
+ }
+
+ saveTemplate = (idx) => {
+ var saveModal = () => {
+ this.setState(
+ {
+ showSaveModal: true,
+ saveSuccessfulMsg: false,
+ isPublicChecked: this.state.isPublicChecked,
+ isEditModal:false,
+ queryName:'',
+ queryDescription:'',
+ category:'',
+ queryId:'',
+ isPublicChecked: this.state.isPublicCheckedList[idx],
+ isAggregateChecked: this.state.isAggregateCheckedList[idx],
+ enableTreeLoadBusyFeedback: true
+ });
+ this.getTreeFromDSL(this.state.value).then(tree => {
+ this.setState({enableTreeLoadBusyFeedback: false, dslConfigArray: this.getConfigArrayFromDSLTree(tree, [], [])});
+ });
+ }
+ this.populateTemplate(false, saveModal, idx);
+ }
+
+ runTemplate = (idx) =>{
+ this.populateTemplate(true, null, idx);
+ }
+ submitEditAndRunDSL = () =>{
+ this.setState({ showEditModal: false, value: this.state.editModel,aggregateActivePage:1,activePage:1 }, () => this.formQueryString(false,false,false));
+ }
+ showEditDSLModal = (idx) => {
+ console.log("enabling DSL edit modal");
+ var openModal = () => {
+ this.setState({ editModel: this.state.value, enableTreeLoadBusyFeedback: true, showEditModal: true });
+ }
+ this.populateTemplate(false, openModal, idx);
+ }
+ closeEditDSLModal = () => {
+ console.log("closing DSL edit modal");
+ this.setState({ showEditModal: false, enableTreeLoadBusyFeedback: false });
+ }
+ bindEdits = (e) => {
+ this.setState({ editModel: e.target.value });
+ }
+ populateTemplate = (shouldRun, callback, indx) =>{
+ console.log('CustomDSL:populateTemplate this.state>>>>>>>>>>>>>>>>>>>*',this.state);
+ let query=this.formFinalTemplateQuery(indx);
+ console.log('CustomDSL:query>>>>>>>>>*',query);
+ console.log('CustomDSL:query>>>>>>>>>BTOA*',btoa(query));
+ this.setState({ value: query,aggregateActivePage:1,activePage:1}, () => {if(shouldRun){this.formQueryString(false,false,false)}else{callback()}});
+ }
+ formFinalTemplateQuery = (indx)=>{
+ console.log('formFinalTemplateQuery>> forming finalQuery before Run scenarios>>>>');
+ var query = this.state.templateQueryList[indx];
+ for(var i = 0; i < this.state.filterTemplateEntriesList[indx].length; i++){
+ let filterTemplateEntries=this.state.filterTemplateEntriesList[indx][i];
+ Object.keys(filterTemplateEntries).map((key)=>{
+ Object.keys(filterTemplateEntries[key]).map((entry)=>{
+ let templateEntry=filterTemplateEntries[key][entry];
+ if(templateEntry.name !== ''){
+ let templateFilterQuery = "'" + templateEntry.name + "','" + templateEntry.value + "'";
+ console.log('Before templateFilterQuery>>>>>',templateFilterQuery);
+ let valueArray=templateEntry.value.split('^');
+ let typeArray=templateEntry.type.split('^');
+ templateFilterQuery = "'" + templateEntry.name + "'";
+ let templatekeyValues='';
+ for(var x=0;x<valueArray.length;x++){
+ if(valueArray[x] !==''){
+ if(templatekeyValues === ''){
+ templatekeyValues = (this.state.enableRealTime)?typeArray[x] +"('" + valueArray[x] + "')":"'"+valueArray[x]+"'";
+ }else{
+ templatekeyValues = (this.state.enableRealTime)?templatekeyValues+","+typeArray[x] +"('" + valueArray[x] + "')":templatekeyValues+",'"+ valueArray[x] + "'";
+ }
+ }
+ }
+ templateFilterQuery=templateFilterQuery+","+templatekeyValues;
+ console.log('templateFilterQuery>>>>>',templateFilterQuery);
+ query = query.replace('$' + (templateEntry.templateKey + 1),templateFilterQuery);
+ query = query.replace(/\"/g,'\'');
+ }
+ })
+ });
+ }
+ return query;
+ }
+ stripFirstCharacter=(str)=>{
+ return str.substr(1);
+ }
+ stripLastCharacter=(str)=>{
+ return str.substr(0, str.length - 1);
+ }
+ stripFirstTwoCharacter(str){
+ return str.substr(2);
+ }
+ updateTemplateFilterValues=(key,templateKey,value,id,idx)=>{
+ if(value!==''){
+ var filterTemplateEntriesList = this.state.filterTemplateEntriesList;
+ var filterTemplateHeaderList=this.state.filterTemplateHeaderList;
+ var filterMap = filterTemplateEntriesList[idx];
+ var filterTemplateHeader=filterTemplateHeaderList[idx];
+ let idArray=id.split('_');
+ let ind=parseInt(idArray[idArray.length-1]);
+ let finalSelectedProp='';
+ let existing=false;
+ console.log(ind+'<<<updateTemplateFilterValues>>>>'+key+'<><>',value);
+ console.log(templateKey+'filterMap>>>>>>>>>>>>>>>>',filterMap);
+ Object.keys(filterMap).forEach((index) =>{
+ if(filterMap[index][key]){
+ Object.keys(filterMap[index][key]).forEach((i)=>{
+ if(filterMap[index][key][i].templateKey === templateKey){
+ console.log(key+'<<filterMap[index][key][templateKey]>>>'+filterMap[index][key][i]);
+ let filterValue=filterMap[index][key][i].value.split('^');
+ filterValue[ind]=value;
+ filterMap[index][key][i].value=filterValue.join('^');
+ console.log('Updated Filtered Template Entries map' + JSON.stringify(filterMap));
+ if(filterMap[index][key][i].name !== '' ){
+ filterTemplateHeader[key]['propName'] = filterMap[index][key][i].name;
+ existing =true;
+ }else{
+ console.log('set listname >>>>***',filterTemplateHeader[key]['propName']);
+ finalSelectedProp=filterTemplateHeader[key]['propName'];
+ let status=false;
+ if(filterTemplateHeader[key]['propName'] !== this.state.filterDisplay){
+ filterMap[index][key][i].name= filterTemplateHeader[key]['propName'];
+ status=true;
+ }else{
+ filterMap[index][key][i].name= 'ERROR';
+ if(!(this.templateErrorList[idx] && this.templateErrorList[idx].length>0)){
+ this.templateErrorList[idx]=[];
+ }
+ this.templateErrorList[idx].push(key);
+ }
+ let selectedProp=[];
+ console.log('filterTemplateHeader[key][selectedProp]>>>>',filterTemplateHeader[key]['selectedProp']);
+ if(filterTemplateHeader[key]['selectedProp'] && status){
+ selectedProp=filterTemplateHeader[key]['selectedProp'];
+ let indSelect= selectedProp.indexOf(filterTemplateHeader[key]['propName']);
+ if(indSelect !== -1){
+ selectedProp=selectedProp.splice(indSelect,1);
+ filterTemplateHeader[key]['selectedProp']=selectedProp;
+ }
+ }
+ }
+ filterTemplateHeader[key]['enableAnd'] = true;
+ this.updateSavedQueryTemplate('add',key,templateKey,filterMap,filterTemplateHeader,idx);
+ }
+ });
+ }
+ });
+ }
+ // this.setState({filterTemplateError: true});
+}
+updateSavedQueryTemplate=(action,key,templatekey,templateMaps,templateHeader,idx)=>{
+ console.log(action+'updateSavedQueryTemplate>>>>>>>>>>>>>*');
+ let templateEntriesList = this.state.filterTemplateEntriesList;
+ let filterTemplateHeaderList=this.state.filterTemplateHeaderList;
+ let templateEntries = templateEntriesList[idx];
+ let filterTemplateHeader= filterTemplateHeaderList[idx];
+ let finalSelectedProp='';
+ idx=parseInt(idx);
+ if(templateMaps){
+ templateEntries=templateMaps;
+ }
+ if(templateHeader){
+ filterTemplateHeader=templateHeader
+ }
+ let templateQuery = this.state.templateQueryList[idx];
+ if(templateQuery.charAt(templateQuery.length-1) !== ']'){
+ templateQuery=templateQuery+',';
+ }
+ let keyact=isNaN(parseInt(key.substr(key.length-2,key.length-1)));
+ console.log('keyact>>>>****',keyact);
+ console.log('TemplateQuery>>>&&*',templateQuery);
+ let nodeInd=0;
+ let tempkey =key;
+ if(!keyact){
+ let actKey=key.split('-');
+ nodeInd=parseInt(actKey[actKey.length-1]);
+ actKey.splice(actKey.length-1,1);
+ tempkey=actKey.join('-');
+ }
+ let dslObject=this.dslObjectList[idx];
+ if(action === 'add'){
+ Object.keys(dslObject).map((nodekey)=>{
+ if(nodekey === key){
+ let tempEntries=[];
+ Object.keys(templateEntries).map((index) =>{if(templateEntries[index][key] && nodekey === key){ tempEntries= templateEntries[index][key]}});
+ console.log('tempEntries>>>>',tempEntries);
+ dslObject[nodekey]['templateEntries']=tempEntries;
+ dslObject[nodekey]['filterTemplateHeader']=filterTemplateHeader[nodekey];
+ }
+ })
+ }else{
+ let findEntry=true;
+ Object.keys(templateEntries).map((index) =>{
+ console.log('templateEntries[index][key]??????',templateEntries[index][key]);
+ if(templateEntries[index][key]){
+ Object.keys(templateEntries[index][key]).map((i)=>{
+ console.log(i+'templateEntries[index][key][i].templateKey>>>',templateEntries[index][key][i]);
+ if(findEntry && templateEntries[index][key][i].templateKey === templatekey){
+ findEntry=false;
+ let name = templateEntries[index][key][i].name;
+ finalSelectedProp=name;
+ templateEntries[index][key].splice(i,1);
+ filterTemplateHeader[key]['enableAnd'] = true;
+ filterTemplateHeader[key]['propName'] = this.state.filterDisplay;
+ let selectedProp=[];
+ console.log('filterTemplateHeader[key][selectedProp]???????',filterTemplateHeader[key]['selectedProp']);
+ if(filterTemplateHeader[key]['selectedProp']){
+ selectedProp=filterTemplateHeader[key]['selectedProp'];
+ let ind= selectedProp.indexOf(name);
+ if(ind !== -1){
+ selectedProp=selectedProp.splice(ind,1);
+ filterTemplateHeader[key]['selectedProp']=selectedProp;
+ }
+ }
+ if(name=='ERROR'){
+ if(this.templateErrorList[idx] && this.templateErrorList[idx].length>0){
+ this.templateErrorList[idx].pop();
+ }
+ }
+ console.log('selectedProp>>>>',filterTemplateHeader[key]['selectedProp']);
+ }
+ });
+ }
+ });
+ Object.keys(dslObject).map((nodekey)=>{
+ if(nodekey === key && !findEntry){
+ let tempEntries=[];
+ Object.keys(templateEntries).map((index) =>{if(templateEntries[index][key] && nodekey === key){ tempEntries= templateEntries[index][key]}});
+ console.log('Delete tempEntries>>>>',tempEntries);
+ dslObject[nodekey]['templateEntries']=tempEntries;
+ dslObject[nodekey]['filterTemplateHeader']=filterTemplateHeader[nodekey];
+ }
+ })
+ }
+ console.log(action+' .......Update Saved ***************this.dslObject',dslObject);
+ Object.keys(dslObject).map((nodekey)=>{
+ //console.log(nodekey+'this.dslObject[nodekey][0]>>>>>',dslObject[nodekey][0]);
+ //console.log('key>>>>',key);
+ if(nodekey === key && dslObject[nodekey][0]){
+ Object.keys(templateEntries).map((index) =>{
+ console.log('templateEntries[index][key]>>>>',templateEntries[index][key]);
+ if(templateEntries[index][key]){
+ let props='{';
+ Object.keys(templateEntries[index][key]).map((i)=>{
+ console.log(i+'templateEntries[index][key]>>>>',templateEntries[index][key][i]);
+ let prop='';
+ let newProps=(parseInt(i)!==0)?',\''+templateEntries[index][key][i]['name']+'\'':'\''+templateEntries[index][key][i]['name']+'\'';
+ props+=newProps;
+ if(templateEntries[index][key][i].templateKey === templatekey){
+ let name=templateEntries[index][key][i]['name']
+ let value=templateEntries[index][key][i]['value'].split('^');
+ let type=templateEntries[index][key][i]['type'].split('^');
+ prop='(\''+name+'\',';
+ for(var x=0;x<value.length;x++){
+ if(this.state.enableRealTime){
+ prop+=type[x]+'(\''+value[x]+'\')';
+ if(x===value.length-1){
+ prop+=')';
+ }else{
+ prop+=',';
+ }
+ }else{
+ prop+='\''+value[x]+'\'';
+ if(x===value.length-1){
+ prop+=')';
+ }else{
+ prop+=',';
+ }
+ }
+ }
+ let values=dslObject[nodekey][0]['values'];
+ //console.log('values>>>>>',values);
+ if(values && values.length>0){
+ let findState=false;
+ let errorPropMsg=null;
+ for(var n=0;n<values.length;n++){
+ if(values[n].indexOf('!(\''+name+'\'') !==-1){
+ values[n]='!'+prop;
+ findState=true;
+ }else if(values[n].indexOf('(\''+name+'\'') !==-1){
+ values[n]=prop;
+ findState=true;
+ }
+ if(values[n].indexOf('(\'ERROR\',') !==-1){
+ errorPropMsg=n;
+ }
+ }
+ if(errorPropMsg){
+ values.splice(errorPropMsg,1);
+ }
+ if(!findState){
+ values.push(prop);
+ }
+ dslObject[nodekey][0]['values']=values;
+ }else{
+ dslObject[nodekey][0]['values']=[];
+ dslObject[nodekey][0]['values'].push(prop);
+ }
+ //console.log(prop+'this.dslObject[nodekey][0][values]>>>>',dslObject[nodekey][0]['values']);
+ }
+ });
+ props+='}';
+ if(action!=='add' && dslObject[nodekey][0]['values']){
+ dslObject[nodekey][0]['values'].splice(idx,1);
+ }
+ }
+ });
+ }
+ });
+ //console.log('After Setting ***************this.dslObject',dslObject);
+ this.dslObjectList[idx]=dslObject;
+ let queryList=this.state.templateQueryList;
+ let dslquery=queryList[idx];
+ var limitPattern = /limit[\s]\d+|limit\d+/ig
+ var limitkey = dslquery.match(limitPattern);
+ //this.tempDslQuery=this.formTempDslQuery(dsl);
+ let query=this.formTemplateQuery('savedQuery',idx);
+ query=query.replace(/\'(as)\'/g,'\' as \'').replace(/\(\'\s(as)\s\'\)/g,'(\'as\')');
+ if(limitkey){
+ query+=' '+limitkey[limitkey.length-1];
+ }
+ console.log('query>>>>>>>>>>>>>',query);
+ queryList[idx]=query;
+ templateEntriesList[idx]=templateEntries;
+ filterTemplateHeaderList[idx]=filterTemplateHeader;
+ this.setState({filterTemplateEntriesList:templateEntriesList,filterTemplateHeaderList:filterTemplateHeaderList,templateQueryList:queryList});
+
+ }
+ capturingGroups=(dsl)=>{
+ var capturedGroups=[];
+ let findGroup=true;
+ var block = dsl;
+ do{
+ var startIndex = block.indexOf('['),/* index of first bracket */
+ currPos = startIndex,
+ openBrackets = 0,
+ stillSearching = true,
+ waitForChar = false;
+ if(currPos === -1){
+ findGroup=false;
+ }
+ while (stillSearching && currPos <= block.length) {
+ var currChar = block.charAt(currPos);
+ switch (currChar) {
+ case '[':
+ openBrackets++;
+ break;
+ case ']':
+ openBrackets--;
+ break;
+ }
+ currPos++
+ if (openBrackets === 0) { stillSearching = false; }
+ }
+ console.log('capturingGroups>>>>>>>>>>>>',block.substring(startIndex , currPos));
+ if(block.substring(startIndex , currPos) !==''){
+ capturedGroups.push(block.substring(startIndex , currPos));
+ block=block.replace(block.substring(startIndex , currPos),'#$')
+ }
+ }while(findGroup);
+ return capturedGroups;
+ }
+ formTempDslQuery=(dsl) =>{
+ let tempQuery='';
+ tempQuery=dsl.replace(/\!\((?:[^>)(]|\((?:[^)(]+)\))*\)/g,'').replace(/\((?:[^>)(]|\((?:[^)(]+)\))*\)/g,'').replace(/\{(.*?)\}/g,'').replace(/\*/g,'').trim('')+',';
+ tempQuery = tempQuery.replace(/\s+/g, '');
+ tempQuery=tempQuery.replace(/[a-zA-Z0-9*\-]/g,'#').replace(/\!\!/g,'!').replace(/\!\>/g,'>');
+ tempQuery=tempQuery.replace(/\#(.*?)(?=\>|\!|\(|\)|\,|\])/g,'#').trim('');
+ tempQuery=this.stripLastCharacter(tempQuery);
+ return tempQuery;
+ }
+ loadTemplateForm=(dsl,idx) =>{
+ console.log('loadTemplateForm>>>idx>>>>',idx);
+ this.dslObject={};
+ this.nodeTypeArray=[];
+ var limitPattern = /limit[\s]\d+|limit\d+/ig;
+ var limitkey = dsl.match(limitPattern);
+ if(limitkey){
+ dsl = dsl.replace(limitkey[limitkey.length-1],'').trim();
+ }
+ dsl = this.alterDslQueryByRemoveSpaces(dsl);
+ //create placeholders for NodeTypes with Propand Propvalues
+ this.tempDslQuery=this.formTempDslQuery(dsl);
+ this.tempDslQueryList.push(this.tempDslQuery);
+ //Preparinga Json Object to render into Placeholder
+ this.contructDslNodes(dsl,'node',false,false,false,false);
+ console.log('dsl>>>>>>>>>>>>>',dsl);
+ //Query to replace placeholders with JSON Object values depends on Flow either SavedQuery or TableFilters
+ let query=this.formTemplateQuery('savedQuery',idx,true);
+ query=query.replace(/\'(as)\'/g,'\' as \'').replace(/\(\'\s(as)\s\'\)/g,'(\'as\')');
+ if(limitkey){
+ query+=' '+limitkey[limitkey.length-1];
+ }
+ let filterEntries=[];
+ let filterTemplateHeader={};
+ var errorOccurred=false;
+ console.log('before setting DSLOBJECT>>',this.dslObject);
+ Object.keys(this.dslObject).map((key)=>{
+ filterEntries.push(this.dslObject[key]['filterEntries'][0]);
+ filterTemplateHeader[key]= {}
+ filterTemplateHeader[key]=this.dslObject[key]['filterTemplateHeader'][key];
+ if(!errorOccurred){
+ errorOccurred=this.dslObject[key]['errorOccurred'];
+ }
+ });
+ let filterEntriesList=[];
+ let filterTemplateHeaderList=[];
+ let filterTemplateErrorList=[];
+ let nodeTypeOfDslTemplateList=[];
+ let templateQueryList=[];
+ let valueList=[];
+ if(idx === 0){
+ this.setState({ valueList: [],
+ templateQueryList: [],
+ filterTemplateEntriesList: [],
+ filterTemplateHeaderList:[],
+ filterTemplateErrorList: [],
+ nodeTypeOfDslTemplateList:[]
+ });
+ }
+ filterEntriesList.push(filterEntries);
+ filterTemplateHeaderList.push(filterTemplateHeader);
+ filterTemplateErrorList.push(errorOccurred);
+ nodeTypeOfDslTemplateList.push(this.nodeTypeArray);
+ templateQueryList.push(query);
+ valueList.push(dsl);
+ this.dslObjectList.push(this.dslObject);
+ this.setState({ valueList: valueList,
+ templateQueryList: templateQueryList,
+ filterTemplateEntriesList: filterEntriesList,
+ filterTemplateHeaderList:filterTemplateHeaderList,
+ filterTemplateErrorList: filterTemplateErrorList,
+ nodeTypeOfDslTemplateList:nodeTypeOfDslTemplateList,
+ isInitialLoad:false
+ },()=>{GeneralCommonFunctions.scrollTo('templateList');});
+
+ }
+ formTemplateQuery=(flow,idx,state)=>{
+ let query='';
+ let count = 0;
+ let tempDslQueryArr=(idx !== undefined && !state)?this.tempDslQueryList[idx].split('#'):this.tempDslQuery.split('#');
+ let newCustomQuery=(idx !== undefined && !state)?this.dslObjectList[idx]:this.dslObject;
+ Object.keys(newCustomQuery).map((key)=>{
+ query='';
+ let newDslObject=newCustomQuery[key][0];
+ let filterValues='';
+ if(newDslObject){
+ //console.log('this>>>>>>>>>>>>>>>>>>>>>>',this);
+ if(flow==='savedQuery'){
+ //reformed the DSL Object with Filter Entries and Template Entries
+ this.formTemplateFilterValues(newDslObject['values'],newDslObject['nodeName'],key,idx);
+ let entries=[];
+ if(newCustomQuery[key]['templateEntries']){
+ entries=newCustomQuery[key]['templateEntries'];
+ }else{
+ entries='';
+ }
+ filterValues=(newDslObject['values']) ? this.replaceFilterValues(newDslObject['values'],entries) :'';
+ }else{
+ filterValues=(newDslObject['values'])? this.formFilterValues(newDslObject['values']):'';
+ }
+ query+=newDslObject['nodeName'];
+ if(newDslObject['props']){
+ query+=newDslObject['props'];
+ }
+ if(newDslObject['values']){
+ query+=filterValues;
+ }
+ tempDslQueryArr[count]=tempDslQueryArr[count]+query;
+ count++;
+ }
+ });
+ query=tempDslQueryArr.join('');
+ return query;
+ }
+ contructDslNodes=(dsl,type,groupStart,groupEnd,edgeStart,edgeEnd)=>{
+ console.log(type+'contructDslNodes>>>>>>>>>>>>>>',dsl);
+ dsl=dsl.replace(/\s*\,\s*/g, ',')
+ var declareEdgePattern=/\(\>(?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)|\!\(\>(?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/g;
+ let localEdges=dsl.match(declareEdgePattern);
+ let edgesDsl=dsl;
+ if(localEdges){
+ this.edgesArray=localEdges.concat(this.edgesArray);
+ edgesDsl=dsl.replace(declareEdgePattern,'>@$');
+ edgesDsl=edgesDsl.replace(/\!\>\@\$/g,'>!@$');
+ }
+ //capturing relations group b/w [] Parent only
+ let relations=this.capturingGroups(edgesDsl);
+ if(relations){
+ this.relationsArray=relations.concat(this.relationsArray);
+ for(var z in relations){
+ edgesDsl=edgesDsl.replace(relations[z],'#$');
+ }
+ }
+ //console.log('edgesDsl to padd getDslNodes>>>>>',edgesDsl);
+ this.getDslNodes(edgesDsl,type,groupStart,groupEnd,edgeStart,edgeEnd);
+}
+
+ getDslNodes=(dsl,type,groupStart,groupEnd,edgeStart,edgeEnd)=>{
+ console.log('getDslNodes>>>>',dsl);
+ let dslArray=[];
+ let localDslNodes='';
+ let relations=false;
+ let edges=false;
+ let traversal=false;
+ dslArray = dsl.split('>');
+ if(type === 'relationalNode'){
+ traversal=(dsl.indexOf('#$') === -1 && dslArray.length>1 && dsl.indexOf('@$') === -1);
+ }
+ for(var i=0;i<dslArray.length;i++){
+ if(dslArray[i] !== ''){
+ if(dslArray[i] === '#$'){//RelationalNode
+ //relations to be enables
+ localDslNodes=this.relationsArray[0];
+ console.log(dslArray[i]+'<<<dslArray[i] localDslNodes>>>>>>>****>>>>',localDslNodes);
+ localDslNodes=this.stripLastCharacter(this.stripFirstCharacter(localDslNodes));
+ type='relationalNode';
+ this.relationsArray=this.relationsArray.slice(1,this.relationsArray.length);
+ this.getDslRelationalNodes(localDslNodes,type);
+ }else if(dslArray[i].trim() === '@$' || dslArray[i].trim() === '!@$'){//EdgeNode
+ //edges should be enable
+ localDslNodes=this.edgesArray[0];
+ type='edgeNode'
+ localDslNodes=this.stripLastCharacter(localDslNodes);
+ if(localDslNodes.startsWith('!')){
+ localDslNodes=localDslNodes.substr(3);
+ type='negEdgeNode';
+ }else{
+ localDslNodes=localDslNodes.substr(2);
+ type='edgeNode';
+ }
+ this.edgesArray=this.edgesArray.slice(1,this.edgesArray.length);
+ this.getDslEdgeNodes(localDslNodes,type);
+ }
+ //node,traversal,relationalEdges
+ let x=i+1;
+ if(dslArray[x] && dslArray[x] === '#$'){
+ relations=true;
+ }
+ if(dslArray[x] && dslArray[x] === '@$'){
+ edges=true;
+ }
+ let tStart=(parseInt(i) === 0 && traversal)?true:false;
+ let tEnd=(parseInt(i) === dslArray.length-1 && traversal)?true:false;
+ if(i === dslArray.length-1){
+ if(type==='edgeNode' || type === 'negEdgeNode'){
+ edgeEnd=true;
+ edgeStart=(dslArray.length===1)?true:false;
+ groupStart=false;
+ groupEnd=false;
+ }else if(type==='relationalNode'){
+ edgeEnd=false;
+ edgeStart=false;
+ }else{
+ groupStart=false;
+ groupEnd=false;
+ edgeEnd=false;
+ edgeStart=false;
+ }
+ }
+ if(!(dslArray[i] === '#$' || dslArray[i].trim() === '@$' || dslArray[i].trim() === '!@$')){
+ dslArray[i]=dslArray[i].replace(/\,$/g,'').replace(/\]$/g,'').replace(/\>$/g,'').trim();
+ this.formDslObject(dslArray[i],type,groupStart,groupEnd,relations,traversal,tStart,tEnd,edges,edgeStart,edgeEnd);
+ }
+ }
+ }
+ console.log('<<formDslObject>>>>>',JSON.stringify(this.dslObject));
+}
+getDslEdgeNodes=(edgesDsl,type)=>{
+ //space for future changes
+ this.contructDslNodes(edgesDsl,type,false,false,true,false);
+}
+getDslRelationalNodes=(relationDsl,type)=>{
+ console.log('getDslRelationalNodes>>>>>>>>>>>>',relationDsl)
+ //var dslRelationNodes=relationDsl.substring(relationDsl.indexOf('['),relationDsl.lastIndexOf(']')+1);
+ let dslRelationNodes=this.capturingGroups(relationDsl);
+ let dslRelations= relationDsl;
+ if(dslRelationNodes){
+ for(var z in dslRelationNodes){
+ dslRelations=dslRelations.replace(dslRelationNodes[z],'#$');
+ }
+ this.relationsArray=dslRelationNodes.concat(this.relationsArray);
+ }
+ let relationsList=dslRelations.replace(/\((?:[^)(]+|\((?:[^)(]+)\))*\)/g,'').replace(/\{(.*?)\}/g,'').trim('').replace(/\>\#\$/g,'').replace(/\>\@\$/g,'').replace(/\>\!\@\$/g,'').replace(/\!/g,'').split(',');
+ dslRelations=','+dslRelations+'&&';
+ let groupStart=false;
+ let groupEnd=false;
+ //relationsList: have all Relations like node [node1>#$,node2,node3>node4]: possible to contain EdgeNodes,Traversal condition and inner relationNodes
+ for(var k in relationsList){
+ console.log(k+'relationsList>>>>**',relationsList);
+ if(parseInt(k)===0){
+ groupStart=true;
+ groupEnd=false;
+ }else if(parseInt(k) === relationsList.length-1){
+ groupStart=false;
+ groupEnd=true;
+ }else{
+ groupStart=false;
+ groupEnd=false;
+ }
+ if(relationsList.length === 1){
+ groupStart=true;
+ groupEnd=true;
+ }
+ var relationPattern='';
+
+ console.log('dslRelations>>>>>>>>>>>>',dslRelations);
+ let pattern=relationsList[k]+"(.*?)>\\#\\$(?=\\,|\\&&)|"+relationsList[k]+"(.*?)>\\@\\$(?=\\,|\\&&)|"+relationsList[k]+"(.*?)>\\!\\@\\$(?=\\,|\\&&)";
+ console.log('pattern>>>>>',pattern);
+ let relationP1 = new RegExp(pattern, 'g');
+ let findDslRelation=dslRelations.match(relationP1);
+ console.log('findDslRelation>>>>>>',findDslRelation);
+ if(findDslRelation){//dslRelations.indexOf(relationsList[k]+'>#') !==-1 || dslRelations.indexOf(relationsList[k]+'>@$') !==-1){
+ relationPattern="(?:[^-]"+relationsList[k].split('>')[0]+"(.*?)(?=\,[a-z]|&&))|"+"(?:[^-]"+relationsList[k].split('>')[0]+"(?=\,[a-z]|&&))";
+ }else if(dslRelations.indexOf(relationsList[k]+',#') !== -1){
+ relationPattern="(?:[^-]"+relationsList[k]+"(.*?)(?=\,#))|"+"(?:[^-]"+relationsList[k]+"(?=\,#))";
+ }else if(relationsList[k] !== '#$'){
+ relationPattern="(?:[^-|^>]"+relationsList[k]+"(.*?)(?=\,[a-z]|>|&&))|"+"(?:[^-|^>]"+relationsList[k]+"(?=\,[a-z]|>|&&))";
+ }
+ if(relationsList[k] !== '#$'){
+ console.log(k+'for relationPattern>>>',relationPattern);
+ console.log(k+'for dslRelations>>>>',dslRelations);
+ let relationPatternExp = new RegExp(relationPattern, 'g');
+ let dslRelationArray=dslRelations.match(relationPatternExp);
+ console.log(k+'for dslRelationArray>>>>',dslRelationArray);
+ if(dslRelationArray){
+ for(var j in dslRelationArray){
+ console.log('dslRelationArray[j]>>>',dslRelationArray[j]);
+ let dslRelationNode=null;
+ dslRelationArray[j]= dslRelationArray[j].substr(1);
+ dslRelations=dslRelations.replace(dslRelationArray[j],'@');
+ console.log('groupStart>>>>>>>>>>',groupStart);
+ this.contructDslNodes(dslRelationArray[j],type,groupStart,groupEnd);
+ }
+ }else{
+ var relationPatternArray=relationsList[k].split('>');
+ relationPattern='';
+ for(var x=0;x<relationPatternArray.length;x++){
+ if(x === 0){
+ relationPattern=relationPatternArray[x]+'(.*?)';
+ }else{
+ relationPattern=relationPattern+'>'+relationPatternArray[x]+'(.*?)';
+ if(x===relationPatternArray.length-1){
+ relationPattern=relationPattern+'(?=\,[a-z]|&&)';
+ }
+ }
+ }
+ console.log('relationPattern>>>>>>',relationPattern);
+ relationPatternExp = new RegExp(relationPattern, 'g');
+ dslRelationArray=dslRelations.match(relationPatternExp);
+ if(dslRelationArray){
+ dslRelations=dslRelations.replace(dslRelationArray[0],'@');
+ console.log('dslRelationArray!!!!!!!!!!!!!>>>>>',dslRelationArray);
+ this.contructDslNodes(dslRelationArray[0],type,groupStart,groupEnd);
+ }
+ }
+ }else{
+ let localDslNodes=this.relationsArray[0];
+ relationsList[k]=this.stripLastCharacter(this.stripFirstCharacter(localDslNodes));
+ this.relationsArray=this.relationsArray.slice(1,this.relationsArray.length);
+ console.log('relationsList[k]>***>>>',relationsList[k]);
+ //dslRelations=dslRelations.replace(dslRelationArray[j],'@');
+ this.contructDslNodes(relationsList[k],type,groupStart,groupEnd);
+
+ }
+ }
+}
+formDslObject=(dslArray,type,groupStart,groupEnd,relationState,traversal,tStart,tEnd,edges,eStart,eEnd,id)=>{
+ let nodeType=dslArray.replace(/\((?:[^)(]+|\((?:[^)(]+)\))*\)/g,'').replace(/\{(.*?)\}/g,'').replace(/\!/g,'').trim('');
+ let props=dslArray.match(/\{(.*?)\}/g);
+ let propValues=dslArray.match(/\((?:[^)(]+|\((?:[^)(]+)\))*\)|\!\((?:[^)(]+|\((?:[^)(]+)\))*\)/g);
+ var entries=[]
+ var entry = {};
+ entry.type = type;
+ entry.relationsStart = groupStart;
+ entry.relationsEnd= groupEnd;
+ entry.relations=relationState;
+ entry.nodeName = nodeType;
+ entry.props=props;
+ entry.traversal=traversal;
+ entry.traversalStart=tStart;
+ entry.traversalEnd=tEnd;
+ entry.edgeEnable=(edges)?edges:false;
+ entry.edgeStart=(eStart)?eStart:false;
+ entry.edgeEnd=(eEnd)?eEnd:false;
+ entry.values=propValues;
+ entries.push(entry);
+ let entityId=nodeType.replace(/\*/g,'');
+ if(!this.nodeTypeArray.includes(entityId)){
+ this.nodeTypeArray.push(entityId);
+ this.dslObject[entityId] = entries;
+ }else{
+ let newNodeType='';
+ let repeatMode=true;
+ for(var n=1;n<=this.nodeTypeArray.length;n++){
+ if(!this.nodeTypeArray.includes(entityId+'-'+n) && repeatMode){
+ newNodeType=entityId+'-'+n;
+ repeatMode=false;
+ }
+ }
+ this.nodeTypeArray.push(newNodeType);
+ this.dslObject[newNodeType] = entries;
+ }
+ console.log('nodeTypeArray>>>>',this.nodeTypeArray);
+ console.log('this.dslObject>>>>',this.dslObject);
+}
+formFilterValues=(propValues)=>{
+ let templateQuery='';
+ let negQuery='';
+ for(var k = 0; k < propValues.length; k++){
+ if(propValues[k].indexOf('!') !== -1){
+ negQuery += propValues[k];
+ }else{
+ templateQuery += propValues[k];
+ }
+ }
+ if(negQuery!==''){
+ templateQuery+=negQuery;
+ }
+ console.log('templateQuery>>>>>>>>>>>>',templateQuery);
+ return templateQuery;
+}
+replaceFilterValues=(propValues,entries)=>{
+ console.log(propValues+'<<<propValues>>>>>',entries);
+ let templateQuery='';
+ let negQuery='';
+ let count=1;
+ for(var k = 0; k < propValues.length; k++){
+ let templatekey=(entries)?entries[k].templateKey+1:count;
+ if(propValues[k].indexOf('!') !== -1){
+ negQuery += "!($" + templatekey + ")";
+ }else{
+ templateQuery += "($" + templatekey + ")";
+ }
+ count++;
+ }
+ if(negQuery!==''){
+ templateQuery+=negQuery;
+ }
+ console.log('templateQuery>>>>>>>>>>>>',templateQuery);
+ return templateQuery;
+}
+formTemplateFilterValues=(propvalues,nodeName,nodeId,idx)=>{
+ let filterTemplateHeader = {};
+ let filterEntries=[];
+ var spaceRemoverPattern=/\,\s/g;
+ var errorOccurred = false;
+ var filterTypeDisplayArray = this.state.filterTypeDisplayList;
+ let filterTypeDisplay= {'default':'Filter Type'};
+ if(!filterTypeDisplayArray[idx] || filterTypeDisplayArray[idx] === undefined){
+ filterTypeDisplayArray.push(filterTypeDisplay);
+ }
+ var entries = [];
+ var filterTypeEntries =[];
+ var selectedProp=[];
+ if(propvalues){
+ for(var i = 0; i < propvalues.length; i++){
+ console.log('propvalues['+i+']>>>>',propvalues[i]);
+ var entry = {};
+ let propVal = '';
+ if(propvalues[i].indexOf('!') !==-1){
+ propVal=this.stripLastCharacter(this.stripFirstTwoCharacter(propvalues[i].trim()));
+ }else{
+ propVal=this.stripLastCharacter(this.stripFirstCharacter(propvalues[i].trim()));
+ }
+ propVal = propVal.replace(spaceRemoverPattern,',');
+ //console.log('propVal>>>>>>>>>>>',propVal);
+ var matchesList = propVal.split(/',|\),/g)
+ //console.log('matchesList>>>>',matchesList);
+ let type='';
+ let value='';
+ let errorFound=true;
+ let entryState=true;
+ for(var n=0;n<matchesList.length;n++){
+ let scenario=true;
+ let found=true;
+ if(n==0){
+ entry.name = this.stripFirstCharacter(matchesList[n].trim());
+ selectedProp.push(this.stripFirstCharacter(matchesList[n].trim()));
+ }else{
+ let obj={};
+ var lastChar=matchesList[n].charAt(matchesList[n].length-1);
+ for(var x in filterTypeList){
+ if(found){
+ let pattern= new RegExp('^'+filterTypeList[x]+'\\((.*?)', 'g');
+ var filterExist=matchesList[n].match(pattern);
+ //console.log(matchesList[n]+'filterExist>>>>>',filterExist);
+ if(filterExist){
+ var nodevalue='';
+ if(lastChar===')'){
+ nodevalue=matchesList[n].replace(filterTypeList[x],'').replace(/\(\'/,'').replace(/\'\)/,'');
+ }else{
+ nodevalue=this.stripLastCharacter(matchesList[n].replace(filterTypeList[x],'').replace(/\(\'/,''));
+ }
+ //console.log('before srtip>>>',nodevalue);
+ type=(type==='')?filterTypeList[x]:type+'^'+filterTypeList[x];
+ value=(value==='')?nodevalue:value+'^'+nodevalue;
+ scenario=false;
+ found=false;
+ errorFound=false;
+ entryState=false;
+ obj[entry.templateKey+1] = filterTypeList[x];
+ filterTypeEntries.push(obj);
+ console.log('filterTypeDisplayArray....>*',filterTypeEntries);
+ }
+ }
+ console.log(found+'found>>>>>>>>>>>>',value);
+ }
+ if(scenario){
+ console.log('inside else');
+ type=(type==='')?'EQ':type+'^'+'EQ';
+ let val=this.stripFirstCharacter(matchesList[n].trim());
+ if(lastChar == '\''){
+ val=this.stripLastCharacter(val);
+ }
+ value=(value==='')?val:value+'^'+val;
+ entryState=false;
+ found=false;
+ errorFound=false;
+ }
+ }
+ }
+ if(!entryState){
+ entry.type =type;
+ entry.value = value;
+ entry.templateKey = i;
+ entries.push(entry);
+ }
+ if(errorFound && !errorOccurred){
+ errorOccurred=true;
+ }
+ }
+ }
+ console.log('Initial Filtered Template Entries ' + JSON.stringify(entries));
+ //nodeTypeOfDsl.push(nodeTypes[z]);
+ let obj = {};
+ obj[nodeId] = entries;
+ filterTemplateHeader[nodeId]= {};
+ filterTemplateHeader[nodeId]['enableAnd'] = true;
+ filterTemplateHeader[nodeId]['propName'] = this.state.filterDisplay;
+ filterTemplateHeader[nodeId]['selectedProp']=selectedProp;
+ filterEntries.push(obj)
+ filterTypeDisplayArray[idx][nodeId] = filterTypeEntries;
+ let dslObject=this.dslObjectList[idx];
+ if(dslObject){
+ dslObject[nodeId]['filterTemplateHeader']= filterTemplateHeader;
+ dslObject[nodeId]['filterEntries']=filterEntries;
+ dslObject[nodeId]['errorOccurred']=errorOccurred;
+ this.dslObjectList[idx]=dslObject;
+ }else{
+ this.dslObject[nodeId]['filterTemplateHeader']= filterTemplateHeader;
+ this.dslObject[nodeId]['filterEntries']=filterEntries
+ this.dslObject[nodeId]['errorOccurred']=errorOccurred;
+ }
+ }
+
+ onAssociatedNodesCheckbox(e) {
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ }else {
+ cbValue = false;
+ }
+ this.setState({ associatedNodesEnabled: cbValue });
+ }
+ onAggregateCheckbox(e) {
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ this.setState({associatedNodesEnabled: false});
+ }else {
+ cbValue = false;
+ }
+ this.setState({ isAggregateChecked: cbValue });
+ }
+ onPublicCheckbox(e) {
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ this.setState({ isPublicChecked: cbValue, isCommunitySharedChecked: false });
+ }else {
+ cbValue = false;
+ this.setState({ isPublicChecked: cbValue });
+ }
+ }
+ onMergedTabsCheckbox(e){
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ this.setState({ isMergedTabsChecked: cbValue});
+ }else {
+ cbValue = false;
+ this.setState({ isMergedTabsChecked: cbValue });
+ }
+ }
+ onGenerateEmailButton(){
+ let path='email-bulk-dsl-to-excel';
+ this.generatebulkDslToExcel(path,true);
+ }
+ onCommunitySharedCheckbox(e) {
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ }else {
+ cbValue = false;
+ }
+ this.setState({ isCommunitySharedChecked: cbValue });
+ }
+ onDslConfigCheckbox(e, key) {
+ var cbValue = false;
+ var staticTemplateFilters = this.state.staticTemplateFilters;
+ if (e.target.checked) {
+ cbValue = true;
+ staticTemplateFilters = staticTemplateFilters.filter(e => e !== key);
+ }else {
+ cbValue = false;
+ staticTemplateFilters.push(key);
+ }
+ this.setState({ staticTemplateFilters: staticTemplateFilters });
+ }
+ handleOnFilter = (columnFilter,value) =>{
+ console.log('handleOnFilter to Re-render', this.state.columnFilter);
+ var applyState = true;
+ if(value === ''){
+ for(var i= 0; i < columnFilter.length; i++){
+ var x = columnFilter[i];
+ console.log('handleOnfilter ColumnFilterList.....',Object.keys(x));
+ Object.keys(x).forEach(function(key){
+ if(x[key] !==''){
+ applyState=false;
+ }
+ });
+ }
+ }else{
+ applyState = false;
+ }
+
+ this.setState({columnFilter : columnFilter,reRender:true,disableFilter: applyState});
+ }
+
+ alterDslQueryByRemoveSpaces = (dslQuery) =>{
+ var p2='';
+ if((dslQuery.indexOf('(>') !==-1) || (dslQuery.indexOf('!(>') !==-1)){
+ p2=/\((?:[^>)(]|\((?:[^)(]+)\))*\)/g;
+ }
+ else{
+ p2 = /\((?:[^)(]+|\((?:[^)(]+)\))*\)/g;
+ }
+ var prop = dslQuery.match(p2);
+ var spacepattern = /\s(?!(^)]*\()/g;
+ var newDslQuery='';
+ if(prop && prop.length > 0){
+ var x = dslQuery.replace(p2,'{*$}');
+ var matchStr = x.replace(spacepattern,'');
+ var propArray=matchStr.split('{*$}');
+ for(var i in prop){
+ newDslQuery=newDslQuery+propArray[i]+prop[i];
+ }
+ newDslQuery = newDslQuery + propArray[propArray.length-1];
+ }else{
+ newDslQuery = dslQuery.replace(spacepattern,'');
+ }
+ newDslQuery = newDslQuery.trim();
+ console.log('New DSl Query after alterDslQueryByRemoveSpaces>>>>>>',newDslQuery);
+ return newDslQuery;
+ }
+
+ isTableFilterForAggregation = (columnFilterList,columnsList) => {
+ console.log('isTableFilterForAggregation:aggregateTableFilterColumns>>>>>>',this.state.aggregateTableFilterColumns);
+ //console.log('isTableFilterForAggregation:columnFilterList>>>>>>>>',columnFilterList);
+ var nodeTypeArray = [];
+ var columnsList = {};
+ var filterMessage = {};
+ var j = 0;
+ for(var i= 0; i < columnFilterList.length; i++){
+ var x = columnFilterList[i];
+ console.log('isTableFilterForAggregation:Aggregate columnFilterList.....',Object.keys(x));
+ var propValue = '';
+ Object.keys(x).forEach((key)=>{
+ var grabNode = key.split("|");
+ let indx=false;
+ let index='';
+ if(nodeTypeArray.indexOf(grabNode[0]) === -1){
+ nodeTypeArray.push(grabNode[0]);
+ j = j + 1;
+ indx=true;
+ index=j-1;
+ }else{
+ index=nodeTypeArray.indexOf(grabNode[0]);
+ }
+
+ if(!columnsList[nodeTypeArray[index]]){
+ columnsList[nodeTypeArray[index]] = [];
+ }
+ if(!filterMessage[nodeTypeArray[index]]){
+ filterMessage[nodeTypeArray[index]]=[];
+ }
+ let col='';
+ if(this.tableFilterAliasColumns[grabNode[0]][0] && this.tableFilterAliasColumns[grabNode[0]][0][grabNode[1]]){
+ col=this.tableFilterAliasColumns[grabNode[0]][0][grabNode[1]];
+ }else{
+ col=grabNode[1];
+ }
+ if(columnsList[nodeTypeArray[index]].indexOf(col) === -1){
+ columnsList[nodeTypeArray[index]].push(col);
+ if(x[key] != ''){
+ let filterMsg = '';
+ if(this.state.enableRealTime){
+ filterMsg='(\''+col +'\'' + ',' + TABULAR_FILTER_TYPE+'(\'' + x[key]+ '\'))';
+ }else{
+ filterMsg='(\''+col +'\'' + ',' + '\'' + x[key] + '\')';
+ }
+ filterMessage[nodeTypeArray[j-1]].push(filterMsg);
+ }
+ }
+ propValue=x[key];
+ });
+ }
+ console.log('isTableFilterForAggregation:nodeTypeArray><><><>',nodeTypeArray);
+ console.log('isTableFilterForAggregation:columnsList<><><>',columnsList);
+ console.log('isTableFilterForAggregation:filterMessage>>>>>>>>',filterMessage);
+ let dslQuery = this.state.value;
+ var limitPattern = /limit[\s]\d+|limit\d+/ig
+ var limitkey = dslQuery.match(limitPattern);
+ if(limitkey){
+ dslQuery = dslQuery.replace(limitkey[limitkey.length-1],'').trim();
+ }
+ dslQuery = this.alterDslQueryByRemoveSpaces(dslQuery);
+ //New adding
+ this.dslObject={};
+ this.nodeTypeArray=[];
+ //create placeholders for NodeTypes with Propand Propvalues
+ this.tempDslQuery=this.formTempDslQuery(dslQuery);
+ //Preparing Json Object to render into Placeholder
+ this.contructDslNodes(dslQuery,'node',false,false,false,false);
+ console.log('dslQuerydsl>>>>>>>>>>>>>',dslQuery);
+ //adding
+ Object.keys(this.dslObject).map((nodekey)=>{
+ let nodeNo=parseInt(nodekey.substr(nodekey.length-2,nodekey.length-1).replace(/\-/g,''));
+ console.log('nodeNo>>>>>>>>>>>>>>',nodeNo);
+ let keyact=isNaN(nodeNo);
+ let nodeType=nodekey;
+ let actKey=nodekey.split('-');
+ console.log(nodeType+'>>>>nodeType<<<<nodeType>>>>',actKey);
+ if(!keyact){
+ actKey.splice(actKey.length-1,1);
+ nodeType=actKey.join('-')+nodeNo;
+ }
+ if(!nodeTypeArray.includes(nodeType) && nodeTypeArray.includes(actKey.join('-'))){
+ nodeType=actKey.join('-');
+ }
+ console.log('nodeType>>>>>>>>>>',nodeType);
+ var columns = columnsList[nodeType];
+ var filterMsg= filterMessage[nodeType];
+ console.log('CustomDsl js filterMsg:',filterMsg);
+ if(nodeType && this.dslObject[nodekey][0]){
+ if(filterMsg && filterMsg.length>0){
+ for(var i=0;i<filterMsg.length;i++){
+ let values=this.dslObject[nodekey][0]['values'];
+ let nonExist=true
+ let columnCompare=filterMsg[i].split(',')[0];
+ if(values && values.length>0){
+ for(var n=0;n<values.length;n++){
+ console.log('values[n].indexOf(columnCompare)>>>>',values[n].indexOf(columnCompare));
+ if(values[n].indexOf(columnCompare) !==-1 && values[n].indexOf('!'+columnCompare) ===-1){
+ values[n]=filterMsg[i];
+ nonExist=false;
+ }
+ }
+ if(nonExist){
+ this.dslObject[nodekey][0]['values'].push(filterMsg[i]);
+ }else{
+ this.dslObject[nodekey][0]['values']=values;
+ }
+ }else{
+ this.dslObject[nodekey][0]['values']=[];
+ this.dslObject[nodekey][0]['values'].push(filterMsg[i]);
+ }
+ }
+ }
+ }
+ });
+ this.dslObjectList =[];
+ this.dslObjectList.push(this.dslObject);
+ //Query to replace placeholders with JSON Object values depends on Flow either SavedQuery or TableFilters
+ let newDslQuery=this.formTemplateQuery('tableFilter');
+ newDslQuery=newDslQuery.replace(/\'(as)\'/g,'\' as \'').replace(/\(\'\s(as)\s\'\)/g,'(\'as\')');
+ if(limitkey){
+ newDslQuery+=' '+limitkey[limitkey.length-1];
+ }
+ console.log('query>>>>>>>>>>>>>>>>>>>>>****',newDslQuery);
+ this.setState({value : newDslQuery, viewName: "CellLayout", aggregateActivePage:1}, function () { this.formQueryString(false,false,false); }.bind(this));
+ //End
+ }
+
+ isTableFilterApply = (columnFilterList,nodeTypeList,columnsList,aliasColumnList) => {
+ console.log('CustomDSL js ....columnFilterList:',columnFilterList);
+ console.log('CustomDSL js .... nodeTypeList:',nodeTypeList);
+ var nodeTypeListArray = [];
+ if(!Array.isArray(nodeTypeList)){
+ nodeTypeListArray.push(nodeTypeList);
+ nodeTypeList = nodeTypeListArray;
+ }
+ console.log('CustomDSL js .... nodeTypeList After set:',nodeTypeList);
+ var dslQuery = this.state.value;
+ var limitPattern = /limit[\s]\d+|limit\d+/ig
+ var limitkey = dslQuery.match(limitPattern);
+ if(limitkey){
+ dslQuery = dslQuery.replace(limitkey[limitkey.length-1],'').trim();
+ }
+ dslQuery = this.alterDslQueryByRemoveSpaces(dslQuery);
+ //New adding
+ this.dslObject={};
+ this.nodeTypeArray=[];
+ //create placeholders for NodeTypes with Propand Propvalues
+ this.tempDslQuery=this.formTempDslQuery(dslQuery);
+ //Preparinga Json Object to render into Placeholder
+ this.contructDslNodes(dslQuery,'node',false,false,false,false);
+ console.log('dslQuerydsl>>>>>>>>>>>>>',dslQuery);
+ //adding
+ Object.keys(this.dslObject).map((nodekey)=>{
+ var nodeType=this.dslObject[nodekey][0]['nodeName'].replace(/\*/g,'');
+ console.log('nodeType>>>>>>>>>>',nodeType);
+ var columnFilter = (columnFilterList[nodeType])?columnFilterList[nodeType][0]:[];
+ var aliasColumnFilters = (aliasColumnList[nodeType])?aliasColumnList[nodeType][0]:[];
+ console.log('CustomDsl js columnFilter:',columnFilter);
+ var columns = columnsList[nodeType];
+ console.log('CustomDsl js Columns:',columns);
+ if(columns && columnFilter.length>0){
+ for(var i=0;i<columns.length;i++){
+ console.log(columnFilter[i]+'<<<<<<columnFilter[i]columns[i].value>>>>',columns[i]);
+ var colAliasFilter='';
+ for(var z=0;z<aliasColumnFilters.length;z++){
+ if(aliasColumnFilters[z][columns[i].value]){
+ colAliasFilter=aliasColumnFilters[z][columns[i].value];
+ }
+ }
+ var colFilterValue = columnFilter[i][columns[i].value];
+ if(colFilterValue != ""){
+ let filterMsg = '';
+ let col=(colAliasFilter)?colAliasFilter:columns[i].value;
+ if(this.state.enableRealTime){
+ filterMsg='(\''+col +'\'' + ',' + TABULAR_FILTER_TYPE+'(\'' + colFilterValue + '\'))';
+ }else{
+ filterMsg='(\''+col +'\'' + ',' +'\'' + colFilterValue + '\')';
+ }
+ let values=this.dslObject[nodekey][0]['values'];
+ let nonExist=true;
+ if(values && values.length>0){
+ for(var n=0;n<values.length;n++){
+ if(values[n].indexOf('(\''+col+'\'') !==-1 && values[n].indexOf('!(\''+col+'\'') ===-1){
+ values[n]=filterMsg;
+ nonExist=false;
+ }
+ }
+ if(nonExist){
+ this.dslObject[nodekey][0]['values'].push(filterMsg);
+ }else{
+ this.dslObject[nodekey][0]['values']=values;
+ }
+ }else{
+ this.dslObject[nodekey][0]['values']=[];
+ this.dslObject[nodekey][0]['values'].push(filterMsg);
+ }
+ }
+ }
+ }
+ });
+ //Query to replace placeholders with JSON Object values depends on Flow either SavedQuery or TableFilters
+ this.dslObjectList =[];
+ this.dslObjectList.push(this.dslObject);
+ let newDslQuery=this.formTemplateQuery('tableFilter');
+ newDslQuery=newDslQuery.replace(/\'(as)\'/g,'\' as \'').replace(/\(\'\s(as)\s\'\)/g,'(\'as\')');
+ if(limitkey){
+ newDslQuery+=' '+limitkey[limitkey.length-1];
+ }
+ console.log('query>>>>>>>>>>>>>>>>>>>>>****',newDslQuery);
+ this.setState({value : newDslQuery, viewName: "CellLayout", activePage:1}, function () { this.formQueryString(false,false,false); }.bind(this));
+ //End
+ }
+
+ onTargetMenuOfFilterTypes = (listName,id) => {
+ console.log('onTargetMenuOfFilterTypes>>>>',listName);
+ let idArray=id.split('#');
+ let key=idArray[0];
+ let templateKey=parseInt(idArray[1]);
+ let filterTypeIndex = parseInt(idArray[2]);
+ let idx= parseInt(idArray[3]);
+ var filterTypeDisplayList = this.state.filterTypeDisplayList;
+ var filterTypeDisplayArray = filterTypeDisplayList[idx];
+ Object.keys(filterTypeDisplayArray).map((entry) => {
+ if(entry === key){
+ console.log('filterTypeDisplayArray.entry....',filterTypeDisplayArray[entry]);
+ if(filterTypeDisplayArray[entry][templateKey]){
+ filterTypeDisplayArray[key][templateKey] = listName;
+ }else{
+ let obj={};
+ obj[templateKey+1]=listName;
+ filterTypeDisplayArray[key].push(obj);
+ }
+ }
+ });
+ let filterTemplateEntriesList = this.state.filterTemplateEntriesList;
+ var filterTemplateEntriesArray = filterTemplateEntriesList[idx];
+ Object.keys(filterTemplateEntriesArray).map((entry)=>{
+ if(filterTemplateEntriesArray[entry][key]){
+ Object.keys(filterTemplateEntriesArray[entry][key]).map((ind) =>{
+ if(filterTemplateEntriesArray[entry][key][ind].templateKey === templateKey){
+ let type=filterTemplateEntriesArray[entry][key][ind].type.split('^');
+ if(type[filterTypeIndex]){
+ type[filterTypeIndex]=listName
+ }else{
+ type.push(listName);
+ }
+ filterTemplateEntriesArray[entry][key][ind].type=type.join('^');
+ }
+ })
+ }
+ });
+ console.log('onTargetMenuOfFilterTypes filterTemplateEntriesArray>>>',filterTemplateEntriesArray);
+ filterTemplateEntriesList[idx]=filterTemplateEntriesArray;
+ filterTypeDisplayList[idx]=filterTypeDisplayArray;
+ this.setState({filterTypeDisplayList:filterTypeDisplayList,filterTemplateEntriesList:filterTemplateEntriesList});
+ }
+ filterTags = (type,templateKey,key,idx) =>{
+ console.log(key+'<<<filterTags>>>>>*',type);
+ let filterType = (type === '')? this.state.filterTypeDisplayList[idx]['default']:type;
+ let filterTag = '';
+ if(APERTURE_SERVICE && this.state.enableRealTime){
+ console.log(filterType+'before passing Filter>*',this.state);
+ let filterTypesArray=filterType.split('^');
+ let filters = Object.keys(filterTypesArray).map((index)=>{
+ return <div style={{margin:'0px 0px 0px 5px'}}>
+ <label>
+ <FilterTypes param={this.state}
+ selectedFilter={filterTypesArray[index]}
+ id={key+'#'+templateKey+'#'+index+'#'+idx}
+ onMenuSelect={this.onTargetMenuOfFilterTypes} />
+ </label>
+ </div>
+ });
+ filterTag=<td width='20%'>{filters}</td>;
+ }
+ return filterTag;
+ }
+ populateFilteredColumnOptions = (nodekey,indx) =>{
+ let keyact=isNaN(parseInt(nodekey.substr(nodekey.length-2,nodekey.length-1)));
+ let actColumns ='';
+ if(keyact){
+ actColumns =this.populateColumnOptions(nodekey);//this.populateColumnOptions(key);
+ }else{
+ let actKey=nodekey.split('-');
+ actKey.splice(actKey.length-1,1);
+ actColumns =this.populateColumnOptions(actKey.join('-'));
+ }
+ let filterTemplateEntries=this.state.filterTemplateEntriesList[indx];
+ let filterTemplateHeader=this.state.filterTemplateHeaderList[indx];
+ let selectedColumns=[];
+ Object.keys(filterTemplateEntries).map((index) => {
+ let filterTemplateEntry = filterTemplateEntries[index];
+ Object.keys(filterTemplateEntry).map((key) =>{
+ let filterTemplateEntryKey=filterTemplateEntry[key];
+ if(nodekey === key){
+ Object.keys(filterTemplateEntryKey).sort().map((entryKey, entry) => {
+ if(filterTemplateEntryKey[entryKey].name !==''){
+ let index=actColumns.indexOf(filterTemplateEntryKey[entryKey].name);
+ actColumns.splice(index,1);
+ selectedColumns.push(filterTemplateEntryKey[entryKey].name);
+ }
+ });
+ filterTemplateHeader[key]['selectedProp']=selectedColumns;
+ }
+ });
+ });
+ return actColumns;
+ };
+ /**AND OR functionality */
+ addAndTemplate = (key,idx) =>{
+ console.log('addAndTemplate:key',key);
+ let templateEntriesList = this.state.filterTemplateEntriesList;
+ let filterTemplateHeaderList= this.state.filterTemplateHeaderList;
+ let templateEntries = this.state.filterTemplateEntriesList[idx];
+ let filterTemplateHeader= this.state.filterTemplateHeaderList[idx];
+ Object.keys(templateEntries).map((index) =>{
+ Object.keys(templateEntries[index]).map((entryKey)=>{
+ if(entryKey === key){
+ let length=templateEntries[index][entryKey].length;
+ let tempKey = (length===0)?length:templateEntries[index][entryKey][length-1].templateKey+1;
+ let obj ={}
+ obj['name']='';
+ obj['value']='';
+ obj['type']=(this.state.enableRealTime)?'EQ':'';
+ obj['templateKey']=tempKey;
+ obj['addition']=true;
+ templateEntries[index][entryKey].push(obj);
+ //templateEntries[index][entryKey]['enableAnd']=false;
+ filterTemplateHeader[key]['enableAnd'] = false;
+ filterTemplateHeader[key]['propName'] = this.state.filterDisplay;
+ }
+ });
+ });
+ templateEntriesList[idx]=templateEntries;
+ filterTemplateHeaderList[idx]=filterTemplateHeader;
+ this.setState({filterTemplateHeaderList:filterTemplateHeaderList,filterTemplateEntriesList:templateEntriesList});
+ }
+ addOrTemplate = (key,name,templateKey,idx) =>{
+ console.log('addOrTemplate: key',key);
+ let templateEntriesList = this.state.filterTemplateEntriesList;
+ let templateEntries = templateEntriesList[idx];
+ Object.keys(templateEntries).map((index) =>{
+ Object.keys(templateEntries[index]).map((entryKey)=>{
+ let templateEntry=templateEntries[index][entryKey];
+ if(entryKey === key){
+ Object.keys(templateEntry).map((entry)=>{
+ if(templateEntry[entry].templateKey === templateKey){
+ let value = templateEntry[entry].value;
+ let type = templateEntry[entry].type;
+ templateEntry[entry].value=value+'^';
+ let fType=(this.state.enableRealTime)?'EQ':'';
+ templateEntry[entry].type=type+'^'+fType;
+ templateEntry[entry].name = name;
+ }
+ })
+ }
+ });
+ });
+ console.log('addOrTemplate templateEntries>>>>',templateEntries);
+ templateEntriesList[idx]=templateEntries;
+ this.setState({filterTemplateEntriesList:templateEntriesList});
+ }
+ deleteOrTemplate = (key,templatekey,id,idx) =>{
+ console.log('deleteOrTemplate');
+ let templateEntriesList = this.state.filterTemplateEntriesList;
+ let templateEntries = templateEntriesList[idx];
+ let delIndx=parseInt(id.split('-')[1]);
+ Object.keys(templateEntries).map((index) =>{
+ if(templateEntries[index][key]){
+ Object.keys(templateEntries[index][key]).map((i)=>{
+ if(templateEntries[index][key][i].templateKey===templatekey){
+ let valueArray = templateEntries[index][key][i].value.split('^');
+ let typeArray = templateEntries[index][key][i].type.split('^');
+ valueArray.splice(delIndx,1);
+ typeArray.splice(delIndx,1)
+ console.log('valueArray>>>>>>',valueArray);
+ templateEntries[index][key][i].value=valueArray.join('^');
+ templateEntries[index][key][i].type=typeArray.join('^');
+ }
+ })
+ }
+ });
+ console.log('deleteOrTemplate templateEntries>>>>',templateEntries);
+ templateEntriesList[idx]=templateEntries;
+ this.setState({filterTemplateEntriesList:templateEntriesList});
+ }
+ updatePropertyFilter = (listName,idkey) =>{
+ console.log('updatePropertyFilter:',listName)
+ let keys=idkey.split('#');
+ let key=keys[0];
+ let idx=parseInt(keys[2]);
+ let templateKey=parseInt(keys[1]);
+ let filterTemplateHeaderList = this.state.filterTemplateHeaderList;
+ let filterTemplateHeader= filterTemplateHeaderList[idx];
+ var filterTemplateEntriesList = this.state.filterTemplateEntriesList;
+ var filterMap = filterTemplateEntriesList[idx];
+ filterTemplateHeader[key]['propName']=listName;
+ //this.setState({filterTemplateHeader:filterTemplateHeader});
+ let status=false;
+ Object.keys(filterMap).forEach((index) =>{
+ if(filterMap[index][key]){
+ Object.keys(filterMap[index][key]).forEach((i)=>{
+ if(filterMap[index][key][i].templateKey === templateKey){
+ if(filterMap[index][key][i].name === 'ERROR'){
+ filterMap[index][key][i].name= listName;
+ let selectedProp=[];
+ console.log('filterTemplateHeader[key][selectedProp]>>>>',filterTemplateHeader[key]['selectedProp']);
+ if(filterTemplateHeader[key]['selectedProp']){
+ selectedProp=filterTemplateHeader[key]['selectedProp'];
+ let indSelect= selectedProp.indexOf(listName);
+ if(indSelect !== -1){
+ selectedProp=selectedProp.splice(indSelect,1);
+ filterTemplateHeader[key]['selectedProp']=selectedProp;
+ }
+ }
+ filterTemplateHeader[key]['enableAnd'] = true;
+ console.log('ERRROOR CONDITION HANDLING!!!!');
+ this.templateErrorList[idx].pop();
+ this.updateSavedQueryTemplate('add',key,templateKey,filterMap,filterTemplateHeader,idx);
+ }else{
+ console.log('Regular Scenario>>>>>');
+ filterTemplateHeaderList[idx]=filterTemplateHeader;
+ this.setState({filterTemplateHeaderList:filterTemplateHeaderList});
+ }
+ }
+ })
+ }
+ });
+ };
+ /** */
+ prepareDownloadRangeModel = () =>{
+ let downloadExcelsFunc= this.getAllExcels;
+ if(this.state.isAggregate){
+ downloadExcelsFunc=this.downloadAllAggregate;
+ }
+ let downloadRangeModel = (this.state.showDownloadResultsModal)? <DownloadRangeModel
+ showDownloadResultsModal={this.state.showDownloadResultsModal}
+ totalPages={this.state.totalPages}
+ totalResults={this.state.totalResults}
+ triggerDownload={downloadExcelsFunc}
+ errorDownloadResults={this.state.errorDownloadResults}
+ downloadErrorMsg={this.state.downloadErrorMsg}
+ triggerClose={this.closeDownloadResults}
+ enableModelBusyFeedback={this.state.enableModelBusyFeedback}
+ /> : '';
+ return downloadRangeModel;
+ }
+ toggleRealTimeAnalysisCallback=(checked)=>{
+ console.log('toggleRealTimeAnalysisCallback>>>>',checked);
+ sessionStorage.setItem(ENVIRONMENT + 'ENABLE_ANALYSIS', !checked);
+ TABULAR_FILTER_TYPE=(APERTURE_SERVICE && !checked)?'CONTAINS':'=';
+ this.baseState.enableRealTime=!checked;
+ this.baseState.header='';
+ this.baseState.templateQuery='';
+ this.baseState.filterTemplateEntries=[];
+ this.baseState.filterTemplateHeader=[];
+ this.baseState.filterTemplateError=false;
+ this.baseState.nodeTypeOfDslTemplate=[];
+ this.baseState.filterTemplateEntriesList=[];
+ this.baseState.filterTemplateHeaderList=[];
+ this.baseState.filterTemplateErrorList=[];
+ this.baseState.nodeTypeOfDslTemplateList=[];
+ this.baseState.templateQueryList=[];
+ this.baseState.valueList=[];
+ this.dslObject={};
+ this.nodeTypeArray=[];
+ this.dslObjectList=[];
+ this.nodeTypeArrayList=[];
+ this.edgesArray=[];
+ this.relationsArray=[];
+ this.tempDslQuery='';
+ this.tempDslQueryList=[];
+ this.templateError=[];
+ this.templateErrorList={};
+ this.setState({...this.baseState},()=>{this.buildDynamicByoq();});
+ }
+ templateheaderSaveQuery = (id)=>{
+ console.log('templateheaderSaveQuery>>>>>>>>>>>>>',id);
+ let templateSavedQuery = '';
+ let entityKeyAddition = 1;
+ let templateheaderSaveQuery = '';
+ let filterTemplateHeaderList = this.state.filterTemplateHeaderList;
+ //templateheaderSaveQuery=Object.keys(this.state.filterTemplateEntriesList).map((id)=>{
+ //let tempheaderSavedQuery=''
+ if(this.state.filterTemplateEntriesList[id].length > 0 && !this.state.filterTemplateErrorList[id]){
+ let filterTemplateEntries=this.state.filterTemplateEntriesList[id];
+ let staticTemplateFilters = this.state.staticTemplateFiltersList[id];
+ templateheaderSaveQuery= <div>
+ {Object.keys(filterTemplateEntries).map((index) => {
+ let filterTemplateEntry = filterTemplateEntries[index];
+ return Object.keys(filterTemplateEntry).map((key) =>{
+ let filterTemplateEntryKey=filterTemplateEntry[key];
+ let columns =this.populateFilteredColumnOptions(key,id);//this.populateColumnOptions(key);
+ return <table className='table table-hover table-striped savedQueryTemplate' style={{margin:'0px',padding:'2px'}} id={'table_'+key}>
+ <thead>
+ <tr>
+ <th colSpan='2'>{key.toUpperCase()}</th>
+ {this.state.enableRealTime && <th width='20%'></th>}
+ <th width={(this.state.enableRealTime)?'30%':'25%'}></th>
+ <th width={(this.state.enableRealTime)?'20%':'25%'}>
+ <button id={key+'_addAND'} className='btn btn-secondary' disabled ={!filterTemplateHeaderList[id][key]['enableAnd']} type='button' onClick={e => {this.addAndTemplate(key,id)}}>Add Filter</button>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ {Object.keys(filterTemplateEntryKey).sort().map((entryKey, entry) => {
+ entityKeyAddition = parseInt(entryKey) + 2;
+ let valueArray = filterTemplateEntryKey[entryKey].value.split('^');
+ console.log("Comparing Static Array: " + JSON.stringify(staticTemplateFilters) + " with " + key + "|" + filterTemplateHeaderList[id][key]['propName']);
+ if(staticTemplateFilters.indexOf(key + "|" + filterTemplateEntryKey[entryKey].name) === -1 ){
+ return(
+ <tr>
+ <td width={(this.state.enableRealTime)?'10%':'25%'}>
+ <label>{'$' + (filterTemplateEntryKey[entryKey].templateKey + 1)}</label>
+ </td>
+ <td width={(this.state.enableRealTime)?'20%':'25%'}>
+ {filterTemplateEntryKey[entryKey].name !== '' && filterTemplateEntryKey[entryKey].name !== 'ERROR' && <label>{filterTemplateEntryKey[entryKey].name}</label>}
+ {filterTemplateEntryKey[entryKey].name === '' && <SelectFilter param={this.state}
+ filterList={columns}
+ id={key+'#'+filterTemplateEntryKey[entryKey].templateKey+'#'+id}
+ selectedFilter={filterTemplateHeaderList[id][key]['propName']}
+ onMenuSelect={this.updatePropertyFilter}/>}
+ {filterTemplateEntryKey[entryKey].name === 'ERROR' && <div className='inputBoxError'><SelectFilter param={this.state}
+ filterList={columns}
+ id={key+'#'+filterTemplateEntryKey[entryKey].templateKey+'#'+id}
+ selectedFilter={this.state.filterDisplay}
+ onMenuSelect={this.updatePropertyFilter}/></div>}
+ </td>
+ {this.filterTags(filterTemplateEntryKey[entryKey].type,filterTemplateEntryKey[entryKey].templateKey,key,id)}
+ <td width={(this.state.enableRealTime)?'30%':'25%'}>
+ {Object.keys(valueArray).map((indx) =>{
+ return(
+ <div style={{margin:'5px'}}>
+ {valueArray[indx] === '' && <input id={key+'_'+indx} onBlur={e => this.updateTemplateFilterValues(key,filterTemplateEntryKey[entryKey].templateKey,e.target.value,e.target.id,id)}/>}
+ {valueArray[indx] !== '' && <input id={key+'_'+valueArray[indx]+'_'+indx} value={valueArray[indx]} onChange={e => this.updateTemplateFilterValues(key,filterTemplateEntryKey[entryKey].templateKey,e.target.value,e.target.id,id)}/>}
+ {indx == 0 && <button className={(filterTemplateEntryKey[entryKey].name !== '')?'btn btn-primary':'btn btn-secondary'} style={{padding:'2px',margin:'0px 0px 7px 5px'}} disabled={filterTemplateEntryKey[entryKey].name === ''} type='button' onClick={e => {this.addOrTemplate(key,filterTemplateEntryKey[entryKey].name,filterTemplateEntryKey[entryKey].templateKey,id)}}>+</button>}
+ {indx>0 && <button style={{padding:'2px',margin:'0px 0px 7px 5px'}} id={'delete-'+indx} className='btn btn-danger' type='button' onClick={e => {this.deleteOrTemplate(key,filterTemplateEntryKey[entryKey].templateKey,e.target.id,id)}}>x</button> }
+ </div>
+ )
+ })}
+ </td>
+ <td width={(this.state.enableRealTime)?'20%':'25%'}>
+ {filterTemplateEntryKey[entryKey].addition &&<button id='deleteAnd' className='btn btn-secondary' type='button' onClick={e => {this.updateSavedQueryTemplate('delete',key,filterTemplateEntryKey[entryKey].templateKey,'','',id)}}>Delete</button>}
+ </td>
+ </tr>);
+ }else {
+ return;
+ }
+ })}
+ </tbody>
+ </table>
+ })
+ })}
+ </div>
+ }
+ return templateheaderSaveQuery;
+ };
+ downloadBulkDslToExcel = () =>{
+ console.log('downloadBulkDslToExcel>>>>>>>>>>>');
+ let path='bulk-dsl-to-excel';
+ this.generatebulkDslToExcel(path,false)
+ }
+ generatebulkDslToExcel = (path,state) =>{
+ this.setState({isLoading: true});
+ Object.keys(settings).forEach((key)=>{
+ if(key==='ISAPERTURE' || key==='ISTABULAR'){
+ delete settings[key];
+ }
+ })
+ let mergedTabs=this.state.isMergedTabsChecked;
+ var payload = {'headers':{
+ 'X-DslApiVersion':'V2',
+ 'use-aperture': this.state.enableRealTime,
+ 'schema-version': INVLIST.VERSION,
+ 'merge-tabs':mergedTabs,
+ 'accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+ },'dsls': []};
+
+ Object.keys(this.state.queryNameList).map((index)=>{
+ if(!this.state.filterTemplateErrorList[index]){
+ let query=this.formFinalTemplateQuery(index);
+ let obj={
+ "query-id": parseInt(index)+1,
+ "query-name": this.state.queryNameList[index],
+ "query-description": this.state.queryDescriptionList[index],
+ "is-aggregate": this.state.isAggregateCheckedList[index],
+ "dsl": query
+ };
+ payload['dsls'].push(obj);
+ }
+ });
+ var email='';
+ if(state){
+ let userid = sessionStorage.getItem(ENVIRONMENT + 'userId');
+ if(userid ==='testuid'){// For testing Purpose
+ email='AAI-UI-DEV@list.att.com';
+ }else{
+ email=userid+EMAIL_EXT;
+ }
+ payload['headers']['email'] = email;
+ }
+ console.dir('CustomDSL:payload:' + JSON.stringify(payload));
+ commonApi(settings, path, 'POST', payload, '',GlobalExtConstants.OVERRIDE_DOMAIN, null, [{
+ "name":"X-DslApiVersion",
+ "value": "V2"},
+ {
+ "name":"use-aperture",
+ "value": this.state.enableRealTime
+ },
+ {
+ "name":"schema-version",
+ "value":INVLIST.VERSION},
+ {
+ "name":"accept",
+ "value":"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
+ },{
+ "name":"encode-response",
+ "value":true}
+ ])
+ .then(res => {
+ let success =true;
+ let failures=[];
+ if(!state){
+ if(res['headers']['failures']){
+ failures=res['headers']['failures'].split(',');
+ for (var i = 0; i < failures.length; i++) {
+ var a = failures[i].split('|');
+ a.splice(1, 1);
+ failures[i] = a.join();
+ }
+ success=false;
+ }else{
+ let filename='';
+ if(res['headers']['content-disposition']){
+ filename=res['headers']['content-disposition'].split('=')[1];
+ }else if(res['headers']['Content-Disposition']){
+ filename=res['headers']['content-disposition'].split('=')[1];
+ }
+ const blob = new Blob([this.s2ab(atob(res.data))],
+ { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,'});
+ const url = window.URL.createObjectURL(blob);
+ const anchor = document.createElement('a');
+ document.body.appendChild(anchor);
+ anchor.href = url;
+ anchor.download = filename;
+ anchor.click();
+ window.URL.revokeObjectURL(url);
+ }
+ this.setState({
+ isLoading: false,
+ downloadTemplateStatus:success,
+ failedDownloadedTemplate:failures,
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:'',
+ emailTriggerMsg:''
+ },()=>{GeneralCommonFunctions.scrollTo("downloadTemplateStatusAlert");});
+ }else{
+ let emailTriggerMsg='';
+ let failedEmailTriggerMsg='';
+ success=false;
+ failures=[];
+ if(res.status === 202){
+ emailTriggerMsg='The job has been successfully triggered. The results will be emailed to '+ email +' when finished.'
+ }else{
+ failedEmailTriggerMsg='Failed to Generate an Email for selected template queries';
+ }
+ this.setState({
+ isLoading: false,
+ downloadTemplateStatus:success,
+ failedDownloadedTemplate:failures,
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:failedEmailTriggerMsg,
+ emailTriggerMsg:emailTriggerMsg
+ },()=>{GeneralCommonFunctions.scrollTo("downloadTemplateStatusAlert");});
+ }
+ }).catch(error => {
+ console.log('Bulk download xls Catch the Error>>>>>',error.response);
+ let ErrorMessage=(state)?'Failed to Generate an Email for selected template queries':'Failed to Download selected template queries';
+ if (error.response && error.response.data) {
+ if(error.response.data.status){
+ ErrorMessage += " Code: " + error.response.data.status;
+ }
+ if(error.response.data.msg){
+ ErrorMessage += " - " + JSON.stringify(error.response.data.msg);
+ }
+ }
+ if(state){
+ this.setState({
+ isLoading: false,
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:ErrorMessage
+ },()=>{GeneralCommonFunctions.scrollTo("downloadTemplateStatusAlert");});
+ }else{
+ this.setState({
+ isLoading: false,
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:ErrorMessage,
+ failedEmailTemplateMsg:'',
+ emailTriggerMsg:''
+ },()=>{GeneralCommonFunctions.scrollTo("downloadTemplateStatusAlert");});
+ }
+
+ });
+ }
+ s2ab=(s)=> {
+ var buf = new ArrayBuffer(s.length);
+ var view = new Uint8Array(buf);
+ for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
+ return buf;
+ }
+ templateList = () =>{
+ var filterTypeHeader='';
+ if(APERTURE_SERVICE){
+ filterTypeHeader = (this.state.enableRealTime)?<th scope='col' width='20%'>Filter Type</th>:'';
+ }
+ var listOfTemplate=[];
+ Object.keys(this.state.filterTemplateEntriesList).map((idx)=>{
+ let templateList =<div id={"template_"+idx} className="col-lg-10 templateview">
+ {this.state.filterTemplateEntriesList[idx].length > 0 && !this.state.filterTemplateErrorList[idx] &&
+ <div className='card d3-model-card model-card-content'>
+ <Alert id='saveSuccess' bsStyle='success' className={this.state.saveSuccessfulMsg && !this.state.isEditModal ? 'show' : 'hidden'} onDismiss={() => this.setState({saveSuccessfulMsg: false})}>
+ <h3>Query Saved Successfully</h3>
+ <p>
+ {this.state.saveSuccessfulMsg}
+ </p>
+ </Alert>
+ <div className='card-header'>
+ <div>
+ <h3><strong>{parseInt(idx)+1}.{this.state.queryNameList[idx]}</strong> - {this.state.queryDescriptionList[idx]}</h3>
+ </div>
+ </div>
+ <div>
+ <div className='card-header'>
+ <h5>{this.state.templateQueryList[idx]}</h5>
+ </div>
+ <table className="table table-hover table-striped" style={{margin:'0px',padding:'2px'}}>
+ <thead>
+ <tr>
+ <th scope="col" width={(this.state.enableRealTime)?'10%':'25%'}>Filter Key</th>
+ <th scope="col" width={(this.state.enableRealTime)?'20':'25%'}>Filter Name</th>
+ {filterTypeHeader}
+ <th scope="col" width={(this.state.enableRealTime)?'30%':'25%'}>Filter Value</th>
+ <th scope="col" width={(this.state.enableRealTime)?'20%':'25%'}> Action</th>
+ </tr>
+ </thead>
+ </table>
+ </div>
+ <div className='card-content model-card-content' style={{margin:'0px'}}>
+ {this.templateheaderSaveQuery(idx)}
+ </div>
+ <div className='card-footer'>
+ <button id='runSavedQuery' className='btn btn-primary btn-space' type='button' onClick={e => {this.runTemplate(idx)}}>Run Query</button>
+ <button id='manualEditQuery' className='btn btn-secondary btn-space' type='button' onClick={e =>{this.showEditDSLModal(idx)}} disabled={this.templateError.length>0}>Manual Edit & Run</button>
+ <button id='saveQuery' className='btn btn-outline-secondary btn-space' type='button' onClick={e =>{this.saveTemplate(idx)}} disabled={this.templateError.length>0}>Save</button>
+ <div className={'checkbox ' + (GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <label>
+ <input type="checkbox" id='aggregateObjects' checked={this.state.isAggregateCheckedList[idx]} onChange={this.onAggregateCheckbox.bind(this)} />
+ Aggregate Objects
+ </label>
+ </div>
+ </div>
+ </div>
+ }
+ {this.state.queryNameList[idx] && this.state.filterTemplateEntriesList[idx].length === 0 && !this.state.filterTemplateErrorList[idx] &&
+ <div className='addPaddingTop alert alert-warning' role="alert">
+ No filters present to populate for this saved query, please run as is or edit the query manually and run.
+ </div>
+ }
+ {this.state.filterTemplateErrorList[idx] &&
+ <div className='addPaddingTop alert alert-danger' role="alert">
+ An error occurred in parsing the template, please try a different template or contact the data steward to resolve this issue.
+ </div>
+ }
+ </div>;
+ listOfTemplate.push(templateList);
+ });
+ console.log('listOfTemplate>>>>>#####>>>>>>>',listOfTemplate);
+ return listOfTemplate;
+ }
+
+
+ render(){
+ let downloadRangeModel = this.prepareDownloadRangeModel();
+ let templateList= this.templateList();
+ var toggelRealtimeAnalysis = '';
+ var emailCheckbox = <div className={(this.dslObjectList.length>0)?'show':'hidden'}>
+ <div className="checkbox">
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>{'Report will be generated and emailed to '+sessionStorage.getItem(ENVIRONMENT + 'userId')+'@att.com when finished'}</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <Button bsSize='small' disabled={(this.dslObjectList.length===0)} onClick={() => {this.onGenerateEmailButton()}}>
+ Generate & Email <i className='icon-documents-folder'></i>
+ </Button>
+ </span>
+ </OverlayTrigger>
+ </div>
+ </div>
+ var mergedTabs = <div className={(this.dslObjectList.length>0)?'show':'hidden'}>
+ <div className="checkbox">
+ <label>
+ <input type="checkbox" checked={this.state.isMergedTabsChecked} onChange={this.onMergedTabsCheckbox.bind(this)} />
+ Merge Tabs
+ </label>
+ </div>
+ </div>
+ var downloadAllTemplateQueries = <div className={(this.dslObjectList.length>0)?'show':'hidden'}>
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>{this.downloadBulkTooltip}</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <Button bsSize='small' disabled={(this.dslObjectList.length===0)} onClick={() => {this.downloadBulkDslToExcel()}}>
+ Download Loaded Queries <i className='icon-documents-downloadablefile'></i>
+ </Button>
+ </span>
+ </OverlayTrigger>
+ </div>
+ let downloadTemplateStatusAlert= <div className={(this.dslObjectList.length>0)?'show':'hidden'}>
+ <Alert id="saveSuccess" bsStyle="success" className={(this.state.downloadTemplateStatus && this.state.failedDownloadedTemplate.length===0)?'show':'hide'} onDismiss={() => this.setState({
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:'',
+ emailTriggerMsg:''})}>
+ <h3>Download Loaded Templates are Successfully</h3>
+ <p>
+ The selected templates downloaded successfull.
+ </p>
+ </Alert>
+ {this.state.failedDownloadedTemplate.length>0 && <Alert id="saveFailure" bsStyle="danger" onDismiss={() => this.setState({
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:'',
+ emailTriggerMsg:''})}>
+ <h3>Download Loaded Templates are Failed</h3>
+ <p>
+ {this.state.failedDownloadedTemplate.toString()} templates are failed to download.Please refer the downloaded spreadsheet for more details.
+ </p>
+ </Alert>}
+ {this.state.failedDownloadedTemplateMsg !=='' && <Alert id="saveFailure" bsStyle="danger" onDismiss={() => this.setState({
+ downloadTemplateStatus:false,
+ failedDownloadedTemplate:[],
+ failedDownloadedTemplateMsg:'',
+ failedEmailTemplateMsg:'',
+ emailTriggerMsg:''})}>
+ <h3>Download Loaded Templates are Failed</h3>
+ <p>
+ {this.state.failedDownloadedTemplateMsg}
+ </p>
+ </Alert>}
+ {this.state.emailTriggerMsg !=='' && <Alert id="saveSuccess" bsStyle="success" onDismiss={() => this.setState({failedEmailTemplateMsg:'',emailTriggerMsg:''})}>
+ <h3>Generate & Email Triggered</h3>
+ <p>
+ {this.state.emailTriggerMsg}
+ </p>
+ </Alert>}
+ {this.state.failedEmailTemplateMsg !=='' && <Alert id="saveFailure" bsStyle="danger" onDismiss={() => this.setState({failedEmailTemplateMsg:'',emailTriggerMsg:''})}>
+ <h3>Generate & Email Templates is Failed</h3>
+ <p>
+ {this.state.failedEmailTemplateMsg}
+ </p>
+ </Alert>}
+ </div>
+ if(APERTURE_SERVICE){
+ toggelRealtimeAnalysis = <div className='toggleSwitch'><BootstrapSwitchButton
+ checked={!this.state.enableRealTime}
+ onlabel='Real Time'
+ onstyle='danger'
+ offlabel='Analysis'
+ offstyle='success'
+ style='w-100 mx-3'
+ onChange={(checked) => {
+ this.toggleRealTimeAnalysisCallback(checked);
+ }}
+ /></div>
+ }
+ const inputProps = {
+ placeholder: 'Please enter a query',
+ value: this.state.value,
+ onChange: this.onChange,
+ onSelect: this.onSelect,
+ onClick: this.onClick
+ };
+
+ let nodes = [];
+ if ( this.state.isAggregate && this.state.aggregateNodes.length > 0 ) {
+
+ console.log('nodes exist', JSON.stringify(this.state.aggregateNodes[0]));
+ if(this.state.isAggregate && this.state.viewName === 'CardLayout'){
+ var nodeDetails = this.state.aggregateNodes.map(entry => {
+ return <Col lg={4} md={4} sm={6} xs={12}>
+ <div className='card aggregate-card'>
+ <div className='card-header'>
+ <h4 className='card-title'>{entry.nodePath}</h4>
+ </div>
+ <div className='card-content aggregate-card-content'>
+ <span>
+ {entry && typeof entry.map === 'function' && entry.map(subEntry =>
+ { let nodesPropList={};
+ return Object.keys(subEntry).map((node) => {
+ console.log("subentry : " + JSON.stringify(node + ' ' + JSON.stringify(subEntry[node])));
+ let description='';
+ let nodeType=subEntry[node]['node-type'];
+ if(!nodesPropList[nodeType]){
+ var requiredParams = buildAttrList(nodeType,[],'mandatory');
+ nodesPropList[nodeType]=requiredParams;
+ }
+ return (<span>
+ {this.state.associatedNodesEnabled && (<Alert bsStyle="info"><strong>{node}</strong></Alert>)}
+ {Object.keys(subEntry[node].properties).map((key)=>{
+ let propKey=key.split('|')[1];
+ let found=true;
+ for(var a in nodesPropList[nodeType]){
+ if(propKey===nodesPropList[nodeType][a].value){
+ found=false;
+ return (<p className="aggregate-attribute"><strong title={nodesPropList[nodeType][a].description}>{key}</strong> : {"" + subEntry[node].properties[key]}</p>);
+ }
+ }
+ if(found){
+ return (<p className="aggregate-attribute"><strong>{key}</strong> : {"" + subEntry[node].properties[key]}</p>);
+ }
+ })
+ }
+ </span>)
+ })
+ })
+ }
+
+ {this.state.associatedNodesEnabled && (<Alert bsStyle="info"><strong>{entry.fullPath}</strong></Alert>)}
+ </span>
+ </div>
+ </div>
+ </Col>;
+ });
+ nodes =
+ <div className='model-container'>
+ {nodeDetails}
+ </div>;
+ }else if(this.state.isAggregate && this.state.viewName === 'CellLayout'){
+ if(this.state.aggregateAttrList.length > 0 && this.state.aggregatePaths){
+ var types = this.state.aggregatePaths;
+ var type = types[0];
+ let tabs=types.map((nodeType,index) => {
+ if(this.state.tabularAggregateData[nodeType] && this.state.tabularAggregateColumns[nodeType]){
+ return(
+ <Tab eventKey={nodeType} title={nodeType}>
+ <BootstrapTable
+ id={nodeType}
+ keyField='id'
+ data={this.state.tabularAggregateData[nodeType]}
+ columns={this.state.tabularAggregateColumns[nodeType]}
+ bordered={ true }
+ headerClasses='table-header-view'
+ columnFilter={ true }
+ filter={ filterFactory() }
+ bootstrap4 striped hover condensed
+ />
+ </Tab>
+ )
+ }
+ });
+
+ nodes =
+ <div>
+ <button type='button' className={(this.state.disableFilter)? 'btn btn-outline-secondary' : 'btn btn-primary'} disabled={this.state.disableFilter} onClick={() => {this.isTableFilterForAggregation(this.state.columnFilter,this.state.tabularAggregateColumns[type])}} style={{float: 'right', margin: '2px'}}>Apply Filters (All)</button>
+ <Tabs defaultActiveKey={type} id="multipleTabularView">
+ {tabs}
+ </Tabs>
+ </div>;
+ }
+ }else if(this.state.isAggregate && this.state.viewName === 'VisualLayout'){
+ nodes = <span></span>;
+ }
+ }else if (this.state.nodes.length > 0){
+ const modelGalleryElement = <ModelGallery
+ nodes={this.state.nodes}
+ viewName={this.state.viewName}
+ historyStackString={this.props.location.historyStackString}
+ openHistoryModal={this.openHistory}
+ isPageNumberChange={this.state.isPageNumberChange}
+ resetColumnInd={this.state.resetColumnFilters}
+ isTableFilterApply={this.isTableFilterApply}
+ dslQuery={this.state.value}
+ enableRealTime={this.state.enableRealTime}
+ tableFilterAliasColumns={this.tableFilterAliasColumns}/>;
+ nodes =
+ <div className='model-container'>
+ {modelGalleryElement}
+ </div>;
+ }
+ return(
+ <div>
+ {toggelRealtimeAnalysis}
+ <div className='addPadding customDsl'>
+ <div className='static-modal'>
+ <Modal show={this.state.showHistoryModal} onHide={this.closeHistory}>
+ <Modal.Header>
+ <Modal.Title>Retrieve {(this.state.focusedNodeType) ? this.state.focusedNodeType: ' BYOQ Query '} History</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <form className={this.state.showModelOptions ? 'show' : 'hidden'} id='historyForm' name='historyForm'>
+ <div className="radio">
+ <label>
+ <input type="radio" value="nodeState"
+ checked={this.state.historyType === 'nodeState'}
+ onChange={(e) => this.setHistoryType(e)} />
+ View state at
+ </label>
+ </div>
+ <div className="radio">
+ <label>
+ <input type="radio" value="nodeLifeCycleSince"
+ checked={this.state.historyType === 'nodeLifeCycleSince'}
+ onChange={(e) => this.setHistoryType(e)} />
+ View updates since
+ </label>
+ </div>
+ <div className="radio">
+ <label>
+ <input type="radio" value="nodeLifeCycle"
+ checked={this.state.historyType === 'nodeLifeCycle'}
+ onChange={(e) => this.setHistoryType(e)} />
+ View all updates
+ </label>
+ </div>
+ </form>
+ <div className={this.state.enableCalendar ? 'show' : 'hidden'}>
+ <DatePicker
+ inline
+ selected={this.state.startDate}
+ onChange={(newDate) => this.handleDateChange(newDate)}
+ showTimeSelect
+ timeFormat="HH:mm"
+ timeIntervals={15}
+ dateFormat="MMMM D, YYYY h:mm a"
+ timeCaption="time"
+ />
+ </div>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeHistory}>Close</Button>
+ <Button onClick={this.submitHistory}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ <div className='static-modal'>
+ <Modal show={this.state.showEditModal} onHide={this.closeEditDSLModal}>
+ <Modal.Header>
+ <Modal.Title>Edit DSL Query</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <form id='dslQueryEditable' name='dslQueryEditable'>
+ <FormGroup controlId="dslQuery">
+ <ControlLabel>DSL Query</ControlLabel>
+ <FormControl className="template-textarea" onChange={this.bindEdits.bind(this)} value={this.state.editModel} componentClass="textarea" placeholder="Enter DSL Query" />
+ </FormGroup>
+ </form>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeEditDSLModal}>Close</Button>
+ <Button onClick={this.submitEditAndRunDSL}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ <div className='static-modal'>
+ <Modal show={this.state.showNodeModal} onHide={this.closeNodeModal} dialogClassName="modal-override">
+ <Modal.Header>
+ <Modal.Title>Retrieve {this.state.nodeDisplay}</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Grid fluid={true}>
+ <Row className='show-grid'>
+ <Col lg={12} md={12} sm={12} xs={12}>
+ <ModelCard
+ key={this.state.focusedNode.id}
+ nodeId={this.state.focusedNode.id}
+ nodeType={this.state.focusedNode['node-type']}
+ nodeProps={this.state.focusedNode.properties}
+ nodeRelatives={this.state.focusedNode['related-to']}
+ nodeUrl={this.state.focusedNode.url}
+ historyStackString={this.props.location.historyStackString}
+ openHistoryModal={this.openHistory}
+ enableRealTime={this.state.enableRealTime}/>
+ </Col>
+ </Row>
+ </Grid>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeNodeModal}>Close</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ <div className='static-modal'>
+ <Modal show={this.state.showSaveModal} onHide={this.closeSaveModal} dialogClassName="modal-override">
+ <Spinner loading={this.state.enableSaveBusyFeedback}>
+ <Modal.Header>
+ <Modal.Title>{this.state.isEditModal ? 'Edit' : 'Save'} DSL Query</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Alert id="saveFailure" bsStyle="danger" className={this.state.saveFailureMsg ? 'show' : 'hidden'} onDismiss={() => this.setState({saveFailureMsg: false})}>
+ <h3>Query Save Failed</h3>
+ <p>
+ {this.state.saveFailureMsg}
+ </p>
+ </Alert>
+ <form className={!this.state.showQueryExistsWarning ? 'show' : 'hidden'} id='saveDslQueryForm' name='saveDslQueryForm'>
+ <FormGroup controlId="queryName">
+ <ControlLabel>Query Name</ControlLabel>
+ {!this.state.isEditModal && (<input id='dslNameHelp' type='name' className='form-control' id='queryName' aria-describedby='dslNameHelp' placeholder='Enter query name' value={this.state.queryName} onChange={this.handleQueryNameChange}/>)}
+ {!this.state.isEditModal && (<small id='queryNameHelp' className='form-text text-muted'>Select a name for your saved query, do not reuse names.</small>)}
+ {this.state.isEditModal && (<p>{this.state.queryName}</p>)}
+ </FormGroup>
+ <FormGroup controlId="queryDescription">
+ <ControlLabel>Query Description</ControlLabel>
+ <FormControl componentClass="textarea" id="queryDescription" aria-describedby="queryDescriptionHelp" placeholder="Enter query description" value={this.state.queryDescription} onChange={this.handleQueryDescriptionChange} />
+ <small id="queryDescriptionHelp" className="form-text text-muted">Be as descriptive as possible to describe the purpose of the saved query (this will be searchable)</small>
+ </FormGroup>
+ <FormGroup controlId="category">
+ <ControlLabel>Category</ControlLabel>
+ <input id='category' type="name" className="form-control" aria-describedby="category of SavedQuery" placeholder="Enter category" value={this.state.category} onChange={this.handleCategoryChange}/>
+ </FormGroup>
+ <FormGroup controlId="privacy_indicator">
+ {this.state.isDataSteward && (<div className="checkbox">
+ <label>
+ <input type="checkbox" checked={this.state.isPublicChecked} onChange={this.onPublicCheckbox.bind(this)} />
+ Public
+ </label>
+ </div>)}
+ <div className={"checkbox " + ((!this.state.isPublicChecked || !this.state.isDataSteward) ? 'show' : 'hidden')}>
+ <label>
+ <input type="checkbox" checked={this.state.isCommunitySharedChecked} onChange={this.onCommunitySharedCheckbox.bind(this)} />
+ Share with Community
+ </label>
+ </div>
+ {!this.state.isDataSteward && (<ControlLabel>Personal Query</ControlLabel>)}
+ </FormGroup>
+ <FormGroup controlId='aggregate'>
+ {this.state.isAggregateChecked && !(this.state.isEditModal || this.state.isSavedQueryFlow) && (<ControlLabel>Aggregate Query</ControlLabel>)}
+ {!this.state.isAggregateChecked && !(this.state.isEditModal || this.state.isSavedQueryFlow) && (<ControlLabel>Standard Query</ControlLabel>)}
+ {(this.state.isEditModal || this.state.isSavedQueryFlow) && (<div className='checkbox'>
+ <label>
+ <input type='checkbox' checked={this.state.isAggregateChecked} onChange={this.onAggregateCheckbox.bind(this)}/>
+ Aggregate Query
+ </label>
+ </div>)}
+ </FormGroup>
+ <FormGroup controlId='queryDSL'>
+ <ControlLabel>DSL Query</ControlLabel>
+ {!this.state.isEditModal && !this.state.isSavedQueryFlow ? <p>{this.state.value}</p> : <FormControl componentClass='textarea' id='queryDSL' aria-describedby='queryDSLHelp' placeholder='Enter dsl query' value={this.state.value} onChange={this.handleQueryChange} />}
+ </FormGroup>
+ <FormGroup controlId='templateDetails'>
+ <Spinner loading={this.state.enableTreeLoadBusyFeedback}>
+ <div className={!this.state.treeLoadErrMsg ? 'show' : 'hidden'}>
+ <ControlLabel>Configuration Template Details - check for configurable, uncheck for static</ControlLabel>
+ {Object.keys(this.state.dslConfigArray).map(key => {
+ return (this.state.dslConfigArray[key].filters).map(filter =>{
+ return (<div className='checkbox'>
+ <label>
+ <input type='checkbox' checked={this.state.staticTemplateFilters.indexOf(key + '|' + filter) === -1} onChange={(e) => {this.onDslConfigCheckbox(e, key + '|' + filter)}} />
+ {key} - {filter}
+ </label>
+ </div>)
+ })
+ })
+ }
+ </div>
+ <Alert bsStyle="danger" className={this.state.treeLoadErrMsg ? 'show' : 'hidden'}>
+ <h3>Error Loading Configurable Filters</h3>
+ <p>
+ {this.state.treeLoadErrMsg}
+ </p>
+ </Alert>
+ </Spinner>
+ </FormGroup>
+ </form>
+ <Alert bsStyle="warning" className={this.state.showQueryExistsWarning ? 'show' : 'hidden'} onDismiss={() => this.setState({showQueryExistsWarning: false})}>
+ <h3>Query Name Already Exists</h3>
+ <p>
+ There is already a query with the name {this.state.queryName}, do you wish to overwrite the existing query?
+ </p>
+ </Alert>
+ </Modal.Body>
+ <Modal.Footer className={!this.state.showQueryExistsWarning ? 'show' : 'hidden'}>
+ <Button onClick={this.closeSaveModal}>Close</Button>
+ <Button disabled={this.state.queryName.trim() === '' || this.state.queryDescription.trim() === ''} onClick={() => {this.submitSave()}}>Save</Button>
+ </Modal.Footer>
+ <Modal.Footer className={this.state.showQueryExistsWarning ? 'show' : 'hidden'}>
+ <Button onClick={() => this.setState({showQueryExistsWarning : false})}>No</Button>
+ <Button onClick={() => {this.submitSave(true)}}>Yes</Button>
+ </Modal.Footer>
+ </Spinner>
+ </Modal>
+ </div>
+ <div id="jumbotron" className='row'>
+ <div className={'row container-fluid my-4 ' + (this.state.isDSLFlow ? 'show' : 'hidden')}>
+ <div className='col-lg-12'>
+ <header className='jumbotron'>
+ <h1 className='display-2'><strong>B</strong>uild <strong>Y</strong>our <strong>O</strong>wn <strong>Q</strong>uery</h1>
+ <p className='lead'>
+ On this page you have the ability to craft your own query to retrieve objects from the database.
+ There are help menus in the accordions and a modal triggered from the light bulb icon to help with syntax.
+ There are is also a typeahead feature that will help you build your query as you type, providing valid nodes and attributes to use.
+ </p>
+ </header>
+ </div>
+ </div>
+ <div className={'row container-fluid my-4 ' + (this.state.isSavedQueryFlow ? 'show' : 'hidden')}>
+ <div className='col-lg-12'>
+ <header className='jumbotron'>
+ <h1 className='display-2'>Saved Queries</h1>
+ <p className='lead'>
+ On this page you have the ability to load and run previously saved queries.
+ You can run them as they are saved or choose to load them to replace the filters
+ in the template.
+ </p>
+ </header>
+ </div>
+ </div>
+ </div>
+ <div className='row'>
+ <div className={'addPadding col-md-12 ' + (this.state.isSavedQueryFlow ? 'show' : 'hidden')}>
+ <div className='row'>
+ <div className='col-lg-10'>
+ <Alert id="saveSuccessEdit" bsStyle="success" className={this.state.saveSuccessfulMsg && this.state.isEditModal ? 'show' : 'hidden'} onDismiss={() => this.setState({saveSuccessfulMsg: false})}>
+ <h3>Query Saved Successfully</h3>
+ <p>
+ {this.state.saveSuccessfulMsg}
+ </p>
+ </Alert>
+ </div>
+ </div>
+ <CustomDSLSaveLoad loadCallback={this.loadCallback} loadBulkCallback={this.loadBulkCallback} setQueriesState={this.setQueriesState} ref={this.saveLoadComponent} isDataSteward={this.state.isDataSteward} isSavedQueryFlow={this.state.isSavedQueryFlow} editCallback={this.editCallback}/>
+ <div className={'col-xs-1 ' + (GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )} >
+ <a href={INVLIST.USERGUIDE_URL} target="_blank">
+ <i className="dsl-hint icon-documents-manual"></i>
+ </a>
+ <pre>User<br />Guide</pre>
+ </div>
+ <div className='col-lg-11'><InfoToggle/></div>
+ </div>
+ <div className='row'>
+ <div className='col-md-12' id='templateList'>
+ {templateList}
+ </div>
+ <div className='col-md-10' id='downloadTemplateStatusAlert'>
+ <div className='col-md-6'>
+ {downloadTemplateStatusAlert}
+ </div>
+ <div className='col-md-6'>
+ <div style={{float:'right'}}>
+ {emailCheckbox}
+ </div>
+ <div style={{float:'right',margin: '10px'}}>
+ {downloadAllTemplateQueries}
+ </div>
+ <div style={{float:'right',margin: '10px'}}>
+ {mergedTabs}
+ </div>
+ </div>
+ </div>
+ </div>
+ <div className={'addPadding col-md-9 ' + (this.state.isDSLFlow ? 'show' : 'hidden')}>
+ <form onSubmit={this.onAddItem} id='byoqFormForQuery' name='byoqFormForQuery'>
+ <div className='row'>
+ <div className='col-lg-9 form-group'>
+ <Alert id="saveSuccess" bsStyle="success" className={this.state.saveSuccessfulMsg ? 'show' : 'hidden'} onDismiss={() => this.setState({saveSuccessfulMsg: false})}>
+ <h3>Query Saved Successfully</h3>
+ <p>
+ {this.state.saveSuccessfulMsg}
+ </p>
+ </Alert>
+ <div id="byoqInput"><label htmlFor='newQuery'>Build Your Own Query</label></div>
+ <div className={this.state.isTypeahead ? 'show' : 'hidden'}>
+ <Autosuggest
+ suggestions={this.state.suggestions}
+ onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
+ onSuggestionsClearRequested={this.onSuggestionsClearRequested}
+ getSuggestionValue={this.getSuggestionValue}
+ renderSuggestion={this.renderSuggestion}
+ inputProps={inputProps}
+ shouldRenderSuggestions={this.shouldRenderSuggestions}
+ onSuggestionSelected={this.onSuggestionSelected}
+ ref={this.storeInputReference}
+ />
+ </div>
+ <div className={this.state.isTypeahead ? 'hidden' : 'show'}>
+ <FormControl componentClass="textarea"
+ rows="4"
+ onChange={this.onTextAreaChange}
+ style={{width: '655px'}}
+ value={this.state.value}
+ />
+ </div>
+ </div>
+ <div className={'col-xs-1 ' + (GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <a href={INVLIST.USERGUIDE_URL} target="_blank">
+ <i className="dsl-hint icon-documents-manual"></i>
+ </a>
+ <pre>User<br />Guide</pre>
+ </div>
+ <InfoToggle/>
+ <div className='col-xs-1'>
+ <i className='dsl-hint fa fa-question-circle-o' onClick={this.hint} ></i>
+ </div>
+ <div className='static-modal'>
+ <Modal show={this.state.showModal} onHide={this.close}>
+ <Modal.Header>
+ <Modal.Title>DSL Syntax</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ {
+ this.state.hintHtml.map(hints => {
+ return <div key={hints.notation}>
+ <label>{hints.notation}</label> =>
+ <pre style={{color: 'blue'}}> {hints.description}</pre>
+ </div>;
+ })
+ }
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.close}>Close</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ </div>
+ <div className='row'>
+ <div className='col-sm-10'>
+ <button id='runByoqQuery' className='btn btn-primary' type='submit'>Run</button>
+ { !INVLIST.IS_ONAP &&(<button id='saveByoqQuery' className='btn btn-outline-secondary' type='button' disabled={this.state.value.trim() === ''} onClick={this.openSaveModal}>Save</button>)}
+ { INVLIST.isHistoryEnabled && (<button id='historyByoqQuery' className='btn btn-outline-secondary' type='button' disabled={this.state.value.trim() === ''} onClick={this.openHistory}>History</button>)}
+ <button id='clearByoqQuery' className='btn btn-outline-secondary' type='button' onClick={this.clear}>Clear</button>
+ <Toggle
+ id="typeAheadToggle"
+ defaultChecked={this.state.isTypeahead}
+ checked={this.state.isTypeahead}
+ className='toggle-theme'
+ onChange={this.handleTypeaheadChange} />
+ <span className='addPaddingLeft'>Typeahead</span>
+ </div>
+ </div>
+ </form>
+ <div className={this.state.isInitialLoad ? 'hidden' : 'show'} id='dslInputError'>
+ <Row className={this.state.validInput ? 'hidden' : 'show show-grid'}>
+ <Col md={12}>
+ <span className='label badge-pill label-danger'><strong>Error </strong>: Please enter a valid query input</span>
+ </Col>
+ </Row>
+ </div>
+ <div className={'checkbox ' + (GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <label>
+ <input type="checkbox" id='aggregateObjectsChkbox' checked={this.state.isAggregateChecked} onChange={this.onAggregateCheckbox.bind(this)} />
+ Aggregate Objects
+ </label>
+ {this.state.isAggregateChecked && (<label>
+ <input id='includeAssociatedNodes' type="checkbox" checked={this.state.associatedNodesEnabled} onChange={this.onAssociatedNodesCheckbox.bind(this)} />
+ Include Associated Nodes
+ </label>)}
+ </div>
+ <CustomDSLSaveLoad loadCallback={this.loadCallback} loadBulkCallback={this.loadBulkCallback} setQueriesState={this.setQueriesState} ref={this.saveLoadComponentDsl} isDataSteward={this.state.isDataSteward} editCallback={this.editCallback}/>
+ </div>
+ <div className={'col-lg-2 col-md-12 ' + (this.state.isDSLFlow ? 'show' : 'hidden')}>
+ <PanelGroup accordion id='rb-accordion'>
+ <Panel eventKey='1'>
+ <Panel.Heading>
+ <Panel.Title toggle>+ Simple Queries</Panel.Title>
+ </Panel.Heading>
+ <Panel.Body collapsible>
+ <div className='cardwrap'>
+ <div className='cardWrapHeaderTxt'>
+ <label>{this.state.simpleQueries.abstract}</label>
+ </div>
+ <div>
+ {this.state.simpleQueries.notation.map(entry => {
+ return (
+ <div key={entry.notation}>
+ <b><label>{entry.notation}</label></b> =>
+ <span style={{color: 'blue'}}> {entry.description}</span>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </Panel.Body>
+ </Panel>
+ <Panel eventKey='2'>
+ <Panel.Heading>
+ <Panel.Title toggle>+ Traversal Queries</Panel.Title>
+ </Panel.Heading>
+ <Panel.Body collapsible>
+ <div className='cardwrap'>
+ <div className='cardWrapHeaderTxt'>
+ <label>{this.state.traversalQueries.abstract}</label>
+ </div>
+ <div>
+ {this.state.traversalQueries.notation.map(entry => {
+ return (
+ <div key={entry.notation}>
+ <b><label>{entry.notation}</label></b> =>
+ <span style={{color: 'blue'}}> {entry.description}</span>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </Panel.Body>
+ </Panel>
+ <Panel eventKey='3'>
+ <Panel.Heading>
+ <Panel.Title toggle>+ Union Queries</Panel.Title>
+ </Panel.Heading>
+ <Panel.Body collapsible>
+ <div className='cardwrap'>
+ <div className='cardWrapHeaderTxt'>
+ <label>{this.state.unionQueries.abstract}</label>
+ </div>
+ <div>
+ {this.state.unionQueries.notation.map(entry => {
+ return (
+ <div key={entry.notation}>
+ <b><label>{entry.notation}</label></b> =>
+ <span style={{color: 'blue'}}> {entry.description}</span>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </Panel.Body>
+ </Panel>
+ <Panel eventKey='4'>
+ <Panel.Heading>
+ <Panel.Title toggle>+ Limit Queries</Panel.Title>
+ </Panel.Heading>
+ <Panel.Body collapsible>
+ <div className='cardwrap'>
+ <div className='cardWrapHeaderTxt'>
+ <label>{this.state.limitQueries.abstract}</label>
+ </div>
+ <div>
+ {this.state.limitQueries.notation.map(entry => {
+ return (
+ <div key={entry.notation}>
+ <b><label>{entry.notation}</label></b> =>
+ <span style={{color: 'blue'}}> {entry.description}</span>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </Panel.Body>
+ </Panel>
+ <Panel eventKey='5'>
+ <Panel.Heading>
+ <Panel.Title toggle>+ Negation Queries</Panel.Title>
+ </Panel.Heading>
+ <Panel.Body collapsible>
+ <div className='cardwrap'>
+ <div className='cardWrapHeaderTxt'>
+ <label>{this.state.negationQueries.abstract}</label>
+ </div>
+ <div>
+ {this.state.negationQueries.notation.map(entry => {
+ return (
+ <div key={entry.notation}>
+ <b><label>{entry.notation}</label></b> =>
+ <span style={{color: 'blue'}}> {entry.description}</span>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </Panel.Body>
+ </Panel>
+ <Panel eventKey='6'>
+ <Panel.Heading>
+ <Panel.Title toggle>+ Topology Queries</Panel.Title>
+ </Panel.Heading>
+ <Panel.Body collapsible>
+ <div className='cardwrap'>
+ <div className='cardWrapHeaderTxt'>
+ <label>{this.state.topologyQueries.abstract}</label>
+ </div>
+ <div>
+ {this.state.topologyQueries.notation.map(entry => {
+ return (
+ <div key={entry.notation}>
+ <b><label>{entry.notation}</label></b> =>
+ <span style={{color: 'blue'}}> {entry.description}</span>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </Panel.Body>
+ </Panel>
+ <Panel eventKey='7' className={(this.state.enableRealTime) ? 'show' : 'hidden'}>
+ <Panel.Heading>
+ <Panel.Title toggle>+ Advanced Queries</Panel.Title>
+ </Panel.Heading>
+ <Panel.Body collapsible>
+ <div className='cardwrap'>
+ <div className='cardWrapHeaderTxt'>
+ <label>{this.state.advancedQueries.abstract}</label>
+ </div>
+ <div>
+ {this.state.advancedQueries.notation.map(entry => {
+ return (
+ <div key={entry.notation}>
+ <b><label>{entry.notation}</label></b> =>
+ <span style={{color: 'blue'}}> {entry.description}</span>
+ </div>
+ );
+ })}
+ </div>
+ </div>
+ </Panel.Body>
+ </Panel>
+ </PanelGroup>
+ </div>
+ </div>
+ <div className='row'>
+ <div className='multipleNodes' id="outputBlock">
+ <Spinner loading={this.state.isLoading && this.state.isInitialLoad}>
+ </Spinner>
+ <div className={this.state.isInitialLoad ? 'hidden' : 'show'}>
+ <Spinner loading={this.state.isLoading} fullscreen={true}>
+ <div className={this.state.validInput ? 'show' : 'hidden'}>
+ <Col md={12}>
+ <h2 className='pre-wrap-text'>{this.state.header}</h2>
+ <br/>
+ <h5>Total Results: <strong>{this.state.totalResults}</strong></h5>
+ </Col>
+ {this.state.showResults && <div className="addPaddingTop" >
+ <OutputToggle scope={this} visualDisabled={this.state.totalResults > PAGINATION_CONSTANT}/>
+ </div> }
+ {!this.state.isAggregate && (<div id="standardOutput" className="col-md-12">
+ <Row className={this.state.showResults ? 'show' : 'hidden'}>
+ <Col md={8} className={this.state.showPagination ? 'show' : 'hidden'}>
+ <Pagination
+ activePage={this.state.activePage}
+ itemsCountPerPage={PAGINATION_CONSTANT.RESULTS_PER_PAGE}
+ totalItemsCount={this.state.totalResults}
+ pageRangeDisplayed={PAGINATION_CONSTANT.PAGE_RANGE_DISPLAY}
+ onChange={this.handlePageChange} />
+ </Col>
+ <Col md={2} className='text-right'>
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>{this.downloadAllTooltip}</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <Button bsSize='small' onClick={() => {this.getAllExcels(this.state.downloadCount)}}>
+ Download XLSX <i className='icon-documents-downloadablefile'></i>
+ </Button>
+ </span>
+ </OverlayTrigger>
+ </Col>
+ <Col md={2} className='text-right'>
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>{this.downloadRangeTooltip}</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <Button bsSize='small' onClick={this.openDownloadRange}>
+ Download XLSX (Range) <i className='icon-documents-downloadablefile'></i>
+ </Button>
+ </span>
+ </OverlayTrigger>
+ </Col>
+ </Row>
+ <hr/>
+ <div className={'addPaddingTop alert alert-danger ' +(this.state.errorResults ? 'show' : 'hidden')} role="alert">
+ An error occurred, please try again later. If this issue persists, please contact the system administrator. {this.state.errorMessage}
+ </div>
+ <Row className={this.state.noResults ? 'show' : 'hidden'}>
+ <Col md={12}>
+ <h2>No Results Found</h2>
+ </Col>
+ </Row>
+ <div className={this.state.errorResults || this.state.noResults ? 'hidden' : 'show'}>
+ <div className='nodes container-fluid'>
+ <div className='row-dsl'>
+ {nodes}
+ </div>
+ </div>
+ </div>
+ <Row className={this.state.showPagination ? 'show' : 'hidden'}>
+ <Col md={6}>
+ <Pagination
+ activePage={this.state.activePage}
+ itemsCountPerPage={PAGINATION_CONSTANT.RESULTS_PER_PAGE}
+ totalItemsCount={this.state.totalResults}
+ pageRangeDisplayed={PAGINATION_CONSTANT.PAGE_RANGE_DISPLAY}
+ onChange={this.handlePageChange} />
+ </Col>
+ </Row>
+ </div>)}
+ {this.state.isAggregate && (<div id="aggregateOutput">
+ <Row className={ this.state.errorResults || this.state.noResults ? 'hidden' : 'show'}>
+ <Col md={8} className={this.state.showPagination ? 'show' : 'hidden'}>
+ <Pagination
+ activePage={this.state.aggregateActivePage}
+ itemsCountPerPage={PAGINATION_CONSTANT.RESULTS_PER_PAGE}
+ totalItemsCount={this.state.totalResults}
+ pageRangeDisplayed={PAGINATION_CONSTANT.PAGE_RANGE_DISPLAY}
+ onChange={this.handlePageChange} />
+ </Col>
+ <Col md={2} className='text-right'>
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>{this.downloadAllTooltip}</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <Button bsSize='small' onClick={() => {this.downloadAllAggregate(this.state.downloadCount)}}>
+ Download XLSX <i className='icon-documents-downloadablefile'></i>
+ </Button>
+ </span>
+ </OverlayTrigger>
+ </Col>
+ <Col md={2} className='pull-right text-right'>
+ <OverlayTrigger placement='top' overlay={<Tooltip id='tooltip-top'>Download All Aggregate Objects By Custom Range Selection</Tooltip>}>
+ <span className="d-inline-block" style={{display: 'inline-block'}}>
+ <Button bsSize='small' onClick={this.openDownloadRange}>
+ Download XLSX (Range) <i className='icon-documents-downloadablefile'></i>
+ </Button>
+ </span>
+ </OverlayTrigger>
+ </Col>
+ </Row>
+ <hr/>
+ <div className={'addPaddingTop alert alert-danger ' + (this.state.errorResults ? 'show' : 'hidden')} role="alert">
+ An error occurred, please try again later. If this issue persists, please contact the system administrator. {this.state.errorMessage}
+ </div>
+ <Row className={this.state.noResults ? 'show' : 'hidden'}>
+ <Col md={12}>
+ <h2>No Results Found</h2>
+ </Col>
+ </Row>
+ <div className={this.state.errorResults || this.state.noResults ? 'hidden' : 'show'}>
+ <div className='nodes container-fluid'>
+ <div className='row-dsl'>
+ {nodes}
+ <div className={this.state.viewName === "VisualLayout" ? 'show' : 'hidden'}>
+ <OutputVisualization identifier="currentStateAggregate" width={ window.outerWidth * 0.8 } height="1200" overflow="scroll"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ <Row className={this.state.showPagination ? 'show' : 'hidden'}>
+ <Col md={6}>
+ <Pagination
+ activePage={this.state.aggregateActivePage}
+ itemsCountPerPage={PAGINATION_CONSTANT.RESULTS_PER_PAGE}
+ totalItemsCount={this.state.totalResults}
+ pageRangeDisplayed={PAGINATION_CONSTANT.PAGE_RANGE_DISPLAY}
+ onChange={this.handlePageChange} />
+ </Col>
+ </Row>
+ </div>)}
+ </div>
+ <Spinner loading={this.state.enableModelBusyFeedback}>
+ {downloadRangeModel}
+ </Spinner>
+ </Spinner>
+ </div>
+ <div className='row'>
+ <div className='col-sm-10'></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
+
+export default CustomDsl;
diff --git a/src/app/byoq/CustomDslBuilder.jsx b/src/app/byoq/CustomDslBuilder.jsx
new file mode 100644
index 0000000..1e034fa
--- /dev/null
+++ b/src/app/byoq/CustomDslBuilder.jsx
@@ -0,0 +1,1725 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import React, {Component} from 'react';
+import commonApi from 'utils/CommonAPIService.js';
+import {GeneralCommonFunctions} from 'utils/GeneralCommonFunctions.js';
+import Modal from 'react-bootstrap/lib/Modal';
+import Grid from 'react-bootstrap/lib/Grid';
+import FormGroup from 'react-bootstrap/lib/FormGroup';
+import FormControl from 'react-bootstrap/lib/FormControl';
+import ControlLabel from 'react-bootstrap/lib/ControlLabel';
+import Button from 'react-bootstrap/lib/Button';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+import Spinner from 'utils/SpinnerContainer.jsx';
+import Row from 'react-bootstrap/lib/Row';
+import Col from 'react-bootstrap/lib/Col';
+import Panel from 'react-bootstrap/lib/Panel';
+import Tooltip from 'react-bootstrap/lib/Tooltip';
+import FilterTypes from 'generic-components/filter/components/FilterTypes.jsx';
+import PathFilterDslBuilder from './PathFilterDslBuilder.jsx';
+import CustomDSLSaveLoad from 'app/byoq/CustomDSLSaveLoad.jsx';
+import BootstrapSwitchButton from 'bootstrap-switch-button-react';
+import * as d3 from "d3";
+import 'd3-selection-multi';
+
+
+let EDGERULES = GlobalExtConstants.EDGERULES;
+let OXM = GlobalExtConstants.OXM;
+let INVLIST = GlobalExtConstants.INVLIST;
+let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
+let APERTURE_SERVICE = JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+
+
+let nodeTypes = [];
+let properties = null;
+let traverseRulesDsl = [];
+
+const settings = {
+ 'NODESERVER': INVLIST.NODESERVER,
+ 'PROXY': INVLIST.PROXY,
+ 'PREFIX': INVLIST.PREFIX,
+ 'VERSION': INVLIST.VERSION,
+ 'APERTURE': INVLIST.APERTURE,
+ 'USESTUBS': INVLIST.useStubs
+};
+class CustomDslBuilder extends Component {
+ constructor(props) {
+ console.log('props>>>>',props);
+ super(props);
+ this.saveLoadComponent = React.createRef();
+ APERTURE_SERVICE=JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+ this.state = {edgeRules : null,
+ connectableNodes:[],
+ showNodeModal: false,
+ enableModalFeedback: false,
+ showEditNodeModal: false,
+ treemap: null,
+ root: null,
+ svg: null,
+ duration: null,
+ g: null,
+ selectedNode: null,
+ traverseToNodes:[],
+ traverseToNodeAttributes: [],
+ nodeDetails: [],
+ dslQuery: '',
+ editModel:'',
+ showEditModal: false,
+ zoomFit: null,
+ autoZoomEnabled: true,
+ aggregateObjects: false,
+ init: true,
+ filterTypeDisplay: 'Filter Type',
+ selectedfilterType:[],
+ oxmMapping: null,
+ initialRootEdit: true,
+ showPathFilterDslBuilder: false,
+ pathFilterNodeType: '',
+ pathFilterNodeName:'',
+ pathFIlterAttrDetails: [],
+ dslPathBuilder:'',
+ dslPathTree:'',
+ loadedQueries: [],
+ queryDescription: '',
+ queryName: '',
+ category:'',
+ queryId:'',
+ treeLoadErrMsg: '',
+ isEditEnable:false,
+ pathFilterIndex:0,
+ isDataSteward: sessionStorage.getItem(ENVIRONMENT + 'roles') && sessionStorage.getItem(ENVIRONMENT + 'roles').indexOf('data_steward_ui_view') > -1,
+ isPublicChecked: sessionStorage.getItem(ENVIRONMENT + 'roles') && sessionStorage.getItem(ENVIRONMENT + 'roles').indexOf('data_steward_ui_view') > -1,
+ enableRealTime: JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'ENABLE_ANALYSIS'))
+ }
+ this.baseState=this.state;
+ }
+ componentDidMount () {
+ console.log('componentDidMount',JSON.stringify(this.props));
+ //this.buildSQLStatementsFromSchema();
+ this.processEdgeRules(EDGERULES);
+ if(this.props.match.params.type && this.props.match.params.propId) {
+ this.build(this.props.match.params.type, this.props.match.params.propId);
+ }
+ }
+ initialize = () =>{
+ this.setState({enableModalFeedback: true}, function () {
+ //console.log("EnableModalFeedback: " + this.state.enableModalFeedback);
+ setTimeout(() => {this.postSpinner()},1);
+ });
+ }
+
+ postSpinner = () => {
+
+ var nodeDetails = [];
+ var node = null;
+ console.log('initializing');
+ var id = GeneralCommonFunctions.generateID();
+ var nodeTypes = GeneralCommonFunctions.getNodeTypes();
+ for (var i = 0; i < nodeTypes.length; i++) {
+ node = nodeTypes[i] + id;
+ var attributes = GeneralCommonFunctions.getFilteringOptions(nodeTypes[i]);
+ if(!nodeDetails[node] && Object.keys(attributes).length > 0){
+ nodeDetails[node] = {};
+ nodeDetails[node].nodeType = nodeTypes[i];
+ nodeDetails[node].isSelected = false;
+ nodeDetails[node].attrDetails = attributes;
+ nodeDetails[node].parentContainer = GeneralCommonFunctions.populateContainer(nodeTypes[i]);
+ }
+ }
+ let nodesSorted = nodeDetails.sort(function (filter1, filter2) {
+ if (filter1.nodeType < filter2.nodeType) {
+ return -1;
+ } else if (filter1.nodeType > filter2.nodeType) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ //console.log('Node Types List' + JSON.stringify(nodesSorted));
+ nodeDetails = nodesSorted;
+ this.setState({nodeDetails: nodeDetails, showNodeModal: true, enableModalFeedback: false});
+ }
+ processEdgeRules = (data) => {
+ this.setState({
+ edgeRules: data.rules
+ },()=>{this.baseState=this.state});
+ }
+ closeNodeModal = () =>{
+ this.setState({
+ showNodeModal: false,
+ enableModalFeedback: false,
+ traverseToNodes: [],
+ selectedNode: null
+ });
+ }
+ closeEditNodeModal = () =>{
+ this.setState({
+ showEditNodeModal: false,
+ selectedNode: null,
+ showPathFilterDslBuilder: false
+ });
+ }
+ closePathNodeModal = () =>{
+ console.log('closePathNodeModal>>>>>>>');
+ this.setState({
+ showPathFilterDslBuilder: false,
+ pathFilterNodeType: '',
+ pathFilterNodeName:'',
+ pathFIlterAttrDetails: []
+ });
+ }
+ submitPathNodeModal = (dslQuery,nodetype,dslQueryTree,isEditEnable,pathFilterIndex) =>{
+ console.log('CustomDSLBuilder submitPathNodeModel>>>>>dslQuery ###',dslQuery);
+ console.log(isEditEnable+'<<submitPathNodeModal this.state.nodeDetails>>>>',this.state.nodeDetails)
+ var nodeDetails = this.state.nodeDetails;
+ if(!nodeDetails[nodetype].dslPath){
+ nodeDetails[nodetype].dslPath=[];
+ nodeDetails[nodetype].dslPathTree=[];
+ }
+ if(isEditEnable){
+ nodeDetails[nodetype].dslPath[pathFilterIndex]=dslQuery;
+ nodeDetails[nodetype].dslPathTree[pathFilterIndex]=dslQueryTree;
+ console.log('nodeDetails on edit>>>>>>>>>',nodeDetails);
+ }else{
+ nodeDetails[nodetype].dslPath.push(dslQuery);
+ nodeDetails[nodetype].dslPathTree.push(dslQueryTree);
+ }
+ this.setState({ nodeDetails: nodeDetails },()=>{this.closePathNodeModal()});
+ }
+ editPathNodeModal = (key,path,tree,indx) =>{
+ console.log('editPathNodeModal>>>>>>>>>###',indx);
+ let attrDetails=this.state.nodeDetails[key].attrDetails;
+ let nodeType=this.state.nodeDetails[key].nodeType;
+ this.setState({showPathFilterDslBuilder: true,pathFilterNodeType: key,pathFilterNodeName:nodeType,pathFIlterAttrDetails: '',dslPathBuilder: path,dslPathTree:tree,isEditEnable:true,pathFilterIndex:indx});
+ }
+ deletePathNodeModal = (key,path,tree,index) =>{
+ console.log(index+'<<deletePathNodeModal>>>>>',key);
+ var nodeDetails = this.state.nodeDetails;
+ nodeDetails[key].dslPath.splice(index,1);
+ nodeDetails[key].dslPathTree.splice(index,1);
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ onNodeCheckbox(e) {
+ var nodeDetails = this.state.nodeDetails;
+ if (e.target.checked) {
+ nodeDetails[e.target.value].isSelected = true;
+ this.selectAll(e.target.value);
+ }else {
+ nodeDetails[e.target.value].isSelected = false;
+ this.deselectAll(e.target.value);
+ }
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ onNodeRadio(e) {
+ var nodeDetails = this.state.nodeDetails;
+ if (e.target.checked) {
+ nodeDetails[e.target.value].isSelected = true;
+ this.selectAll(e.target.value);
+ }
+ for (var key in nodeDetails) {
+ if(key != e.target.value && nodeDetails[key].isSelected ){
+ nodeDetails[key].isSelected = false;
+ this.deselectAll(key);
+ }
+ }
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ onAutoZoomCheckbox(e) {
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ }else {
+ cbValue = false;
+ }
+ this.setState({ autoZoomEnabled: cbValue });
+ }
+ onAggregateCheckbox(e) {
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ }else {
+ cbValue = false;
+ }
+ this.setState({ aggregateObjects: cbValue });
+ }
+ onAttributeCheckbox(e){
+ let splitVal = e.target.value.split("|");
+ let nodeKey = splitVal[0];
+ let attrValue = splitVal[1];
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ let attribute = null;
+ if(!node.attrDetails){
+ node.attrDetails = [];
+ }
+ if(!node.attrDetails[attrValue]){
+ node.attrDetails[attrValue] = {};
+ node.attrDetails[attrValue].isSelected = true;
+ node.attrDetails[attrValue].filterValue = [];
+ node.attrDetails[attrValue].filterType = [];
+ node.attrDetails[attrValue].dslPath = [];
+ node.attrDetails[attrValue].dslPathTree = [];
+ }
+
+ // check if the check box is checked or unchecked
+ if (e.target.checked) {
+ // add the value of the checkbox to nodes array
+ node.attrDetails[attrValue].isSelected = true;
+ node.attrDetails[attrValue].filterType[0]='EQ';
+ } else {
+ // or remove the value from the unchecked checkbox from the array
+ node.attrDetails[attrValue].isSelected = false;
+ //node.attrDetails[attrValue].filterType = [''];
+ //node.attrDetails[attrValue].filterValue = [''];
+ }
+ nodeDetails[nodeKey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ onFilterValueChange(e, nodeKey, attrKey, indx){
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ if(!node.attrDetails){
+ node.attrDetails = [];
+ }
+ if(!node.attrDetails[attrKey]){
+ node.attrDetails[attrKey] = {};
+ node.attrDetails[attrKey].isSelected = true;
+ node.attrDetails[attrKey].filterValue = [];
+ node.attrDetails[attrKey].filterType = [];
+ node.attrDetails[attrValue].dslPath = [];
+ node.attrDetails[attrValue].dslPathTree = [];
+ }
+ // add the value of the checkbox to nodes array
+ //node.attrDetails[attrKey].filterValue.push(e.target.value);
+ let filterValArr=node.attrDetails[attrKey].filterValue;
+ filterValArr[indx]=e.target.value;
+ node.attrDetails[attrKey].filterValue=filterValArr;
+ nodeDetails[nodeKey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ submitNodeModal = () =>{
+ if(this.state.selectedNode){
+ var d = this.state.selectedNode;
+ for(var node in this.state.nodeDetails){
+ if(this.state.nodeDetails[node].isSelected){
+ var newNodeObj = {
+ type: 'node',
+ name: this.state.nodeDetails[node].nodeType,
+ details: {}
+ };
+ //Creates new Node
+ Object.assign(newNodeObj.details, this.state.nodeDetails[node]);
+ var newNode = d3.hierarchy(newNodeObj);
+ newNode.depth = d.depth + 1;
+ newNode.height = d.height - 1;
+ newNode.parent = d;
+ newNode.id = node;
+ if(!d.children){
+ d.children = [];
+ }
+ if(newNodeObj.details){
+ var selectedAttributeCount = 0;
+ for (var key in newNodeObj.details.attrDetails){
+ if (newNodeObj.details.attrDetails[key].isSelected){
+ selectedAttributeCount++;
+ }
+ if(selectedAttributeCount === Object.keys(newNodeObj.details.attrDetails).length){
+ newNodeObj.details.includeInOutput = true;
+ }
+ }
+ }
+ d.children.push(newNode);
+ this.setState({ nodeDetails: [] });
+ }
+ }
+ this.update(this, d);
+ this.setState({
+ showNodeModal: false,
+ enableModalFeedback: false,
+ traverseToNodes: [],
+ selectedNode: null
+ });
+ }else{
+ var nodeType = "";
+ var attrDetails = null;
+ var dslPath =[];
+ var dslPathTree=[];
+ for (var key in this.state.nodeDetails) {
+ if(this.state.nodeDetails[key].isSelected){
+ nodeType = this.state.nodeDetails[key].nodeType;
+ attrDetails = this.state.nodeDetails[key].attrDetails;
+ dslPath =this.state.nodeDetails[key].dslPath;
+ dslPathTree=this.state.nodeDetails[key].dslPathTree;
+ }
+ }
+ this.build(nodeType, null, attrDetails,null,dslPath,dslPathTree);
+ this.setState({ nodeDetails: [], showNodeModal: false, enableModalFeedback:false, traverseToNodes: [], selectedNode: null });
+ }
+ }
+ submitEditNodeModal = () =>{
+ this.update(this, this.state.selectedNode);
+ this.setState({showEditNodeModal: false,showPathFilterDslBuilder:false});
+ }
+ populateEdgeRules = (nodeType) => {
+ let nodeDetails=GeneralCommonFunctions.populateEdgeRules(nodeType,this.state.edgeRules);
+ this.setState({
+ nodeDetails: nodeDetails
+ });
+ }
+
+ buildOXMAttributesAndReturn = (nodeType) =>{
+ var oxmArray = [];
+ var result = JSON.parse(OXM);
+ var arrayOfTypes = result['xml-bindings']['java-types'][0]['java-type'];
+ for (var i = 0; i < arrayOfTypes.length; i++) {
+ var propertiesDsl = [];
+ for (var j = 0; j < arrayOfTypes[i]['java-attributes'][0]['xml-element'].length; j++) {
+ let property = arrayOfTypes[i]['java-attributes'][0]['xml-element'][j]['$']['name'];
+ let type = arrayOfTypes[i]['java-attributes'][0]['xml-element'][j]['$']['type'];
+ if (type === 'java.lang.String' || type === 'java.lang.Boolean') {
+ propertiesDsl[property] = {};
+ propertiesDsl[property].isSelected = false;
+ propertiesDsl[property].attributeName = property;
+ propertiesDsl[property].filterValue = [''];
+ propertiesDsl[property].filterType = [''];
+ propertiesDsl[property].dslPath = [];
+ propertiesDsl[property].dslPathTree = [];
+ }
+ }
+ let sortedPropertiesDsl = propertiesDsl.sort(function (filter1, filter2) {
+ if (filter1.attributeName < filter2.attributeName) {
+ return -1;
+ } else if (filter1.attributeName > filter2.attributeName) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ oxmArray[GeneralCommonFunctions.camelToDash(arrayOfTypes[i]['xml-root-element'][0]['$']['name'])] = sortedPropertiesDsl;
+ }
+ this.setState({oxmMapping: oxmArray});
+ return oxmArray[nodeType];
+ }
+
+ runDSL = () => {
+ console.log("running DSL");
+ let paramToPassThrough = '';
+ if(this.state.aggregateObjects){
+ paramToPassThrough = '/customDsl/built-aggregate/' + btoa('<pre>' + this.state.dslQuery + '</pre>');
+ }else{
+ paramToPassThrough = '/customDsl/built/' + btoa('<pre>' + this.state.dslQuery + '</pre>');
+ }
+ this.props.history.push(paramToPassThrough);
+ }
+ submitEditAndRunDSL = () =>{
+ this.setState({ dslQuery: this.state.editModel }, () => this.runDSL());
+ }
+ showEditDSLModal = () => {
+ console.log("enabling DSL edit modal");
+ this.setState({ editModel: this.state.dslQuery, showEditModal: true });
+ }
+ closeEditDSLModal = () => {
+ console.log("closing DSL edit modal");
+ this.setState({ showEditModal: false });
+ }
+ bindEdits = (e) => {
+ this.setState({ editModel: e.target.value });
+ }
+ populateDSL = (tree, isInit) =>{
+ var DSL = '';
+ var treeArray = '';
+ var treeArrayLength = 0;
+ if(isInit){
+ treeArray = tree;
+ treeArrayLength = 1;
+ }else{
+ treeArray = tree.children;
+ treeArrayLength = tree.children.length;
+ }
+ for(var k = 0; treeArray && k < treeArrayLength; k++){
+ if(k === 0 && treeArrayLength > 1){
+ DSL += '[';
+ }
+ var node = '';
+ if(isInit){
+ node = tree;
+ }else{
+ node = treeArray[k];
+ }
+ if(node.data){
+ console.log('Node data while rendering DSl path>>',JSON.stringify(node.data));
+ DSL += node.data.name;
+ let propState=false;
+ if(node.data.details){
+ var tempAttributeString = '';
+ var selectedAttributeCount = 0;
+ for (var key in node.data.details.attrDetails){
+ if (node.data.details.attrDetails[key].isSelected){
+ selectedAttributeCount++;
+ let aliasWithProp=node.data.details.attrDetails[key].attributeName;
+ if(node.data.details.attrDetails[key].alias){
+ aliasWithProp= aliasWithProp+'\' as \''+node.data.details.attrDetails[key].alias;
+ }
+ if(selectedAttributeCount === 1){
+ tempAttributeString += '{\'' + aliasWithProp +'\'';
+ propState=true;
+ }else{
+ tempAttributeString += ',\'' + aliasWithProp + '\'';
+ }
+ }
+ }
+ if(selectedAttributeCount === Object.keys(node.data.details.attrDetails).length){
+ DSL+= '*';
+ }
+ if((selectedAttributeCount < Object.keys(node.data.details.attrDetails).length) && propState){
+ DSL += tempAttributeString + '}';
+ }
+ for (var key in node.data.details.attrDetails){
+ if(node.data.details.attrDetails[key].filterValue && node.data.details.attrDetails[key].filterValue[0] !==''){
+ DSL += '(\'' + node.data.details.attrDetails[key].attributeName + '\',';
+ let dslValues='';
+ for(var indx=0; indx<node.data.details.attrDetails[key].filterValue.length; indx++){
+ dslValues=(indx>0) ? dslValues+',':dslValues;
+ if(this.state.enableRealTime && node.data.details.attrDetails[key].filterType && node.data.details.attrDetails[key].filterType[indx]){
+ dslValues += node.data.details.attrDetails[key].filterType[indx]+'(\''+ node.data.details.attrDetails[key].filterValue[indx] + '\')';
+ }else{
+ dslValues +='\''+node.data.details.attrDetails[key].filterValue[indx] + '\'';
+ }
+ if(node.data.details.attrDetails[key].filterValue.length-1 === indx){
+ dslValues +=')';
+ }
+ }
+ DSL += dslValues;
+ }
+ }
+ if(node.data.details.dslPath && node.data.details.dslPath.length>0){
+ for(var n in node.data.details.dslPath){
+ DSL += node.data.details.dslPath[n];
+ }
+ }
+ }
+ }
+ if(node.children){
+ DSL+= '>' + this.populateDSL(node);
+ }
+ if(k !== treeArrayLength - 1){
+ DSL += ',';
+ }
+ if(k === treeArrayLength - 1 && treeArrayLength > 1){
+ DSL += ']';
+ }
+ }
+ return DSL;
+ }
+ update = (base, source, isInit) => {
+
+ // Assigns the x and y position for the nodes
+ var treeData = base.state.treemap(base.state.root);
+
+ var DSL = base.populateDSL(treeData, true);
+ console.log(JSON.stringify("DSL :" + DSL));
+
+ this.setState({ dslQuery: DSL });
+
+ // Compute the new tree layout.
+ var nodes = treeData.descendants(),
+ links = treeData.descendants().slice(1);
+
+ var list1 = d3.selectAll(".fa")
+ .filter(".fa-plus")
+ .style("display", "block");
+
+ // Normalize for fixed-depth.
+ nodes.forEach(function(d){ d.y = d.depth * 100});
+ // ****************** Nodes section ***************************
+
+ // Update the nodes...
+ var node = base.state.g.selectAll('g.node')
+ .data(nodes, function(d) {return d.id });
+
+ // Enter any new modes at the parent's previous position.
+ var nodeEnter = node.enter().append('g')
+ .attr('class', 'node')
+ .attr("transform", function(d) {
+ return "translate(" + source.y0 + "," + source.x0 + ")";
+ })
+ // .on('click', click)
+ .on('dblclick', doubleClick);
+
+ // Add Circle for the nodes
+ nodeEnter.append('circle')
+ .attr('class', 'node')
+ .attr('r', 1e-6)
+ .style("fill", "lightsteelblue");
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 20)
+ .attr("height", 25)
+ .attr("y", -14)
+ .attr("x", -10)
+ .append("xhtml:span")
+ .attr("class", function (d) {
+ let icon = '';
+ if(!INVLIST.IS_ONAP){
+ icon = 'icon-datanetwork-serverL';
+ }else{
+ icon = 'browse-fa fa fa-server';
+ }
+ if(d.data.details && d.data.details.parentContainer){
+ var iconKey = ((d.data.details.parentContainer).replace(/-/g, '')).toUpperCase();
+ if(INVLIST.INVENTORYLIST[iconKey] && INVLIST.INVENTORYLIST[iconKey].icon){
+ return INVLIST.INVENTORYLIST[iconKey].icon;
+ }else{
+ return icon;
+ }
+ }else{
+ return icon;
+ }
+ })
+ .style("font-size", function (d) {
+ if (!INVLIST.IS_ONAP){
+ return "20px";
+ } else {
+ return "16px";
+ }
+ })
+ .attr("id", function (d) {return "nodeIcon" + d.id})
+ .style("color", '#387dff')
+ .style("display", "block")
+ .style("padding-top",function(d){
+ if (!INVLIST.IS_ONAP){
+ return "0px";
+ } else {
+ return "8px";
+ }
+ });
+
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 6)
+ .attr("height", 6)
+ .attr("y", 10)
+ .attr("x", -10)
+ .on('click', function (d) {
+ if(d.data.details.isRootNode){
+ d = null;
+ base.resetBuilder();
+ }else{
+ for(var i = 0; d.parent.children && i < d.parent.children.length; i++){
+ if (d.parent.children.length > 1 && d.data.name === d.parent.children[i].data.name){
+ d.parent.children.splice(i, 1);
+ }else if (d.parent.children.length === 1 && d.data.name === d.parent.children[i].data.name){
+ d.parent.children = null;
+ }
+ }
+ base.update(base, d);
+ }
+ })
+ .append("xhtml:span")
+ .attr("class", "fa fa-minus")
+ .style("padding-top", "1px")
+ .style("font-size", function (d){ return "5px";})
+ .attr("id", function (d) {return "nodeDelete" + d.data.id})
+ .style("color", '#387dff')
+ .style("display", function (d) {return "block";});
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 6)
+ .attr("height", 6)
+ .attr("y", 10)
+ .attr("x", 5)
+ .on('click', function (d) { base.setState({enableModalFeedback: true}, function () {setTimeout(() => {add(d)},1);})})
+ .append("xhtml:span")
+ .attr("class", "fa fa-plus")
+ .style("padding-top", "1px")
+ .style("font-size", function (d){ return "5px";})
+ .attr("id", function (d) {return "nodeAdd" + d.data.id})
+ .style("color", '#387dff');
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 6)
+ .attr("height", 6)
+ .attr("y", -17)
+ .attr("x", -10)
+ .on('click', function (d) { edit(d)})
+ .append("xhtml:span")
+ .attr("class", "fa fa-pencil-square")
+ .style("padding-top", "1px")
+ .style("font-size", function (d){ return "5px";})
+ .attr("id", function (d) {return "nodeEdit" + d.data.id})
+ .style("color", '#387dff');
+ // Add labels for the nodes
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 60)
+ .attr("height", 40)
+ .attr("y", -10)
+ .attr("x", -75)
+ .append("xhtml:span")
+ .append('text')
+ .attr("dy", ".35em")
+ .attr("x", function(d) {
+ return d.children ? -13 : 13;
+ })
+ .text(function(d) { return d.data.name; })
+ .style("float","right")
+ .style("color", '#000000');
+
+ // UPDATE
+ var nodeUpdate = nodeEnter.merge(node);
+ var postNodeDrawnCallBack = function (d){
+ if(!isInit && base.state.autoZoomEnabled || d.data.details.isRootNode){
+ base.state.zoomFit();
+ }
+ }
+ // Transition to the proper position for the node
+ nodeUpdate.transition()
+ .duration(base.state.duration)
+ .attr("transform", function(d) {
+ return "translate(" + d.y + "," + d.x + ")"
+ }).on("end", postNodeDrawnCallBack);
+
+ // Update the node attributes and style
+ nodeUpdate.select('circle.node')
+ .attr('r', 11)
+ .style("fill", "lightsteelblue")
+ .attr('cursor', 'pointer');
+
+
+ // Remove any exiting nodes
+ var nodeExit = node.exit().transition()
+ .duration(base.state.duration)
+ .attr("transform", function(d) {
+ return "translate(" + source.y + "," + source.x + ")";
+ })
+ .remove();
+
+ // On exit reduce the node circles size to 0
+ nodeExit.select('circle')
+ .attr('r', 1e-6);
+
+ // On exit reduce the opacity of text labels
+ nodeExit.select('text')
+ .style('fill-opacity', 1e-6);
+
+ // ****************** links section ***************************
+
+ // Update the links...
+ var link = base.state.g.selectAll('path.link')
+ .data(links, function(d) { return d.id; });
+
+ // Enter any new links at the parent's previous position.
+ var linkEnter = link.enter().insert('path', "g")
+ .attr("class", "link")
+ .attr('d', function(d){
+ var o = {x: source.x0, y: source.y0}
+ return diagonal(o, o)
+ });
+
+ // UPDATE
+ var linkUpdate = linkEnter.merge(link);
+
+ // Transition back to the parent element position
+ linkUpdate.transition()
+ .duration(base.state.duration)
+ .attr('d', function(d){ return diagonal(d, d.parent) });
+
+ // Remove any exiting links
+ var linkExit = link.exit().transition()
+ .duration(base.state.duration)
+ .attr('d', function(d) {
+ var o = {x: source.x, y: source.y}
+ return diagonal(o, o)
+ })
+ .remove();
+
+ // Store the old positions for transition.
+ nodes.forEach(function(d){
+ d.x0 = d.x;
+ d.y0 = d.y;
+ });
+
+ // Creates a curved (diagonal) path from parent to the child nodes
+ function diagonal(s, d) {
+ 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;
+ return path
+ }
+ base.state.svg.on("dblclick.zoom", null);
+ // Toggle children on click.
+ function add(d){
+ base.populateEdgeRules(d.data.name,base.state.edgeRules);
+ if(!d.children){
+ d.children = [];
+ d.data.children = [];
+ }
+ base.setState({
+ selectedNode: d,
+ showNodeModal: true,
+ enableModalFeedback: false
+ });
+
+ }
+ function edit(d){
+ console.log("object editing: " + d);
+ var nodeDetails = base.state.nodeDetails;
+ //set up node details to have the node to edit
+ if(d.data.details.isRootNode && base.props.match.params.type){
+ var attributes = GeneralCommonFunctions.getFilteringOptions(d.data.details.nodeType);
+ if(Object.keys(attributes).length > 0){
+ nodeDetails[0] = {};
+ nodeDetails[0].isRootNode = true;
+ nodeDetails[0].nodeType = base.props.match.params.type;
+ nodeDetails[0].isSelected = true;
+ nodeDetails[0].attrDetails = attributes;
+ if(base.state.initialRootEdit){
+ for (var key in nodeDetails[0].attrDetails) {
+ nodeDetails[0].attrDetails[key].isSelected = true;
+ }
+ }
+ nodeDetails[0].parentContainer = GeneralCommonFunctions.populateContainer(base.props.match.params.type);
+ for (var key in d.data.details.attrDetails) {
+ nodeDetails[0].attrDetails[key] = d.data.details.attrDetails[key];
+ if(base.state.initialRootEdit){
+ nodeDetails[0].attrDetails[key].filterType = [];
+ nodeDetails[0].attrDetails[key].filterType.push('EQ');
+ }
+ }
+ }
+ d.data.details = nodeDetails[0];
+ base.setState({
+ initialRootEdit: false
+ });
+ }else{
+ nodeDetails[0] = d.data.details;
+ }
+ base.setState({
+ selectedNode: d,
+ showEditNodeModal: true,
+ showPathFilterDslBuilder: false
+ });
+ }
+ function doubleClick(d) {
+ edit(d);
+ }
+ }
+ selectAll = (nodeKey) =>{
+ var nodeDetails = this.state.nodeDetails;
+ for (var key in nodeDetails[nodeKey].attrDetails) {
+ nodeDetails[nodeKey].attrDetails[key].isSelected = true;
+ }
+ this.setState({nodeDetails: nodeDetails});
+ }
+ deselectAll = (nodeKey) =>{
+ var nodeDetails = this.state.nodeDetails;
+ for (var key in nodeDetails[nodeKey].attrDetails) {
+ nodeDetails[nodeKey].attrDetails[key].isSelected = false;
+ }
+ this.setState({nodeDetails: nodeDetails});
+ }
+ build = (type, propID, attrDetails, preBuiltTree,dslPath,dslPathTree) =>{
+ var selected = null;
+ var treeData;
+ if(!preBuiltTree && type && (propID || attrDetails)){
+ let nodeType = type;
+ treeData = {
+ "name": nodeType,
+ "id": nodeType,
+ "children": [],
+ "details":{},
+ "dslPath":[],
+ "dslPathTree":[]
+ }
+ treeData.details.includeInOutput = true;
+ treeData.details.isSelected = true;
+ treeData.details.isRootNode = true;
+ treeData.details.nodeType = nodeType;
+ if(attrDetails){
+ treeData.details.attrDetails = attrDetails;
+ } else{
+ treeData.details.attrDetails = {};
+ }
+ if(dslPath && dslPath.length>0 && dslPathTree && dslPathTree.length>0){
+ treeData.details.dslPath=dslPath;
+ treeData.details.dslPathTree=dslPathTree;
+ }
+ if(propID){
+ let propIds = (propID) ? propID.split(';') : '';
+ let propertyValue = '';
+ for(var i in propIds){
+ let propValue = propIds[i].split(':');
+ console.log(propValue[0] + '....' + propValue[1]);
+ treeData.details.attrDetails[propValue[0]] = {};
+ treeData.details.attrDetails[propValue[0]].filterValue=[];
+ treeData.details.attrDetails[propValue[0]].filterValue.push(atob(propValue[1]).replace('<pre>','').replace('</pre>',''));
+ treeData.details.attrDetails[propValue[0]].attributeName = propValue[0];
+ treeData.details.attrDetails[propValue[0]].isSelected = true;
+ }
+ }
+ }else if (preBuiltTree){
+ treeData = preBuiltTree;
+ if(treeData.details && treeData.details.dslPathTree && treeData.details.dslPathTree.length>0){
+ for(var x=0;x<treeData.details.dslPathTree.length;x++){
+ treeData.details.dslPath.push(GeneralCommonFunctions.populatePathDSL(treeData.details.dslPathTree[x],true,true,this.state.enableRealTime));
+ }
+ }
+ if(treeData.children && treeData.children.length>0){
+ for(var x=0;x<treeData.children.length;x++){
+ treeData.children[x]=this.updateDslPathValueOnExtract(treeData.children[x]);
+ }
+ }
+ }
+
+ // append the svg object to the body of the page
+ // appends a 'group' element to 'svg'
+ // moves the 'group' element to the top left margin
+ var svg = d3.select("#DSLBuilder");
+ // Set the dimensions and margins of the diagram
+
+ var margin = {top: 20, right: 120, bottom: 20, left: 120},
+ width = +svg.attr("width") - margin.right - margin.left,
+ height = +svg.attr("height") - margin.top - margin.bottom;
+
+ var g = svg.append("g")
+ .attr("transform", "translate("
+ + margin.left + "," + margin.top + ")");
+
+ var duration = 750,
+ root;
+
+ // declares a tree layout and assigns the size
+ var treemap = d3.tree().size([height - 200, width]);
+
+ // Assigns parent, children, height, depth
+ root = d3.hierarchy(treeData, function(d) { return d.children; });
+ root.x0 = height / 2;
+ root.y0 = 0;
+
+ //Zoom functions
+ function zoom_actions(){
+ g.attr("transform", d3.event.transform)
+ }
+ //add zoom capabilities
+ var zoom_handler = d3.zoom()
+ .on("zoom", zoom_actions);
+
+ zoom_handler(svg);
+
+ function zoomFit() {
+ var bounds = g.node().getBBox();
+ var parent = g.node().parentElement;
+ if(bounds && parent){
+ var fullWidth = parent.clientWidth || parent.parentNode.clientWidth,
+ fullHeight = parent.clientHeight || parent.parentNode.clientHeight;
+ var width = bounds.width,
+ height = bounds.height;
+ var midX = bounds.x + width / 2,
+ midY = bounds.y + height / 2;
+ if (width == 0 || height == 0) return; // nothing to fit
+ var scale = Math.min((0.95 / Math.max(width / fullWidth, height / fullHeight)), 4);
+ var translate = [fullWidth / 2 - scale * midX, fullHeight / 2 - scale * midY];
+
+ var transform = d3.zoomIdentity
+ .translate(300, translate[1])
+ .scale(scale);
+ svg.transition().duration(350)
+ .call(zoom_handler.transform, transform);
+ }
+
+ }
+
+ //Set Default zoom
+ svg.call(zoom_handler)
+ .call(zoom_handler.transform, d3.zoomIdentity.translate(80, -1000).scale(4));
+ this.setState({
+ init: false,
+ svg: svg,
+ g: g,
+ treemap: treemap,
+ root: root,
+ duration: duration,
+ zoomFit: zoomFit
+ }, ()=>{this.update(this, root, true);})
+
+ // Collapse the node and all it's children
+ function collapse(d) {
+ if(d.children) {
+ d.children.forEach(collapse)
+ d.children = null
+ }
+ }
+ }
+
+ updateDslPathValueOnExtract=(treeDataChildren)=>{
+ if(treeDataChildren.details && treeDataChildren.details.dslPathTree && treeDataChildren.details.dslPathTree.length>0){
+ for(var x=0;x<treeDataChildren.details.dslPathTree.length;x++){
+ let dsl=GeneralCommonFunctions.populatePathDSL(treeDataChildren.details.dslPathTree[x],true,true,this.state.enableRealTime);
+ treeDataChildren.details.dslPath.push(dsl);
+ }
+ }
+ if(treeDataChildren && treeDataChildren.children && treeDataChildren.children.length>0){
+ for(var x=0;x<treeDataChildren.children.length;x++){
+ treeDataChildren.children[x]=this.updateDslPathValueOnExtract(treeDataChildren.children[x]);
+ }
+ }
+ return treeDataChildren;
+ }
+ onTargetMenuOfFilterTypes=(listname,id)=>{
+ console.log(listname+'onTargetMenuOfFilterTypes',id);
+ let keysOfArray=id.split('#');
+ let nodekey=keysOfArray[0];
+ let attrKey=keysOfArray[1];
+ let indx=parseInt(keysOfArray[2]);
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodekey];
+ if(!node.attrDetails){
+ node.attrDetails = [];
+ }
+ if(!node.attrDetails[attrKey]){
+ node.attrDetails[attrKey] = {};
+ node.attrDetails[attrKey].isSelected = true;
+ node.attrDetails[attrKey].filterValue = [];
+ node.attrDetails[attrKey].filterType = [];
+ }else{
+ let filterTypes=node.attrDetails[attrKey].filterType;
+ filterTypes[indx]=listname;
+ node.attrDetails[attrKey].filterType=filterTypes;
+ }
+ nodeDetails[nodekey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ };
+ filterTags = (key,property,state) =>{
+ let filterTags ='';
+ let filters='';
+ state=true;//always enable, in future if wants to disable remove this line
+ if(APERTURE_SERVICE && this.state.enableRealTime){
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[key];
+ filterTags= Object.keys(Object.keys(node.attrDetails[property].filterType)).map((indx) =>{
+ let selectedFilter=(node.attrDetails[property].filterType[indx]!=='')?node.attrDetails[property].filterType[indx]:this.state.filterTypeDisplay;
+ return <div style={{margin:'0px 0px 0px 5px'}}>
+ <label>
+ <FilterTypes param={this.state}
+ selectedFilter={selectedFilter}
+ id={key+'#'+property+'#'+indx}
+ onMenuSelect={this.onTargetMenuOfFilterTypes}
+ state={!state}/>
+ </label>
+ </div>
+ });
+ filters= <Col md={4} className='removeLeftPadding'>{filterTags}</Col>;
+ }
+ return filters;
+ };
+ addOrTemplate=(nodeKey,attrKey,indx)=>{
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ node.attrDetails[attrKey].filterValue.push('');
+ node.attrDetails[attrKey].filterType.push('EQ');
+ nodeDetails[nodeKey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ };
+ deleteOrTemplate=(nodeKey,attrKey,index)=>{
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ let filterValuesArray=node.attrDetails[attrKey].filterValue;
+ let filterTypeArray=node.attrDetails[attrKey].filterType;
+ filterValuesArray.splice(index,1);
+ filterTypeArray.splice(index,1);
+ node.attrDetails[attrKey].filterValue=filterValuesArray;
+ node.attrDetails[attrKey].filterType=filterTypeArray;
+ nodeDetails[nodeKey] = node;
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ toggleRealTimeAnalysisCallback=(checked)=>{
+ console.log('toggleRealTimeAnalysisCallback>>>>',checked);
+ sessionStorage.setItem(ENVIRONMENT + 'ENABLE_ANALYSIS', !checked);
+ this.baseState.enableRealTime=!checked;
+ this.baseState.init= true;
+ this.setState({...this.baseState},()=>{document.getElementById("DSLBuilder").innerHTML='';});
+ }
+ renderPathFilterBuilder=(key,dslPath,dslPathTree)=>{
+ console.log('renderPathFilterBuilder>>>>',key);
+ let attrDetails=this.state.nodeDetails[key].attrDetails;
+ let nodeType=this.state.nodeDetails[key].nodeType;
+ this.setState({showPathFilterDslBuilder: true,pathFilterNodeType: key,pathFilterNodeName:nodeType,pathFIlterAttrDetails: attrDetails,dslPathBuilder: dslPath,dslPathTree:dslPathTree,isEditEnable:false});
+ }
+ /* Load Functions */
+ getAndPopulateTreeFromDSL = (dslQuery) =>{
+ var treeObject = [];
+ var payload = {dsl: dslQuery};
+ settings['ISAPERTURE'] = true;
+ commonApi(settings, 'dsl/convert-query-to-tree', 'PUT', payload, 'ConvertQueryToTree')
+ .then(res => {
+ console.log('res:' + res.data, 'load');
+ if(res.status === 200 || res.status === 404){
+ if(res.data.status && (res.data.status !== 200 && res.data.status !== 201 && res.data.status !== 404)){
+ this.triggerError(res.data, 'treeLoad');
+ }else{
+ treeObject = res.data;
+ this.setState({
+ enableTreeLoadBusyFeedback:false,
+ treeLoadErrMsg: null
+ });
+ console.log("TREE OBJECT: " + JSON.stringify(treeObject));
+ //clear the svg
+ if(this.state.svg){
+ this.state.svg.selectAll("*").remove();
+ }
+ //set the init state
+ this.setState({init: true, dslQuery: '', initialRootEdit: false, nodeDetails: [], selectedNode: null });
+ var initNode = this.extractNodeDetails(treeObject.children[0], true);
+ if(!this.state.treeLoadErrMsg || this.state.treeLoadErrMsg === ''){
+ console.log(JSON.stringify(initNode));
+ this.build(null, null, null, initNode);
+ setTimeout(() => { this.state.zoomFit() }, 600);
+ //scroll to the hidden static modal since svg offsetTop doesnt work for DSLBuilder id
+ GeneralCommonFunctions.scrollTo('customDslBuilderModel');
+ }else{
+ this.triggerError(null, 'invalidQuery');
+ }
+ }
+ }else{
+ this.triggerError(res.data, 'treeLoad');
+ }
+ }, error=>{
+ if(error.response.status === 404){
+ this.setState({enableTreeLoadBusyFeedback:false});
+ }else{
+ this.triggerError(error.response.data, 'treeLoad');
+ }
+ }).catch(error => {
+ this.triggerError(error, 'treeLoad');
+ })
+
+ };
+ resetBuilder = () => {
+ if(this.state.svg){
+ this.state.svg.selectAll("*").remove();
+ }
+ this.setState({
+ init: true,
+ dslQuery: '',
+ queryName:'',
+ queryDescription:'',
+ initialRootEdit: false,
+ nodeDetails: [],
+ selectedNode: null,
+ treeLoadErrMsg: '',
+ enableTreeLoadBusyFeedback: false,
+ aggregateObjects: false
+ });
+ }
+ triggerError = (error, type) => {
+ console.error('[CustomDslBuilder.jsx] error : ', JSON.stringify(error));
+ let errMsg = '';
+ if(error && error.status && error.message){
+ errMsg += "Error Occurred: " + error.status + ' - ' +error.message;
+ }else{
+ errMsg += "Error Occurred: " + JSON.stringify(error);
+ }
+ console.log(errMsg);
+ if(type === 'treeLoad' || type === 'invalidQuery'){
+ this.resetBuilder();
+ var errorMessage = errMsg;
+ if(type === 'invalidQuery'){
+ errorMessage = 'The loaded query uses DSL syntax not supported by the DSL Builder,'
+ + ' please only load queries compatible with the builder. For more'
+ + ' information on this error, please contact an administrator.';
+ }
+ this.setState({treeLoadErrMsg: errorMessage});
+ GeneralCommonFunctions.scrollTo('treeLoadErrorMessage');
+ }else{
+ console.log('[CustomDslBuilder.jsx] :: triggerError invoked with invalid type : ' + type);
+ }
+ }
+ validLoadableDSL = (dslQuery) => {
+ var valid = false;
+ dslQuery = dslQuery.replace(/\s/g, '');
+ valid = dslQuery.indexOf(']>') === -1 && !(new RegExp("LIMIT[0-9]+$").test(dslQuery));
+ return valid;
+ }
+ loadCallback = (name, description, category, dslQuery, isAggregate, type, queryId, id, templateDetails, makeCall) =>{
+ var decodedDslQuery = atob(dslQuery).replace('<pre>','').replace('</pre>','');
+ if(this.validLoadableDSL(decodedDslQuery)){
+ if(name !== '' && description !== ''){
+ this.setState({
+ queryName:name,
+ queryDescription:description,
+ category:category,
+ isPublicChecked: type === 'public',
+ queryId: queryId,
+ treeLoadErrMsg: null,
+ aggregateObjects: isAggregate === "true"
+ });
+ console.log("DSL Query Loaded: "+ decodedDslQuery);
+ console.log("DSL Query Name: "+ name);
+ console.log("DSL Query Description: "+ description);
+ console.log("DSL Query ID: "+ queryId);
+ console.log("DSL Query Category: "+ category);
+ console.log("DSL Query isAggregate: "+ isAggregate);
+ console.log("DSL Query type: "+ type);
+ var treeObject = this.getAndPopulateTreeFromDSL(decodedDslQuery);
+ }
+ }else{
+ this.triggerError(null, "invalidQuery");
+ }
+ }
+ extractNodeDetails = (node, isRoot) =>{
+ let nodeType = node['node-type'];
+ let nodeData = {
+ "name": nodeType,
+ "id": nodeType,
+ "children": [],
+ "details":{}
+ }
+ nodeData.details.includeInOutput = node.store;
+ nodeData.details.isSelected = true;
+ nodeData.details.isRootNode = isRoot;
+ nodeData.details.nodeType = nodeType;
+ var attributes = GeneralCommonFunctions.getFilteringOptions(nodeType);
+ nodeData.details.attrDetails = attributes;
+ nodeData.details.parentContainer = GeneralCommonFunctions.populateContainer(nodeType);
+ if(node.store && !node['requested-props']){
+ for(var key in nodeData.details.attrDetails){
+ nodeData.details.attrDetails[key].isSelected = true;
+ }
+ }else if (node.store && node['requested-props']){
+ for(var key in node['requested-props']){
+ nodeData.details.attrDetails[key].isSelected = true;
+ nodeData.details.attrDetails[key].alias=node['requested-props'][key];
+ }
+ }
+ var isValid = true;
+ for (var x in node['node-filter']){
+ if(isValid){
+ for (var y in node['node-filter'][x]) {
+ if(isValid){
+ var attrKey = node['node-filter'][x][y]['key'];
+ var filter = node['node-filter'][x][y]['filter'];
+ //If aperture is not turned on and query loaded uses anything besides EQ throw error
+ if(!APERTURE_SERVICE && filter !== 'EQ'){
+ this.triggerError(null, "invalidQuery");
+ isValid = false;
+ }
+ if(!nodeData.details.attrDetails[attrKey]){
+ nodeData.details.attrDetails[attrKey] = {};
+ }
+ if(nodeData.details.attrDetails[attrKey].filterType.length > 0 && nodeData.details.attrDetails[attrKey].filterType[0] === ''){
+ nodeData.details.attrDetails[attrKey].filterType = [];
+ }
+ if(nodeData.details.attrDetails[attrKey].filterValue.length > 0 && nodeData.details.attrDetails[attrKey].filterValue[0] === ''){
+ nodeData.details.attrDetails[attrKey].filterValue = [];
+ }
+ //if a filter had no values associated to it throw a not supported error
+ if(node['node-filter'][x][y]['value'][0]){
+ for (var i in node['node-filter'][x][y]['value']){
+ nodeData.details.attrDetails[attrKey].filterType.push(filter);
+ nodeData.details.attrDetails[attrKey].filterValue.push(node['node-filter'][x][y]['value'][i]);
+ }
+ if(!nodeData.details.attrDetails[attrKey].attributeName){
+ nodeData.details.attrDetails[attrKey].attributeName = attrKey;
+ }
+ }else{
+ this.triggerError(null, "invalidQuery");
+ isValid = false;
+ }
+ }
+ }
+ }
+ }
+ var initWhereNode = null;
+ if(node['where-filter'].length > 0){
+ for(var index in node['where-filter']){
+ initWhereNode = this.extractNodeDetails(node['where-filter'][index].children[0], true);
+ }
+ }
+ if(initWhereNode){
+ nodeData.details.dslPath=[];
+ nodeData.details.dslPathTree=[];
+ nodeData.details.dslPathTree.push(initWhereNode);
+ }
+ if(node.children.length > 0){
+ for(var i = 0; i < node.children.length; i++){
+ nodeData.children[i] = this.extractNodeDetails(node.children[i], false);
+ }
+ }
+ return nodeData;
+ }
+
+ setQueriesState = (savedQueries) =>{
+ this.setState({
+ loadedQueries: savedQueries
+ });
+ };
+ /* End Load Functions */
+ render(){
+ var toggelRealtimeAnalysis = '';
+ if(APERTURE_SERVICE){
+ toggelRealtimeAnalysis = <div className='toggleSwitch'><BootstrapSwitchButton
+ checked={!this.state.enableRealTime}
+ onlabel='Real Time'
+ onstyle='danger'
+ offlabel='Analysis'
+ offstyle='success'
+ style='w-100 mx-3'
+ onChange={(checked) => {
+ this.toggleRealTimeAnalysisCallback(checked);
+ }}
+ /></div>
+ }
+ return(
+ <div>
+ {toggelRealtimeAnalysis}
+ <div className="addPadding">
+ <div className='row container-fluid my-4'>
+ <div className='col-lg-9'>
+ <header className='jumbotron'>
+ <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>
+ <p className='lead'>
+ Visually build your own query, you can click the + icon to add objects to your query,
+ - icon to remove objects from your query, or the pencil icon/double click to edit attributes.
+ Single click and drag in the view to pan, use scrollwheel or pinch to zoom. <br/>
+ </p>
+ </header>
+ </div>
+ </div>
+ <div className={'addPaddingTop alert alert-danger ' +(this.state.treeLoadErrMsg && this.state.treeLoadErrMsg !== '' ? 'show' : 'hidden')} id="treeLoadErrorMessage" role="alert">
+ An error occurred in loading the query. Please see details {this.state.treeLoadErrMsg}
+ </div>
+ <CustomDSLSaveLoad loadCallback={this.loadCallback} setQueriesState={this.setQueriesState} ref={this.saveLoadComponent} isDataSteward={this.state.isDataSteward} isDSLBuilder={true}/>
+ <div className={'row ' + (this.state.init ? 'show' : 'hidden')}>
+ <button className='btn btn-primary' type='button' onClick={this.initialize.bind(this)}>Start Building (+)</button>
+ </div>
+ <div className={'row ' + (!this.state.init ? 'show' : 'hidden')}>
+ <button className='btn btn-primary' type='button' onClick={this.runDSL}>Run Query</button>
+ <button className='btn btn-outline-secondary' type='button' onClick={this.showEditDSLModal}>Manual Edit & Run</button>
+ <div className={'checkbox ' + (GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <label>
+ <input type="checkbox" checked={this.state.aggregateObjects} onChange={this.onAggregateCheckbox.bind(this)} />
+ Aggregate Objects
+ </label>
+ <label>
+ <input type="checkbox" checked={this.state.autoZoomEnabled} onChange={this.onAutoZoomCheckbox.bind(this)} />
+ Auto Zoom Enabled
+ </label>
+ </div>
+ </div>
+
+ <div className='static-modal' id='customDslBuilderModel'>
+ <Modal show={this.state.showNodeModal} onHide={this.closeNodeModal}>
+ <Modal.Header>
+ <Modal.Title>Modify Query</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <form>
+ {Object.keys(this.state.nodeDetails).sort().map((key, node) => (
+ <div className="dsl-panel">
+ <Panel>
+ <Panel.Heading>
+ <Panel.Title>
+ <div className={'checkbox ' + (!this.state.init ? 'show' : 'hidden')}>
+ <label>
+ <input type="checkbox" checked={this.state.nodeDetails[key].isSelected} value={key} onChange={this.onNodeCheckbox.bind(this)} />
+ {this.state.nodeDetails[key].nodeType}
+ </label>
+ <Panel.Toggle>
+ <div className="pull-right">Options</div>
+ </Panel.Toggle>
+ </div>
+ <div className={(this.state.init ? 'show' : 'hidden')}>
+ <label>
+ <input type="radio" value={key} checked={this.state.nodeDetails[key].isSelected} onChange={this.onNodeRadio.bind(this)} />
+ {" " + this.state.nodeDetails[key].nodeType}
+ </label>
+ <Panel.Toggle>
+ <div className="pull-right">Options</div>
+ </Panel.Toggle>
+ </div>
+ </Panel.Title>
+ </Panel.Heading>
+ <Panel.Collapse>
+ <Panel.Body className='cardwrap'>
+ <div>
+ <div style={{float:'right'}}>
+ <button type='button' className='btn btn-primary pull-right' onClick={()=>this.renderPathFilterBuilder(key)}>Build Path Filter</button>
+ </div>
+ </div>
+ {this.state.nodeDetails[key].dslPath && this.state.nodeDetails[key].dslPath.length>0 &&
+ <Grid fluid={true} className='addPaddingTop'>
+ <Row className='show-grid addPaddingTop'>
+ <Col md={10}>
+ <strong>DSL PATH Filter</strong>
+ </Col>
+ <Col md={2} className='removeLeftPadding'>
+ <strong>Action</strong>
+ </Col>
+ </Row>
+ </Grid>}
+ <Grid fluid={true}>
+ {this.state.nodeDetails[key].dslPath && Object.keys(this.state.nodeDetails[key].dslPath).map((indx) => {
+ return(
+ <Row className='show-grid'>
+ <Col md={9}>
+ <div style={{float:'left',width:'100%',margin:'10px 0px'}}>
+ {this.state.nodeDetails[key].dslPath[indx]}
+ </div>
+ </Col>
+ <Col md={3}>
+ <button
+ className='btn btn-primary'
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ type='button'
+ onClick={e => {this.editPathNodeModal(key,this.state.nodeDetails[key].dslPath[indx],this.state.nodeDetails[key].dslPathTree[indx],indx)}}>Edit</button>
+ <button
+ className='btn btn-primary'
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ type='button'
+ onClick={e => {this.deletePathNodeModal(key,this.state.nodeDetails[key].dslPath[indx],this.state.nodeDetails[key].dslPathTree[indx],indx)}}>Delete</button>
+ </Col>
+ </Row>
+ )
+ })}
+ </Grid>
+ <div style={{float:'left'}} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <button type='button' className='btn btn-outline-primary pull-right' onClick={()=>this.deselectAll(key)}>Deselect All</button>
+ <button type='button' className='btn btn-primary pull-right' onClick={()=>this.selectAll(key)}>Select All</button>
+ </div>
+ <Grid fluid={true} className='addPaddingTop'>
+ <Row className='show-grid addPaddingTop'>
+ <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <strong>Include in Output</strong>
+ </Col>
+ {APERTURE_SERVICE && this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
+ <strong>Filter Types</strong>
+ </Col>}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ <strong>Filter By (Optional)</strong>
+ </Col>
+ </Row>
+ {Object.keys(this.state.nodeDetails[key].attrDetails).sort().map((attrKey, attr) => {
+ return(
+ <Row className='show-grid'>
+ <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <div className="checkbox">
+ <label>
+ <input type="checkbox" checked={this.state.nodeDetails[key].attrDetails
+ && this.state.nodeDetails[key].attrDetails[attrKey]
+ && this.state.nodeDetails[key].attrDetails[attrKey].isSelected }
+ value={key + "|" + attrKey} onChange={this.onAttributeCheckbox.bind(this)} />
+ {attrKey}
+ </label>
+ </div>
+ </Col>
+ {this.filterTags(key,attrKey,this.state.nodeDetails[key].attrDetails[attrKey].isSelected)}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ {Object.keys(this.state.nodeDetails[key].attrDetails[attrKey].filterValue).map((indx) =>{
+ return(
+ <div>
+ {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ onBlur={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
+ />
+ }
+ {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
+ onChange={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ value={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]}
+ />
+ }
+ {indx == 0 && <button
+ className={(this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='')?'btn btn-primary':'btn btn-secondary'}
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ disabled={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]===''}
+ type='button'
+ onClick={e => {this.addOrTemplate(key,attrKey,indx)}}>+</button>}
+ {indx > 0 && <button
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ id={'delete-'+indx}
+ className='btn btn-danger'
+ type='button'
+ onClick={e => {this.deleteOrTemplate(key,attrKey,indx)}}>x</button>}
+
+ </div>
+ )
+ })}
+
+ </Col>
+ </Row>
+ );
+ }
+ )}
+ </Grid>
+ </Panel.Body>
+ </Panel.Collapse>
+ </Panel>
+ </div>
+ ))}
+ </form>
+ <div className={this.state.showPathFilterDslBuilder ? 'show' : 'hidden'}>
+ <Modal show={this.state.showPathFilterDslBuilder} onHide={!this.state.showPathFilterDslBuilder} style={{width:'100%'}}>
+ <Modal.Header>
+ <Modal.Title>Build DSL Path</Modal.Title>
+ </Modal.Header>
+ <Modal.Body style={{overflow:'scroll'}}>
+ <PathFilterDslBuilder nodeType={this.state.pathFilterNodeType}
+ nodeName={this.state.pathFilterNodeName}
+ attrDetails={this.state.pathFIlterAttrDetails}
+ closePathNodeModal={this.closePathNodeModal}
+ submitPathNodeModal={this.submitPathNodeModal}
+ showPathFilterDslBuilder={this.state.showPathFilterDslBuilder}
+ dslPath={this.state.dslPathBuilder}
+ dslPathTree={this.state.dslPathTree}
+ isEditEnable={this.state.isEditEnable}
+ pathFilterIndex={this.state.pathFilterIndex}/>
+ </Modal.Body>
+ </Modal>
+ </div>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeNodeModal}>Close</Button>
+ <Button onClick={this.submitNodeModal}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ <div className='static-modal' id='editNodeModel'>
+ <Modal show={this.state.showEditNodeModal} onHide={this.closeEditNodeModal}>
+ <Modal.Header>
+ <Modal.Title>Modify Node</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <form>
+ <div className="dsl-panel">
+ <Panel>
+ <Panel.Heading>
+ <Panel.Title>
+ <div>
+ <label>{this.state.selectedNode
+ && this.state.selectedNode.data
+ && this.state.selectedNode.data.details ?
+ this.state.selectedNode.data.details.nodeType
+ : ""
+ }
+ </label>
+ </div>
+ </Panel.Title>
+ </Panel.Heading>
+ <Panel.Body className='cardwrap'>
+ <Grid fluid={true} className='addPaddingTop'>
+ <Row className='show-grid addPaddingTop'>
+ <div style={{float:'right'}}>
+ <button type='button' className='btn btn-primary pull-right' onClick={()=>this.renderPathFilterBuilder(0)}>Build Path Filter</button>
+ </div>
+ </Row>
+ {this.state.selectedNode
+ && this.state.selectedNode.data
+ && this.state.selectedNode.data.details
+ && this.state.nodeDetails[0]
+ && this.state.nodeDetails[0].dslPath && this.state.nodeDetails[0].dslPath.length>0 &&
+ <Row className='show-grid addPaddingTop'>
+ <Col md={10}>
+ <strong>DSL PATH Filter</strong>
+ </Col>
+ <Col md={2} className='removeLeftPadding'>
+ <strong>Action</strong>
+ </Col>
+ </Row>}
+ </Grid>
+ {this.state.selectedNode
+ && this.state.selectedNode.data
+ && this.state.selectedNode.data.details
+ && this.state.nodeDetails[0]
+ && this.state.nodeDetails[0].dslPath && Object.keys(this.state.nodeDetails[0].dslPath).map((indx) => {
+ return(
+ <Row className='show-grid'>
+ <Col md={9}>
+ <div style={{float:'left',width:'100%',margin:'10px 0px'}}>
+ {this.state.nodeDetails[0].dslPath[indx]}
+ </div>
+ </Col>
+ <Col md={3}>
+ <button
+ className='btn btn-primary'
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ type='button'
+ onClick={e => {this.editPathNodeModal(0,this.state.nodeDetails[0].dslPath[indx],this.state.nodeDetails[0].dslPathTree[indx],indx)}}>Edit</button>
+ <button
+ className='btn btn-primary'
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ type='button'
+ onClick={e => {this.deletePathNodeModal(0,this.state.nodeDetails[0].dslPath[indx],this.state.nodeDetails[0].dslPathTree[indx],indx)}}>Delete</button>
+ </Col>
+ </Row>
+ )
+ })}
+ <div style={{float:'left'}} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <button type='button' className='btn btn-outline-primary pull-right' onClick={()=>this.deselectAll(0)}>Deselect All</button>
+ <button type='button' className='btn btn-primary pull-right' onClick={()=>this.selectAll(0)}>Select All</button>
+ </div>
+ <Grid fluid={true} className='addPaddingTop'>
+ <Row className='show-grid addPaddingTop'>
+ <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <strong>Include in Output</strong>
+ </Col>
+ {this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
+ <strong>Filter Types</strong>
+ </Col>}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ <strong>Filter By (Optional)</strong>
+ </Col>
+ </Row>
+ {this.state.selectedNode
+ && this.state.selectedNode.data
+ && this.state.selectedNode.data.details
+ && this.state.nodeDetails[0]
+ && Object.keys(this.state.nodeDetails[0].attrDetails).sort().map((attrKey, attr) => {
+ return(
+ <Row className='show-grid'>
+ <Col md={(this.state.enableRealTime)?4:6} className={(GlobalExtConstants.INVLIST.IS_ONAP ? 'hidden' : '' )}>
+ <div className="checkbox">
+ <label>
+ <input type="checkbox" checked={this.state.nodeDetails[0].attrDetails
+ && this.state.nodeDetails[0].attrDetails[attrKey]
+ && this.state.nodeDetails[0].attrDetails[attrKey].isSelected }
+ value={0 + "|" + attrKey} onChange={this.onAttributeCheckbox.bind(this)} />
+ {attrKey}
+ </label>
+ </div>
+ </Col>
+ {this.filterTags(0,attrKey, this.state.nodeDetails[0].attrDetails[attrKey].isSelected)}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ {Object.keys(this.state.nodeDetails[0].attrDetails[attrKey].filterValue).map((indx) =>{
+ return(
+ <div>
+
+ {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ onBlur={(e)=>{this.onFilterValueChange(e, 0, attrKey, indx);}}
+ />
+ }
+ {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
+ onChange={(e)=>{this.onFilterValueChange(e, 0, attrKey,indx);}}
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ value={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]}
+ />
+ }
+ {indx == 0 && <button
+ className={(this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]!=='')?'btn btn-primary':'btn btn-secondary'}
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ disabled={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]===''}
+ type='button'
+ onClick={e => {this.addOrTemplate(0 ,attrKey,indx)}}>+</button>}
+ {indx > 0 && <button
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ id={'delete-'+indx}
+ className='btn btn-danger'
+ type='button'
+ onClick={e => {this.deleteOrTemplate(0 ,attrKey,indx)}}>x</button>}
+
+ </div>
+ )
+ })}
+
+ </Col>
+ </Row>
+ );
+ }
+ )}
+ </Grid>
+ </Panel.Body>
+ </Panel>
+ </div>
+ </form>
+ <div className={(this.state.showPathFilterDslBuilder && this.state.showEditNodeModal) ? 'show' : 'hidden'}>
+ <Modal show={this.state.showPathFilterDslBuilder} onHide={!this.state.showPathFilterDslBuilder} style={{width:'100%'}}>
+ <Modal.Header>
+ <Modal.Title>Build DSL Path</Modal.Title>
+ </Modal.Header>
+ <Modal.Body style={{overflow:'scroll'}}>
+ <PathFilterDslBuilder nodeType={this.state.pathFilterNodeType}
+ nodeName={this.state.pathFilterNodeName}
+ attrDetails={this.state.pathFIlterAttrDetails}
+ closePathNodeModal={this.closePathNodeModal}
+ submitPathNodeModal={this.submitPathNodeModal}
+ showPathFilterDslBuilder={this.state.showPathFilterDslBuilder}
+ dslPath={this.state.dslPathBuilder}
+ dslPathTree={this.state.dslPathTree}
+ isEditEnable={this.state.isEditEnable}
+ pathFilterIndex={this.state.pathFilterIndex}/>
+ </Modal.Body>
+ </Modal>
+ </div>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeEditNodeModal}>Close</Button>
+ <Button onClick={this.submitEditNodeModal}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ <div className='static-modal'>
+ <Modal show={this.state.showEditModal} onHide={this.closeEditDSLModal}>
+ <Modal.Header>
+ <Modal.Title>Edit DSL Query</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <form>
+ <FormGroup controlId="dslQuery">
+ <ControlLabel>DSL Query</ControlLabel>
+ <FormControl onChange={this.bindEdits.bind(this)} value={this.state.editModel} componentClass="textarea" placeholder="Enter DSL Query" />
+ </FormGroup>
+ </form>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeEditDSLModal}>Close</Button>
+ <Button onClick={this.submitEditAndRunDSL}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ <div>
+ <div className={'card-header ' + (this.state.queryName && this.state.queryName !== '' ? 'show' : 'hidden')}>
+ <div>
+ <h3>{this.state.queryName}</h3>
+ </div>
+ </div>
+ <div className={'card-header ' + (this.state.queryDescription && this.state.queryDescription !== '' ? 'show' : 'hidden')}>
+ <div>
+ <h4>{this.state.queryDescription}</h4>
+ </div>
+ </div>
+ <div className={'card-header ' + (this.state.dslQuery && this.state.dslQuery !== '' ? 'show' : 'hidden')}>
+ <div>
+ <h4><strong>DSL Query: </strong><span className='pre-wrap-text'>{this.state.dslQuery}</span></h4>
+ </div>
+ </div>
+ </div>
+ {this.state.enableModalFeedback && <Spinner loading={true}><span height="100%" width="100%"></span></Spinner>}
+ <svg id='DSLBuilder' width='1800' height='800'></svg>
+ </div>
+ </div>
+ );
+ }
+}
+
+export default CustomDslBuilder;
diff --git a/src/app/byoq/PathFilterDslBuilder.jsx b/src/app/byoq/PathFilterDslBuilder.jsx
new file mode 100644
index 0000000..2c6e7bb
--- /dev/null
+++ b/src/app/byoq/PathFilterDslBuilder.jsx
@@ -0,0 +1,1105 @@
+/*
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+import React, {Component} from 'react';
+import Modal from 'react-bootstrap/lib/Modal';
+import Grid from 'react-bootstrap/lib/Grid';
+import FormGroup from 'react-bootstrap/lib/FormGroup';
+import FormControl from 'react-bootstrap/lib/FormControl';
+import ControlLabel from 'react-bootstrap/lib/ControlLabel';
+import Button from 'react-bootstrap/lib/Button';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+import Spinner from 'utils/SpinnerContainer.jsx';
+import Row from 'react-bootstrap/lib/Row';
+import Col from 'react-bootstrap/lib/Col';
+import Panel from 'react-bootstrap/lib/Panel';
+import Tooltip from 'react-bootstrap/lib/Tooltip';
+import FilterTypes from 'generic-components/filter/components/FilterTypes.jsx';
+import BootstrapSwitchButton from 'bootstrap-switch-button-react';
+import {GeneralCommonFunctions} from 'utils/GeneralCommonFunctions.js';
+import * as d3 from "d3";
+import 'd3-selection-multi';
+
+
+let EDGERULES = GlobalExtConstants.EDGERULES;
+let OXM = GlobalExtConstants.OXM;
+let INVLIST = GlobalExtConstants.INVLIST;
+let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
+let APERTURE_SERVICE = JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+
+let nodeTypes = [];
+let properties = null;
+let traverseRulesDsl = [];
+
+const settings = {
+ 'NODESERVER': INVLIST.NODESERVER,
+ 'PROXY': INVLIST.PROXY,
+ 'PREFIX': INVLIST.PREFIX,
+ 'VERSION': INVLIST.VERSION,
+ 'USESTUBS': INVLIST.useStubs
+};
+class PathFilterDslBuilder extends Component {
+ constructor(props) {
+ console.log('PathFilter props>>>>',props);
+ super(props);
+ APERTURE_SERVICE=JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'APERTURE_SERVICE'));
+ this.state = {edgeRules : null,
+ showNodeModal: false,
+ treemap: null,
+ root: null,
+ svg: null,
+ duration: null,
+ g: null,
+ selectedNode: null,
+ traverseToNodes:[],
+ nodeDetails: [],
+ dslQuery: '',
+ dslQueryTree:'',
+ editModel:'',
+ showEditModal: false,
+ zoomFit: null,
+ autoZoomEnabled: true,
+ aggregateObjects: false,
+ init: true,
+ filterTypeDisplay: 'Filter Type',
+ selectedfilterType:[],
+ oxmMapping:null,
+ closePathNodeModal:true,
+ submitPathNodeModal:false,
+ parentNodeType:'',
+ parentAttrDetails:'',
+ showPathFilterDslBuilder:false,
+ dslPath:'',
+ dslPathTree:null,
+ isInitialize:true,
+ treeData:'',
+ showEditNodeModal:false,
+ enableRealTime: JSON.parse(sessionStorage.getItem(ENVIRONMENT + 'ENABLE_ANALYSIS'))
+ }
+ }
+
+ componentDidMount () {
+ console.log('Path Filter componentDidMount',JSON.stringify(this.props));
+ //this.buildSQLStatementsFromSchema();
+ this.processEdgeRules(EDGERULES);
+ }
+ componentDidUpdate (nextProps) {
+ console.log('Path Filter componentDidUpdate>>>>>>>',nextProps);
+ if(this.state.isInitialize){
+ this.props=nextProps;
+ console.log('this.props>>>>>>>>>>>>>',this.props);
+ this.setState({submitPathNodeModal:this.props.submitPathNodeModal,
+ closePathNodeModal:this.props.closePathNodeModal,
+ parentNodeType:this.props.nodeType,
+ parentAttrDetails:this.props.attrDetails,
+ showPathFilterDslBuilder:this.props.showPathFilterDslBuilder,
+ dslPath:this.props.dslPath,
+ dslPathTree:this.props.dslPathTree,
+ isInitialize: false},()=>{
+ if(this.props.dslPathTree){
+ this.build(this.props.nodeType,null,this.props.attrDetails,this.props.dslPathTree);
+ }else{
+ //this.initialize(this.props.nodeName);
+ this.setState({showNodeModal: true,isInitialize:false},()=>{this.populateEdgeRules(this.props.nodeName,this.state.edgeRules)});
+ }
+ });
+ }
+ console.log('this.state under Update>>>>>',this.state);
+ }
+ componentWillReceiveProps(nextProps) {
+ console.log('path Filter componentWillReceiveProps>>>>');
+ }
+ initialize = () => {
+ var nodeDetails = [];
+ var node = null;
+ console.log('initializing');
+ var id = GeneralCommonFunctions.generateID();
+ var nodeTypes = GeneralCommonFunctions.getNodeTypes();
+ for (var i = 0; i < nodeTypes.length; i++) {
+ node = nodeTypes[i] + id;
+ if(this.props.nodeName === nodeTypes[i]){
+ var attributes = GeneralCommonFunctions.getFilteringOptions(nodeTypes[i]);
+ if(!nodeDetails[node] && Object.keys(attributes).length > 0){
+ nodeDetails[node] = {};
+ nodeDetails[node].nodeType = nodeTypes[i];
+ nodeDetails[node].isSelected = false;
+ nodeDetails[node].attrDetails = attributes;
+ nodeDetails[node].parentContainer = GeneralCommonFunctions.populateContainer(nodeTypes[i]);
+ }
+ }
+ }
+ let nodesSorted = nodeDetails.sort(function (filter1, filter2) {
+ if (filter1.nodeType < filter2.nodeType) {
+ return -1;
+ } else if (filter1.nodeType > filter2.nodeType) {
+ return 1;
+ } else {
+ return 0;
+ }
+ });
+ console.log('Node Types List' + JSON.stringify(nodesSorted));
+ nodeDetails = nodesSorted;
+ this.setState({
+ nodeDetails: nodeDetails,
+ showNodeModal: true,
+ isInitialize:false
+ });
+ }
+ initialLoadWhileClose= ()=>{
+ this.setState({showNodeModal: true,isInitialize:false},()=>{this.populateEdgeRules(this.props.nodeName,this.state.edgeRules)});
+ }
+ processEdgeRules = (data) => {
+ this.setState({
+ edgeRules: data.rules
+ });
+ }
+ closeNodeModal = () =>{
+ this.setState({
+ showNodeModal: false,
+ traverseToNodes: [],
+ selectedNode: null
+ });
+ }
+ onNodeCheckbox(e) {
+ var nodeDetails = this.state.nodeDetails;
+ if (e.target.checked) {
+ nodeDetails[e.target.value].isSelected = true;
+ this.selectAll(e.target.value);
+ }else {
+ nodeDetails[e.target.value].isSelected = false;
+ this.deselectAll(e.target.value);
+ }
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ onNodeRadio(e) {
+ var nodeDetails = this.state.nodeDetails;
+ if (e.target.checked) {
+ nodeDetails[e.target.value].isSelected = true;
+ this.selectAll(e.target.value);
+ }
+ for (var key in nodeDetails) {
+ if(key != e.target.value && nodeDetails[key].isSelected ){
+ nodeDetails[key].isSelected = false;
+ this.deselectAll(key);
+ }
+ }
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ onAutoZoomCheckbox(e) {
+ var cbValue = false;
+ if (e.target.checked) {
+ cbValue = true;
+ }else {
+ cbValue = false;
+ }
+ this.setState({ autoZoomEnabled: cbValue });
+ }
+
+ onAttributeCheckbox(e){//delete
+ let splitVal = e.target.value.split("|");
+ let nodeKey = splitVal[0];
+ let attrValue = splitVal[1];
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ let attribute = null;
+ if(!node.attrDetails){
+ node.attrDetails = [];
+ }
+ if(!node.attrDetails[attrValue]){
+ node.attrDetails[attrValue] = {};
+ node.attrDetails[attrValue].isSelected = true;
+ node.attrDetails[attrValue].filterValue = [];
+ node.attrDetails[attrValue].filterType = [];
+ }
+
+ // check if the check box is checked or unchecked
+ if (e.target.checked) {
+ // add the value of the checkbox to nodes array
+ node.attrDetails[attrValue].isSelected = true;
+ node.attrDetails[attrValue].filterType[0]='EQ';
+ } else {
+ // or remove the value from the unchecked checkbox from the array
+ node.attrDetails[attrValue].isSelected = false;
+ node.attrDetails[attrValue].filterType = [''];
+ node.attrDetails[attrValue].filterValue = [''];
+ }
+ nodeDetails[nodeKey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ onFilterValueChange(e, nodeKey, attrKey, indx){
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ if(!node.attrDetails){
+ node.attrDetails = [];
+ }
+ if(!node.attrDetails[attrKey]){
+ node.attrDetails[attrKey] = {};
+ node.attrDetails[attrKey].isSelected = true;
+ node.attrDetails[attrKey].filterValue = [];
+ node.attrDetails[attrKey].filterType = [];
+ }
+ // add the value of the checkbox to nodes array
+ //node.attrDetails[attrKey].filterValue.push(e.target.value);
+ let filterValArr=node.attrDetails[attrKey].filterValue;
+ filterValArr[indx]=e.target.value;
+ node.attrDetails[attrKey].filterValue=filterValArr;
+ nodeDetails[nodeKey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ submitPathNodeModal= () =>{
+ console.log('PathFinder submitPathNodeModal>>>>>',this.props);
+ this.props.submitPathNodeModal(this.state.dslQuery,this.props.nodeType,this.state.dslQueryTree,this.props.isEditEnable,this.props.pathFilterIndex);
+ }
+ submitNodeModal = () =>{
+ if(this.state.selectedNode){
+ var treeData=this.state.dslQueryTree;
+ var updatedTreeData='';
+ var d = this.state.selectedNode;
+ for(var node in this.state.nodeDetails){
+ if(this.state.nodeDetails[node].isSelected){
+ var newNodeObj = {
+ type: 'node',
+ name: this.state.nodeDetails[node].nodeType,
+ id: node,
+ details: {}
+ };
+ //Creates new Node
+ Object.assign(newNodeObj.details, this.state.nodeDetails[node]);
+ var newNode = d3.hierarchy(newNodeObj);
+ newNode.depth = d.depth + 1;
+ newNode.height = d.height - 1;
+ newNode.parent = d;
+ newNode.id = node;
+ if(!d.children){
+ d.children = [];
+ }
+ if(newNodeObj.details){
+ var selectedAttributeCount = 0;
+ for (var key in newNodeObj.details.attrDetails){
+ if (newNodeObj.details.attrDetails[key].isSelected){
+ selectedAttributeCount++;
+ }
+ if(selectedAttributeCount === Object.keys(newNodeObj.details.attrDetails).length){
+ newNodeObj.details.includeInOutput = true;
+ }
+ }
+ }
+ console.log('submit node newNodeObj>>>>>',newNodeObj);
+ treeData=(updatedTreeData==='')?treeData:updatedTreeData;
+ updatedTreeData=this.handlingTreeDataWhileAddRemove(treeData,newNodeObj,d.data.id,d.data.name);
+ d.children.push(newNode);
+ this.setState({ nodeDetails: [] });
+ }
+ }
+ this.setState({
+ showNodeModal: false,
+ traverseToNodes: [],
+ selectedNode: null,
+ dslQueryTree:updatedTreeData
+ }, ()=>{this.update(this, d)});
+ }else{
+ var nodeType = "";
+ var attrDetails = null;
+ for (var key in this.state.nodeDetails) {
+ if(this.state.nodeDetails[key].isSelected){
+ nodeType = this.state.nodeDetails[key].nodeType;
+ attrDetails = this.state.nodeDetails[key].attrDetails;
+ }
+ }
+ this.build(nodeType, null, attrDetails);
+ this.setState({ nodeDetails: [], showNodeModal: false, traverseToNodes: [], selectedNode: null });
+ }
+ }
+ handlingTreeDataWhileAddRemove = (treeData,addObject,id,name)=>{
+ if(addObject===''){
+ if(treeData.children && treeData.children.length>0){
+ for(var y=0;y<treeData.children.length;y++){
+ if(treeData.children[y].id=== id && treeData.children[y].name===name){
+ treeData.children.splice(y,1);
+ }else{
+ treeData.children[y]=this.handlingTreeDataWhileAddRemove(treeData.children[y],'',id,name);
+ }
+ }
+ }
+ }else{
+ if(treeData.id === id && treeData.name===name){
+ if(!treeData.children){
+ treeData.children=[];
+ }
+ treeData.children.push(addObject);
+ }else if(treeData.children && treeData.children.length>0){
+ for(var y=0;y<treeData.children.length;y++){
+ if(treeData.children[y].id=== id && treeData.children[y].name===name){
+ if(!treeData.children[y].children){
+ treeData.children[y].children=[];
+ }
+ treeData.children[y].children.push(addObject);
+ }else{
+ treeData.children[y]=this.handlingTreeDataWhileAddRemove(treeData.children[y],addObject,id,name);
+ }
+ }
+ }
+ }
+ return treeData;
+ }
+
+ populateEdgeRules = (nodeType) => {
+ let nodeDetails=GeneralCommonFunctions.populateEdgeRules(nodeType,this.state.edgeRules);
+ this.setState({
+ nodeDetails: nodeDetails
+ });
+ }
+
+
+ closeEditDSLModal = () => {
+ console.log("closing DSL edit modal");
+ this.setState({ showEditModal: false });
+ }
+ submitEditNodeModal = () =>{
+ this.update(this, this.state.selectedNode);
+ this.setState({showEditNodeModal: false});
+ }
+ closeEditNodeModal = () =>{
+ this.setState({
+ showEditNodeModal: false,
+ selectedNode: null
+ });
+ }
+ bindEdits = (e) => {
+ this.setState({ editModel: e.target.value });
+ }
+
+ update = (base, source, isInit) => {
+
+ // Assigns the x and y position for the nodes
+ var treeData = base.state.treemap(base.state.root);
+
+ var DSL = GeneralCommonFunctions.populatePathDSL(treeData,true,false,this.state.enableRealTime);
+ console.log(JSON.stringify("DSL :" + DSL));
+
+ this.setState({ dslQuery: DSL });
+
+ // Compute the new tree layout.
+ var nodes = treeData.descendants(),
+ links = treeData.descendants().slice(1);
+
+ var list1 = d3.selectAll(".fa")
+ .filter(".fa-plus")
+ .style("display","block");
+
+ // Normalize for fixed-depth.
+ nodes.forEach(function(d){ d.y = d.depth * 100});
+
+ // ****************** Nodes section ***************************
+
+ // Update the nodes...
+ var node = base.state.g.selectAll('g.node')
+ .data(nodes, function(d) {return d.id });
+
+ // Enter any new modes at the parent's previous position.
+ var nodeEnter = node.enter().append('g')
+ .attr('class', 'node')
+ .attr("transform", function(d) {
+ return "translate(" + source.y0 + "," + source.x0 + ")";
+ })
+ // .on('click', click)
+ .on('dblclick', doubleClick);
+
+ // Add Circle for the nodes
+ nodeEnter.append('circle')
+ .attr('class', 'node')
+ .attr('r', 1e-6)
+ .style("fill", function(d) {
+ return d.data.details && d.data.details.includeInOutput ? "lightsteelblue" : "#fff";
+ });
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 20)
+ .attr("height", 25)
+ .attr("y", -14)
+ .attr("x", -10)
+ .append("xhtml:span")
+ .attr("class", function (d) {
+ let icon = '';
+ if(!INVLIST.IS_ONAP){
+ icon = 'icon-datanetwork-serverL';
+ }else{
+ icon = 'browse-fa fa fa-server';
+ }
+ if(d.data.details && d.data.details.parentContainer){
+ var iconKey = ((d.data.details.parentContainer).replace(/-/g, '')).toUpperCase();
+ if(INVLIST.INVENTORYLIST[iconKey] && INVLIST.INVENTORYLIST[iconKey].icon){
+ return INVLIST.INVENTORYLIST[iconKey].icon;
+ }else{
+ return icon;
+ }
+ }else{
+ return icon;
+ }
+ })
+ .style("font-size", function (d) {
+ if (!INVLIST.IS_ONAP){
+ return "20px";
+ } else {
+ return "16px";
+ }
+ })
+ .attr("id", function (d) {return "nodeIcon" + d.id})
+ .style("color", '#387dff')
+ .style("display", "block")
+ .style("padding-top",function(d){
+ if (!INVLIST.IS_ONAP){
+ return "0px";
+ } else {
+ return "8px";
+ }
+ });
+
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 6)
+ .attr("height", 6)
+ .attr("y", 10)
+ .attr("x", -10)
+ .on('click', function (d) {
+ if(d.data.details.isRootNode){
+ d = null;
+ base.state.svg.selectAll("*").remove();
+ base.setState({init: true, dslQuery: '',dslQueryTree:''});
+ }else{
+ let dslQueryTree=base.state.dslQueryTree;
+ for(var i = 0; d.parent.children && i < d.parent.children.length; i++){
+ if (d.parent.children.length > 1 && d.data.name === d.parent.children[i].data.name){
+ d.parent.children.splice(i, 1);
+ dslQueryTree=base.handlingTreeDataWhileAddRemove(dslQueryTree,'',d.data.id,d.data.name);
+ base.setState({dslQueryTree:dslQueryTree});
+ }else if (d.parent.children.length === 1 && d.data.name === d.parent.children[i].data.name){
+ d.parent.children = null;
+ }
+ }
+ base.update(base, d);
+ }
+ })
+ .append("xhtml:span")
+ .attr("class", "fa fa-minus")
+ .style("padding-top", "1px")
+ .style("font-size", function (d){ return "5px";})
+ .attr("id", function (d) {return "nodeDelete" + d.id})
+ .style("color", '#387dff')
+ .style("display", function (d) {return "block";});
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 6)
+ .attr("height", 6)
+ .attr("y", 10)
+ .attr("x", 5)
+ .on('click', function (d) { add(d)})
+ .append("xhtml:span")
+ .attr("class", "fa fa-plus")
+ .style("font-size", function (d){ return "5px";})
+ .style("padding-top", "1px")
+ .attr("id", function (d) {return "nodeAdd" + d.id})
+ .style("color", '#387dff');
+ nodeEnter.append("svg:foreignObject")
+ .attr("width", 6)
+ .attr("height", 6)
+ .attr("y", -17)
+ .attr("x", -10)
+ .on('click', function (d) { edit(d)})
+ .append("xhtml:span")
+ .attr("class", "fa fa-pencil-square")
+ .style("padding-top", "1px")
+ .style("font-size", function (d){ return "5px";})
+ .attr("id", function (d) {return "nodeEdit" + d.id})
+ .style("color", '#387dff');
+ // Add labels for the nodes
+ nodeEnter.append('text')
+ .attr("dy", ".35em")
+ .attr("x", function(d) {
+ return d.children ? -13 : 13;
+ })
+ .attr("text-anchor", function(d) {
+ return d.children ? "end" : "start";
+ })
+ .text(function(d) { return d.data.name; });
+
+ // UPDATE
+ var nodeUpdate = nodeEnter.merge(node);
+ var postNodeDrawnCallBack = function (d){
+ if(!isInit && base.state.autoZoomEnabled || d.data.details.isRootNode){
+ base.state.zoomFit();
+ }
+ }
+ // Transition to the proper position for the node
+ nodeUpdate.transition()
+ .duration(base.state.duration)
+ .attr("transform", function(d) {
+ return "translate(" + d.y + "," + d.x + ")"
+ }).on("end", postNodeDrawnCallBack);
+
+ // Update the node attributes and style
+ nodeUpdate.select('circle.node')
+ .attr('r', 11)
+ .style("fill", function(d) {
+ return d.data.details && d.data.details.includeInOutput ? "lightsteelblue" : "#fff";
+ })
+ .attr('cursor', 'pointer');
+
+
+ // Remove any exiting nodes
+ var nodeExit = node.exit().transition()
+ .duration(base.state.duration)
+ .attr("transform", function(d) {
+ return "translate(" + source.y + "," + source.x + ")";
+ })
+ .remove();
+
+ // On exit reduce the node circles size to 0
+ nodeExit.select('circle')
+ .attr('r', 1e-6);
+
+ // On exit reduce the opacity of text labels
+ nodeExit.select('text')
+ .style('fill-opacity', 1e-6);
+
+ // ****************** links section ***************************
+
+ // Update the links...
+ var link = base.state.g.selectAll('path.link')
+ .data(links, function(d) { return d.id; });
+
+ // Enter any new links at the parent's previous position.
+ var linkEnter = link.enter().insert('path', "g")
+ .attr("class", "link")
+ .attr('d', function(d){
+ var o = {x: source.x0, y: source.y0}
+ return diagonal(o, o)
+ });
+
+ // UPDATE
+ var linkUpdate = linkEnter.merge(link);
+
+ // Transition back to the parent element position
+ linkUpdate.transition()
+ .duration(base.state.duration)
+ .attr('d', function(d){ return diagonal(d, d.parent) });
+
+ // Remove any exiting links
+ var linkExit = link.exit().transition()
+ .duration(base.state.duration)
+ .attr('d', function(d) {
+ var o = {x: source.x, y: source.y}
+ return diagonal(o, o)
+ })
+ .remove();
+
+ // Store the old positions for transition.
+ nodes.forEach(function(d){
+ d.x0 = d.x;
+ d.y0 = d.y;
+ });
+
+ // Creates a curved (diagonal) path from parent to the child nodes
+ function diagonal(s, d) {
+ 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;
+ return path
+ }
+ base.state.svg.on("dblclick.zoom", null);
+ // Toggle children on click.
+ function add(d){
+ base.populateEdgeRules(d.data.name,base.state.edgeRules);
+ if(!d.children){
+ d.children = [];
+ d.data.children = [];
+ }
+ base.setState({
+ selectedNode: d,
+ showNodeModal: true
+ });
+
+ }
+ function edit(d){
+ console.log("object editing: " + d);
+ var nodeDetails = base.state.nodeDetails;
+ //set up node details to have the node to edit
+ nodeDetails[0] = d.data.details;
+ base.setState({
+ selectedNode: d,
+ showEditNodeModal: true
+ });
+ }
+ function doubleClick(d) {
+ edit(d);
+ }
+ }
+ selectAll = (nodeKey) =>{//delete
+ var nodeDetails = this.state.nodeDetails;
+ for (var key in nodeDetails[nodeKey].attrDetails) {
+ nodeDetails[nodeKey].attrDetails[key].isSelected = true;
+ }
+ this.setState({nodeDetails: nodeDetails});
+ }
+ deselectAll = (nodeKey) =>{//delete
+ var nodeDetails = this.state.nodeDetails;
+ for (var key in nodeDetails[nodeKey].attrDetails) {
+ nodeDetails[nodeKey].attrDetails[key].isSelected = false;
+ }
+ this.setState({nodeDetails: nodeDetails});
+ }
+ build = (type, propID, attrDetails,preBuiltTree) =>{
+ console.log('build>>>>>>>>',type);
+ var selected = null;
+ var treeData =
+ {
+ "name": "complex",
+ "id": "complex",
+ "children": []
+ };
+ if(!preBuiltTree && type && (propID || attrDetails)){
+ let nodeType = type;
+ treeData = {
+ "name": nodeType,
+ "id": nodeType,
+ "children": [],
+ "details":{}
+ }
+ treeData.details.includeInOutput = true;
+ treeData.details.isSelected = true;
+ treeData.details.isRootNode = true;
+ treeData.details.nodeType = nodeType;
+ if(attrDetails){
+ treeData.details.attrDetails = attrDetails;
+ } else{
+ treeData.details.attrDetails = {};
+ }
+ if(propID){
+ let propIds = (propID) ? propID.split(';') : '';
+ let propertyValue = '';
+ for(var i in propIds){
+ let propValue = propIds[i].split(':');
+ console.log(propValue[0] + '....' + propValue[1]);
+ treeData.details.attrDetails[propValue[0]] = {};
+ treeData.details.attrDetails[propValue[0]].filterValue=[];
+ treeData.details.attrDetails[propValue[0]].filterValue.push(atob(propValue[1]).replace('<pre>','').replace('</pre>',''));
+ treeData.details.attrDetails[propValue[0]].attributeName = propValue[0];
+ treeData.details.attrDetails[propValue[0]].isSelected = true;
+ }
+ }
+ }else if (preBuiltTree){
+ treeData = preBuiltTree;
+ }
+
+ // append the svg object to the body of the page
+ // appends a 'group' element to 'svg'
+ // moves the 'group' element to the top left margin
+ var svg = d3.select("#PathDSLBuilder");
+ // Set the dimensions and margins of the diagram
+ var margin = {top: 20, right: 120, bottom: 20, left: 120},
+ width = +svg.attr("width") - margin.right - margin.left,
+ height = +svg.attr("height") - margin.top - margin.bottom;
+
+ var g = svg.append("g")
+ .attr("transform", "translate("
+ + margin.left + "," + margin.top + ")");
+
+ var duration = 750,
+ root;
+
+ // declares a tree layout and assigns the size
+ var treemap = d3.tree().size([height - 200, width]);
+ // Assigns parent, children, height, depth
+ root = d3.hierarchy(treeData, function(d) { return d.children; });
+ root.x0 = height / 2;
+ root.y0 = 0;
+
+ //Zoom functions
+ function zoom_actions(){
+ g.attr("transform", d3.event.transform)
+ }
+ //add zoom capabilities
+ var zoom_handler = d3.zoom()
+ .on("zoom", zoom_actions);
+
+ zoom_handler(svg);
+
+ function zoomFit() {
+ var bounds = g.node().getBBox();
+ var parent = g.node().parentElement;
+ var fullWidth = parent.clientWidth || parent.parentNode.clientWidth,
+ fullHeight = parent.clientHeight || parent.parentNode.clientHeight;
+ var width = bounds.width,
+ height = bounds.height;
+ var midX = bounds.x + width / 2,
+ midY = bounds.y + height / 2;
+ if (width == 0 || height == 0) return; // nothing to fit
+ var scale = Math.min((0.95 / Math.max(width / fullWidth, height / fullHeight)), 2);
+ var translate = [fullWidth / 2 - scale * midX, fullHeight / 2 - scale * midY];
+
+ var transform = d3.zoomIdentity
+ .translate(80, translate[1])
+ .scale(scale);
+ svg.transition().duration(350)
+ .call(zoom_handler.transform, transform);
+
+ }
+
+ //Set Default zoom
+ svg.call(zoom_handler)
+ .call(zoom_handler.transform, d3.zoomIdentity.translate(80, -500).scale(2));
+ this.setState({
+ init: false,
+ svg: svg,
+ g: g,
+ treemap: treemap,
+ root: root,
+ duration: duration,
+ zoomFit: zoomFit,
+ dslQueryTree: treeData
+ }, ()=>{this.update(this, root, true);})
+
+ // Collapse the node and all it's children
+ function collapse(d) {
+ if(d.children) {
+ d.children.forEach(collapse)
+ d.children = null
+ }
+ }
+
+
+ }
+ onTargetMenuOfFilterTypes=(listname,id)=>{
+ console.log(listname+'onTargetMenuOfFilterTypes',id);
+ let keysOfArray=id.split('#');
+ let nodekey=keysOfArray[0];
+ let attrKey=keysOfArray[1];
+ let indx=parseInt(keysOfArray[2]);
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodekey];
+ if(!node.attrDetails){
+ node.attrDetails = [];
+ }
+ if(!node.attrDetails[attrKey]){
+ node.attrDetails[attrKey] = {};
+ node.attrDetails[attrKey].isSelected = true;
+ node.attrDetails[attrKey].filterValue = [];
+ node.attrDetails[attrKey].filterType = [];
+ }else{
+ let filterTypes=node.attrDetails[attrKey].filterType;
+ filterTypes[indx]=listname;
+ node.attrDetails[attrKey].filterType=filterTypes;
+ }
+ nodeDetails[nodekey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ };
+ filterTags = (key,property,state) =>{
+ let filterTags ='';
+ let filters='';
+ state=true;//always enable, in future if wants to disable remove this line
+ if(APERTURE_SERVICE && this.state.enableRealTime){
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[key];
+ filterTags= Object.keys(Object.keys(node.attrDetails[property].filterType)).map((indx) =>{
+ let selectedFilter=(node.attrDetails[property].filterType[indx]!=='')?node.attrDetails[property].filterType[indx]:this.state.filterTypeDisplay;
+ return <div style={{margin:'0px 0px 0px 5px'}}>
+ <label>
+ <FilterTypes param={this.state}
+ selectedFilter={selectedFilter}
+ id={key+'#'+property+'#'+indx}
+ onMenuSelect={this.onTargetMenuOfFilterTypes}
+ state={!state}/>
+ </label>
+ </div>
+ });
+ filters= <Col md={4} className='removeLeftPadding'>{filterTags}</Col>;
+ }
+ return filters;
+ };
+ addOrTemplate=(nodeKey,attrKey,indx)=>{
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ node.attrDetails[attrKey].filterValue.push('');
+ node.attrDetails[attrKey].filterType.push('EQ');
+ nodeDetails[nodeKey] = node;
+ // update the state with the new array of traverse to nodes
+ this.setState({ nodeDetails: nodeDetails });
+ };
+ deleteOrTemplate=(nodeKey,attrKey,index)=>{
+ let nodeDetails = this.state.nodeDetails;
+ let node = nodeDetails[nodeKey];
+ let filterValuesArray=node.attrDetails[attrKey].filterValue;
+ let filterTypeArray=node.attrDetails[attrKey].filterType;
+ filterValuesArray.splice(index,1);
+ filterTypeArray.splice(index,1);
+ node.attrDetails[attrKey].filterValue=filterValuesArray;
+ node.attrDetails[attrKey].filterType=filterTypeArray;
+ nodeDetails[nodeKey] = node;
+ this.setState({ nodeDetails: nodeDetails });
+ }
+ render(){
+ return(
+ <div id='pathFilterDSLModel'>
+ <div className="addPadding">
+ <div className={'row ' + (!this.state.init ? 'show' : 'hidden')}>
+ <div className="checkbox" style={{float:'left',width:'70%'}}>
+ <label>
+ <input type="checkbox" checked={this.state.autoZoomEnabled} onChange={this.onAutoZoomCheckbox.bind(this)}/>
+ Auto Zoom Enabled
+ </label>
+ </div>
+ <div style={{float:'right'}}>
+ <Button onClick={this.props.closePathNodeModal}>Close</Button>
+ <Button onClick={this.submitPathNodeModal} disabled={(this.state.dslQuery === '')}>Submit</Button>
+ </div>
+ </div>
+ <div className={'row ' + (!this.state.init ? 'show' : 'hidden')}>
+ <div style={{fontWeight:'bold'}}>
+ <span>DSL PATH Query :</span> {this.state.dslQuery}
+ </div>
+ </div>
+ <div className={'row ' + ((this.state.dslQuery != '') ? 'hidden' : 'show')}>
+ <div style={{float:'left'}}>
+ <button className='btn btn-primary' type='button' onClick={this.initialLoadWhileClose}>Start Building (+)</button>
+ </div>
+ <div style={{float:'right'}}>
+ <Button onClick={this.props.closePathNodeModal}>Close</Button>
+ <Button onClick={this.submitPathNodeModal} disabled={(this.state.dslQuery === '')}>Submit</Button>
+ </div>
+ </div>
+ </div>
+ <svg id='PathDSLBuilder' width='1800' height='800'></svg>
+ <div className='static-modal' id='customDslPathBuilderModel'>
+ <Modal show={this.state.showNodeModal} onHide={this.closeNodeModal}>
+ <Modal.Header>
+ <Modal.Title>Modify Dsl Path Query</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <form>
+ {Object.keys(this.state.nodeDetails).sort().map((key, node) => (
+ <div className="dsl-panel">
+ <Panel>
+ <Panel.Heading>
+ <Panel.Title>
+ <div className={'checkbox ' + (!this.state.init ? 'show' : 'hidden')}>
+ <label>
+ <input type="checkbox" checked={this.state.nodeDetails[key].isSelected} value={key} onChange={this.onNodeCheckbox.bind(this)} />
+ {this.state.nodeDetails[key].nodeType}
+ </label>
+ <Panel.Toggle>
+ <div className="pull-right">Options</div>
+ </Panel.Toggle>
+ </div>
+ <div className={'form-check ' + (this.state.init ? 'show' : 'hidden')}>
+ <label className="form-check-label">
+ <input className="form-check-input" type="radio" value={key} checked={this.state.nodeDetails[key].isSelected} onChange={this.onNodeRadio.bind(this)} />
+ {" " + this.state.nodeDetails[key].nodeType}
+ </label>
+ <Panel.Toggle>
+ <div className="pull-right">Options</div>
+ </Panel.Toggle>
+ </div>
+ </Panel.Title>
+ </Panel.Heading>
+ <Panel.Collapse>
+ <Panel.Body className='cardwrap'>
+ <Grid fluid={true} className='addPaddingTop'>
+ <Row className='show-grid addPaddingTop'>
+ <Col md={(this.state.enableRealTime)?4:6}>
+ <strong>PROPERTIES</strong>
+ </Col>
+ {this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
+ <strong>Filter Types</strong>
+ </Col>}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ <strong>Filter By (Optional)</strong>
+ </Col>
+ </Row>
+ {Object.keys(this.state.nodeDetails[key].attrDetails).sort().map((attrKey, attr) => {
+ return(
+ <Row className='show-grid'>
+ <Col md={(this.state.enableRealTime)?4:6}>
+ <div className="checkbox">
+ <label>
+ {attrKey}
+ </label>
+ </div>
+ </Col>
+ {this.filterTags(key,attrKey,this.state.nodeDetails[key].attrDetails[attrKey].isSelected)}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ {Object.keys(this.state.nodeDetails[key].attrDetails[attrKey].filterValue).map((indx) =>{
+ return(
+ <div>
+ {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ onBlur={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
+ />
+ }
+ {this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
+ onChange={(e)=>{this.onFilterValueChange(e, key, attrKey,indx);}}
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ value={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]}
+ />
+ }
+ {indx == 0 && <button
+ className={(this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx] !=='')?'btn btn-primary':'btn btn-secondary'}
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ disabled={this.state.nodeDetails[key].attrDetails[attrKey].filterValue[indx]===''}
+ type='button'
+ onClick={e => {this.addOrTemplate(key,attrKey,indx)}}>+</button>}
+ {indx > 0 && <button
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ id={'delete-'+indx}
+ className='btn btn-danger'
+ type='button'
+ onClick={e => {this.deleteOrTemplate(key,attrKey,indx)}}>x</button>}
+
+ </div>
+ )
+ })}
+ </Col>
+ </Row>
+ );
+ }
+ )}
+ </Grid>
+ </Panel.Body>
+ </Panel.Collapse>
+ </Panel>
+ </div>
+ ))}
+ </form>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeNodeModal}>Close</Button>
+ <Button onClick={this.submitNodeModal}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ <div className='static-modal' id='editNodeModel'>
+ <Modal show={this.state.showEditNodeModal} onHide={this.closeEditNodeModal}>
+ <Modal.Header>
+ <Modal.Title>Modify Node</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <form>
+ <div className="dsl-panel">
+ <Panel>
+ <Panel.Heading>
+ <Panel.Title>
+ <div>
+ <label>{this.state.selectedNode
+ && this.state.selectedNode.data
+ && this.state.selectedNode.data.details ?
+ this.state.selectedNode.data.details.nodeType
+ : ""
+ }
+ </label>
+ </div>
+ </Panel.Title>
+ </Panel.Heading>
+ <Panel.Body className='cardwrap'>
+ <Grid fluid={true} className='addPaddingTop'>
+ <Row className='show-grid addPaddingTop'>
+ <Col md={(this.state.enableRealTime)?4:6}>
+ <strong>Include in Output</strong>
+ </Col>
+ {this.state.enableRealTime && <Col md={4} className='removeLeftPadding'>
+ <strong>Filter Types</strong>
+ </Col>}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ <strong>Filter By (Optional)</strong>
+ </Col>
+ </Row>
+ {this.state.selectedNode
+ && this.state.selectedNode.data
+ && this.state.selectedNode.data.details
+ && this.state.nodeDetails[0]
+ && Object.keys(this.state.nodeDetails[0].attrDetails).sort().map((attrKey, attr) => {
+ return(
+ <Row className='show-grid'>
+ <Col md={(this.state.enableRealTime)?4:6}>
+ <div className="checkbox">
+ <label>
+ {attrKey}
+ </label>
+ </div>
+ </Col>
+ {this.filterTags(0,attrKey, this.state.nodeDetails[0].attrDetails[attrKey].isSelected)}
+ <Col md={(this.state.enableRealTime)?4:6} className='removeLeftPadding'>
+ {Object.keys(this.state.nodeDetails[0].attrDetails[attrKey].filterValue).map((indx) =>{
+ return(
+ <div>
+
+ {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] ==='' && <input type="text"
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ onBlur={(e)=>{this.onFilterValueChange(e, 0, attrKey, indx);}}
+ />
+ }
+ {this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx] !=='' && <input type="text"
+ onChange={(e)=>{this.onFilterValueChange(e, 0, attrKey,indx);}}
+ placeholder={"Enter " + attrKey }
+ className='inputFilter'
+ value={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]}
+ />
+ }
+ {indx == 0 && <button
+ className={(this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]!=='')?'btn btn-primary':'btn btn-secondary'}
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ disabled={this.state.nodeDetails[0].attrDetails[attrKey].filterValue[indx]===''}
+ type='button'
+ onClick={e => {this.addOrTemplate(0 ,attrKey,indx)}}>+</button>}
+ {indx > 0 && <button
+ style={{padding:'2px',margin:'0px 0px 7px 3px'}}
+ id={'delete-'+indx}
+ className='btn btn-danger'
+ type='button'
+ onClick={e => {this.deleteOrTemplate(0 ,attrKey,indx)}}>x</button>}
+
+ </div>
+ )
+ })}
+
+ </Col>
+ </Row>
+ );
+ }
+ )}
+ </Grid>
+ </Panel.Body>
+ </Panel>
+ </div>
+ </form>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeEditNodeModal}>Close</Button>
+ <Button onClick={this.submitEditNodeModal}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ </div>
+ );
+ }
+}
+
+export default PathFilterDslBuilder;