summaryrefslogtreecommitdiffstats
path: root/src/app/model/modelSearch/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/model/modelSearch/components')
-rw-r--r--src/app/model/modelSearch/components/ModelBreadcrumb.jsx72
-rw-r--r--src/app/model/modelSearch/components/ModelCard.jsx75
-rw-r--r--src/app/model/modelSearch/components/ModelGallery.jsx672
-rw-r--r--src/app/model/modelSearch/components/ModelNodeCard.jsx51
-rw-r--r--src/app/model/modelSearch/components/ModelNodeGallery.jsx46
-rw-r--r--src/app/model/modelSearch/components/ModelRelationships.jsx137
-rw-r--r--src/app/model/modelSearch/components/ModelTabularView.jsx197
7 files changed, 1250 insertions, 0 deletions
diff --git a/src/app/model/modelSearch/components/ModelBreadcrumb.jsx b/src/app/model/modelSearch/components/ModelBreadcrumb.jsx
new file mode 100644
index 0000000..ffcddb1
--- /dev/null
+++ b/src/app/model/modelSearch/components/ModelBreadcrumb.jsx
@@ -0,0 +1,72 @@
+/*
+ * ============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 from 'react';
+import Col from 'react-bootstrap/lib/Col';
+import Label from 'react-bootstrap/lib/Label';
+import { Link } from 'react-router-dom';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+
+const modelBreadcrumb = (props) => {
+
+ let links = null;
+ let historyStackArr = [];
+ var setURIInSession = function(uri){
+ sessionStorage.setItem(GlobalExtConstants.ENVIRONMENT + 'URI', uri);
+ }
+ if (props.historyStackString) {
+ historyStackArr = props.historyStackString.split('||');
+ for(var i = 0; i < historyStackArr.length; i++){
+ historyStackArr[i] = historyStackArr[i].split(',');
+ console.log('[ModelBreadcrumb.jsx] previous url ' + historyStackArr[i][0] + ' previous api call '+ historyStackArr[i][1]);
+ }
+ links = historyStackArr.map((link, idx) => {
+ let breadCrumbTxt=decodeURI(link[2]).replace(/%2F/g,'/');
+ return (
+ <div className='customBreadCrumb'>
+ {idx === historyStackArr.length - 2 ? (
+ <b id={'breadcrumbStatic' + idx} style={{'float' : 'left'}}>{breadCrumbTxt}</b>
+ ) : idx !== historyStackArr.length - 1 ? (
+ <div id={'breadcrumbLink' + idx}>
+ <div style={{'float' : 'left'}}>
+ <Link
+ key={idx}
+ to={{
+ pathname: link[0],
+ uri: link[1],
+ historyStackString: (breadCrumbTxt==='Origin')?'':props.historyStackString
+ }} onClick={() => setURIInSession(link[1])}>{breadCrumbTxt}
+ </Link>
+ </div>
+ <div style={{'float' : 'left'}}>&nbsp;&nbsp;&#x3E;&#x3E;&nbsp;&nbsp;</div>
+ </div>
+ ):(<div></div>)}
+ </div>
+ );
+ });
+ }
+ return (
+ <Col md={12} className='addPaddingTop'>
+ {links}
+ </Col>
+ );
+};
+
+export default modelBreadcrumb;
diff --git a/src/app/model/modelSearch/components/ModelCard.jsx b/src/app/model/modelSearch/components/ModelCard.jsx
new file mode 100644
index 0000000..2890b52
--- /dev/null
+++ b/src/app/model/modelSearch/components/ModelCard.jsx
@@ -0,0 +1,75 @@
+/*
+ * ============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 from 'react';
+import ModelRelationships from './ModelRelationships.jsx';
+import { Link } from 'react-router-dom';
+import {ExportExcel} from 'utils/ExportExcel.js';
+let buildAttrList = ExportExcel.buildAttrList;
+
+const modelCard = (props) => {
+
+ var propKey = '';
+ var navigateQueryBuilder = '';
+ var editModalIcon = '';
+ var requiredParams = buildAttrList(props.nodeType,[],'mandatory');
+ const properties = Object.keys(props.nodeProps).map((prop, idx) => {
+ let description='';
+ for(var a in requiredParams){
+ if(requiredParams[a].value === prop){
+ description=requiredParams[a].description;
+ if(propKey === ''){
+ propKey = prop + ':' + btoa('<pre>' + props.nodeProps[prop].toString() + '</pre>');
+ }else{
+ propKey = propKey + ';' + prop + ':' + btoa('<pre>' + props.nodeProps[prop].toString() + '</pre>');
+ }
+ }
+ }
+ return (
+ <p className='pre-wrap-text' key={idx}><strong title={description}>{prop}:</strong> {props.nodeProps[prop].toString()}</p>
+ );
+ });
+ let pathNameStr = '/customDslBuilder/' + props.nodeType + '/' + propKey;
+ editModalIcon = <a className={props.isWriteAllowed ? 'show' : 'hidden'} onClick={e => {props.openEditNodeModal(props.nodeUrl)}}><i style={{cursor: 'pointer'}} className="pull-right fa fa-pencil-square-o" aria-hidden="true"></i></a>;
+ navigateQueryBuilder = <Link
+ to={{
+ pathname: pathNameStr
+ }}>
+ <i className={'icon-misc-operationsL pull-right'} role="img"></i>
+ </Link>;
+ return (
+ <div className='card model-card'>
+ <div className='card-header'>
+ <h4 className='card-title'>{props['nodeType']}{editModalIcon}{navigateQueryBuilder}</h4>
+ </div>
+ <div className='card-header'>
+ {props.nodeUrl}
+ </div>
+ <div className='card-content model-card-content'>
+ {properties}
+ </div>
+ <div className='card-footer'>
+ <ModelRelationships historyStackString={props.historyStackString} relatives={props} openHistoryModal={props.openHistoryModal} />
+ </div>
+ </div>
+ );
+};
+
+export default modelCard;
diff --git a/src/app/model/modelSearch/components/ModelGallery.jsx b/src/app/model/modelSearch/components/ModelGallery.jsx
new file mode 100644
index 0000000..d192708
--- /dev/null
+++ b/src/app/model/modelSearch/components/ModelGallery.jsx
@@ -0,0 +1,672 @@
+/*
+ * ============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 Grid from 'react-bootstrap/lib/Grid';
+import Row from 'react-bootstrap/lib/Row';
+import Col from 'react-bootstrap/lib/Col';
+import ModelCard from './ModelCard.jsx';
+import Modal from 'react-bootstrap/lib/Modal';
+import Button from 'react-bootstrap/lib/Button';
+import BootstrapTable from 'react-bootstrap-table-next';
+import {ExportExcel} from 'utils/ExportExcel.js';
+import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
+//import overlayFactory from 'react-bootstrap-table2-overlay';
+import OutputVisualization from 'generic-components/OutputVisualization.jsx';
+import RelationshipList from './ModelTabularView.jsx';
+import PropTypes from 'prop-types';
+import Tabs from 'react-bootstrap/lib/Tabs';
+import Tab from 'react-bootstrap/lib/Tab';
+import commonApi from 'utils/CommonAPIService.js';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+import {GeneralCommonFunctions} from 'utils/GeneralCommonFunctions.js';
+import Spinner from 'utils/SpinnerContainer.jsx';
+
+let INVLIST = GlobalExtConstants.INVLIST;
+let ENVIRONMENT = GlobalExtConstants.ENVIRONMENT;
+
+/**
+ * This function will take all of the node objects and turn them into
+ * a ui grid of ModelCard components. This function is essentially a container
+ * for the ModelCards
+ * @param props
+ * @returns {*}
+ */
+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 = '';
+ if(filterText === ''){
+ filterText = 'Enter ' + this.props.column.text;
+ }
+ return filterText;
+ }
+ setFilterValue = () =>{
+ let filterText = '';
+ var columnFilter = this.props.columnFilterList[this.props.nodeType][0];
+ for(var i=0;i<columnFilter.length;i++){
+ if(columnFilter[i][this.props.column.text] != undefined){
+ filterText = columnFilter[i][this.props.column.text];
+ }
+ }
+ return filterText;
+ }
+ filter = () => {
+ let txt=this.props.column.text;
+ let obj = {};
+ obj[txt] = this.getValue();
+ var columnFilterList = this.props.columnFilterList;
+ var columnFilter = columnFilterList[this.props.nodeType][0];
+ for(var i=0;i<columnFilter.length;i++){
+ if(columnFilter[i][txt] != undefined){
+ columnFilter[i][txt] = this.getValue();
+ columnFilterList[this.props.nodeType] = [];
+ columnFilterList[this.props.nodeType].push(columnFilter);
+ this.props.handleOnFilter(columnFilterList,this.props.nodeType,this.props.columns,this.getValue(),this.props.aliasColumnList);
+ this.props.onFilter(this.getValue());
+ }
+ }
+ }
+ render() {
+ return (
+ <div>
+
+ <input
+ key="input"
+ ref={ node => this.input = node }
+ type="text"
+ placeholder={this.setPlaceHolder()}
+ // value={this.setFilterValue}
+ onChange={this.filter}
+ />
+
+ </div>
+ )
+ }
+}
+
+class ModelGallery extends Component {
+ constructor(props){
+ super(props);
+ this.props = props;
+ this.state = {
+ rerender: false,
+ expanded: [],
+ columnFilterList : {},
+ columnsList: {},
+ aliasColumnList: {},
+ nodeType: '',
+ disableFilter: true,
+ showEditNodeModal: false,
+ focusedNode: null,
+ isEditSuccess: false,
+ isWriteAllowed: sessionStorage.getItem(ENVIRONMENT + 'roles') && sessionStorage.getItem(ENVIRONMENT + 'roles').indexOf('ui_write') > -1,
+ editInputFields: []
+ }
+ }
+ componentWillMount() {
+ console.log('Model gallery component will mount****');
+ }
+ componentWillUnmount() {
+ console.log('Model Gallery component will unmount****');
+ }
+ handleOnExpand = (row, isExpand, rowIndex, e) => {
+ console.log('handleOnExpand single Row...',row.id);
+ if (isExpand) {
+ this.setState(() => ({
+ expanded: [...this.state.expanded,row.id]
+ }));
+ } else {
+ this.setState(() => ({
+ expanded: this.state.expanded.filter(x => x !== row.id)
+ }),function () { this.forceUpdate(); }.bind(this));
+
+ }
+ }
+ handleOnExpandAll = (isExpand, rows, e) => {
+ console.log('handleOnExpandAll to expand all rows');
+ var expandArr = [];
+ if (isExpand) {
+ for(var r=0; r < rows.length; r++){
+ expandArr.push(rows[r].id);
+ }
+ }
+ this.setState(() => ({
+ expanded: expandArr
+ }),function () { this.forceUpdate(); }.bind(this));
+
+ }
+ handleOnFilter = (colFilterList,nodeType,columns,value,aliasColumnList) =>{
+ console.log('handleOnFilter to Re-render',colFilterList);
+ var applyState = true;
+ if(value === ''){
+ Object.keys(colFilterList).forEach(function(pkey){
+ var filterList = colFilterList[pkey][0];
+ for(var j in filterList){
+ Object.keys(filterList[j]).forEach(function(key){
+ if(filterList[j][key] !== ''){
+ applyState = false;
+ }
+ });
+ }
+ });
+ }else{
+ applyState = false;
+ }
+ this.setState({columnFilterList : colFilterList,rerender:true,columnsList : columns,nodeType: nodeType, disableFilter: applyState,aliasColumnList: aliasColumnList});
+ }
+ generateRegexForDsl= (nodeType) =>{
+ var nodePatternwithProp = nodeType+"\\*\\{.*?\\}\\(.*?\\)[\\,|\\>|\\]|\\)]|"+nodeType+"\\*\\(.*?\\)\\{.*?\\}[\\,|\\>|\\]|\\)]|"+nodeType+"\\{.*?\\}\\(.*?\\)[\\,|\\>|\\]|\\)]|"+nodeType+"\\(.*?\\)\\{.*?\\}[\\,|\\>|\\]|\\)]|"+nodeType+"\\{.*?\\}[\\,|\\>|\\]|\\)]|"+nodeType+"\\*\\{.*?\\}[\\,|\\>|\\]|\\)]";
+ return nodePatternwithProp;
+ }
+ /* Start Edit Node Modal Functions */
+ closeEditNodeModal = () =>{
+ this.setState({editErrMsg: null, editInfoMsg: null, showEditNodeModal:false});
+ }
+ submitEditNodeModal = () =>{
+ var payload = {"operations": []};
+ const settings = {
+ 'NODESERVER': INVLIST.NODESERVER,
+ 'PROXY': INVLIST.PROXY,
+ 'PREFIX': INVLIST.PREFIX,
+ 'VERSION': INVLIST.VERSION,
+ 'USESTUBS': INVLIST.useStubs,
+ 'APERTURE': INVLIST.APERTURE,
+ 'APERTURE_SERVICENAME':INVLIST.APERTURE_SERVICENAME
+ };
+ let delimiter = '\/';
+ let start = 3;
+ if((this.state.focusedNode.url).indexOf("/aperture/v") > -1){
+ start = 4;
+ }
+ let tokens = (this.state.focusedNode.url).split(delimiter).slice(start);
+ let patchURL = tokens.join(delimiter);
+ var entry = {
+ "action": "patch",
+ "uri": patchURL,
+ "body": {}
+ };
+ let path = "bulk/single-transaction";
+ this.setState({editErrMsg: null, isPatchLoading: true});
+ for(var key in this.state.editInputFields){
+ if(this.state.editInputFields[key].isEdited){
+ if(this.state.editInputFields[key].newValue !== ""){
+ entry.body[key] = encodeURI(this.state.editInputFields[key].newValue);
+ }else{
+ entry.body[key] = null;
+ }
+ }
+ }
+ payload.operations.push(entry);
+ console.log('ModelGallery: settings:' + JSON.stringify(settings));
+ console.log('ModelGallery: path:' + path);
+ console.log('ModelGallery: payload:' + JSON.stringify(payload));
+ commonApi(settings, path, 'POST', payload, 'SingleTransactionEdit', null, null, null, true)
+ .then(res => {
+ console.log('ModelGallery: Response', Object.keys(res.data));
+ if(res.status === 201 || res.status === 200){
+ if(res.data["operation-responses"] && res.data["operation-responses"][0] && res.data["operation-responses"][0]["response-status-code"] === 200 ){
+ this.setState({isEditSuccess: true, isPatchLoading: false, showEditNodeModal:false});
+ GeneralCommonFunctions.scrollTo("editSuccessMessage");
+ }else{
+ this.triggerError(res.data);
+ }
+ }else{
+ this.triggerError(res.data);
+ }
+ }, error=>{
+ this.triggerError(error);
+ }).catch(error => {
+ this.triggerError(error);
+ });
+ }
+ triggerError = (error) => {
+ console.error('[ModelGallery.jsx] error : ', JSON.stringify(error));
+ let errMsg = this.renderErrorMsg(error);
+ this.setState({
+ isPatchLoading: false,
+ isEditSuccess: false,
+ editErrMsg: errMsg
+ });
+ };
+ 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('[ModeGallery.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["requestError"]){
+ errMsg += JSON.stringify(error["requestError"]);
+ } 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;
+ }
+ openEditNodeModal = (nodeKey) => {
+ console.log("ModelGallery :: openEditNodeModal called with " + nodeKey);
+ var focusedNode = null;
+ for (var i = 0; i < this.props.nodes.length && !focusedNode; i++){
+ if(nodeKey === this.props.nodes[i].url){
+ focusedNode = this.props.nodes[i];
+ break;
+ }
+ }
+ var editInputFields = [];
+ if(focusedNode){
+ var nodeType = focusedNode['node-type'];
+ focusedNode.allowedEditProps = [];
+ //call to check what props can be modified in oxm here;
+ focusedNode.allowedEditProps = GeneralCommonFunctions.getEditableAttributes(nodeType);
+ if(focusedNode.allowedEditProps.length > 0){
+ for (var key in focusedNode.allowedEditProps){
+ var attr = focusedNode.allowedEditProps[key];
+ editInputFields[attr] = {};
+ editInputFields[attr].isEdited = false;
+ if(focusedNode.properties[attr]){
+ editInputFields[attr].oldValue = focusedNode.properties[attr];
+ editInputFields[attr].newValue = focusedNode.properties[attr];
+ }else{
+ editInputFields[attr].oldValue = "";
+ editInputFields[attr].newValue = "";
+ }
+ }
+ }else{
+ this.setState({editInfoMsg: "This element cannot be edited, please contact an administrator if you need the ability to edit the attributes on this element."});
+ }
+ }else{
+ //could not find the node, this shouldn't happen
+ console.log("ModelGallery :: openEditNodeModal could not find " + nodeKey + " in this.props.nodes. This shouldn't happen.");
+ }
+
+ this.setState({showEditNodeModal:true, isEditSuccess: false, focusedNode: focusedNode, editInputFields: editInputFields});
+ }
+ handleInputChange(event) {
+ const target = event.target;
+ const value = target.type === 'checkbox' ? target.checked : target.value;
+ const name = target.name;
+ var editInputFields = this.state.editInputFields;
+ if(target.type === 'text'){
+ editInputFields[name].newValue = value;
+ }else if(target.type === 'checkbox'){
+ if(!value){
+ editInputFields[name].newValue = editInputFields[name].oldValue,
+ editInputFields[name].isEdited = value
+ }else{
+ editInputFields[name].isEdited = value
+ }
+ }
+ this.setState({
+ editInputFields: editInputFields
+ });
+ }
+ /* End Edit Node Modal Functions */
+ render(){
+ let cards = null;
+ let tableColumns = [];
+ let tableValues = [];
+ let rowIndexValue = 0;
+ let svgWidth = window.outerWidth * 0.8;
+ let nodesList=[];
+ let tableColumnsList={};
+ let tableDataList={};
+ let columnFilter = [];
+ let columnFilterList = (this.state.rerender) ? this.state.columnFilterList : {};
+ let aliasColumnList=(this.state.rerender) ? this.state.aliasColumnList: {};
+ let aliasRegex=/\'(\s)as(\s)\'|\'as\'/ig;
+ console.log('Model gallery this.props>>>',this.props);
+ console.log('columnFilterList while rendering:',columnFilterList);
+ this.onTableFilterClick = (nodeType) => {
+ this.setState({rerender:false},function(){this.props.isTableFilterApply(this.state.columnFilterList,nodeType,this.state.columnsList,this.state.aliasColumnList);}.bind(this))
+ }
+ const expandRows = {
+ parentClassName: 'parent-expand-bar',
+ onlyOneExpanding: true,
+ renderer: (row, rowIndex) => (
+ <div>
+ <RelationshipList node={this.props.nodes[parseInt(row.id.split('_')[0])]}
+ key={this.props.nodes[parseInt(row.id.split('_')[0])].id}
+ nodeId={this.props.nodes[parseInt(row.id.split('_')[0])].id}
+ nodeType={this.props.nodes[parseInt(row.id.split('_')[0])]['node-type']}
+ nodeProps={this.props.nodes[parseInt(row.id.split('_')[0])].properties}
+ nodeRelatives={this.props.nodes[parseInt(row.id.split('_')[0])]['related-to']}
+ nodeUrl={this.props.nodes[parseInt(row.id.split('_')[0])].url}
+ historyStackString={this.props.historyStackString}
+ openHistoryModal={this.props.openHistoryModal}
+ openEditNodeModal={this.openEditNodeModal}
+ isWriteAllowed={this.state.isWriteAllowed}
+ rowIndex={parseInt(row.id.split('_')[0])}
+ enableRealTime={this.props.enableRealTime}
+ aliasColumnList={this.props.tableFilterAliasColumns}
+ />
+ </div>
+ ),
+ showExpandColumn: true,
+ expandByColumnOnly: true,
+ onExpandAll: this.handleOnExpandAll,
+ expanded: this.state.expanded,
+ onExpand: this.handleOnExpand
+
+ };
+ const rowEvents = {
+ onClick: (e, row, rowIndex) => {
+ //row index is usefull when single node type exist, for multiple node type use row id
+ rowIndexValue = parseInt(row.id.split('_')[0]);
+ },
+ onMouseEnter: (e, row, rowIndex) => {
+ //row index is usefull when single node type exist, for multiple node type use row id
+ rowIndexValue = parseInt(row.id.split('_')[0]);
+ }
+ };
+ let aliasColumns=[]
+
+ if(this.props.nodes && this.props.nodes[0] && this.props.nodes[0]['node-type'] && this.props.viewName === "CellLayout" ){
+ for(var n=0; n<this.props.nodes.length; n++){
+ let nodeType = this.props.nodes[n]['node-type'];
+ let nodeTypeProperties =[];
+ let aliasProperties=[];
+ let plainNodes ='';
+ let dslQuery = this.props.dslQuery + ',';
+ if(this.props.dslQuery){
+ var nodePatternwithProp = this.generateRegexForDsl(nodeType);
+ var nodeRegularExp = new RegExp(nodePatternwithProp, 'g');
+ plainNodes = dslQuery.match(nodeRegularExp);
+ console.log('plainNodes model Gallery>>>>>*',plainNodes);
+ if(plainNodes){
+ let propertiesPattern ="\\{.*?\\}";
+ var propRegularExp = new RegExp(propertiesPattern, 'g');
+ let nodeTypeProp = plainNodes[0].match(propRegularExp);
+ nodeTypeProp = nodeTypeProp[0].slice(1,-1).split(',');//.replace(/\'/g,'').toLowerCase().split(',');
+ 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,'');
+ }else{
+ nprop=nodeTypeProp[s].replace(/\'/g,'').toLowerCase();
+ }
+ aliasProperties.push(alias);
+ nodeTypeProperties.push(nprop);
+ }
+ }
+ }
+ if(nodesList.indexOf(nodeType) === -1){
+ tableColumns=[];
+ tableValues=[];
+ nodesList.push(nodeType);
+ let tableColumnsBuilt = ExportExcel.buildAttrList(nodeType,[],'required');
+ if(this.props.dslQuery && plainNodes){
+ for(var z=0;z<tableColumnsBuilt.length;z++){
+ let index= nodeTypeProperties.indexOf(tableColumnsBuilt[z].value.toLowerCase());
+ if(index !== -1){
+ if(aliasProperties[index] !==''){
+ let objAlias = {};
+ objAlias[aliasProperties[index]]=nodeTypeProperties[index];
+ aliasColumns.push(objAlias);
+ tableColumnsBuilt[z].value=aliasProperties[index];
+ }
+ tableColumns.push(tableColumnsBuilt[z]);
+ }
+ }
+ }else{
+ tableColumns=tableColumnsBuilt;
+ }
+ console.log('after condition table columns>>>>',tableColumns);
+ tableColumns.push({value:'id'});
+ if(!columnFilterList[nodeType]){
+ columnFilterList[nodeType] = [];
+ columnFilter = [];
+ for(var j = 0; j < tableColumns.length; j++){
+ let txt = tableColumns[j].value;
+ //if(!this.state.reRender && (!columnFilter[j] || (columnFilter[j] && columnFilter[j][txt] === undefined))){
+ let obj = {};
+ obj[txt] = '';
+ obj['description'] = tableColumns[j].description;
+ columnFilter.push(obj);
+ //}
+ }
+ columnFilterList[nodeType].push(columnFilter);
+ }
+ if(!aliasColumnList[nodeType]){
+ aliasColumnList[nodeType]=[];
+ aliasColumnList[nodeType].push(aliasColumns);
+ }
+ for(var j = 0; j < tableColumns.length; j++){
+ if(j === tableColumns.length-1){
+ tableColumns[j].dataField = 'id';
+ tableColumns[j].hidden = true;
+ tableColumns[j].text = tableColumns[j].value;
+ }else{
+ tableColumns[j].dataField = tableColumns[j].value;
+ tableColumns[j].text = tableColumns[j].value;
+ tableColumns[j].headerAttrs= { title:tableColumns[j].description};
+ tableColumns[j].ref=tableColumns[j].value;
+ tableColumns[j].filter = customFilter();
+ tableColumns[j].filterRenderer = (onFilter, column) => <AttributeFilter handleOnFilter= {this.handleOnFilter} onFilter={ onFilter } column={ column } isPageChange={this.props.isPageNumberChange} nodeType={nodeType} columnFilterList={columnFilterList} columns={tableColumnsList} aliasColumnList={aliasColumnList}/>;
+ }
+ }
+ tableColumnsList[nodeType] = tableColumns;
+ tableDataList[nodeType] = [];
+ for(var m=0; m<this.props.nodes.length; m++){
+ let nodeTypeForData = this.props.nodes[m]['node-type'];
+ if(nodeTypeForData === nodeType){
+ let propertiesOfNode = this.props.nodes[m].properties;
+ propertiesOfNode.id = m + '_' + nodeType + '_id';
+ tableValues.push(propertiesOfNode);
+ tableDataList[nodeType].push(tableValues);
+ }
+ }
+ }
+ }
+ }else{
+ cards = this.props.nodes.map(node => {
+ return (
+ <Col key={node.id} lg={3} md={3} sm={6} xs={12}>
+ <ModelCard
+ key={node.id}
+ nodeId={node.id}
+ nodeType={node['node-type']}
+ nodeProps={node.properties}
+ nodeRelatives={node['related-to']}
+ nodeUrl={node.url}
+ historyStackString={this.props.historyStackString}
+ openHistoryModal={this.props.openHistoryModal}
+ openEditNodeModal={this.openEditNodeModal}
+ isWriteAllowed={this.state.isWriteAllowed}
+ enableRealTime={this.props.enableRealTime}
+ aliasColumnList={this.props.tableFilterAliasColumns}/>
+ </Col>
+ );
+ });
+ }
+ let tabs=nodesList.map((nodeType,index) => {
+ return(
+ <Tab eventKey={nodeType} title={nodeType} key={nodeType}>
+ <BootstrapTable
+ id={nodeType}
+ keyField='id'
+ data={tableDataList[nodeType][0]}
+ columns={tableColumnsList[nodeType]}
+ filter={filterFactory()}
+ bordered={true}
+ columnFilter={true}
+ headerClasses='table-header-view'
+ expandRow={expandRows}
+ rowEvents={rowEvents}
+ bootstrap4 striped hover condensed
+ />
+ </Tab>
+ )
+ });
+ return (
+ <div>
+ <div className={'addPaddingTop alert alert-success ' +(this.state.isEditSuccess ? 'show' : 'hidden')} id="editSuccessMessage" role="alert">
+ Update made successfully to {this.state.focusedNode ? this.state.focusedNode.url : ""}. If you wish, you may check your update using a real-time mode query, it may take some time to reflect in analysis mode.
+ </div>
+ <div className='static-modal'>
+ <Modal show={this.state.showEditNodeModal} onHide={this.closeEditNodeModal}>
+ <Modal.Header>
+ <Modal.Title>Edit Element</Modal.Title>
+ </Modal.Header>
+ <Modal.Body>
+ <Spinner loading={this.state.isPatchLoading}>
+ <div className={'addPaddingTop alert alert-danger ' +(this.state.editErrMsg && this.state.editErrMsg !== '' ? 'show' : 'hidden')} id="editErrorMessage" role="alert">
+ An error occurred in editing the element. Please see details {this.state.editErrMsg}
+ </div>
+ <div className={'addPaddingTop alert alert-info ' +(this.state.editInfoMsg && this.state.editInfoMsg !== '' ? 'show' : 'hidden')} id="editNotAllowedMessage" role="alert">
+ {this.state.editInfoMsg}
+ </div>
+ <form>
+ {this.state.focusedNode && Object.keys(this.state.editInputFields).length > 0 && (this.state.focusedNode.allowedEditProps).sort().map((attr) => {
+ return <div class="form-group row">
+ <div className="col-sm-3">
+ <label for={attr} class="col-form-label">{attr}</label>
+ </div>
+ <div class="col-sm-1">
+ <div className="checkbox">
+ <input type="checkbox" name={attr} checked={this.state.editInputFields[attr].isEdited} onChange={this.handleInputChange.bind(this)} />
+ </div>
+ </div>
+ <div class="col-sm-8">
+ <input type="text" class="form-control" id={attr} name={attr} disabled={!this.state.editInputFields[attr].isEdited} onChange={this.handleInputChange.bind(this)} value={this.state.editInputFields[attr].newValue}/>
+ </div>
+ </div>;
+
+ })
+ }
+ </form>
+ </Spinner>
+ </Modal.Body>
+ <Modal.Footer>
+ <Button onClick={this.closeEditNodeModal}>Close</Button>
+ <Button className={this.state.editInfoMsg && this.state.editInfoMsg !== '' ? 'hidden' : ''} onClick={this.submitEditNodeModal}>Submit</Button>
+ </Modal.Footer>
+ </Modal>
+ </div>
+ {(() => {
+ if (this.props.viewName === "CellLayout" && tableValues.length > 0) {
+ if(nodesList.length > 1){
+ if(this.props.isTableFilterApply){
+ return (
+ <div className="addPaddingSide">
+ <button type='button' className={(this.state.disableFilter)? 'btn btn-outline-secondary' : 'btn btn-primary'} disabled={this.state.disableFilter} onClick={() => {this.onTableFilterClick(nodesList)}} style={{float: 'right', margin: '2px'}}>Apply Filters (All)</button>
+ <Tabs defaultActiveKey={nodesList[0]} id="multipleTabularView">
+ {tabs}
+ </Tabs>
+ </div>
+ )
+ }else{
+ return (
+ <div className="addPaddingSide">
+ <Tabs defaultActiveKey={nodesList[0]} id="multipleTabularView">
+ {tabs}
+ </Tabs>
+ </div>
+ )
+ }
+ }else{
+ if(this.props.isTableFilterApply){
+ return(
+ <div className="addPaddingSide">
+ <button type='button' className={(this.state.disableFilter)? 'btn btn-outline-secondary' : 'btn btn-primary'} disabled={this.state.disableFilter} onClick={() => {this.onTableFilterClick(this.state.nodeType)}} style={{float: 'right', margin: '10px'}}>Apply Filters (All)</button>
+ <BootstrapTable
+ id='modelGallery'
+ keyField='id'
+ data={ tableValues }
+ columns={ tableColumns }
+ filter={ filterFactory() }
+ bordered={ true }
+ columnFilter={ true }
+ headerClasses='table-header-view'
+ expandRow={ expandRows }
+ rowEvents={ rowEvents }
+ bootstrap4 striped hover condensed
+ />
+ </div>
+ )
+ }else{
+ return (
+ <div className="addPaddingSide">
+ <BootstrapTable
+ id='modelGallery'
+ keyField='id'
+ data={ tableValues }
+ columns={ tableColumns }
+ filter={ filterFactory() }
+ bordered={ true }
+ columnFilter={ true }
+ headerClasses='table-header-view'
+ expandRow={ expandRows }
+ rowEvents={ rowEvents }
+ bootstrap4 striped hover condensed
+ />
+ </div>
+ )
+ }
+ }
+ } else if (this.props.viewName === "CardLayout") {
+ return (
+ <Grid fluid={true}>
+ <Row className='show-grid'>
+ {cards}
+ </Row>
+ </Grid>
+ )
+ }
+ })()}
+ <div className={this.props.viewName === "VisualLayout" ? 'show' : 'hidden'}>
+ <OutputVisualization identifier="currentState" width={svgWidth} height="1200" overflow="scroll"/>
+ </div>
+ </div>
+ );
+ }
+};
+
+export default ModelGallery;
diff --git a/src/app/model/modelSearch/components/ModelNodeCard.jsx b/src/app/model/modelSearch/components/ModelNodeCard.jsx
new file mode 100644
index 0000000..0caf831
--- /dev/null
+++ b/src/app/model/modelSearch/components/ModelNodeCard.jsx
@@ -0,0 +1,51 @@
+/*
+ * ============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 from 'react';
+import ModelRelationships from './ModelRelationships.jsx';
+import Col from 'react-bootstrap/lib/Col';
+
+const modelNodeCard = (props) => {
+
+ console.log('[Model Node Card] props : ', props);
+ const properties = Object.keys(props.nodeProps).map( (prop, idx) => {
+ return (
+ <p key={idx}><strong> {prop} : </strong> { props.nodeProps[prop].toString()} </p>
+ );
+ });
+
+ return (
+ <Col lg={8} md={8} sm={10}>
+ <div className='card model-card'>
+ <div className='card-header'>
+ Node {props.nodeId}
+ </div>
+ <div className='card-content model-card-content'>
+ {properties}
+ </div>
+ </div>
+ <ModelRelationships relatives={props}/>
+ </Col>
+ );
+};
+
+export default modelNodeCard;
+
+
diff --git a/src/app/model/modelSearch/components/ModelNodeGallery.jsx b/src/app/model/modelSearch/components/ModelNodeGallery.jsx
new file mode 100644
index 0000000..ef6947e
--- /dev/null
+++ b/src/app/model/modelSearch/components/ModelNodeGallery.jsx
@@ -0,0 +1,46 @@
+/*
+ * ============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 from 'react';
+import ModelNodeCard from './ModelNodeCard.jsx';
+
+const modelNodeGallery = (props) => {
+
+ const cards = props.nodes.map(node => {
+ console.log('[Model Node Gallery] : ', node);
+ return (
+ <ModelNodeCard
+ key={node.id}
+ nodeId={node.id}
+ nodeType={node['node-type']}
+ nodeProps={node.properties}
+ nodeRelatives={node['related-to']}
+ nodeUrl={node.url}/>
+ );
+ });
+
+ return (
+ <div>
+ {cards}
+ </div>
+ );
+};
+
+export default modelNodeGallery;
diff --git a/src/app/model/modelSearch/components/ModelRelationships.jsx b/src/app/model/modelSearch/components/ModelRelationships.jsx
new file mode 100644
index 0000000..8dec154
--- /dev/null
+++ b/src/app/model/modelSearch/components/ModelRelationships.jsx
@@ -0,0 +1,137 @@
+/*
+ * ============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 { Link } from 'react-router-dom';
+import Label from 'react-bootstrap/lib/Label';
+import Panel from 'react-bootstrap/lib/Panel';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+import {ExportExcel} from 'utils/ExportExcel.js';
+let buildAttrList = ExportExcel.buildAttrList;
+
+let INVLIST = GlobalExtConstants.INVLIST;
+
+class ModelRelationships extends Component {
+ constructor(props){
+ console.log(props);
+ super(props);
+ this.props = props;
+ }
+
+ render(){
+ console.log('[ModelRelationships.jsx] props : ', this.props);
+ let relationships = null;
+ let navigateByoq = null;
+ let relativesArray = [];
+ this.nodeDisplay = this.props.relatives.nodeType + ' : ' + (this.props.relatives.nodeUrl).split(this.props.relatives.nodeType + '\/').pop();
+ this.historyClick = () => {
+ this.props.openHistoryModal(this.nodeDisplay, this.props.relatives.nodeUrl,this.props.relatives.nodeType);
+ }
+
+ if (this.props.relatives.nodeRelatives && this.props.relatives.nodeRelatives.length > 0) {
+ relationships = this.props.relatives.nodeRelatives.sort(function(a, b) {
+ var compareA = (a['node-type'] + (a.url).split(a['node-type']+'\/').pop()).toLowerCase();
+ var compareB = (b['node-type'] + (b.url).split(a['node-type']+'\/').pop()).toLowerCase();
+ if(compareA < compareB) return -1;
+ if(compareA > compareB) return 1;
+ return 0;
+ }).map((relative, idx) => {
+ if (relativesArray.includes(relative['node-type']) === false) relativesArray.push(relative['node-type']);
+ return (
+ <div>
+ <Link
+ key={idx}
+ to={{
+ pathname: '/model/' + relative['node-type'] + '/' + relative.id + '/'+ this.props.relatives.enableRealTime,
+ uri: relative.url,
+ historyStackString: this.props.historyStackString
+ }}>
+ {relative['node-type']}: {(decodeURI((relative.url).split(relative['node-type']+'\/').pop())).replace(/%2F/g,'/')}</Link> <Label bsStyle='default'>{relative['relationship-label'].slice(33)}</Label>
+ </div>
+ );
+ });
+ }
+ relativesArray = relativesArray.join('&');
+ var propKey = '';
+ var requiredParams = buildAttrList(this.props.relatives.nodeType,[],'mandatory');
+ var aliasColumnFilters = (this.props.relatives.aliasColumnList && this.props.relatives.aliasColumnList[this.props.relatives.nodeType])?this.props.relatives.aliasColumnList[this.props.relatives.nodeType][0]:[];
+ console.log('requiredParams>>>>>>>>>>>>',requiredParams);
+ Object.keys(this.props.relatives.nodeProps).map((prop, idx) => {
+ for(var a in requiredParams){
+ let alias='';
+ if(aliasColumnFilters && aliasColumnFilters[requiredParams[a].value]){
+ alias=requiredParams[a].value;
+ requiredParams[a].value=aliasColumnFilters[requiredParams[a].value];
+ }
+ if(requiredParams[a].value === prop){
+ let tag= (alias!='')? alias: prop;
+ if(propKey === ''){
+ propKey = tag + ':' + btoa('<pre>' + this.props.relatives.nodeProps[prop].toString() + '</pre>');
+ }else{
+ propKey = propKey + ';' + tag + ':' + btoa('<pre>' + this.props.relatives.nodeProps[prop].toString() + '</pre>');
+ }
+ }
+ }
+ });
+ let pathNameStr = (relativesArray.length>0) ? '/customDsl/' + this.props.relatives.nodeType + '/' + propKey + '/' + relativesArray : '/customDsl/' + this.props.relatives.nodeType + '/' + propKey;
+ navigateByoq = <Link
+ to={{
+ pathname: pathNameStr
+ }}>
+ <button type='button' className='btn btn-primary pull-right'>>>BYOQ</button>
+ </Link>;
+ if (this.props.relatives.nodeRelatives && this.props.relatives.nodeRelatives.length > 0) {
+ return (
+ <Panel>
+ <Panel.Heading>
+ <Panel.Toggle>
+ <button type='button' className='btn btn-outline-primary'>
+ Relationships
+ </button>
+ </Panel.Toggle>
+ { INVLIST.isHistoryEnabled && (<button type='button' className='btn btn-outline-primary' onClick={this.historyClick}>
+ History
+ </button>)}
+ {navigateByoq}
+ </Panel.Heading>
+ <Panel.Collapse>
+ <Panel.Body className='cardwrap'>
+ {relationships}
+ </Panel.Body>
+ </Panel.Collapse>
+ </Panel>
+ );
+ } else {
+ return (
+ <div>
+ <button type='button' className='btn btn-outline-disabled'>
+ No relationships
+ </button>
+ { INVLIST.isHistoryEnabled && (<button type='button' className='btn btn-outline-primary' onClick={this.historyClick}>
+ History
+ </button>)}
+ {navigateByoq}
+ </div>
+ );
+ }
+}
+};
+
+export default ModelRelationships;
diff --git a/src/app/model/modelSearch/components/ModelTabularView.jsx b/src/app/model/modelSearch/components/ModelTabularView.jsx
new file mode 100644
index 0000000..3b5a94a
--- /dev/null
+++ b/src/app/model/modelSearch/components/ModelTabularView.jsx
@@ -0,0 +1,197 @@
+/*
+ * ============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 BootstrapTable from 'react-bootstrap-table-next';
+import filterFactory, { textFilter, customFilter } from 'react-bootstrap-table2-filter';
+import PropTypes from 'prop-types';
+import { Link } from 'react-router-dom';
+import Label from 'react-bootstrap/lib/Label';
+import {GlobalExtConstants} from 'utils/GlobalExtConstants.js';
+import {ExportExcel} from 'utils/ExportExcel.js';
+let buildAttrList = ExportExcel.buildAttrList;
+
+let INVLIST = GlobalExtConstants.INVLIST;
+
+ class RelationshipList extends Component {
+
+
+ constructor(props) {
+ super(props);
+ this.props = props;
+ this.relationships = null;
+ this.relativesArray = [];
+ this.state = {
+ filteron:false
+
+ }
+ }
+ render() {
+
+
+ let navigateByoq = null;
+ this.nodeDisplay = this.props.nodeType + ' : ' + (this.props.nodeUrl).split(this.props.nodeType + '\/').pop();
+ this.historyClick = () => {
+ this.props.openHistoryModal(this.nodeDisplay, this.props.nodeUrl,this.props.nodeType);
+ }
+ this.filter = (e) =>{
+ let filterValue = e.target.value;
+ this.returnFilterList(filterValue);
+ this.setState({filteron:true});
+ }
+ this.returnFilterList = (filterValue) =>{
+ if (this.props.nodeRelatives && this.props.nodeRelatives.length > 0) {
+ this.relationships = null;
+ this.relationships = this.props.nodeRelatives.sort(function(a, b) {
+ var compareA = (a['node-type'] + (a.url).split(a['node-type']+'\/').pop()).toLowerCase();
+ var compareB = (b['node-type'] + (b.url).split(a['node-type']+'\/').pop()).toLowerCase();
+ if(compareA < compareB) return -1;
+ if(compareA > compareB) return 1;
+ return 0;
+ }).map((relative, idx) => {
+ if (this.relativesArray.includes(relative['node-type']) === false) this.relativesArray.push(relative['node-type']);
+ if(filterValue === '' || filterValue === ':' || relative['node-type'].toLowerCase().search(filterValue.toLowerCase()) != -1 || (decodeURI((relative.url).split(relative['node-type']+'\/').pop())).replace(/%2F/g,'/').toLowerCase().search(filterValue.toLowerCase()) != -1){
+ return (
+ <li key={idx + '' +relative.id}>
+ <Link
+ key={idx}
+ to={{
+ pathname: '/model/' + relative['node-type'] + '/' + relative.id + '/'+ this.props.enableRealTime,
+ uri: relative.url,
+ historyStackString: this.props.historyStackString
+ }}>
+ {relative['node-type']}: {(decodeURI((relative.url).split(relative['node-type']+'\/').pop())).replace(/%2F/g,'/')}</Link> <Label bsStyle='default'>{relative['relationship-label'].slice(33)}</Label>
+ </li>
+ );
+ }
+ });
+ }
+ }
+ if(!this.state.filteron){
+ this.returnFilterList('');
+ }
+ let relativesArray = (this.relativesArray.length > 0) ? this.relativesArray.join('&') : this.relativesArray;
+ var propKey = '';
+ var requiredParams = buildAttrList(this.props.nodeType,[],'mandatory');
+ var aliasColumnFilters = (this.props.aliasColumnList && this.props.aliasColumnList[this.props.nodeType])?this.props.aliasColumnList[this.props.nodeType][0]:[];
+ Object.keys(this.props.nodeProps).map((prop, idx) => {
+ for(var a in requiredParams){
+ let alias='';
+ if(aliasColumnFilters && aliasColumnFilters[requiredParams[a].value]){
+ alias=requiredParams[a].value;
+ requiredParams[a].value=aliasColumnFilters[requiredParams[a].value];
+ }
+ if(requiredParams[a].value === prop){
+ let tag= (alias!='')? alias: prop;
+ if(propKey === ''){
+ propKey = tag + ':' + btoa(this.props.nodeProps[prop].toString());
+ }else{
+ propKey = propKey + ';' + tag + ':' + btoa(this.props.nodeProps[prop].toString());
+ }
+ }
+ }
+ });
+ let editModalIcon = <a className={this.props.isWriteAllowed ? 'show' : 'hidden'} onClick={e => {this.props.openEditNodeModal(this.props.nodeUrl)}}><i style={{cursor: 'pointer'}} className="pull-right fa fa-pencil-square-o" aria-hidden="true"></i></a>;
+ let pathNameStr = (relativesArray.length>0) ? '/customDsl/' + this.props.nodeType + '/' + propKey + '/' + relativesArray : '/customDsl/' + this.props.nodeType + '/' + propKey;
+ navigateByoq = <Link
+ to={{
+ pathname: pathNameStr
+ }}>
+ <button type='button' className='btn btn-primary pull-right'>>>BYOQ</button>
+ </Link>;
+ let relationships = [];
+ if(this.relationships){
+ for(var n=0 ; n < this.relationships.length ; n++){
+ if(this.relationships[n]){
+ relationships.push(this.relationships[n]);
+ }
+ }
+ }
+ if (this.props.nodeRelatives && this.props.nodeRelatives.length > 0) {
+ return (
+ <div>
+ <div style={{float: 'left'}}>
+ <table className='relationshipTable table-striped table-hover table-bordered table-sm'>
+ <thead>
+ <tr className='table-header-view'>
+ <th titlename='Relationships'>
+ Relationships
+ <div>
+ <input
+ key='input'
+ type='text'
+ placeholder='Enter Relationship...'
+ onChange={(e) => this.filter(e)}
+ />
+ </div>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <ul>
+ {relationships}
+ </ul>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div style={{float: 'left', margin: '10px'}}>
+ { INVLIST.isHistoryEnabled && (<button type='button' className='btn btn-primary pull-right' onClick={this.historyClick}>
+ History
+ </button>)}
+ </div>
+ <div style={{float: 'left',margin: '10px'}}>
+ {navigateByoq}
+ </div>
+ <div style={{float: 'left',margin: '10px'}}>
+ {editModalIcon}
+ </div>
+ </div>
+ )
+ } else {
+ return (
+ <div>
+ <div style={{float: 'left', margin: '10px'}}>
+ <button type='button' className='btn btn-outline-disabled'>
+ No relationships
+ </button>
+ </div>
+ <div style={{float: 'left', margin: '10px'}}>
+ { INVLIST.isHistoryEnabled && (<button type='button' className='btn btn-primary' onClick={this.historyClick}>
+ History
+ </button>)}
+ </div>
+ <div style={{float: 'left', margin: '10px'}}>
+ {navigateByoq}
+ </div>
+ <div style={{float: 'left',margin: '10px'}}>
+ {editModalIcon}
+ </div>
+ </div>
+ );
+ }
+ }
+ }
+
+export default RelationshipList;
+//export default AttributeFilter;