Skip to content
Snippets Groups Projects
MapApp.js 8.13 KiB
Newer Older
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
Esko Ikkala's avatar
Esko Ikkala committed
import Divider from '@material-ui/core/Divider';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
import ChevronRightIcon from '@material-ui/icons/ChevronRight';
import Tabs from '@material-ui/core/Tabs';
import Tab from '@material-ui/core/Tab';
import IntegrationAutosuggest from '../components/IntegrationAutosuggest';
import LeafletMap from '../components/map/LeafletMap';
import Message from '../components/Message';
import VirtualizedTable from '../components/VirtualizedTable';
Esko Ikkala's avatar
Esko Ikkala committed
import DatasetSelector from '../components/DatasetSelector';
import Immutable from 'immutable';
import Pie from '../components/Pie.js';
Esko Ikkala's avatar
Esko Ikkala committed
  toggleDataset,
  fetchSuggestions,
  clearSuggestions,
  fetchResults,
Esko Ikkala's avatar
Esko Ikkala committed
  setMapReady,
  getGeoJSON,
  updateResultFormat
Esko Ikkala's avatar
Esko Ikkala committed
const drawerWidth = 600;

const styles = theme => ({
  root: {
    flexGrow: 1,
  },
  appFrame: {
    height: '100%',
    zIndex: 1,
    overflow: 'hidden',
    position: 'relative',
    display: 'flex',
    width: '100%',
  },
  appBar: {
    position: 'absolute',
    transition: theme.transitions.create(['margin', 'width'], {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.leavingScreen,
    }),
  },
  appBarShift: {
    width: `calc(100% - ${drawerWidth}px)`,
    transition: theme.transitions.create(['margin', 'width'], {
      easing: theme.transitions.easing.easeOut,
      duration: theme.transitions.duration.enteringScreen,
    }),
  },
  'appBarShift-left': {
    marginLeft: drawerWidth,
  },
  'appBarShift-right': {
    marginRight: drawerWidth,
  },
  menuButton: {
    marginLeft: 12,
    marginRight: 20,
  },
  hide: {
    display: 'none',
  },
Esko Ikkala's avatar
Esko Ikkala committed
  // drawerHeader + drawerPaper = whole left column
  drawerPaper: {
    position: 'relative',
    width: drawerWidth,
Esko Ikkala's avatar
Esko Ikkala committed
    overflow: 'hidden',
  },
  drawerHeader: {
    display: 'flex',
    alignItems: 'center',
Esko Ikkala's avatar
Esko Ikkala committed
    justifyContent: 'center',
    padding: '0 8px',
    ...theme.mixins.toolbar,
  },
  drawerSearch: {
    display: 'flex',
    justifyContent: 'center',
  },
Esko Ikkala's avatar
Esko Ikkala committed
  // content = whole rigth column
  content: {
    flexGrow: 1,
    backgroundColor: theme.palette.background.default,
    //padding: theme.spacing.unit * 3,
    transition: theme.transitions.create('margin', {
      easing: theme.transitions.easing.sharp,
      duration: theme.transitions.duration.leavingScreen,
    }),
  },
  'content-left': {
    marginLeft: -drawerWidth,
  },
  'content-right': {
    marginRight: -drawerWidth,
  },
  contentShift: {
    transition: theme.transitions.create('margin', {
      easing: theme.transitions.easing.easeOut,
      duration: theme.transitions.duration.enteringScreen,
    }),
  },
  'contentShift-left': {
    marginLeft: 0,
  },
  'contentShift-right': {
    marginRight: 0,
  },
});

let MapApp = (props) => {
  const { classes, error, theme, drawerIsOpen, mapReady } = props;
  let resultsView = '';
  if (props.search.results.length > 0) {
    switch(props.resultFormat) {
      case 'list':
        resultsView = <VirtualizedTable list={Immutable.List(props.search.results)} />;
        break;
      case 'stats':
        resultsView =  <Pie data={props.search.results} />;
        break;
      default:
        resultsView = <VirtualizedTable list={Immutable.List(props.search.results)} />;
    }
  const drawer = (
    <Drawer
      variant="persistent"
      anchor={anchor}
      open={drawerIsOpen}
Esko Ikkala's avatar
Esko Ikkala committed
      width={drawerWidth}
      classes={{
        paper: classes.drawerPaper,
      }}
    >
      <div className={classes.drawerHeader}>
        <Tabs
          value={0}
          onChange={null}
          fullWidth
          indicatorColor="secondary"
          textColor="secondary"
        >
          <Tab label="Places" />
          <Tab label="Options" disabled />
        <IconButton onClick={props.closeDrawer}>
          {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
        </IconButton>
      </div>
Esko Ikkala's avatar
Esko Ikkala committed
      <Divider />
Esko Ikkala's avatar
Esko Ikkala committed
      <DatasetSelector
        datasets={props.search.datasets}
Esko Ikkala's avatar
Esko Ikkala committed
        toggleDataset={props.toggleDataset}
Esko Ikkala's avatar
Esko Ikkala committed
      />
      <Divider />
      <div className={classes.drawerSearch}>
        <IntegrationAutosuggest
          search={props.search}
          updateQuery={props.updateQuery}
          fetchSuggestions={props.fetchSuggestions}
          clearSuggestions={props.clearSuggestions}
          fetchResults={props.fetchResults}
          clearResults={props.clearResults}
          updateResultFormat={props.updateResultFormat}
      {resultsView}

  let before = null;
  let after = null;

  if (anchor === 'left') {
    before = drawer;
  } else {
    after = drawer;
  }

  if (!mapReady) {
    props.setMapReady();
    setTimeout(() => {
      props.openDrawer();
    }, 300);
  }

  return (
    <div className={classes.root}>
      <div className={classes.appFrame}>
        <AppBar
          className={classNames(classes.appBar, {
            [classes.appBarShift]: drawerIsOpen,
            [classes[`appBarShift-${anchor}`]]: drawerIsOpen,
          })}
        >
          <Toolbar disableGutters={!drawerIsOpen}>
            <IconButton
              color="inherit"
              aria-label="open drawer"
              onClick={props.openDrawer}
              className={classNames(classes.menuButton, drawerIsOpen && classes.hide)}
            >
              <MenuIcon />
            </IconButton>
            <Typography variant="title" color="inherit" noWrap>
              Hipla.fi
            </Typography>
          </Toolbar>
        </AppBar>
        {before}
        <main
          className={classNames(classes.content, classes[`content-${anchor}`], {
            [classes.contentShift]: drawerIsOpen,
            [classes[`contentShift-${anchor}`]]: drawerIsOpen,
          })}
        >
          <div className={classes.drawerHeader} />
          <Message error={error} />
Esko Ikkala's avatar
Esko Ikkala committed
            results={props.search.results}
            geoJSON={props.geoJSON}
esikkala's avatar
esikkala committed
            geoJSONKey={props.geoJSONKey}
Esko Ikkala's avatar
Esko Ikkala committed
            getGeoJSON={props.getGeoJSON}
          />
        </main>
        {after}
      </div>
    </div>
  );
};

const mapStateToProps = (state) => ({
  search: state.search,
  drawerIsOpen: state.options.drawerIsOpen,
Esko Ikkala's avatar
Esko Ikkala committed
  geoJSON: state.map.geoJSON,
  geoJSONKey: state.map.geoJSONKey,
  resultFormat: state.options.resultFormat
});

const mapDispatchToProps = ({
  openDrawer,
  closeDrawer,
  updateQuery,
Esko Ikkala's avatar
Esko Ikkala committed
  toggleDataset,
  fetchSuggestions,
  clearSuggestions,
  fetchResults,
Esko Ikkala's avatar
Esko Ikkala committed
  setMapReady,
  getGeoJSON,
  updateResultFormat
});

MapApp.propTypes = {
  classes: PropTypes.object.isRequired,
  theme: PropTypes.object.isRequired,
  search: PropTypes.object.isRequired,
  error: PropTypes.object.isRequired,
  drawerIsOpen: PropTypes.bool.isRequired,
  mapReady: PropTypes.bool.isRequired,
  openDrawer: PropTypes.func.isRequired,
  closeDrawer: PropTypes.func.isRequired,
  updateQuery: PropTypes.func.isRequired,
Esko Ikkala's avatar
Esko Ikkala committed
  toggleDataset: PropTypes.func.isRequired,
  fetchSuggestions: PropTypes.func.isRequired,
  clearSuggestions: PropTypes.func.isRequired,
  fetchResults: PropTypes.func.isRequired,
  clearResults: PropTypes.func.isRequired,
  setMapReady: PropTypes.func.isRequired,
Esko Ikkala's avatar
Esko Ikkala committed
  geoJSON: PropTypes.object.isRequired,
esikkala's avatar
esikkala committed
  geoJSONKey: PropTypes.number,
Esko Ikkala's avatar
Esko Ikkala committed
  getGeoJSON: PropTypes.func.isRequired,
  updateResultFormat: PropTypes.func.isRequired,
  resultFormat: PropTypes.string.isRequired
};

MapApp = connect(
  mapStateToProps,
  mapDispatchToProps
)(withStyles(styles, {withTheme: true})(MapApp));

export default MapApp;