# containers/Investigation/InvestigationContainer.js

## Maintainability

67.07

## Lines of code

239

## Difficulty

42.89

## Estimated Errors

2.21

## Function weight

### By Complexity

### By SLOC

import React, { Component } from 'react'; import PropTypes from 'prop-types' import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { Grid, Row, Col, Tab, TabContainer, Glyphicon, Badge, Nav, NavItem } from 'react-bootstrap'; import DatasetTable from '../../components/Dataset/DatasetTable.js'; import { PERSPECTIVE } from '../../constants/Perspectives.js'; import { addDatasetById, removeDatasetById } from '../../actions/selection.js'; import LogbookContainer from '../Logbook/LogbookContainer'; import Loader from 'react-loader-advanced'; import { setBreadCrumbs } from '../../actions/breadcrumbs.js'; import { fetchDatasetsByDOI, fetchDatasetsByInvestigationId } from '../../actions/datasets.js'; import _ from "lodash"; import ui from '../../config/ui/config.js'; class InvestigationContainer extends Component { constructor(props) { super(props); this.state = { activeTab: this.props.activeTab || 1 } this.handleSelect = this.handleSelect.bind(this); } onLogbookButtonClicked() { this.setState({ perspective: PERSPECTIVE.EVENTS }); } loadDatasetsByInvestigationId() { let { investigationId } = this.props; if (investigationId) { if (this.props.user.sessionId) { this.props.fetchDatasetsByInvestigationId(this.props.user.sessionId, investigationId); let investigation = _.find(this.props.myInvestigations, (investigation) => { return investigation.id === Number(investigationId) }); if (investigation) { // investigation was found in my Data this.props.setBreadCrumbs([ { name: 'My Data', link: '/investigations' }, { name: investigation.visitId.toUpperCase(), link: '/investigations' }, { badge: investigation.name, name: investigation.summary, link: '/investigation/' + investigation.id + '/datasets' } ]); } else { // investion not found in my data, it can be among closed data investigation = _.find(this.props.investigations, (investigation) => { return investigation.id === Number(investigationId) }); if (investigation) { // investigation was found in my Data this.props.setBreadCrumbs([ { name: 'Closed Data', link: '/closed' }, { name: investigation.visitId.toUpperCase(), link: '/investigations' }, { name: investigation.name + ": " + investigation.summary, link: '/investigation/' + investigation.id + '/datasets' } ]); } } } } } setDOIBreadCrumbs(doi) { this.props.setBreadCrumbs([{ name: 'Open Data', link: '/public' }, { badge: doi, name: '', link: '/public/' + doi }]); } componentWillReceiveProps(nextProps) { /** If component was mounted when sessionId was still not ready */ if (!this.props.user.sessionId) { if (nextProps.user.sessionId) { if (nextProps.user.sessionId !== this.props.user.sessionId) { this.fetchData(nextProps.user.sessionId); this.setDOIBreadCrumbs(this.props.doi); } } } if (this.props.doi) { this.setDOIBreadCrumbs(this.props.doi); } } fetchData(sessionId) { if (this.props.doi != null) { if (sessionId) { this.props.fetchDatasetsByDOI(sessionId, this.props.doi); } } else { this.loadDatasetsByInvestigationId(); } } /** * If this props.doi this method will load the datasets that belongs to a doi * otherwise it will load the datasets of a investigation */ componentDidMount() { this.fetchData(this.props.user.sessionId); } /** * Function triggered when the user click to view another tab * @param key {integer} a number corresponding to the tab which is being clicked. 1=datasets, 2=files, 3=events */ handleSelect(key) { this.setState({ activeTab: key }); // The code below changes the content of the address bar. It does not reload the page. let pathname = this.props.history.location.pathname; let lastSlashPosition = pathname.lastIndexOf('/'); let addressBar = pathname.slice(0, lastSlashPosition) if (key === 1) { addressBar = addressBar + '/datasets' } else if (key === 2) { addressBar = addressBar + '/files' } else if (key === 3) { addressBar = addressBar + '/events' } this.props.history.push(addressBar); } render() { /** Array with ID for the rows that will be expanded by default */ let expanded = []; /** Search proposal */ var _this = this; var investigation = _.find(this.props.releasedInvestigations.concat(this.props.myInvestigations).concat(this.props.investigations), function (i) { return i.id === _this.props.investigationId; }); if (investigation) { if (investigation.visitId === "publisher") { expanded = _.map(this.props.datasets.data, function (d) { return d.id; }); } } /** If no user or sessionId return nothing */ if ((!this.props.user) || (!this.props.user.sessionId)) { return null; } return (<Grid fluid> <TabContainer id="tabs" activeKey={this.state.activeTab} onSelect={this.handleSelect}> <Row > <Col sm={12}> <TabContainerMenu isLogBookTabDisplayed={!this.props.isDOI} datasetCount={this.props.datasets.data.length} /> <Tab.Content animation> { ui.investigationContainer.isDatasetListVisible && <Tab.Pane eventKey={1} mountOnEnter={true}> <Loader show={this.props.datasets.fetching}> <DatasetTable selection={this.props.selection} removeDatasetById={this.props.removeDatasetById} addDatasetById={this.props.addDatasetById} sessionId={this.props.user.sessionId} expanded={expanded} datasets={this.props.datasets.data} fetching={this.props.datasets.fetching}> </DatasetTable> </Loader> </Tab.Pane> } <Tab.Pane eventKey={ui.investigationContainer.isDatasetListVisible ? 3 : 1} mountOnEnter={true}> <LogbookContainer investigationId={this.props.investigationId} /> </Tab.Pane> </Tab.Content> </Col> </Row> </TabContainer> </Grid>) } } function TabContainerMenu(props) { var logbookClassName = ""; if (!props.isLogBookTabDisplayed) { logbookClassName = "hidden"; } return ( <Nav bsStyle="tabs"> { ui.investigationContainer.isDatasetListVisible && <NavItem eventKey={1}> <div> <Glyphicon glyph="list" /> <span style={{ marginLeft: "2px" }}> Dataset List &nbsp;</span> <Badge bsClass="ourBadges-m"> {props.datasetCount} </Badge> </div> </NavItem> } <NavItem className={logbookClassName} eventKey={ui.investigationContainer.isDatasetListVisible ? 3 : 1} > <div> <Glyphicon glyph="comment" /> <span style={{ marginLeft: "2px" }}> Logbook </span> </div> </NavItem> </Nav> ) } function mapStateToProps(state) { return { datasets: state.datasets, events: state.events, investigations: state.investigations.data, myInvestigations: state.myInvestigations.data, releasedInvestigations: state.releasedInvestigations.data, selection: state.selection, user: state.user }; } function mapDispatchToProps(dispatch) { return { removeDatasetById: bindActionCreators(removeDatasetById, dispatch), addDatasetById: bindActionCreators(addDatasetById, dispatch), setBreadCrumbs: bindActionCreators(setBreadCrumbs, dispatch), fetchDatasetsByDOI: bindActionCreators(fetchDatasetsByDOI, dispatch), fetchDatasetsByInvestigationId: bindActionCreators(fetchDatasetsByInvestigationId, dispatch) }; } export default connect( mapStateToProps, mapDispatchToProps )(InvestigationContainer); InvestigationContainer.propTypes = { perspective: PropTypes.oneOf([PERSPECTIVE.DATASETS, PERSPECTIVE.FILES, PERSPECTIVE.EVENTS]), /** * the tab which will be displayed 1=dataset tab, 2=file tab, 3=events tab */ activeTab: PropTypes.number }