src/main/app/src/containers/DataView/DataView.js
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);