Updated OpenMapModalBtn so that it allows showing only active cities

This commit is contained in:
Alejandro Celaya 2019-03-10 12:09:54 +01:00
parent 478ee59bb0
commit 5233f5a07b
4 changed files with 62 additions and 38 deletions

View file

@ -116,14 +116,9 @@ const ShortUrlVisits = ({ processStatsFromVisits }) => class ShortUrlVisits exte
<SortableBarGraph <SortableBarGraph
stats={cities} stats={cities}
title="Cities" title="Cities"
extraHeaderContent={(filterLocations) => extraHeaderContent={(activeCities) =>
mapLocations.length > 0 && ( mapLocations.length > 0 &&
<OpenMapModalBtn <OpenMapModalBtn modalTitle="Cities" locations={mapLocations} activeCities={activeCities} />
modalTitle="Cities"
locations={mapLocations}
filterLocations={filterLocations}
/>
)
} }
sortingItems={{ sortingItems={{
name: 'City name', name: 'City name',

View file

@ -96,11 +96,7 @@ export default class SortableBarGraph extends React.Component {
render() { render() {
const { stats, sortingItems, title, extraHeaderContent, withPagination = true } = this.props; const { stats, sortingItems, title, extraHeaderContent, withPagination = true } = this.props;
const { currentPageStats, pagination, max } = this.determineStats(stats, sortingItems); const { currentPageStats, pagination, max } = this.determineStats(stats, sortingItems);
const filterLocations = (locations) => { const activeCities = keys(currentPageStats);
const validCities = keys(currentPageStats);
return locations.filter(({ cityName }) => validCities.includes(cityName));
};
const computedTitle = ( const computedTitle = (
<React.Fragment> <React.Fragment>
{title} {title}
@ -129,7 +125,7 @@ export default class SortableBarGraph extends React.Component {
)} )}
{extraHeaderContent && ( {extraHeaderContent && (
<div className="float-right"> <div className="float-right">
{extraHeaderContent(pagination ? filterLocations : undefined)} {extraHeaderContent(pagination ? activeCities : undefined)}
</div> </div>
)} )}
</React.Fragment> </React.Fragment>

View file

@ -27,6 +27,10 @@ const OpenStreetMapTile = () => (
); );
const calculateMapProps = (locations) => { const calculateMapProps = (locations) => {
if (locations.length === 0) {
return {};
}
if (locations.length > 1) { if (locations.length > 1) {
return { bounds: locations.map(prop('latLong')) }; return { bounds: locations.map(prop('latLong')) };
} }

View file

@ -1,34 +1,63 @@
import React from 'react'; import React, { useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faMapMarkedAlt as mapIcon } from '@fortawesome/free-solid-svg-icons'; import { faMapMarkedAlt as mapIcon } from '@fortawesome/free-solid-svg-icons';
import { UncontrolledTooltip } from 'reactstrap'; import { Dropdown, DropdownItem, DropdownMenu, UncontrolledTooltip } from 'reactstrap';
import * as PropTypes from 'prop-types'; import * as PropTypes from 'prop-types';
import MapModal from './MapModal'; import MapModal from './MapModal';
import './OpenMapModalBtn.scss'; import './OpenMapModalBtn.scss';
export default class OpenMapModalBtn extends React.Component { const propTypes = {
static propTypes = { modalTitle: PropTypes.string.isRequired,
modalTitle: PropTypes.string.isRequired, locations: PropTypes.arrayOf(PropTypes.object),
locations: PropTypes.arrayOf(PropTypes.object), activeCities: PropTypes.arrayOf(PropTypes.string),
filterLocations: PropTypes.func, };
const OpenMapModalBtn = ({ modalTitle, locations = [], activeCities }) => {
const [ mapIsOpened, setMapIsOpened ] = useState(false);
const [ dropdownIsOpened, setDropdownIsOpened ] = useState(false);
const [ locationsToShow, setLocationsToShow ] = useState([]);
const buttonRef = React.createRef();
const filterLocations = (locations) => locations.filter(({ cityName }) => activeCities.includes(cityName));
const toggleMap = () => setMapIsOpened(!mapIsOpened);
const onClick = () => {
if (mapIsOpened) {
setMapIsOpened(false);
return;
}
if (!activeCities) {
setLocationsToShow(locations);
setMapIsOpened(true);
return;
}
setDropdownIsOpened(true);
};
const openMapWithLocations = (filtered) => () => {
setLocationsToShow(filtered ? filterLocations(locations) : locations);
setMapIsOpened(true);
}; };
state = { mapIsOpened: false }; return (
<React.Fragment>
<button className="btn btn-link open-map-modal-btn__btn" ref={buttonRef} onClick={onClick}>
<FontAwesomeIcon icon={mapIcon} />
</button>
<UncontrolledTooltip placement="left" target={() => buttonRef.current}>Show in map</UncontrolledTooltip>
<Dropdown isOpen={dropdownIsOpened} toggle={() => setDropdownIsOpened(!dropdownIsOpened)} inNavbar>
<DropdownMenu right>
<DropdownItem onClick={openMapWithLocations(false)}>Show all locations</DropdownItem>
<DropdownItem onClick={openMapWithLocations(true)}>Show locations in current page</DropdownItem>
</DropdownMenu>
</Dropdown>
<MapModal toggle={toggleMap} isOpen={mapIsOpened} title={modalTitle} locations={locationsToShow} />
</React.Fragment>
);
};
render() { OpenMapModalBtn.propTypes = propTypes;
const { modalTitle, locations = [], filterLocations } = this.props;
const toggleMap = () => this.setState(({ mapIsOpened }) => ({ mapIsOpened: !mapIsOpened }));
const buttonRef = React.createRef();
const filteredLocations = filterLocations ? filterLocations(locations) : locations;
return ( export default OpenMapModalBtn;
<React.Fragment>
<button className="btn btn-link open-map-modal-btn__btn" ref={buttonRef} onClick={toggleMap}>
<FontAwesomeIcon icon={mapIcon} />
</button>
<UncontrolledTooltip placement="left" target={() => buttonRef.current}>Show in map</UncontrolledTooltip>
<MapModal toggle={toggleMap} isOpen={this.state.mapIsOpened} title={modalTitle} locations={filteredLocations} />
</React.Fragment>
);
}
}