dash-renderer
Version:
render dash components in react
155 lines (135 loc) • 4.36 kB
JavaScript
import {connect} from 'react-redux'
import {any, contains, equals, isEmpty, isNil} from 'ramda'
import React, {Component, PropTypes} from 'react';
import renderTree from './renderTree';
import {
computeGraphs,
computePaths,
hydrateInitialOutputs,
setLayout
} from './actions/index';
import {getDependencies, getLayout} from './actions/api';
import {APP_STATES} from './reducers/constants';
import AccessDenied from './AccessDenied.react';
/**
* Fire off API calls for initialization
*/
class UnconnectedContainer extends Component {
constructor(props) {
super(props);
this.initialization = this.initialization.bind(this);
}
componentDidMount() {
this.initialization(this.props);
}
componentWillReceiveProps(props) {
this.initialization(props);
}
initialization(props) {
const {
appLifecycle,
dependenciesRequest,
dispatch,
graphs,
layout,
layoutRequest,
paths
} = props;
if (isEmpty(layoutRequest)) {
dispatch(getLayout());
} else if (layoutRequest.status === 200) {
if (isEmpty(layout)) {
dispatch(setLayout(layoutRequest.content));
} else if (isNil(paths)) {
dispatch(computePaths({subTree: layout, startingPath: []}));
}
}
if (isEmpty(dependenciesRequest)) {
dispatch(getDependencies());
} else if (dependenciesRequest.status === 200 && isEmpty(graphs)) {
dispatch(computeGraphs(dependenciesRequest.content));
}
if (
// dependenciesRequest and its computed stores
dependenciesRequest.status === 200 &&
!isEmpty(graphs) &&
// LayoutRequest and its computed stores
layoutRequest.status === 200 &&
!isEmpty(layout) &&
!isNil(paths) &&
// Hasn't already hydrated
appLifecycle === APP_STATES('STARTED')
) {
dispatch(hydrateInitialOutputs());
}
}
render () {
const {
appLifecycle,
config,
dependenciesRequest,
lastUpdateComponentRequest,
layoutRequest,
layout
} = this.props;
// Auth protected routes
if (any(equals(true),
[dependenciesRequest, lastUpdateComponentRequest,
layoutRequest].map(
request => (request.status && request.status === 403))
)) {
return (<AccessDenied config={config}/>);
}
else if (layoutRequest.status &&
!contains(layoutRequest.status, [200, 'loading'])
) {
return (<div>{'Error loading layout'}</div>);
}
else if (
dependenciesRequest.status &&
!contains(dependenciesRequest.status, [200, 'loading'])
) {
return (<div>{'Error loading dependencies'}</div>);
}
else if (appLifecycle === APP_STATES('HYDRATED')) {
return (
<div id="_dash-app-content">
{renderTree(layout, dependenciesRequest.content)}
</div>
);
}
else {
return (<div className="_dash-loading">{'Loading...'}</div>);
}
}
}
UnconnectedContainer.propTypes = {
appLifecycle: PropTypes.oneOf([
APP_STATES('STARTED'),
APP_STATES('HYDRATED')
]),
dispatch: PropTypes.function,
config: PropTypes.object,
dependenciesRequest: PropTypes.object,
lastUpdateComponentRequest: PropTypes.objec,
layoutRequest: PropTypes.object,
layout: PropTypes.object,
paths: PropTypes.object,
history: PropTypes.array
}
const Container = connect(
// map state to props
state => ({
appLifecycle: state.appLifecycle,
config: state.config,
dependenciesRequest: state.dependenciesRequest,
lastUpdateComponentRequest: state.lastUpdateComponentRequest,
layoutRequest: state.layoutRequest,
layout: state.layout,
graphs: state.graphs,
paths: state.paths,
history: state.history
}),
dispatch => ({dispatch})
)(UnconnectedContainer);
export default Container;