Commit 9ca0456c authored by Valeriy Panov's avatar Valeriy Panov
Browse files

#208 Dataset locations

parent 406b8d57
......@@ -8,7 +8,6 @@ import { Dataset } from 'model/dataset.model';
import { Descriptor } from 'model/descriptor.model';
import { RepositoryFile } from 'model/repositoryFile.model';
import { Creator } from 'model/creator.model';
import { Location } from 'model/location.model';
import { AVAILABLE_LICENSES } from 'model/license.model';
import confirm from 'utilities/confirmAlert';
......@@ -256,28 +255,6 @@ class DetailInfo extends React.Component<IDetailInfoProps, any> {
</Grid>
</Grid>
<Divider/>
{ dataset.locations &&
<div>
<div className="pt-15 pb-15 pl-20 pr-20">
<h4 className="font-bold m-0">
Locations
</h4>
</div>
<Divider/>
<Grid container spacing={ 0 } className="p-20">
<Grid item xs={ 12 }>
<Grid container spacing={ 0 } className={ classes.dataContainer }>
<Grid item xs={ 12 }>
<h3 className={ `${classes.gray} ${classes.grayTitleSmall}` }>
{ dataset.locations.map((location: Location) => <LocationMap location={ location } key={ location.id }/>) }
</h3>
</Grid>
</Grid>
</Grid>
</Grid>
<Divider/>
</div>
}
<div className="pt-15 pb-15 pl-20 pr-20">
<h4 className="font-bold m-0">Dataset use and licensing</h4>
</div>
......@@ -353,6 +330,36 @@ class DetailInfo extends React.Component<IDetailInfoProps, any> {
</Grid>
</Grid>
<Divider/>
<div className="pt-15 pb-15 pl-20 pr-20">
<h4 className="font-bold m-0">Creators</h4>
</div>
<Divider/>
<Grid container spacing={ 0 } className="p-20">
<Grid item xs={ 12 }>
{ dataset.creators && dataset.creators.map((e: Creator, i) => (
<Grid container spacing={ 0 } key={ i } className={ `${classes.dataContainer} ${classes.grayRowsOdd}` }>
<Grid item xs={ 12 } md={ 3 }>
<h3 className={ `font-bold ${classes.margin1} ${classes.gray} ${classes.grayTitleSmall}` }>
{ `${e.fullName}` }
</h3>
</Grid>
<Grid item xs={ 12 } md={ 4 } className={ `${classes.margin1} ${classes.gray}` }>
<a href={ `mailto:${e.email}` }
className={ `${classes.grayTitleA}` }>
{ e.email }
</a>
</Grid>
<Grid item xs={ 12 } md={ 5 } className={ `${classes.margin1} ${classes.gray}` }>
<p className={ `${classes.grayTitleSmall} ${classes.pdTop0}` }>
{ e.institutionalAffiliation }
</p>
</Grid>
</Grid>
))
}
</Grid>
</Grid>
<Divider/>
<div className="pt-15 pb-15 pl-20 pr-20">
<h4 className="font-bold m-0">
Other Metadata
......@@ -379,6 +386,16 @@ class DetailInfo extends React.Component<IDetailInfoProps, any> {
</Grid>
<Grid container spacing={ 0 }>
{ dataset.locations && (
<Grid item xs={ 12 } md={ 12 } lg={ 12 } className="p-20">
<Section title="Locations">
<div className="p-20">
<LocationMap locations={ dataset.locations } classes={ {} }/>
</div>
</Section>
</Grid>
) }
{ dataset.descriptors && (
<Grid item xs={ 12 } md={ 12 } lg={ 12 } className="p-20">
<Section title="Traits observed">
......
import * as React from 'react';
import { withStyles } from 'material-ui/styles';
import {withStyles} from 'material-ui/styles';
import Grid from 'material-ui/Grid';
import LocationIcon from 'material-ui-icons/LocationOn';
import { Location } from 'model/location.model';
import {isNumeric} from 'utilities';
import {Location} from 'model/location.model';
let Map;
let Marker;
......@@ -11,7 +11,7 @@ let TileLayer;
interface ILocationMapProps extends React.ClassAttributes<any> {
classes: any;
location: Location;
locations: Location[];
}
const styles = (theme) => ({
......@@ -24,7 +24,7 @@ const styles = (theme) => ({
marginRight: '4px',
width: '20px',
height: '20px',
position: 'relative',
position: 'relative' as 'relative',
top: '4px',
[theme.breakpoints.down('sm')]: {
marginLeft: '0',
......@@ -39,68 +39,89 @@ const styles = (theme) => ({
class LocationMap extends React.Component<ILocationMapProps, any> {
constructor(props: ILocationMapProps, context: any) {
constructor(props, context) {
super(props, context);
this.state = {
show: false,
};
if (typeof window !== 'undefined') {
Map = require('react-leaflet').Map;
Marker = require('react-leaflet').Marker;
TileLayer = require('react-leaflet').TileLayer;
}
}
public componentDidMount() {
// leaflet map doesn't work on server (ssr)
Map = require('react-leaflet').Map;
Marker = require('react-leaflet').Marker;
TileLayer = require('react-leaflet').TileLayer;
}
public render() {
const {classes, locations} = this.props;
private showMap = () => {
const show = !this.state.show;
this.setState({ show });
}
if (!(locations && locations.length)) {
return null;
}
public render() {
const { classes, location } = this.props;
const positions = locations
.filter((location) => isNumeric(location.decimalLatitude) && isNumeric(location.decimalLongitude))
.map((location) => ({
lat: location.decimalLatitude,
lng: location.decimalLongitude,
}));
if (!(positions && positions.length)) {
return null;
}
const min = positions.reduce((p, c) => ({
lat: Math.min(p.lat, c.lat),
lng: Math.min(p.lng, c.lng),
}));
const position = {
lat: location.decimalLatitude,
lng: location.decimalLongitude,
const max = positions.reduce((p, c) => ({
lat: Math.max(p.lat, c.lat),
lng: Math.max(p.lng, c.lng),
}));
const center = {
lat: (min.lat + max.lat) / 2,
lng: (min.lng + max.lng) / 2,
};
return (
<Grid item xs={ 12 }>
<p className="font-normal m-0">
{ `${location.verbatimLocality}, ${location.stateProvince}, ${location.userCountry}` }
<span className={ classes.locationIconWrap }>
<LocationIcon className={ classes.locationIcon }/>
<a onClick={ this.showMap }>
See on map
</a>
</span>
</p>
{
this.state.show ?
(
<div className={ classes.leafletContainer }>
<Map
center={ position }
zoom={ 6 }
>
<TileLayer
attribution={ '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }
url={ 'http://{s}.tile.osm.org/{z}/{x}/{y}.png' }
/>
{ position && <Marker position={ position }/> }
</Map>
</div>
)
: null
typeof window !== 'undefined' && (
<div className={ classes.leafletContainer }>
<Map
center={ center }
bounds={ [min, max] }
maxZoom={ positions.length === 1 ? 6 : 7 }
>
<TileLayer
attribution={ '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' }
url={ 'http://{s}.tile.osm.org/{z}/{x}/{y}.png' }
/>
{ positions && positions.map((position, i) => (
<Marker key={ i } position={ position }/>
),
) }
</Map>
</div>
)
}
<ul>
{
locations
.filter((location) => location.userCountry || location.stateProvince || location.verbatimLocality)
.map((location, i) => (
<li className="font-normal m-0" key={ i }>
{
[location.verbatimLocality, location.stateProvince, location.userCountry]
.filter((e) => e && e.trim())
.join(', ')
}
</li>
))
}
</ul>
</Grid>
);
}
}
export default (withStyles as any)(styles)(LocationMap);
export default withStyles(styles)(LocationMap);
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment