text: import React from 'react';
  import {connect} from 'react-redux';
  import {
    Accordion,
    AccordionSummary,
    Typography,
    AccordionDetails,
    List,
    ListItem,
    ListItemText,
    TextField,
    Fab,
    IconButton,
    Grid,
    Table,
    TableBody,
    TableRow,
    TableCell,
    FormControlLabel,
    Switch,
    Divider,
    Tooltip,
  } from '@material-ui/core';
  import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
  import AddIcon from '@material-ui/icons/Add';
  import DeleteIcon from '@material-ui/icons/Delete';
  import RefreshIcon from '@material-ui/icons/Refresh';
  import ArrowBackIcon from '@material-ui/icons/ArrowBack';
  import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
  import _ from 'lodash';
  import {JsonToTable} from 'react-json-to-table';
  import {ACTIONS,QUERY_ENDPOINT} from '../../constants';
  import axios from "axios";
  import {onFetchQuery} from '../../logics/actionHelper';
  import {stringifyObjectValues} from '../../logics/utils';
  import Checkbox from '@material-ui/core/Checkbox';
  
  class Details extends React.Component {
  
    onAddNodeLabel() {
      this.props.dispatch({ type: ACTIONS.ADD_NODE_LABEL });
    }
  
    onEditNodeLabel(index, nodeLabel) {
      this.props.dispatch(
          { type: ACTIONS.EDIT_NODE_LABEL, payload: { id: index, nodeLabel } });
    }
  
    onRemoveNodeLabel(index) {
      this.props.dispatch({ type: ACTIONS.REMOVE_NODE_LABEL, payload: index });
    }
  
    onEditNodeLimit(limit) {
      this.props.dispatch({ type: ACTIONS.SET_NODE_LIMIT, payload: limit });
    }
  
    onRefresh() {
      this.props.dispatch(
          { type: ACTIONS.REFRESH_NODE_LABELS, payload: this.props.nodeLabels });
    }
  
    onTraverse(nodeId, direction) {
      const query = `g.V('${ nodeId }').${ direction }()`;
      axios.post(
          QUERY_ENDPOINT,
          {
            query: query,
            nodeLimit: this.props.nodeLimit,
          },
          { headers: { 'Content-Type': 'application/json' } },
      ).then((response) => {
        onFetchQuery(response, query, this.props.nodeLabels, this.props.dispatch);
      }).catch((error) => {
        this.props.dispatch(
            { type: ACTIONS.SET_ERROR, payload: error });
      });
    }
  
    onTogglePhysics(enabled) {
      this.props.dispatch(
          { type: ACTIONS.SET_IS_PHYSICS_ENABLED, payload: enabled });
      if (this.props.network) {
        const edges = {
          smooth: {
            type: enabled ? 'dynamic' : 'continuous',
          },
        };
        this.props.network.setOptions({ physics: enabled, edges });
      }
    }
  
    generateList(list) {
      let key = 0;
      return list.map(value => {
        key = key + 1;
        return React.cloneElement((
            <ListItem>
              <ListItemText
                  primary={ value }
              />
            </ListItem>
        ), {
          key,
        })
      });
    }
  
    generateNodeLabelList(nodeLabels) {
      let index = -1;
      return nodeLabels.map(nodeLabel => {
        index = index + 1;
        nodeLabel.index = index;
        return React.cloneElement((
            <ListItem>
              <Checkbox
                  checked={ nodeLabel.show }
                  // onChange={}
                  inputProps={ { 'aria-label': 'primary checkbox' } }
              />
              <TextField id="standard-basic" label="Node Type"
                         InputLabelProps={ { shrink: true } }
                         value={ nodeLabel.type } onChange={ event => {
                const type = event.target.value;
                const field = nodeLabel.field;
                this.onEditNodeLabel(nodeLabel.index, { type, field })
              } }
              />
              <TextField id="standard-basic" label="Label Field"
                         InputLabelProps={ { shrink: true } }
                         value={ nodeLabel.field } onChange={ event => {
                const field = event.target.value;
                const type = nodeLabel.type;
                this.onEditNodeLabel(nodeLabel.index, { type, field })
              } }/>
              <IconButton aria-label="delete" size="small"
                          onClick={ () => this.onRemoveNodeLabel(
                              nodeLabel.index) }>
                <DeleteIcon fontSize="small"/>
              </IconButton>
            </ListItem>
        ), {
          key: index,
        })
      });
    }
  
    render() {
      let hasSelected = false;
      let selectedType = null;
      let selectedId = null;
      let selectedProperties = null;
      let selectedHeader = null;
      if (!_.isEmpty(this.props.selectedNode)) {
        hasSelected = true;
        selectedType = _.get(this.props.selectedNode, 'type');
        selectedId = _.get(this.props.selectedNode, 'id');
        selectedProperties = _.get(this.props.selectedNode, 'properties');
        stringifyObjectValues(selectedProperties);
        selectedHeader = 'Node';
      } else if (!_.isEmpty(this.props.selectedEdge)) {
        hasSelected = true;
        selectedType = _.get(this.props.selectedEdge, 'type');
        selectedId = _.get(this.props.selectedEdge, 'id');
        selectedProperties = _.get(this.props.selectedEdge, 'properties');
        selectedHeader = 'Edge';
        stringifyObjectValues(selectedProperties);
      }
  
      return (
          <div className={ 'details' }>
            <Grid container spacing={ 2 }>
              { hasSelected &&
              <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                <h2>Information: { selectedHeader }</h2>
                { selectedHeader === 'Node' &&
                <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                  <Grid container spacing={ 2 }>
                    <Grid item xs={ 6 } sm={ 6 } md={ 6 }>
                      <Fab variant="extended" size="small"
                           onClick={ () => this.onTraverse(selectedId, 'out') }>
                        Traverse Out Edges
                        <ArrowForwardIcon/>
                      </Fab>
                    </Grid>
                    <Grid item xs={ 6 } sm={ 6 } md={ 6 }>
                      <Fab variant="extended" size="small"
                           onClick={ () => this.onTraverse(selectedId, 'in') }>
                        Traverse In Edges
                        <ArrowBackIcon/>
                      </Fab>
                    </Grid>
                  </Grid>
                </Grid>
                }
                <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                  <Grid container>
                    <Table aria-label="simple table">
                      <TableBody>
                        <TableRow key={ 'type' }>
                          <TableCell scope="row">Type</TableCell>
                          <TableCell align="left">{ String(
                              selectedType) }</TableCell>
                        </TableRow>
                        <TableRow key={ 'id' }>
                          <TableCell scope="row">ID</TableCell>
                          <TableCell align="left">{ String(
                              selectedId) }</TableCell>
                        </TableRow>
                      </TableBody>
                    </Table>
                    <JsonToTable json={ selectedProperties }/>
                  </Grid>
                </Grid>
              </Grid>
              }
              <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                <Accordion>
                  <AccordionSummary
                      expandIcon={ <ExpandMoreIcon/> }
                      aria-controls="panel1a-content"
                      id="panel1a-header"
                  >
                    <Typography>Query History</Typography>
                  </AccordionSummary>
                  <AccordionDetails>
                    <List dense={ true }>
                      { this.generateList(this.props.queryHistory) }
                    </List>
                  </AccordionDetails>
                </Accordion>
                <Accordion defaultExpanded	={true}>
                  <AccordionSummary
                      expandIcon={ <ExpandMoreIcon/> }
                      aria-controls="panel1a-content"
                      id="panel1a-header"
                  >
                    <Typography>Settings</Typography>
                  </AccordionSummary>
                  <AccordionDetails>
                    <Grid container spacing={ 2 }>
                      <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                        <Tooltip title="Automatically stabilize the graph"
                                 aria-label="add">
                          <FormControlLabel
                              control={
                                <Switch
                                    checked={ this.props.isPhysicsEnabled }
                                    onChange={ () => {
                                      this.onTogglePhysics(
                                          !this.props.isPhysicsEnabled);
                                    } }
                                    value="physics"
                                    color="primary"
                                />
                              }
                              label="Enable Physics"
                          />
                        </Tooltip>
                        <Divider/>
                      </Grid>
                      <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                        <Tooltip
                            title="Number of maximum nodes which should return from the query. Empty or 0 has no restrictions."
                            aria-label="add">
                          <TextField label="Node Limit" type="Number"
                                     variant="outlined"
                                     value={ this.props.nodeLimit }
                                     onChange={ event => {
                                       const limit = event.target.value;
                                       this.onEditNodeLimit(limit)
                                     } }/>
                        </Tooltip>
  
                      </Grid>
                      <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                        <Divider/>
                      </Grid>
                      <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                        <Typography>Node Labels</Typography>
                      </Grid>
                      <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                        <List dense={ true }>
                          { this.generateNodeLabelList(this.props.nodeLabels) }
                        </List>
                      </Grid>
                      <Grid item xs={ 12 } sm={ 12 } md={ 12 }>
                        <Fab variant="extended" color="primary" size="small"
                             onClick={ this.onRefresh.bind(this) }>
                          <RefreshIcon/>
                          Refresh
                        </Fab>
                        <Fab variant="extended" size="small"
                             onClick={ this.onAddNodeLabel.bind(this) }>
                          <AddIcon/>
                          Add Node Label
                        </Fab>
                      </Grid>
                    </Grid>
                  </AccordionDetails>
                </Accordion>
              </Grid>
            </Grid>
          </div>
      );
    }
  }
  
  export const DetailsComponent = connect((state) => {
    return {
      network: state.graph.network,
      selectedNode: state.graph.selectedNode,
      selectedEdge: state.graph.selectedEdge,
      queryHistory: state.options.queryHistory,
      nodeLabels: state.options.nodeLabels,
      nodeLimit: state.options.nodeLimit,
      isPhysicsEnabled: state.options.isPhysicsEnabled,
    };
  })(Details);