MapPage.tsx 19.6 KB
Newer Older
1
import * as React from 'react';
2
import { connect } from 'react-redux';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
3
import { Link } from 'react-router-dom';
4
5
6
import { translate } from 'react-i18next';
import { withStyles } from '@material-ui/core/styles';
import { bindActionCreators } from 'redux';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
7
import {showSnackbar} from 'actions/snackbar';
8
import navigateTo from 'actions/navigation';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
9
import {currentClimateRequest, geoJsonRequest, loadAccessionsMapInfo} from 'accessions/actions/public';
10
import AccessionFilter from 'model/accession/AccessionFilter';
11
import Loading from 'ui/common/Loading';
12
import AccessionMapInfo from 'model/accession/AccessionMapInfo';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
13
import MapLayer from 'model/genesys/MapTileLayer';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
14
import ContentHeader from 'ui/common/heading/ContentHeader';
15
import Button from '@material-ui/core/Button';
16
import Tabs, { Tab } from 'ui/common/Tabs';
17
import PrettyFilters from 'ui/common/filter/PrettyFilters';
Oleksii Savran's avatar
Oleksii Savran committed
18
import ButtonBar from 'ui/common/buttons/ButtonBar';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
19
20
import ContentLayout from 'ui/layout/ContentLayout';
import MapConfigSection from './c/MapConfigSection';
21

22
import AccessionsFilters from 'accessions/ui/c/Filters';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
23
24
import BioClimateDisplay from 'accessions/ui/c/BioClimateDisplay';
import {Dialog, Drawer} from '@material-ui/core';
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
25
import PageTitle from 'ui/common/PageTitle';
Oleksii Savran's avatar
Oleksii Savran committed
26
27
28
29
30
31
32
33
import Popover from '@material-ui/core/Popover';
import Paper from '@material-ui/core/Paper';
import Tooltip from '@material-ui/core/Tooltip';
import LayersIcon from '@material-ui/icons/Layers';
import ClimateIcon from '@material-ui/icons/WbSunny';
import FilterIcon from '@material-ui/icons/PermDataSetting';
import CancelIcon from '@material-ui/icons/Cancel';

34

35
let MapComponent;
36
let TileLayer;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
37
let Popup;
Oleksii Savran's avatar
Oleksii Savran committed
38
let Rectangle;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
39
let Control;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
40
41

const popupContentLimit = 11;
42

43
44
45
46
interface IMapPageProps {
    classes?: any;
    t?: any;

47
    apiUrl: string;
48
    mapInfo: AccessionMapInfo;
49
    suggestions: any;
50
51
    currentTab: string;
    filterCode: string;
52
    loadAccessionsMapInfo: any;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
53
    mapLayers: MapLayer[];
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
54
    showSnackbar: (message: string) => void;
55
56
57
    navigateTo: (location: string) => void;
    initialPosition: number[];
    initialZoom: number;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
58
59
60
    loading: boolean;
    geoJsonRequest: (filter, limit: number) => Promise<any>;
    currentClimateRequest: (lat, lng) => Promise<any>;
61
62
63
}

const styles = (theme) => ({
Oleksii Savran's avatar
Oleksii Savran committed
64
    /*tslint:disable*/
65
66
67
    leafletContainer: {
        width: '100%',
        minHeight: '500px',
Oleksii Savran's avatar
Oleksii Savran committed
68
69
70
71
72
73
74
75
76
77
78
79
80
        height: 'calc(100vh - 245px)',
        [theme.breakpoints.down('md')]: {
            height: 'calc(100vh - 211px)',
        },
        [theme.breakpoints.down('sm')]: {
          height: 'calc(100vh - 199px)',
        },
        '& a[aria-label="Zoom in"], & a[aria-label="Zoom out"],': {
            color: '#000',
            '&:hover': {
                color: '#88ba42',
            },
        },
81
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
82
83
84
85
86
87
88
89
90
    crosshair: {
        '& > div': {
            cursor: 'crosshair !important' as 'crosshair !important',
        },
    },
    climateDialog: {
        marginBottom: 0,
        overflow: 'auto' as 'auto',
    },
Oleksii Savran's avatar
Oleksii Savran committed
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    mapButton: {
        height: '34px',
        width: '34px',
        minWidth: 'auto',
        minHeight: 'initial',
        padding: '5px 8px',
        backgroundColor: '#fff',
        borderRadius: '4px',
        border: 'solid 2px #b7b7b7',
        transition: 'none',
        '& > span > svg': {
            color: '#000',
        },
        '&:hover': {
            backgroundColor: '#f4f4f4',
            '& > span > svg': {
                color: '#88ba42',
            },
        },
    },
    mapIcon: {
        fontSize: '20px',
    },
    tooltip: {
        fontSize: '1rem',
    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
117
118
    filterAccessionsButton: {
        position: 'absolute' as 'absolute',
Oleksii Savran's avatar
Oleksii Savran committed
119
        top: '4px',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
120
121
122
    },
    pickPositionButton: {
        position: 'absolute' as 'absolute',
Oleksii Savran's avatar
Oleksii Savran committed
123
        top: '42px',
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
124
    },
Oleksii Savran's avatar
Oleksii Savran committed
125
126
127
128
129
130
131
132
133
134
135
136
    layersButton: {
        width: '50px',
        height: '50px',
        '&:hover > span > svg': {
            color: '#000',
        },
    },
    layersControl: {
        maxHeight: '55vh',
        overflow: 'auto',
    },
    /*tslint:enable*/
137
138
139
});

class BrowsePage extends React.Component<IMapPageProps, any> {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
140
141

    private clickTimeout;
142
    private mapRef = null;
Oleksii Savran's avatar
Oleksii Savran committed
143
    private anchorRef = null;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
144

145
    protected static needs = [
146
147
      ({ params: { filterCode, initialPosition, initialZoom } }) => {
        return loadAccessionsMapInfo(filterCode || '', {center: initialPosition, zoom: initialZoom});
148
149
150
      },
    ];

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
151
    public state = {
Oleksii Savran's avatar
Oleksii Savran committed
152
153
      clickLocation: [],
      searchBox: null,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
154
155
      geoData: [],
      otherCount: 0,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
156
157
158
159
      sidebarOpened: false,
      trackClickPos: false,
      dialogOpened: false,
      climateData: null,
Oleksii Savran's avatar
Oleksii Savran committed
160
      layersControlsIsOpen: false,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
161
162
    };

163
164
165
    constructor(props, context) {
        super(props, context);
        if (typeof window !== 'undefined') {
166
            MapComponent = require('react-leaflet').Map;
167
            TileLayer = require('react-leaflet').TileLayer;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
168
            Popup = require('react-leaflet').Popup;
Oleksii Savran's avatar
Oleksii Savran committed
169
            Rectangle = require('react-leaflet').Rectangle;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
170
            Control = require('react-leaflet-control').default;
171
172
173
174
175
        }
    }


    public componentWillMount() {
176
      const { mapInfo, filterCode, loadAccessionsMapInfo, initialPosition, initialZoom } = this.props;
177
178
179
      // console.log(`Filter code for map ${filterCode} ?== ${mapInfo && mapInfo.filterCode}`, filterCode, mapInfo ? mapInfo.filterCode : 'No mapInfo');
      if (mapInfo && mapInfo.filterCode !== filterCode) {
        // console.log(`mapInfo.filterCode !== filterCode. updatingRoute`);
180
        loadAccessionsMapInfo(filterCode || '', {center: initialPosition, zoom: initialZoom});
181
      } else if (!mapInfo) {
182
        loadAccessionsMapInfo(filterCode || '', {center: initialPosition, zoom: initialZoom});
183
184
185
      }
    }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
186
187
188
189
190
191
192
193
    private openSidebar = () => {
      return this.setState({sidebarOpened: true});
    }

    private closeSidebar = () => {
      return this.setState({sidebarOpened: false});
    }

Oleksii Savran's avatar
Oleksii Savran committed
194
195
196
197
198
199
200
201
    private openLayersControls = () => {
      return this.setState({layersControlsIsOpen: true});
    }

    private closeLayersControls = () => {
      return this.setState({layersControlsIsOpen: false});
    }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
202
203
204
205
206
207
208
209
    private setPositionPick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      this.setState({trackClickPos: !this.state.trackClickPos});
      return false;
    }

    private handleTrackPosition = (e) => {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
210
      const {showSnackbar, t, currentClimateRequest } = this.props;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
211
212
213
214
      const { lat, lng } = e.latlng;

      this.setState({climateData: null});

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
215
      currentClimateRequest(lat, lng)
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
        .then((res) => {
          // @ts-ignore
          if (!res || res === '') {
            return showSnackbar(t('accessions.public.p.map.noClimateData'));
          }
          return this.setState({climateData: res, dialogOpened: true});
        })
        .catch((error) =>  {
          if (error.code === 404) {
            return showSnackbar(t('accessions.public.p.map.noClimateData'));
          }
        });
    }

    private hideDialog = () => {
      this.setState({dialogOpened: false});
    }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
233

234
235
236
237
238
239
240
241
242
243
244
    private handleMoveEnd = (e) => {
      const {navigateTo, filterCode} = this.props;
      if (this.mapRef) {
        const {viewport: {center, zoom}} = this.mapRef;
        // console.log('Updating URL center: ', center, ' Zoom: ', zoom);
        if (center && center[0] !== 0 || center[1] !== 0) {
          navigateTo(`/a/map${filterCode && `/${filterCode}`}/@${center[0]},${center[1]},${zoom}z`);
        }
      }
    }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
245
    private onMapClick = (e) => {
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
246
247
248
249
250
251
252
253
254

        if (e.originalEvent.target.className.indexOf('leaflet-touch') === -1) {
          return;
        }

        if (this.state.trackClickPos) {
          return this.handleTrackPosition(e);
        }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
255
256
257
258
259
260
261
262
263
264
265
266
267
268
        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;
            }

Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
269
            const {mapInfo: {filter}, geoJsonRequest} = this.props;
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
270
271
272
273
274

            const correctLng = Math.abs(e.latlng.lng) > 180 ? (360 + e.latlng.lng) % 180 : e.latlng.lng;

            console.log(e);

Oleksii Savran's avatar
Oleksii Savran committed
275
            const width = Math.pow(2, currentZoom - 2);
276
            // console.log(`zoom=${currentZoom} width=${width} diff=${ 3 / width}`);
Oleksii Savran's avatar
Oleksii Savran committed
277
278
279
280
            const searchBounds: number[][] = [
                [ e.latlng.lat - (3 / width), correctLng - (3 / width) ],
                [ e.latlng.lat + (3 / width), correctLng + (3 / width) ],
            ];
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
281
282
283
284
            const filterWithGeo = {
                ...filter,
                geo: {
                    longitude: {
Oleksii Savran's avatar
Oleksii Savran committed
285
286
                        ge: searchBounds[0][1],
                        le: searchBounds[1][1],
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
287
288
                    },
                    latitude: {
Oleksii Savran's avatar
Oleksii Savran committed
289
290
                        ge: searchBounds[0][0],
                        le: searchBounds[1][0],
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
291
                    },
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
292
                    climate: filter && filter.geo && filter.geo.climate,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
293
294
                },
            };
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
295
            geoJsonRequest(filterWithGeo, popupContentLimit)
Oleksii Savran's avatar
Oleksii Savran committed
296
                .then((res) => this.setState({clickLocation: [ e.latlng.lat,  e.latlng.lng], searchBox: searchBounds, geoData: res.geoJson, otherCount: res.otherCount}));
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
297
298
299
        }, 200);
    }

300
301
302
303
304
    /// Wrap loadAccessionsMapInfo dispatch and fills the current sort selection
    protected myApplyFilters = (filters: AccessionFilter) => {
      const { loadAccessionsMapInfo } = this.props;

      loadAccessionsMapInfo(filters);
305
306
307
    }

    public render() {
Oleksii Savran's avatar
Oleksii Savran committed
308
        const { searchBox, geoData, otherCount, sidebarOpened, trackClickPos, dialogOpened, climateData, layersControlsIsOpen} = this.state;
309
        const { mapInfo, mapLayers, currentTab, classes, filterCode, loading, suggestions, t, loadAccessionsMapInfo, initialPosition, initialZoom } = this.props;
310

311
        const position = initialPosition[0] && initialPosition[1] ? initialPosition : [30, 0];
312
313
314
315

        if (! mapInfo) {
          return <Loading />;
        }
316

317
318
319
320
321
322
323
324
325
326
327
328
        const suggestionTerms = new Map();
        if (suggestions) {
            Object.keys(suggestions).forEach((key) => {
              const overviewEl = suggestions[key];
              const terms = new Map();
              overviewEl.terms.forEach((term) => terms.set(term.term, term.count));
              suggestionTerms.set(key, terms);
            });
        }

        console.log(suggestionTerms);

329
        // const color = 'f00ba0';
330
        const layerUrl = `{s}/acn/tile/{z}/{x}/{y}?f=${filterCode ? filterCode : ''}`; // `&color=${color}`;
331
332

        return (
Oleksii Savran's avatar
Oleksii Savran committed
333
            <ContentLayout customHeaderHeight>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
334
335
              <PageTitle title={ t('accessions.public.p.browse.title') } />
              <ContentHeader title={ t('accessions.public.p.browse.title') } subTitle={ t('accessions.public.p.browse.subTitle') } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
336
337

              <Drawer variant="temporary" open={ sidebarOpened } onClose={ this.closeSidebar }>
338
                    <AccessionsFilters terms={ suggestionTerms } onSubmit={ loadAccessionsMapInfo } initialValues={ mapInfo && mapInfo.filter }/>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
339
340
341
342
343
344
345
346
                </Drawer>


              <Dialog open={ dialogOpened } onClose={ this.hideDialog } maxWidth="md" fullWidth>
                <BioClimateDisplay classes={ {section: classes.climateDialog} } climateData={ climateData }/>
              </Dialog>

                <Tabs
347
348
                    tab={ currentTab }
                    actions={
Oleksii Savran's avatar
Oleksii Savran committed
349
                      <ButtonBar>
350
                        <span>
Matija Obreza's avatar
Matija Obreza committed
351
352
                          <form method="post" action="/proxy/api/v1/acn/downloadKml">
                            <input type="hidden" name="f" value={ filterCode } />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
353
                            <Button type="submit">{ `${t('common:action.download')} ${t('accessions.public.p.map.kml')}` }</Button>
Matija Obreza's avatar
Matija Obreza committed
354
                          </form>
355
                        </span>
Oleksii Savran's avatar
Oleksii Savran committed
356
                      </ButtonBar>
357
358
                    }
                >
Viacheslav Pavlov's avatar
i18n    
Viacheslav Pavlov committed
359
360
361
                  <Tab name="data" to={ `/a/${filterCode || ''}` }>{ t('accessions.tab.data') }</Tab>
                  <Tab name="overview" to={ `/a/overview/${filterCode || ''}` }>{ t('accessions.tab.overview') }</Tab>
                  <Tab name="map" to={ `/a/map/${filterCode || '' }` }>{ t('accessions.tab.map') }</Tab>
362
363
364
                </Tabs>
                <PrettyFilters
                    prefix="accessions"
365
                    filterObj={ mapInfo && mapInfo.filter || {} }
366
                    onSubmit={ this.myApplyFilters }
Oleksii Savran's avatar
Oleksii Savran committed
367
368
                    displayName="accessions.common.modelName"
                    amount={ mapInfo && mapInfo.accessionCount }
369
                />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
370
                <div className={ `${classes.leafletContainer} ${trackClickPos && classes.crosshair}` }>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
371
372
                  { loading && <Loading /> }
                  { mapInfo && typeof window !== 'undefined' &&
373
                    <MapComponent
374
                        onMoveend={ this.handleMoveEnd }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
375
                        onClick={ this.onMapClick }
376
                        center={ position }
377
378
379
                        zoom={ initialZoom || 3 } minZoom={ 2 } maxZoom={ 14 }
                        bounds={ !initialZoom && initialPosition[0] && !initialPosition[1] ? mapInfo.bounds : undefined }
                        ref={ (ref) => this.mapRef = ref }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
380
                    >
Oleksii Savran's avatar
Oleksii Savran committed
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
                        <Control position="topleft">
                            <Tooltip
                              classes={ { tooltip: classes.tooltip } }
                              className={ `${classes.filterAccessionsButton} ${classes.mapButton}` }
                              title={ t(`accessions.public.p.map.filterAccessions`) }
                              placement="right"
                            >
                                <Button variant="outlined" onClick={ this.openSidebar }>
                                    <FilterIcon className={ classes.mapIcon }/>
                                </Button>
                            </Tooltip>
                        </Control>
                        <Control position="topleft">
                            <Tooltip
                              classes={ { tooltip: classes.tooltip } }
                              className={ `${classes.pickPositionButton} ${classes.mapButton}` }
                              title={ t(`accessions.public.p.map.${ trackClickPos ? 'stopPick' : 'pick'}`) }
                              placement="right"
                            >
                                <Button variant="outlined" onClick={ this.setPositionPick }>
                                    { trackClickPos ?
                                        <CancelIcon className={ classes.mapIcon }/> :
                                        <ClimateIcon className={ classes.mapIcon }/>
                                    }
                                </Button>
                            </Tooltip>
                        </Control>
                        <Control position="topright">
                            <div
                              onMouseEnter={ this.openLayersControls }
                              ref={ (ref) => this.anchorRef = ref }
                            >
                                <Button
                                  variant="contained"
                                  className={ `${classes.mapButton} ${classes.layersButton}` } /*onClick={ this.openLayersControls }*/
                                  onClick={ this.openLayersControls }
                                >
                                    <LayersIcon/>
                                </Button>
                                <Popover open={ layersControlsIsOpen }
                                         anchorEl={ this.anchorRef }
                                         onClose={ this.closeLayersControls }
                                         transformOrigin={ {
                                             vertical: 'top',
                                             horizontal: 'right',
                                         } }
                                         anchorOrigin={ {
                                             vertical: 'top',
                                             horizontal: 'right',
                                         } }
                                >
                                    <Paper className={ classes.layersControl } onMouseLeave={ this.closeLayersControls }>
                                        <MapConfigSection/>
                                    </Paper>
                                </Popover>
                            </div>
                        </Control>
                        <TileLayer
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
439
                            zIndex={ 0 }
440
                            opacity={ 0.50 }
441
442
                            attribution={ '<a href="https://www.maptiler.com/copyright/" target="_blank">© MapTiler</a> <a href="https://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>' }
                            url={ 'https://maps.tilehosting.com/styles/positron/{z}/{x}/{y}.png?key=frAVvE3XbD6EF3BM2kDW' }
443
                        />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
444
445
446

                        { mapLayers && mapLayers.filter((layer) => layer.enabled).map((layer, index) => <TileLayer zIndex={ index + 1 } key={ layer.name } { ...layer }/>) }

Matija Obreza's avatar
Matija Obreza committed
447
                        <TileLayer
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
448
                            zIndex={ mapLayers.length + 1 }
449
450
451
452
                            updateInterval={ 1000 }
                            updateWhenZooming={ false }
                            attribution="&amp;copy Accession localities from <a href=&quot;/&quot;>Genesys PGR</a>"
                            url={ layerUrl }
453
                            subdomains={ mapInfo.tileServers }
454
                        />
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
455
                        { geoData && geoData.length > 0 &&
Oleksii Savran's avatar
Oleksii Savran committed
456
457
458
459
                            <Rectangle
                              bounds={ searchBox }
                              ref={ (marker) => marker && marker.leafletElement.openPopup() }
                            >
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
460
461
                                <Popup open>
                                    <div>
462
                                        { geoData.map((feature, idx) => (<div key={ idx }><Link to={ `/a/${feature.properties.uuid}` }>{ `${feature.properties.accessionNumber} ${feature.properties.instCode}` }</Link></div>)) }
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
463
464
465
                                        { otherCount > 0 && <div>{ t('accessions.public.p.map.andMore', {otherMore: otherCount}) }</div> }
                                    </div>
                                </Popup>
Oleksii Savran's avatar
Oleksii Savran committed
466
                            </Rectangle>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
467
                        }
468
                    </MapComponent>
469
470
                }
                </div>
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
471
            </ContentLayout>
472
473
474
475
476
        );
    }
}

const mapStateToProps = (state, ownProps) => ({
477
    suggestions: state.accessions.public.suggestions,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
478
479
    mapInfo: state.accessions.public.mapInfo ? state.accessions.public.mapInfo.data : undefined,
    loading: state.accessions.public.mapInfo ? state.accessions.public.mapInfo.loading : false,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
480
    mapLayers: state.accessions.public.mapLayers,
481
482
    filterCode: ownProps.match.params.filterCode || '',
    currentTab: ownProps.match.params.tab || 'map', // current tab, or ownProps.location.pathname
483
484
    initialPosition: isNaN(Number(ownProps.match.params.lat)) || isNaN(Number(ownProps.match.params.lng)) ? [] : [Number(ownProps.match.params.lat), Number(ownProps.match.params.lng)],
    initialZoom: isNaN(Number(ownProps.match.params.zoom)) ? null : Number(ownProps.match.params.zoom),
485
486
487
});

const mapDispatchToProps = (dispatch) => bindActionCreators({
488
    loadAccessionsMapInfo,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
489
490
    geoJsonRequest,
    currentClimateRequest,
Viacheslav Pavlov's avatar
Viacheslav Pavlov committed
491
    showSnackbar,
492
    navigateTo,
493
494
}, dispatch);

495
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(translate()(BrowsePage)));