Commit fb7702c9 authored by Viacheslav Pavlov's avatar Viacheslav Pavlov Committed by Matija Obreza
Browse files

Accession map: info-click

- AccessionService#geoJson returns correct geoJson value
- mapPage translations
- using double click handle to accession map
parent a12cc784
......@@ -373,7 +373,10 @@
},
"browse": {
"title": "Accession browser",
"subTitle": "Explore curated sets of accessions",
"subTitle": "Explore curated sets of accessions"
},
"map": {
"andMore": "And {{otherMore}} more",
"kml": "KML"
}
}
......
......@@ -54,7 +54,10 @@
},
"browse": {
"title": "Accession browser",
"subTitle": "Explore curated sets of accessions",
"subTitle": "Explore curated sets of accessions"
},
"map": {
"andMore": "And {{otherMore}} more",
"kml": "KML"
}
}
......
import * as React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { translate } from 'react-i18next';
import { withStyles } from '@material-ui/core/styles';
import { bindActionCreators } from 'redux';
......@@ -14,9 +15,14 @@ import Tabs, { Tab } from 'ui/common/Tabs';
import PrettyFilters from 'ui/common/filter/PrettyFilters';
import ButtonBar from 'ui/common/buttons/ButtonBar';
import AccessionService from 'service/genesys/AccessionService';
let Map;
let TileLayer;
let Popup;
let Marker;
const popupContentLimit = 11;
interface IMapPageProps {
classes?: any;
......@@ -38,17 +44,28 @@ const styles = (theme) => ({
});
class BrowsePage extends React.Component<IMapPageProps, any> {
private clickTimeout;
protected static needs = [
({ params: { filterCode } }) => {
return loadAccessionsMapInfo(filterCode || '');
},
];
public state = {
popupPosition: [],
geoData: [],
otherCount: 0,
};
constructor(props, context) {
super(props, context);
if (typeof window !== 'undefined') {
Map = require('react-leaflet').Map;
TileLayer = require('react-leaflet').TileLayer;
Marker = require('react-leaflet').Marker;
Popup = require('react-leaflet').Popup;
}
}
......@@ -64,6 +81,46 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
}
}
private onMapClick = (e) => {
if (this.clickTimeout) {
console.log('prevented');
clearTimeout(this.clickTimeout);
this.clickTimeout = null;
return;
}
this.clickTimeout = setTimeout(() => {
console.log('started');
this.clickTimeout = null;
const currentZoom = e.target._zoom;
if (currentZoom < 4) {
return;
}
const {mapInfo: {filter}} = this.props;
const correctLng = Math.abs(e.latlng.lng) > 180 ? (360 + e.latlng.lng) % 180 : e.latlng.lng;
console.log(e);
const filterWithGeo = {
...filter,
geo: {
longitude: {
ge: correctLng - (3 / currentZoom),
le: correctLng + (3 / currentZoom),
},
latitude: {
ge: e.latlng.lat - (3 / currentZoom),
le: e.latlng.lat + (3 / currentZoom),
},
},
};
AccessionService.geoJson(filterWithGeo, popupContentLimit)
.then((res) => this.setState({popupPosition: [ e.latlng.lat, e.latlng.lng], geoData: res.geoJson, otherCount: res.otherCount}));
}, 200);
}
/// Wrap loadAccessionsMapInfo dispatch and fills the current sort selection
protected myApplyFilters = (filters: AccessionFilter) => {
const { loadAccessionsMapInfo } = this.props;
......@@ -72,6 +129,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
}
public render() {
const {popupPosition, geoData, otherCount} = this.state;
const position = [30, 0];
const { mapInfo, currentTab, classes, filterCode, t } = this.props;
......@@ -93,7 +151,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
<span>
<form method="post" action="/proxy/api/v1/acn/downloadKml">
<input type="hidden" name="f" value={ filterCode } />
<Button type="submit">{ `${t('common:action.download')} ${t('accessions.public.p.browse.kml')}` }</Button>
<Button type="submit">{ `${t('common:action.download')} ${t('accessions.public.p.map.kml')}` }</Button>
</form>
</span>
</ButtonBar>
......@@ -111,6 +169,7 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
<div className={ classes.leafletContainer }>
{ mapInfo && typeof window !== 'undefined' &&
<Map
onClick={ this.onMapClick }
center={ position }
zoom={ 3 } minZoom={ 2 } maxZoom={ 14 }
bounds={ mapInfo.bounds }>
......@@ -126,6 +185,16 @@ class BrowsePage extends React.Component<IMapPageProps, any> {
url={ layerUrl }
subdomains={ mapInfo.tileServers }
/>
{ geoData && geoData.length > 0 &&
<Marker position={ popupPosition } ref={ (marker) => marker && marker.leafletElement.openPopup() } >
<Popup open>
<div>
{ geoData.map((feature) => (<div><Link to={ `/a/${feature.properties.uuid}` }>{ `${feature.properties.accessionNumber} ${feature.properties.instCode}` }</Link></div>)) }
{ otherCount > 0 && <div>{ t('accessions.public.p.map.andMore', {otherMore: otherCount}) }</div> }
</div>
</Popup>
</Marker>
}
</Map>
}
</div>
......
......@@ -18,6 +18,7 @@ class AccessionFilter {
public cropName: string;
public doi: string[];
public elevation: NumberFilter;
public geo: { latitude: NumberFilter, longitude: NumberFilter };
public historic: boolean;
public holder: InstituteFilter;
public id: number[];
......
......@@ -12,6 +12,7 @@ import {AccessionRef} from 'model/accession/AccessionRef';
const URL_GET_BY_DOI = `/api/v1/acn/{doi}`; // UrlTemplate doesn't like the / in DOI
const URL_GET_BY_UUID = UrlTemplate.parse(`/api/v1/acn/{uuid}`);
const URL_GEO_JSON = `/api/v1/acn/geoJson`;
const URL_LIST_BY_UUID = `/api/v1/acn/for-uuid`;
const URL_GET_DETAILS_BY_DOI = `/api/v1/acn/details/{doi}`; // UrlTemplate doesn't like the / in DOI
const URL_GET_DETAILS_BY_UUID = UrlTemplate.parse(`/api/v1/acn/details/{uuid}`);
......@@ -63,6 +64,28 @@ class AccessionService {
}).then(({ data }) => data as Accession);
}
/**
* geoJson at /api/v1/acn/explore/geoJson
*
* @param filter filter
* @param limit limit
*/
public static geoJson(filter: AccessionFilter, limit?: number): Promise<any> {
const qs = QueryString.stringify({
limit: limit || undefined,
}, {});
const apiUrl = URL_GEO_JSON + (qs ? `?${qs}` : '');
// console.log(`Fetching from ${apiUrl}`);
const content = { data: filter };
return axiosBackend.request({
url: apiUrl,
method: 'POST',
...content,
}).then(({ data }) => data as any);
}
/**
* getByDoi at /api/v1/acn/10.{dummy}/**}
*
......
Markdown is supported
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