p632-sp-2017/microservice-catalog-frontend

View on GitHub
src/main/app/src/containers/DataView/DataView.js

Summary

Maintainability
C
1 day
Test Coverage
import React from 'react';
import {connect} from 'react-redux';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';
import { Table } from 'react-bootstrap/lib';
import { LinkContainer } from 'react-router-bootstrap';
import { Alert } from 'react-bootstrap';

import SearchBox from '../../component/SearchBox/SearchBox'
import './DataView.css';
import DetailView from '../../component/DetailView/DetailView';
import {fetchMicroservices} from '../../redux/modules/catalog';

import FontAwesome from 'react-fontawesome';

/**
 * CatalogDataView is Smart component
 * @param {Object} props Varrious props passed by different components
 */
const CatalogDataView = (props) => {
    const { dispatch, catalogData, loading, filterText, errorfetching } = props;
    let open = false;
    let initHeight = 120;
    let intval = null;
    let h;

    if(catalogData.length === 0 && !errorfetching){
      dispatch(fetchMicroservices);
    }

    const slideToggle = (element) => {
      window.clearInterval(intval);
      let mdiv = document.getElementById('mdiv');
      mdiv = element;
      if(getComputedStyle(mdiv).getPropertyValue('display') === "none"){
        open = false;
      }
      else{
        open = true;
      }
      if(open) {
        mdiv.style.visibility="hidden";
        h = mdiv.offsetHeight;
        open = false;
        intval = setInterval(function(){
          h--;
          mdiv.style.height = h + 'px';
          if(h <= 0){
            window.clearInterval(intval);
            mdiv.style.display = 'none';
          }
        }, 1
      );

    }
    else {
      mdiv.style.display = 'block';
      mdiv.style.visibility = "visible";
      h = 0;
      open = true;
      intval = setInterval(function(){
        h++;
        mdiv.style.height = "auto";
        if(h >= initHeight)
        window.clearInterval(intval);
      }, 1
    );
  }
  }

  const header = [{title:"Title", description:"Description", url:"URL", edit:"Edit"}];

  const handleArrowClick = (event) => {
    let classes = event.target.classList;
    let classToAdd = 'fa-caret-down';
    if(classes.contains('fa-caret-down')){
      classToAdd = 'fa-caret-up';
    }
    classes.remove('fa-caret-down','fa-caret-up');
    classes.add(classToAdd);
    let element = event.target.closest('tr').nextSibling;
    slideToggle(element);
  }

  // tableData stores the microservices catalog data
  let tableData = [];

  // populate tableData
  tableData = catalogData.map((dataItem)=>{
    if(filterText==='' || (filterText!=='' && (dataItem.catalog.title.toUpperCase().indexOf(filterText.toUpperCase().trim())!==-1 || dataItem.catalog.description.toUpperCase().indexOf(filterText.toUpperCase().trim())!==-1))){
      let serviceDetails = {
        title: dataItem.catalog.title,
        description: dataItem.catalog.description,
        url: dataItem.catalog.url,
        email: dataItem.catalog.email
      };
      return [
        <tr>
          <td> {dataItem.catalog.title} </td>
          <td> {dataItem.catalog.description}</td>
          <td> {dataItem.catalog.url[0]}</td>
          <td>
            <LinkContainer to={{ pathname: '/addService', query: { id: dataItem.id } }}>
              <FontAwesome title="Edit" name="pencil-square-o" className="fa-lg" />
            </LinkContainer>
          </td>
          <td onClick={handleArrowClick.bind(this)} > <FontAwesome title="Expand/Collapse" className="caret-down" name="caret-down" size="lg" /> </td>
        </tr>,
        <tr className="details">
          <td colSpan="4" className="serviceDetails">
            <DetailView { ...serviceDetails }/>
          </td>
        </tr>
      ];
    }
    else {
      return undefined;
    }
  }, this)

  // return the virtual DOM
  return (
    <div className="Div-container">
      <SearchBox {...props} />
      {
        loading === "LOADING" && catalogData.length<=0 &&
        <FontAwesome name="pulse fa-spinner" className="fa-4x" />
      }
      {
        errorfetching &&
        <div>
          <Alert bsStyle="danger">
            <strong>Sorry! Some error has occurred. Please refresh the page or try again after sometime.</strong>
          </Alert>
        </div>
      }
      {
        loading === "LOADED" && catalogData.length>0 && !errorfetching &&
        <Table responsive hover className="Data">
          <thead>
            {
              header.map((entry,idx) => (
                <tr key={idx}>
                  <th>{entry.title}</th>
                  <th>{entry.description}</th>
                  <th>{entry.url}</th>
                  <th>{entry.edit}</th>
                  <th></th>
                </tr>
              ))
            }
          </thead>
          { catalogData.length > 0 && tableData!==undefined &&
            <tbody>
              { tableData }
            </tbody>
          }
        </Table>
      }
    </div>
  );
}

CatalogDataView.displayName = 'CatalogDataView';

/**
 * Maps the Redux store state into props.
 *
 * @property  {Object} state  - The state from the Redux store.
 */
const mapStateToProps = (state) => {
  return{
    catalogData : state.catalog.catalogData,
    loading : state.catalog.loading,
    filterText: state.catalog.filterText,
    errorfetching: state.catalog.errorfetching
  }
}

export default connect(mapStateToProps)(CatalogDataView);