@eeacms/volto-n2k 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -10
- package/package.json +1 -1
- package/src/components/manage/Blocks/CDDACountryProfileMap/View.jsx +3 -2
- package/src/components/manage/Blocks/CddaShape/View.jsx +3 -2
- package/src/components/manage/Blocks/ExploreHabitats/View.jsx +3 -2
- package/src/components/manage/Blocks/ExploreSites/View.jsx +3 -2
- package/src/components/manage/Blocks/ExploreSpecies/View.jsx +3 -2
- package/src/components/manage/Blocks/HabitatDistribution/View.jsx +3 -2
- package/src/components/manage/Blocks/HabitatProtectedSites/View.jsx +3 -2
- package/src/components/manage/Blocks/HabitatsBanner/View.jsx +60 -38
- package/src/components/manage/Blocks/N2KCountryProfileMap/View.jsx +3 -2
- package/src/components/manage/Blocks/SiteBanner/View.jsx +81 -47
- package/src/components/manage/Blocks/SiteHabitatsList/Filters/SortBy.jsx +2 -0
- package/src/components/manage/Blocks/SiteHabitatsList/Filters/View.jsx +21 -5
- package/src/components/manage/Blocks/SiteHabitatsList/View.jsx +37 -7
- package/src/components/manage/Blocks/SiteHabitatsList/style.less +3 -0
- package/src/components/manage/Blocks/SiteHabitatsList/utils.js +4 -18
- package/src/components/manage/Blocks/SiteProtectedHabitats/View.jsx +1 -1
- package/src/components/manage/Blocks/SiteProtectedSpecies/View.jsx +1 -1
- package/src/components/manage/Blocks/SiteShape/View.jsx +3 -2
- package/src/components/manage/Blocks/SiteSpeciesList/View.jsx +5 -0
- package/src/components/manage/Blocks/SiteSpeciesList/style.less +3 -0
- package/src/components/manage/Blocks/SpeciesBanner/View.jsx +43 -31
- package/src/components/manage/Blocks/SpeciesDistribution/View.jsx +3 -2
- package/src/components/manage/Blocks/SpeciesProtectedSites/View.jsx +73 -16
- package/src/components/manage/Blocks/SpeciesProtectedSites/index.js +10 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,11 +4,51 @@ All notable changes to this project will be documented in this file. Dates are d
|
|
|
4
4
|
|
|
5
5
|
Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
6
6
|
|
|
7
|
-
### [1.1.
|
|
7
|
+
### [1.1.6](https://github.com/eea/volto-n2k/compare/1.1.5...1.1.6) - 23 June 2025
|
|
8
8
|
|
|
9
|
-
#### :
|
|
9
|
+
#### :house: Internal changes
|
|
10
|
+
|
|
11
|
+
- style: Automated code fix [eea-jenkins - [`8231cbf`](https://github.com/eea/volto-n2k/commit/8231cbf9aada31924e4e79e1757d3ca4dbb6ed10)]
|
|
12
|
+
- style: Automated code fix [eea-jenkins - [`924b48f`](https://github.com/eea/volto-n2k/commit/924b48fc053bad993dbef1ca8d64a3847727299c)]
|
|
13
|
+
- style: Automated code fix [eea-jenkins - [`516d098`](https://github.com/eea/volto-n2k/commit/516d0986bbe882686878bb42d9a48eb062222c03)]
|
|
14
|
+
- style: Automated code fix [eea-jenkins - [`6836c3e`](https://github.com/eea/volto-n2k/commit/6836c3e0542f602286eee3321d1f190364f50fb9)]
|
|
15
|
+
- style: Automated code fix [eea-jenkins - [`a513b0e`](https://github.com/eea/volto-n2k/commit/a513b0ee92965caffffd8305f00e1e3c4ecb23cc)]
|
|
16
|
+
- style: Automated code fix [eea-jenkins - [`fcf78ea`](https://github.com/eea/volto-n2k/commit/fcf78eaa96ce7cfdcaa29db08e473f5217d43858)]
|
|
17
|
+
- style: Automated code fix [eea-jenkins - [`4d55dd4`](https://github.com/eea/volto-n2k/commit/4d55dd4199d130e841398b893f51ecb6e2a70487)]
|
|
18
|
+
- style: Automated code fix [eea-jenkins - [`f13d5b5`](https://github.com/eea/volto-n2k/commit/f13d5b5a64f6de9fe87999ae9e87d9e69d171581)]
|
|
19
|
+
- style: Automated code fix [eea-jenkins - [`cea8ba8`](https://github.com/eea/volto-n2k/commit/cea8ba8d6cfb74ced07f3d5cbbd1f74f9aeb28ea)]
|
|
20
|
+
- style: Automated code fix [eea-jenkins - [`73b990c`](https://github.com/eea/volto-n2k/commit/73b990ca03ab0cc97e000a1bda8b503a3463984f)]
|
|
21
|
+
|
|
22
|
+
#### :hammer_and_wrench: Others
|
|
23
|
+
|
|
24
|
+
- update site banner for natda [Claudia Ifrim - [`9a41070`](https://github.com/eea/volto-n2k/commit/9a410704364cafbdfe13bc3c159922f31a6b10c3)]
|
|
25
|
+
- show habitat priotity [Claudia Ifrim - [`205f0ed`](https://github.com/eea/volto-n2k/commit/205f0ed9b1a9c49c824e69f41104cbd5ab36768a)]
|
|
26
|
+
- fix lint [vladcalin-edw - [`ca7b199`](https://github.com/eea/volto-n2k/commit/ca7b1995315ea7d76ecf092e02672bd39e2b6067)]
|
|
27
|
+
- Fixed habitats filter and ui breaking [vladcalin-edw - [`a5e9024`](https://github.com/eea/volto-n2k/commit/a5e90240cf0b653e4f1daf7288b29ed33bd095f8)]
|
|
28
|
+
- fix warnings [Claudia Ifrim - [`87b03f2`](https://github.com/eea/volto-n2k/commit/87b03f2b7ef88814452063dd1f9af2b31f2bc04e)]
|
|
29
|
+
- fix sonar [vladcalin-edw - [`c054b68`](https://github.com/eea/volto-n2k/commit/c054b683522dfd3350eff1a302746dc6810596d2)]
|
|
30
|
+
- fix eslint errors [vladcalin-edw - [`78604e8`](https://github.com/eea/volto-n2k/commit/78604e8fdd7129726d2321c7a3cef04abedebb70)]
|
|
31
|
+
- restart jenkins [vladcalin-edw - [`f61974a`](https://github.com/eea/volto-n2k/commit/f61974a4bbbbfbf829d7867ff301da0492e629fd)]
|
|
32
|
+
- species banner avoiding rerenders [vladcalin-edw - [`82b25dc`](https://github.com/eea/volto-n2k/commit/82b25dcd51408fd5c8926cde71584d9dc4963649)]
|
|
33
|
+
- performance improvement [vladcalin-edw - [`a0db347`](https://github.com/eea/volto-n2k/commit/a0db3478e1abd70d65c615ce7ba5c82ccb57034e)]
|
|
34
|
+
- query layer 3 and layer 7 [Claudia Ifrim - [`64b2c7d`](https://github.com/eea/volto-n2k/commit/64b2c7de6ea82a376f0f9ae2128f98ab20d96def)]
|
|
35
|
+
- fix sonarqube [vladcalin-edw - [`b207555`](https://github.com/eea/volto-n2k/commit/b207555ee533cce97f4f4d2d22a7eb84240dd76f)]
|
|
36
|
+
- fix sonarqube [vladcalin-edw - [`8726d0f`](https://github.com/eea/volto-n2k/commit/8726d0fbed394b6b1dec6be99da8250b159c1be8)]
|
|
37
|
+
- fix lint issue [vladcalin-edw - [`7570ec3`](https://github.com/eea/volto-n2k/commit/7570ec3ee87c9d7e13f96bc0ec17edef48977d4e)]
|
|
38
|
+
- cleanup [vladcalin-edw - [`6dd7033`](https://github.com/eea/volto-n2k/commit/6dd7033385bd9db25107873d1c252a2d890493e5)]
|
|
39
|
+
- cleanup [vladcalin-edw - [`69f712b`](https://github.com/eea/volto-n2k/commit/69f712b733dc5a6a34c03c1c046fcd82c8ac49fd)]
|
|
40
|
+
- added priority filter, sort by coverage, sites [vladcalin-edw - [`340f3d4`](https://github.com/eea/volto-n2k/commit/340f3d4e7eda946d6b1254c19dad854611ab96c4)]
|
|
41
|
+
- changed label naming back to formatLabel [vladcalin-edw - [`4f93eeb`](https://github.com/eea/volto-n2k/commit/4f93eeba28545e28ee31a854da433099d7db5cf2)]
|
|
42
|
+
- habitats filtering with hardcoded values [vladcalin-edw - [`ccdda01`](https://github.com/eea/volto-n2k/commit/ccdda013a90d91a05d50c811bb52a1036e729362)]
|
|
43
|
+
- in progress [vladcalin-edw - [`f2669ec`](https://github.com/eea/volto-n2k/commit/f2669ec6c07237cc574f24a08511294cd3e8e4d7)]
|
|
44
|
+
### [1.1.5](https://github.com/eea/volto-n2k/compare/1.1.4...1.1.5) - 18 February 2025
|
|
10
45
|
|
|
11
|
-
|
|
46
|
+
#### :hammer_and_wrench: Others
|
|
47
|
+
|
|
48
|
+
- Scroll to banner on page change [Miu Razvan - [`3195762`](https://github.com/eea/volto-n2k/commit/31957629fdb1addb596f86183251ac9b272b26b6)]
|
|
49
|
+
- fix font size + decimals [Claudia Ifrim - [`4beb02b`](https://github.com/eea/volto-n2k/commit/4beb02bd8bd69a6ef76510166e240b80190b9d12)]
|
|
50
|
+
- show number of caves [Claudia Ifrim - [`e3876b8`](https://github.com/eea/volto-n2k/commit/e3876b8624886c8055692c4324f258a90578170a)]
|
|
51
|
+
### [1.1.4](https://github.com/eea/volto-n2k/compare/1.1.3...1.1.4) - 16 January 2025
|
|
12
52
|
|
|
13
53
|
### [1.1.3](https://github.com/eea/volto-n2k/compare/1.1.2...1.1.3) - 9 January 2025
|
|
14
54
|
|
|
@@ -66,7 +106,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
66
106
|
|
|
67
107
|
#### :house: Internal changes
|
|
68
108
|
|
|
69
|
-
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`e4f9fc8`](https://github.com/eea/volto-n2k/commit/e4f9fc800b753b97cca7c685bc47dd48804276f0)]
|
|
70
109
|
- chore: husky, lint-staged use fixed versions [valentinab25 - [`647d621`](https://github.com/eea/volto-n2k/commit/647d621d52400c50f5bc629b3ddc4f2121f14ffa)]
|
|
71
110
|
- chore:volto 16 in tests, update docs, fix stylelint overrides [valentinab25 - [`60d94b6`](https://github.com/eea/volto-n2k/commit/60d94b61ff8826abc57af9616793a1a247f585b5)]
|
|
72
111
|
|
|
@@ -81,11 +120,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
81
120
|
- try to use volto-spotlight theme in jenkins [Miu Razvan - [`ec0b952`](https://github.com/eea/volto-n2k/commit/ec0b9525b967f907922ae660bd9f520119cd80c1)]
|
|
82
121
|
- remove waitForResourceToLoad [ana-oprea - [`eaded9b`](https://github.com/eea/volto-n2k/commit/eaded9b9ecd1ca2eb78aa8dd65838c063d95db85)]
|
|
83
122
|
- update image size from 300 to 800 px [Claudia Ifrim - [`8d9270a`](https://github.com/eea/volto-n2k/commit/8d9270a09506278ceaea25e8a72abdf5b22fcc78)]
|
|
84
|
-
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`350f8a6`](https://github.com/eea/volto-n2k/commit/350f8a6928aafbf168472b572f8041a79f71f577)]
|
|
85
|
-
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`99b3a84`](https://github.com/eea/volto-n2k/commit/99b3a84a266710fadf7d430117359b741cadede8)]
|
|
86
|
-
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`050ac98`](https://github.com/eea/volto-n2k/commit/050ac982ec39e9a1b4885b665cdc118fca7b1283)]
|
|
87
|
-
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`3546040`](https://github.com/eea/volto-n2k/commit/35460409817f496fc752ab34e37d6d33a069b2e9)]
|
|
88
|
-
- test: [JENKINS] Improve cypress time [valentinab25 - [`06a4ab1`](https://github.com/eea/volto-n2k/commit/06a4ab151799b8cdf4a316dbcb0c323e0f568e30)]
|
|
89
123
|
- test: EN locales, pre-commit fix, feature PRs checks Refs #257193 [valentinab25 - [`4850d6a`](https://github.com/eea/volto-n2k/commit/4850d6a65349fe49dbe9244c30592ae38c9aeaba)]
|
|
90
124
|
- test: Update Makefile and docker-compose to align it with Jenkinsfile [valentinab25 - [`2c91856`](https://github.com/eea/volto-n2k/commit/2c9185688a2fe6b36e5eeb2963f6c8676e3c5628)]
|
|
91
125
|
### [1.0.33](https://github.com/eea/volto-n2k/compare/1.0.32...1.0.33) - 3 July 2023
|
|
@@ -342,7 +376,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
342
376
|
- Update [razvanMiu - [`42ab50e`](https://github.com/eea/volto-n2k/commit/42ab50e6681a47251d15ac06b836c6f8c27157fa)]
|
|
343
377
|
- Added bubble chart [razvanMiu - [`89fba5e`](https://github.com/eea/volto-n2k/commit/89fba5e5db41aa955ba2d0ed58c9f0042c461504)]
|
|
344
378
|
- Group species by id_eunis in species list [razvanMiu - [`543c957`](https://github.com/eea/volto-n2k/commit/543c9573b53acd8eecc9afbb6ae7beeddba53966)]
|
|
345
|
-
- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`2ca3e4c`](https://github.com/eea/volto-n2k/commit/2ca3e4c092211f92339791d71db81f5b4ca2d562)]
|
|
346
379
|
- update maps - species and habitats distribution maps [Claudia Ifrim - [`ad12eb1`](https://github.com/eea/volto-n2k/commit/ad12eb141907d6f28444f1eafc3f687735d2a68d)]
|
|
347
380
|
- update format for common name and author [Claudia Ifrim - [`26b7a2f`](https://github.com/eea/volto-n2k/commit/26b7a2f3d20c7701b57fb24f39fc7dfeceec3ce8)]
|
|
348
381
|
- update format for species name (common / scientific) [Claudia Ifrim - [`abdedcf`](https://github.com/eea/volto-n2k/commit/abdedcfe645665031dedf050fd2c5cdde8c14a50)]
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import isArray from 'lodash/isArray';
|
|
|
3
3
|
import isString from 'lodash/isString';
|
|
4
4
|
import Map from '@eeacms/volto-openlayers-map/Map';
|
|
5
5
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
6
|
-
import {
|
|
6
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
7
7
|
|
|
8
8
|
// layer definitions
|
|
9
9
|
const smallScaleLayerId = 1;
|
|
@@ -57,6 +57,7 @@ const dynamicLayerDefinition = `
|
|
|
57
57
|
]`;
|
|
58
58
|
|
|
59
59
|
const View = (props) => {
|
|
60
|
+
const { ol: openlayers } = props;
|
|
60
61
|
const [sources, setSources] = useState([]);
|
|
61
62
|
const [tiles, setTiles] = useState([]);
|
|
62
63
|
const [extent, setExtent] = useState(null);
|
|
@@ -200,4 +201,4 @@ const View = (props) => {
|
|
|
200
201
|
);
|
|
201
202
|
};
|
|
202
203
|
|
|
203
|
-
export default View;
|
|
204
|
+
export default withOpenLayers(View);
|
|
@@ -4,11 +4,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
4
4
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
5
5
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
6
6
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
7
|
-
import {
|
|
7
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
8
8
|
import { getCddaShapeURL } from './index';
|
|
9
9
|
import './style.less';
|
|
10
10
|
|
|
11
11
|
const View = (props) => {
|
|
12
|
+
const { ol: openlayers } = props;
|
|
12
13
|
const dataFetched = React.useRef();
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
@@ -121,4 +122,4 @@ const View = (props) => {
|
|
|
121
122
|
);
|
|
122
123
|
};
|
|
123
124
|
|
|
124
|
-
export default View;
|
|
125
|
+
export default withOpenLayers(View);
|
|
@@ -5,11 +5,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
5
5
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
6
6
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
7
7
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
8
|
-
import {
|
|
8
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
9
9
|
import { getActiveHabitatsURL } from './index';
|
|
10
10
|
import './style.less';
|
|
11
11
|
|
|
12
12
|
const View = (props) => {
|
|
13
|
+
const { ol: openlayers } = props;
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
15
16
|
const [tileWMSSources, setTileWMSSources] = useState([]);
|
|
@@ -185,4 +186,4 @@ const View = (props) => {
|
|
|
185
186
|
|
|
186
187
|
export default connect((state) => ({
|
|
187
188
|
search: state.table_search || {},
|
|
188
|
-
}))(View);
|
|
189
|
+
}))(withOpenLayers(View));
|
|
@@ -5,11 +5,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
5
5
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
6
6
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
7
7
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
8
|
-
import {
|
|
8
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
9
9
|
import { getActiveSitesURL } from './index';
|
|
10
10
|
import './style.less';
|
|
11
11
|
|
|
12
12
|
const View = (props) => {
|
|
13
|
+
const { ol: openlayers } = props;
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
15
16
|
const [tileWMSSources, setTileWMSSources] = useState([]);
|
|
@@ -176,4 +177,4 @@ const View = (props) => {
|
|
|
176
177
|
|
|
177
178
|
export default connect((state) => ({
|
|
178
179
|
search: state.table_search || {},
|
|
179
|
-
}))(View);
|
|
180
|
+
}))(withOpenLayers(View));
|
|
@@ -5,11 +5,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
5
5
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
6
6
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
7
7
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
8
|
-
import {
|
|
8
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
9
9
|
import { getActiveSpeciesURL } from './index';
|
|
10
10
|
import './style.less';
|
|
11
11
|
|
|
12
12
|
const View = (props) => {
|
|
13
|
+
const { ol: openlayers } = props;
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
15
16
|
const [tileWMSSources, setTileWMSSources] = useState([]);
|
|
@@ -179,4 +180,4 @@ const View = (props) => {
|
|
|
179
180
|
|
|
180
181
|
export default connect((state) => ({
|
|
181
182
|
search: state.table_search || {},
|
|
182
|
-
}))(View);
|
|
183
|
+
}))(withOpenLayers(View));
|
|
@@ -4,11 +4,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
4
4
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
5
5
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
6
6
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
7
|
-
import {
|
|
7
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
8
8
|
import { getHabitatDistributionURL } from './index';
|
|
9
9
|
import './style.less';
|
|
10
10
|
|
|
11
11
|
const View = (props) => {
|
|
12
|
+
const { ol: openlayers } = props;
|
|
12
13
|
const dataFetched = React.useRef();
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
@@ -110,4 +111,4 @@ const View = (props) => {
|
|
|
110
111
|
);
|
|
111
112
|
};
|
|
112
113
|
|
|
113
|
-
export default View;
|
|
114
|
+
export default withOpenLayers(View);
|
|
@@ -4,11 +4,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
4
4
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
5
5
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
6
6
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
7
|
-
import {
|
|
7
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
8
8
|
import { getHabitatProtectedSitesURL } from './index';
|
|
9
9
|
import './style.less';
|
|
10
10
|
|
|
11
11
|
const View = (props) => {
|
|
12
|
+
const { ol: openlayers } = props;
|
|
12
13
|
const dataFetched = React.useRef();
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
@@ -110,4 +111,4 @@ const View = (props) => {
|
|
|
110
111
|
);
|
|
111
112
|
};
|
|
112
113
|
|
|
113
|
-
export default View;
|
|
114
|
+
export default withOpenLayers(View);
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import React, { useRef, useMemo, useState } from 'react';
|
|
2
|
-
import { compose } from 'redux';
|
|
3
|
-
import cx from 'classnames';
|
|
4
|
-
import loadable from '@loadable/component';
|
|
5
|
-
import { Icon } from '@plone/volto/components';
|
|
6
|
-
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
7
1
|
import { VisibilitySensor } from '@eeacms/volto-datablocks/components';
|
|
8
2
|
import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
|
|
9
3
|
import { replaceQueryParam } from '@eeacms/volto-n2k/helpers';
|
|
10
4
|
import arrowLeft from '@eeacms/volto-n2k/icons/arrow-left.svg';
|
|
11
5
|
import arrowRight from '@eeacms/volto-n2k/icons/arrow-right.svg';
|
|
6
|
+
import loadable from '@loadable/component';
|
|
7
|
+
import { Icon } from '@plone/volto/components';
|
|
8
|
+
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
9
|
+
import cx from 'classnames';
|
|
10
|
+
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
11
|
+
import { compose } from 'redux';
|
|
12
12
|
|
|
13
|
-
import './style.less';
|
|
14
13
|
import 'swiper/css';
|
|
14
|
+
import './style.less';
|
|
15
15
|
|
|
16
16
|
const SwiperLoader = loadable.lib(() => import('swiper'));
|
|
17
17
|
const SwiperReactLoader = loadable.lib(() => import('swiper/react'));
|
|
@@ -23,21 +23,34 @@ const getSource = (source) => {
|
|
|
23
23
|
return parsedSource;
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
const
|
|
26
|
+
const ViewComponent = (props) => {
|
|
27
27
|
const swiperEl = useRef();
|
|
28
28
|
const previewEl = useRef();
|
|
29
29
|
const [activeSlide, setActiveSlide] = useState(0);
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
props.data.
|
|
30
|
+
|
|
31
|
+
const habitat_provider = useMemo(
|
|
32
|
+
() => flattenToAppURL(props.data.habitat_provider),
|
|
33
|
+
[props.data.habitat_provider],
|
|
34
|
+
);
|
|
35
|
+
const habitat_pictures_provider = useMemo(
|
|
36
|
+
() => flattenToAppURL(props.data.habitat_pictures_provider),
|
|
37
|
+
[props.data.habitat_pictures_provider],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const habitat = useMemo(
|
|
41
|
+
() => props.providers_data?.[habitat_provider] || {},
|
|
42
|
+
[props.providers_data, habitat_provider],
|
|
33
43
|
);
|
|
34
|
-
const habitat = props.providers_data?.[habitat_provider] || {};
|
|
35
44
|
const habitat_pictures = useMemo(
|
|
36
45
|
() => props.providers_data?.[habitat_pictures_provider] || {},
|
|
37
46
|
[props.providers_data, habitat_pictures_provider],
|
|
38
47
|
);
|
|
39
48
|
|
|
40
|
-
const {
|
|
49
|
+
const {
|
|
50
|
+
code_2000 = [],
|
|
51
|
+
scientific_name = [],
|
|
52
|
+
habitat_prioriy = [],
|
|
53
|
+
} = habitat;
|
|
41
54
|
const { attribution_copyright = [] } = habitat_pictures;
|
|
42
55
|
|
|
43
56
|
const pictures = useMemo(
|
|
@@ -49,6 +62,28 @@ const _View = (props) => {
|
|
|
49
62
|
[pictures],
|
|
50
63
|
);
|
|
51
64
|
|
|
65
|
+
const handleSliderPrevious = useCallback(() => {
|
|
66
|
+
swiperEl.current.slidePrev();
|
|
67
|
+
if (previewEl.current?.[0]) {
|
|
68
|
+
previewEl.current[0].slidePrev();
|
|
69
|
+
}
|
|
70
|
+
if (previewEl.current?.[1]) {
|
|
71
|
+
previewEl.current[1].slidePrev();
|
|
72
|
+
}
|
|
73
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
74
|
+
}, []);
|
|
75
|
+
|
|
76
|
+
const handleSliderNext = useCallback(() => {
|
|
77
|
+
swiperEl.current.slideNext();
|
|
78
|
+
if (previewEl.current?.[0]) {
|
|
79
|
+
previewEl.current[0].slideNext();
|
|
80
|
+
}
|
|
81
|
+
if (previewEl.current?.[1]) {
|
|
82
|
+
previewEl.current[1].slideNext();
|
|
83
|
+
}
|
|
84
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
85
|
+
}, []);
|
|
86
|
+
|
|
52
87
|
if (!habitat_provider && props.mode === 'edit') {
|
|
53
88
|
return 'Habitat banner block, habitat provider undefined';
|
|
54
89
|
}
|
|
@@ -64,6 +99,11 @@ const _View = (props) => {
|
|
|
64
99
|
<p className="info">
|
|
65
100
|
Habitats Directive Annex I code {code_2000[0]}
|
|
66
101
|
</p>
|
|
102
|
+
{habitat_prioriy[0] && (
|
|
103
|
+
<p className="info" style={{ marginTop: '1rem' }}>
|
|
104
|
+
Priority habitat type
|
|
105
|
+
</p>
|
|
106
|
+
)}
|
|
67
107
|
</div>
|
|
68
108
|
{pictures_length > 0 && (
|
|
69
109
|
<div className={cx('carousel one-slide')}>
|
|
@@ -74,16 +114,7 @@ const _View = (props) => {
|
|
|
74
114
|
<>
|
|
75
115
|
<button
|
|
76
116
|
className="swiper-button image-swiper-button-prev"
|
|
77
|
-
onClick={
|
|
78
|
-
swiperEl.current.slidePrev();
|
|
79
|
-
if (previewEl.current?.[0]) {
|
|
80
|
-
previewEl.current[0].slidePrev();
|
|
81
|
-
}
|
|
82
|
-
if (previewEl.current?.[1]) {
|
|
83
|
-
previewEl.current[1].slidePrev();
|
|
84
|
-
}
|
|
85
|
-
setActiveSlide(swiperEl.current.realIndex);
|
|
86
|
-
}}
|
|
117
|
+
onClick={handleSliderPrevious}
|
|
87
118
|
>
|
|
88
119
|
<Icon
|
|
89
120
|
className="icon-left"
|
|
@@ -94,16 +125,7 @@ const _View = (props) => {
|
|
|
94
125
|
</button>
|
|
95
126
|
<button
|
|
96
127
|
className="swiper-button image-swiper-button-next"
|
|
97
|
-
onClick={
|
|
98
|
-
swiperEl.current.slideNext();
|
|
99
|
-
if (previewEl.current?.[0]) {
|
|
100
|
-
previewEl.current[0].slideNext();
|
|
101
|
-
}
|
|
102
|
-
if (previewEl.current?.[1]) {
|
|
103
|
-
previewEl.current[1].slideNext();
|
|
104
|
-
}
|
|
105
|
-
setActiveSlide(swiperEl.current.realIndex);
|
|
106
|
-
}}
|
|
128
|
+
onClick={handleSliderNext}
|
|
107
129
|
>
|
|
108
130
|
<Icon
|
|
109
131
|
className="icon-right"
|
|
@@ -139,7 +161,7 @@ const _View = (props) => {
|
|
|
139
161
|
}}
|
|
140
162
|
>
|
|
141
163
|
{pictures.map((source, index) => (
|
|
142
|
-
<SwiperSlide>
|
|
164
|
+
<SwiperSlide key={source}>
|
|
143
165
|
<img
|
|
144
166
|
src={getSource(source)}
|
|
145
167
|
alt={pictures[index]}
|
|
@@ -162,7 +184,7 @@ const _View = (props) => {
|
|
|
162
184
|
);
|
|
163
185
|
};
|
|
164
186
|
|
|
165
|
-
const
|
|
187
|
+
const ViewCompose = compose(
|
|
166
188
|
connectToMultipleProviders((props) => ({
|
|
167
189
|
providers: [
|
|
168
190
|
{
|
|
@@ -171,12 +193,12 @@ const View = compose(
|
|
|
171
193
|
{ provider_url: props.data?.habitat_pictures_provider },
|
|
172
194
|
],
|
|
173
195
|
})),
|
|
174
|
-
)(
|
|
196
|
+
)(ViewComponent);
|
|
175
197
|
|
|
176
|
-
export default function
|
|
198
|
+
export default function View(props) {
|
|
177
199
|
return (
|
|
178
200
|
<VisibilitySensor Placeholder={() => <div>loading.... </div>}>
|
|
179
|
-
<
|
|
201
|
+
<ViewCompose {...props} />
|
|
180
202
|
</VisibilitySensor>
|
|
181
203
|
);
|
|
182
204
|
}
|
|
@@ -3,7 +3,7 @@ import isArray from 'lodash/isArray';
|
|
|
3
3
|
import isString from 'lodash/isString';
|
|
4
4
|
import Map from '@eeacms/volto-openlayers-map/Map';
|
|
5
5
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
6
|
-
import {
|
|
6
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
7
7
|
|
|
8
8
|
let dynamicLayerDefinition = `
|
|
9
9
|
[
|
|
@@ -43,6 +43,7 @@ let dynamicLayerDefinition = `
|
|
|
43
43
|
]`;
|
|
44
44
|
|
|
45
45
|
const View = (props) => {
|
|
46
|
+
const { ol: openlayers } = props;
|
|
46
47
|
const mapRef = useRef();
|
|
47
48
|
const [sources, setSources] = useState([]);
|
|
48
49
|
const [tiles, setTiles] = useState([]);
|
|
@@ -159,4 +160,4 @@ const View = (props) => {
|
|
|
159
160
|
);
|
|
160
161
|
};
|
|
161
162
|
|
|
162
|
-
export default View;
|
|
163
|
+
export default withOpenLayers(View);
|
|
@@ -12,14 +12,15 @@ const View = (props) => {
|
|
|
12
12
|
country_name,
|
|
13
13
|
site_name,
|
|
14
14
|
designation = [],
|
|
15
|
-
|
|
15
|
+
iucn_category = [],
|
|
16
16
|
site_type = [],
|
|
17
17
|
site_code = [],
|
|
18
|
+
national_id = [],
|
|
18
19
|
area_ha = [],
|
|
19
20
|
year_stablished = [],
|
|
20
21
|
number_protected_habitat_types = [],
|
|
21
22
|
number_protected_species = [],
|
|
22
|
-
|
|
23
|
+
marine_area_percentage = [],
|
|
23
24
|
} = provider_data;
|
|
24
25
|
|
|
25
26
|
if (!site_code[0]) return '';
|
|
@@ -31,7 +32,9 @@ const View = (props) => {
|
|
|
31
32
|
<h2 className="country-title">{site_name}</h2>
|
|
32
33
|
<p className="site-name">{country_name}</p>
|
|
33
34
|
{designation ? (
|
|
34
|
-
<p className="site-designation">
|
|
35
|
+
<p className="site-designation">
|
|
36
|
+
Designation type: {designation}
|
|
37
|
+
</p>
|
|
35
38
|
) : (
|
|
36
39
|
''
|
|
37
40
|
)}
|
|
@@ -42,68 +45,99 @@ const View = (props) => {
|
|
|
42
45
|
<>
|
|
43
46
|
<div className="site-detail">
|
|
44
47
|
<div className="upper">
|
|
45
|
-
{
|
|
46
|
-
|
|
48
|
+
{site_code[0] ? <div>{site_code}</div> : <div>-</div>}
|
|
49
|
+
</div>
|
|
50
|
+
<div className="lower">NatDA Site Code</div>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div className="site-detail">
|
|
54
|
+
<div className="upper">
|
|
55
|
+
{isNumber(area_ha[0]) ? (
|
|
56
|
+
<div>{area_ha} ha</div>
|
|
47
57
|
) : (
|
|
48
|
-
<div
|
|
58
|
+
<div>No data</div>
|
|
49
59
|
)}
|
|
50
60
|
</div>
|
|
51
|
-
<div className="lower">
|
|
61
|
+
<div className="lower">Reported area</div>
|
|
52
62
|
</div>
|
|
53
63
|
|
|
54
64
|
<div className="site-detail">
|
|
55
65
|
<div className="upper">
|
|
56
|
-
{
|
|
66
|
+
{year_stablished[0] ? (
|
|
67
|
+
<div>{year_stablished}</div>
|
|
68
|
+
) : (
|
|
69
|
+
<div>-</div>
|
|
70
|
+
)}
|
|
57
71
|
</div>
|
|
58
|
-
<div className="lower">
|
|
72
|
+
<div className="lower">Site established</div>
|
|
59
73
|
</div>
|
|
60
|
-
</>
|
|
61
|
-
)}
|
|
62
74
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
<div className="site-detail">
|
|
71
|
-
<div className="upper">
|
|
72
|
-
{isNumber(area_ha[0]) ? (
|
|
73
|
-
<div>{area_ha} ha</div>
|
|
75
|
+
{national_id > 0 ? (
|
|
76
|
+
<div className="site-detail">
|
|
77
|
+
<div className="upper">
|
|
78
|
+
<div>{national_id}</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div className="lower">National Site Code</div>
|
|
81
|
+
</div>
|
|
74
82
|
) : (
|
|
75
|
-
|
|
83
|
+
''
|
|
76
84
|
)}
|
|
77
|
-
</div>
|
|
78
|
-
<div className="lower">Reported area</div>
|
|
79
|
-
</div>
|
|
80
85
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
<div className="site-detail">
|
|
87
|
+
<div className="upper">
|
|
88
|
+
{iucn_category[0] ? (
|
|
89
|
+
<div>{iucn_category}</div>
|
|
90
|
+
) : (
|
|
91
|
+
<div>Not Reported</div>
|
|
92
|
+
)}
|
|
93
|
+
</div>
|
|
94
|
+
<div className="lower">IUCN Management Category</div>
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
{marine_area_percentage > 0 ? (
|
|
98
|
+
<div className="site-detail">
|
|
99
|
+
<div className="upper">
|
|
100
|
+
<div>{marine_area_percentage} %</div>
|
|
101
|
+
</div>
|
|
102
|
+
<div className="lower">Marine Area</div>
|
|
103
|
+
</div>
|
|
85
104
|
) : (
|
|
86
|
-
|
|
105
|
+
''
|
|
87
106
|
)}
|
|
88
|
-
|
|
89
|
-
<div className="lower">Site established</div>
|
|
90
|
-
</div>
|
|
91
|
-
|
|
92
|
-
{site_type[0] === 'CDDA' && (
|
|
93
|
-
<div className="site-detail">
|
|
94
|
-
<div className="upper">
|
|
95
|
-
{major_ecosystem_type[0] ? (
|
|
96
|
-
<div>{major_ecosystem_type}</div>
|
|
97
|
-
) : (
|
|
98
|
-
<div>-</div>
|
|
99
|
-
)}
|
|
100
|
-
</div>
|
|
101
|
-
<div className="lower">Ecosystem</div>
|
|
102
|
-
</div>
|
|
107
|
+
</>
|
|
103
108
|
)}
|
|
104
109
|
|
|
105
|
-
{site_type[0]
|
|
110
|
+
{['Natura2000', 'Emerald'].includes(site_type[0]) && (
|
|
106
111
|
<>
|
|
112
|
+
<div className="site-detail">
|
|
113
|
+
<div className="upper">
|
|
114
|
+
{site_code[0] ? <div>{site_code}</div> : <div>-</div>}
|
|
115
|
+
</div>
|
|
116
|
+
<div className="lower">Site code</div>
|
|
117
|
+
</div>
|
|
118
|
+
|
|
119
|
+
<div className="site-detail">
|
|
120
|
+
<div className="upper">
|
|
121
|
+
{isNumber(area_ha[0]) ? (
|
|
122
|
+
<div>{area_ha} ha</div>
|
|
123
|
+
) : (
|
|
124
|
+
<div>No data</div>
|
|
125
|
+
)}
|
|
126
|
+
</div>
|
|
127
|
+
<div className="lower">Reported area</div>
|
|
128
|
+
</div>
|
|
129
|
+
|
|
130
|
+
<div className="site-detail">
|
|
131
|
+
<div className="upper">
|
|
132
|
+
{year_stablished[0] ? (
|
|
133
|
+
<div>{year_stablished}</div>
|
|
134
|
+
) : (
|
|
135
|
+
<div>-</div>
|
|
136
|
+
)}
|
|
137
|
+
</div>
|
|
138
|
+
<div className="lower">Site established</div>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
107
141
|
<div className="site-detail">
|
|
108
142
|
<div className="upper">
|
|
109
143
|
{isNumber(number_protected_habitat_types[0]) ? (
|
|
@@ -14,6 +14,8 @@ const View = (props) => {
|
|
|
14
14
|
|
|
15
15
|
const sortByOptions = [
|
|
16
16
|
{ text: 'Name', value: 'scientific_name', key: 'scientific_name' },
|
|
17
|
+
{ text: 'Coverage', value: 'coverage_ha', key: 'coverage_ha' },
|
|
18
|
+
{ text: 'Sites', value: 'number_sites', key: 'number_sites' },
|
|
17
19
|
];
|
|
18
20
|
|
|
19
21
|
return (
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
Label,
|
|
8
8
|
} from 'semantic-ui-react';
|
|
9
9
|
import { Icon } from '@plone/volto/components';
|
|
10
|
-
|
|
10
|
+
import filterSVG from '@plone/volto/icons/filter.svg';
|
|
11
11
|
import clearSVG from '@plone/volto/icons/clear.svg';
|
|
12
12
|
|
|
13
13
|
import HabitatsGroups from './HabitatsGroups';
|
|
@@ -15,8 +15,10 @@ import SortBy from './SortBy';
|
|
|
15
15
|
|
|
16
16
|
import { filtersLabels } from '../utils';
|
|
17
17
|
|
|
18
|
+
// TODO: Display the correct filters for habitats based on existing data
|
|
18
19
|
const SidebarFilter = (props) => {
|
|
19
20
|
const { activeFilters, filters, filter, index, setActiveFilters } = props;
|
|
21
|
+
|
|
20
22
|
return (
|
|
21
23
|
<div className="filter">
|
|
22
24
|
<div className="header">
|
|
@@ -97,8 +99,22 @@ const View = (props) => {
|
|
|
97
99
|
if (key !== 'getTitle') {
|
|
98
100
|
newFilters[filter][key] =
|
|
99
101
|
filteredHabitats.filter((habitats) => {
|
|
100
|
-
return !!habitats.filter((habitat) =>
|
|
101
|
-
|
|
102
|
+
return !!habitats.filter((habitat) => {
|
|
103
|
+
if (
|
|
104
|
+
filtersLabels[filter][key] ===
|
|
105
|
+
filtersLabels.habitat_prioriy.wp
|
|
106
|
+
) {
|
|
107
|
+
return habitat[filter] === 1;
|
|
108
|
+
}
|
|
109
|
+
if (
|
|
110
|
+
filtersLabels[filter][key] ===
|
|
111
|
+
filtersLabels.habitat_prioriy.np
|
|
112
|
+
) {
|
|
113
|
+
return habitat[filter] === null;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return habitat[filter] === filtersLabels[filter][key];
|
|
117
|
+
}).length;
|
|
102
118
|
}).length || 'none';
|
|
103
119
|
}
|
|
104
120
|
}
|
|
@@ -160,9 +176,9 @@ const View = (props) => {
|
|
|
160
176
|
setPagination({ ...pagination, itemsPerPage: data.value });
|
|
161
177
|
}}
|
|
162
178
|
/>
|
|
163
|
-
|
|
179
|
+
<button aria-label="Set filters" onClick={() => setVisible(!visible)}>
|
|
164
180
|
<Icon name={filterSVG} size="24px" />
|
|
165
|
-
</button>
|
|
181
|
+
</button>
|
|
166
182
|
</div>
|
|
167
183
|
</Container>
|
|
168
184
|
<Sidebar
|
|
@@ -3,9 +3,9 @@ import { Link } from 'react-router-dom';
|
|
|
3
3
|
import { Container, Pagination, Grid } from 'semantic-ui-react';
|
|
4
4
|
import { getObjectByIndex, photoPlaceholders } from '@eeacms/volto-n2k/helpers';
|
|
5
5
|
import { Filters } from './Filters';
|
|
6
|
-
// import { getPopulationString, getLabelString } from './utils';
|
|
7
6
|
|
|
8
7
|
import './style.less';
|
|
8
|
+
import { filtersLabels } from './utils';
|
|
9
9
|
|
|
10
10
|
const getCurrentPageLength = (pagination, arr) => {
|
|
11
11
|
const totalPages = Math.ceil(pagination.totalItems / pagination.itemsPerPage);
|
|
@@ -56,13 +56,36 @@ const View = (props) => {
|
|
|
56
56
|
|
|
57
57
|
const filteredHabitats = habitats.filter((items, index) => {
|
|
58
58
|
let itemsHaveFilter = true;
|
|
59
|
+
|
|
59
60
|
Object.keys(activeFilters).forEach((filter) => {
|
|
60
61
|
let habitatHasFilter = false;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
|
|
63
|
+
activeFilters[filter].forEach((key) => {
|
|
64
|
+
if (filter in filtersLabels) {
|
|
65
|
+
if (
|
|
66
|
+
filtersLabels[filter][key] === filtersLabels.habitat_prioriy.wp
|
|
67
|
+
) {
|
|
68
|
+
habitatHasFilter = items[0][filter] === 1;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (
|
|
72
|
+
filtersLabels[filter][key] === filtersLabels.habitat_prioriy.np
|
|
73
|
+
) {
|
|
74
|
+
habitatHasFilter = items[0][filter] === null;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (filtersLabels[filter][key] === items[0][filter]) {
|
|
79
|
+
habitatHasFilter = true;
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
64
82
|
}
|
|
65
83
|
});
|
|
84
|
+
|
|
85
|
+
if (activeFilters[filter].includes(items[0][filter])) {
|
|
86
|
+
habitatHasFilter = true;
|
|
87
|
+
}
|
|
88
|
+
|
|
66
89
|
if (!habitatHasFilter) {
|
|
67
90
|
itemsHaveFilter = false;
|
|
68
91
|
}
|
|
@@ -188,10 +211,13 @@ const View = (props) => {
|
|
|
188
211
|
style={{ fontSize: '1.2rem' }}
|
|
189
212
|
key={`habitat-${index}-${habitat.code_2000}`}
|
|
190
213
|
>
|
|
191
|
-
Cover: {habitat.coverage_ha.toFixed(2)} ha (
|
|
192
|
-
{(habitat.coverage_ha / 100).toFixed(4)} km²)
|
|
193
214
|
{habitat.habitat_prioriy
|
|
194
|
-
?
|
|
215
|
+
? `Priority habitat type; `
|
|
216
|
+
: ''}
|
|
217
|
+
Cover: {habitat.coverage_ha.toFixed(2)} ha (
|
|
218
|
+
{(habitat.coverage_ha / 100).toFixed(2)} km²)
|
|
219
|
+
{habitat.caves > 0
|
|
220
|
+
? `; Number of caves: ${habitat.caves}`
|
|
195
221
|
: ''}
|
|
196
222
|
</p>
|
|
197
223
|
))}
|
|
@@ -220,6 +246,10 @@ const View = (props) => {
|
|
|
220
246
|
)}
|
|
221
247
|
onPageChange={(e, data) => {
|
|
222
248
|
setPagination({ ...pagination, activePage: data.activePage });
|
|
249
|
+
const el = document.getElementById('habitats-banner');
|
|
250
|
+
el.scrollIntoView({
|
|
251
|
+
block: 'start',
|
|
252
|
+
});
|
|
223
253
|
}}
|
|
224
254
|
prevItem={null}
|
|
225
255
|
nextItem={null}
|
|
@@ -10,9 +10,12 @@ div#view .site-habitats-list .habitats-list .ui.container > * {
|
|
|
10
10
|
.habitats-filters {
|
|
11
11
|
.ui.container {
|
|
12
12
|
display: flex;
|
|
13
|
+
align-items: center;
|
|
13
14
|
justify-content: space-between;
|
|
14
15
|
|
|
15
16
|
.active-filters {
|
|
17
|
+
margin-top: 0;
|
|
18
|
+
|
|
16
19
|
.ui.label.active-filter {
|
|
17
20
|
display: inline-flex;
|
|
18
21
|
flex-flow: row;
|
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
export const filtersLabels = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
w: 'Wintering',
|
|
7
|
-
getTitle: () => 'Population type',
|
|
8
|
-
},
|
|
9
|
-
counting_unit: {
|
|
10
|
-
i: 'Individuals',
|
|
11
|
-
p: 'Pairs',
|
|
12
|
-
getTitle: () => 'Unit',
|
|
13
|
-
},
|
|
14
|
-
abundance_category: {
|
|
15
|
-
C: 'Common',
|
|
16
|
-
R: 'Rare',
|
|
17
|
-
V: 'Very rare',
|
|
18
|
-
P: 'Present',
|
|
19
|
-
getTitle: () => 'Abundance',
|
|
2
|
+
habitat_prioriy: {
|
|
3
|
+
wp: 'With priority',
|
|
4
|
+
np: 'Without priority',
|
|
5
|
+
getTitle: () => 'Habitat priority',
|
|
20
6
|
},
|
|
21
7
|
};
|
|
22
8
|
|
|
@@ -23,7 +23,7 @@ const View = (props) => {
|
|
|
23
23
|
}, [JSON.stringify(provider_data)]);
|
|
24
24
|
|
|
25
25
|
return (
|
|
26
|
-
<div className="habitats-banner full-width">
|
|
26
|
+
<div className="habitats-banner full-width" id="habitats-banner">
|
|
27
27
|
<div className="habitats-container">
|
|
28
28
|
<Container className="habitats-wrapper">
|
|
29
29
|
<div className="habitats-wrapper">
|
|
@@ -11,7 +11,7 @@ const View = (props) => {
|
|
|
11
11
|
}, {});
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
|
-
<div className="species-banner full-width">
|
|
14
|
+
<div className="species-banner full-width" id="species-banner">
|
|
15
15
|
<div className="species-container">
|
|
16
16
|
<Container className="species-wrapper">
|
|
17
17
|
{/* <Grid size="12">
|
|
@@ -4,11 +4,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
4
4
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
5
5
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
6
6
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
7
|
-
import {
|
|
7
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
8
8
|
import { getSiteShapeURL } from './index';
|
|
9
9
|
import './style.less';
|
|
10
10
|
|
|
11
11
|
const View = (props) => {
|
|
12
|
+
const { ol: openlayers } = props;
|
|
12
13
|
const dataFetched = React.useRef();
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
@@ -119,4 +120,4 @@ const View = (props) => {
|
|
|
119
120
|
);
|
|
120
121
|
};
|
|
121
122
|
|
|
122
|
-
export default View;
|
|
123
|
+
export default withOpenLayers(View);
|
|
@@ -181,6 +181,7 @@ const View = (props) => {
|
|
|
181
181
|
{filteredSpecies[index].map((specimen, index) => (
|
|
182
182
|
<p
|
|
183
183
|
className="specimen-data"
|
|
184
|
+
style={{ fontSize: '1.2rem' }}
|
|
184
185
|
key={`specimen-${index}-${specimen.id_eunis}`}
|
|
185
186
|
>
|
|
186
187
|
{getLabelString(
|
|
@@ -233,6 +234,10 @@ const View = (props) => {
|
|
|
233
234
|
)}
|
|
234
235
|
onPageChange={(e, data) => {
|
|
235
236
|
setPagination({ ...pagination, activePage: data.activePage });
|
|
237
|
+
const el = document.getElementById('species-banner');
|
|
238
|
+
el.scrollIntoView({
|
|
239
|
+
block: 'start',
|
|
240
|
+
});
|
|
236
241
|
}}
|
|
237
242
|
prevItem={null}
|
|
238
243
|
nextItem={null}
|
|
@@ -10,9 +10,12 @@ div#view .site-species-list .species-list .ui.container > * {
|
|
|
10
10
|
.species-filters {
|
|
11
11
|
.ui.container {
|
|
12
12
|
display: flex;
|
|
13
|
+
align-items: center;
|
|
13
14
|
justify-content: space-between;
|
|
14
15
|
|
|
15
16
|
.active-filters {
|
|
17
|
+
margin-top: 0;
|
|
18
|
+
|
|
16
19
|
.ui.label.active-filter {
|
|
17
20
|
display: inline-flex;
|
|
18
21
|
flex-flow: row;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/* eslint-disable react/jsx-no-target-blank */
|
|
2
|
-
import React, { useRef, useMemo, useState } from 'react';
|
|
2
|
+
import React, { useRef, useMemo, useState, useCallback } from 'react';
|
|
3
3
|
import { compose } from 'redux';
|
|
4
4
|
import cx from 'classnames';
|
|
5
5
|
import loadable from '@loadable/component';
|
|
@@ -24,15 +24,23 @@ const getSource = (source) => {
|
|
|
24
24
|
return parsedSource;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
const
|
|
27
|
+
const ViewComponent = (props) => {
|
|
28
28
|
const swiperEl = useRef();
|
|
29
29
|
const previewEl = useRef();
|
|
30
30
|
const [activeSlide, setActiveSlide] = useState(0);
|
|
31
|
-
const species_provider =
|
|
32
|
-
|
|
33
|
-
props.data.
|
|
31
|
+
const species_provider = useMemo(
|
|
32
|
+
() => flattenToAppURL(props.data.species_provider),
|
|
33
|
+
[props.data.species_provider],
|
|
34
|
+
);
|
|
35
|
+
const species_pictures_provider = useMemo(
|
|
36
|
+
() => flattenToAppURL(props.data.species_pictures_provider),
|
|
37
|
+
[props.data.species_pictures_provider],
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const species = useMemo(
|
|
41
|
+
() => props.providers_data?.[species_provider] || {},
|
|
42
|
+
[props.providers_data, species_provider],
|
|
34
43
|
);
|
|
35
|
-
const species = props.providers_data?.[species_provider] || {};
|
|
36
44
|
const species_pictures = useMemo(
|
|
37
45
|
() => props.providers_data?.[species_pictures_provider] || {},
|
|
38
46
|
[props.providers_data, species_pictures_provider],
|
|
@@ -63,6 +71,28 @@ const _View = (props) => {
|
|
|
63
71
|
[pictures],
|
|
64
72
|
);
|
|
65
73
|
|
|
74
|
+
const handleSliderPrevious = useCallback(() => {
|
|
75
|
+
swiperEl.current.slidePrev();
|
|
76
|
+
if (previewEl.current?.[0]) {
|
|
77
|
+
previewEl.current[0].slidePrev();
|
|
78
|
+
}
|
|
79
|
+
if (previewEl.current?.[1]) {
|
|
80
|
+
previewEl.current[1].slidePrev();
|
|
81
|
+
}
|
|
82
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
83
|
+
}, []);
|
|
84
|
+
|
|
85
|
+
const handleSliderNext = useCallback(() => {
|
|
86
|
+
swiperEl.current.slideNext();
|
|
87
|
+
if (previewEl.current?.[0]) {
|
|
88
|
+
previewEl.current[0].slideNext();
|
|
89
|
+
}
|
|
90
|
+
if (previewEl.current?.[1]) {
|
|
91
|
+
previewEl.current[1].slideNext();
|
|
92
|
+
}
|
|
93
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
94
|
+
}, []);
|
|
95
|
+
|
|
66
96
|
if (!species_provider && props.mode === 'edit') {
|
|
67
97
|
return 'species banner block, species provider undefined';
|
|
68
98
|
}
|
|
@@ -110,16 +140,7 @@ const _View = (props) => {
|
|
|
110
140
|
<>
|
|
111
141
|
<button
|
|
112
142
|
className="swiper-button image-swiper-button-prev"
|
|
113
|
-
onClick={
|
|
114
|
-
swiperEl.current.slidePrev();
|
|
115
|
-
if (previewEl.current?.[0]) {
|
|
116
|
-
previewEl.current[0].slidePrev();
|
|
117
|
-
}
|
|
118
|
-
if (previewEl.current?.[1]) {
|
|
119
|
-
previewEl.current[1].slidePrev();
|
|
120
|
-
}
|
|
121
|
-
setActiveSlide(swiperEl.current.realIndex);
|
|
122
|
-
}}
|
|
143
|
+
onClick={handleSliderPrevious}
|
|
123
144
|
>
|
|
124
145
|
<Icon
|
|
125
146
|
className="icon-left"
|
|
@@ -130,16 +151,7 @@ const _View = (props) => {
|
|
|
130
151
|
</button>
|
|
131
152
|
<button
|
|
132
153
|
className="swiper-button image-swiper-button-next"
|
|
133
|
-
onClick={
|
|
134
|
-
swiperEl.current.slideNext();
|
|
135
|
-
if (previewEl.current?.[0]) {
|
|
136
|
-
previewEl.current[0].slideNext();
|
|
137
|
-
}
|
|
138
|
-
if (previewEl.current?.[1]) {
|
|
139
|
-
previewEl.current[1].slideNext();
|
|
140
|
-
}
|
|
141
|
-
setActiveSlide(swiperEl.current.realIndex);
|
|
142
|
-
}}
|
|
154
|
+
onClick={handleSliderNext}
|
|
143
155
|
>
|
|
144
156
|
<Icon
|
|
145
157
|
className="icon-right"
|
|
@@ -176,7 +188,7 @@ const _View = (props) => {
|
|
|
176
188
|
}}
|
|
177
189
|
>
|
|
178
190
|
{pictures.map((source, index) => (
|
|
179
|
-
<SwiperSlide>
|
|
191
|
+
<SwiperSlide key={source}>
|
|
180
192
|
<img
|
|
181
193
|
src={getSource(source)}
|
|
182
194
|
alt={pictures[index]}
|
|
@@ -198,7 +210,7 @@ const _View = (props) => {
|
|
|
198
210
|
);
|
|
199
211
|
};
|
|
200
212
|
|
|
201
|
-
const
|
|
213
|
+
const ViewCompose = compose(
|
|
202
214
|
connectToMultipleProviders((props) => ({
|
|
203
215
|
providers: [
|
|
204
216
|
{
|
|
@@ -207,12 +219,12 @@ const View = compose(
|
|
|
207
219
|
{ provider_url: props.data?.species_pictures_provider },
|
|
208
220
|
],
|
|
209
221
|
})),
|
|
210
|
-
)(
|
|
222
|
+
)(ViewComponent);
|
|
211
223
|
|
|
212
|
-
export default function
|
|
224
|
+
export default function View(props) {
|
|
213
225
|
return (
|
|
214
226
|
<VisibilitySensor Placeholder={() => <div>loading.... </div>}>
|
|
215
|
-
<
|
|
227
|
+
<ViewCompose {...props} />
|
|
216
228
|
</VisibilitySensor>
|
|
217
229
|
);
|
|
218
230
|
}
|
|
@@ -4,11 +4,12 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
4
4
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
5
5
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
6
6
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
7
|
-
import {
|
|
7
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
8
8
|
import { getSpeciesDistributionURL } from './index';
|
|
9
9
|
import './style.less';
|
|
10
10
|
|
|
11
11
|
const View = (props) => {
|
|
12
|
+
const { ol: openlayers } = props;
|
|
12
13
|
const dataFetched = React.useRef();
|
|
13
14
|
const [options, setOptions] = React.useState({});
|
|
14
15
|
const [vectorSource, setVectorSource] = useState(null);
|
|
@@ -115,4 +116,4 @@ const View = (props) => {
|
|
|
115
116
|
);
|
|
116
117
|
};
|
|
117
118
|
|
|
118
|
-
export default View;
|
|
119
|
+
export default withOpenLayers(View);
|
|
@@ -4,11 +4,14 @@ import Map from '@eeacms/volto-openlayers-map/Map';
|
|
|
4
4
|
import { Interactions } from '@eeacms/volto-openlayers-map/Interactions';
|
|
5
5
|
import { Controls } from '@eeacms/volto-openlayers-map/Controls';
|
|
6
6
|
import { Layers, Layer } from '@eeacms/volto-openlayers-map/Layers';
|
|
7
|
-
import {
|
|
7
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
8
8
|
import { getSpeciesProtectedSitesURL } from './index';
|
|
9
9
|
import './style.less';
|
|
10
10
|
|
|
11
|
+
const DEFAULT_LAYERS = [3, 7];
|
|
12
|
+
|
|
11
13
|
const View = (props) => {
|
|
14
|
+
const { ol: openlayers } = props;
|
|
12
15
|
const dataFetched = React.useRef();
|
|
13
16
|
const [options, setOptions] = React.useState({});
|
|
14
17
|
const [vectorSource, setVectorSource] = useState(null);
|
|
@@ -16,6 +19,7 @@ const View = (props) => {
|
|
|
16
19
|
const { extent, format, proj, style, source } = openlayers;
|
|
17
20
|
const provider_data = props.provider_data || {};
|
|
18
21
|
const { code_2000 = [] } = provider_data;
|
|
22
|
+
const layers = DEFAULT_LAYERS;
|
|
19
23
|
|
|
20
24
|
useEffect(() => {
|
|
21
25
|
if (__SERVER__) return;
|
|
@@ -32,36 +36,89 @@ const View = (props) => {
|
|
|
32
36
|
}),
|
|
33
37
|
]);
|
|
34
38
|
/* eslint-disable-next-line */
|
|
35
|
-
}, []);
|
|
39
|
+
}, [source]);
|
|
36
40
|
|
|
37
41
|
useEffect(() => {
|
|
38
|
-
if (__SERVER__ || !vectorSource || !code_2000[0]
|
|
42
|
+
if (__SERVER__ || !vectorSource || !code_2000[0]) {
|
|
43
|
+
dataFetched.current = false;
|
|
39
44
|
return;
|
|
45
|
+
}
|
|
40
46
|
|
|
41
47
|
const esrijsonFormat = new format.EsriJSON();
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
const urls = getSpeciesProtectedSitesURL(code_2000[0], layers);
|
|
49
|
+
|
|
50
|
+
let isMounted = true;
|
|
51
|
+
dataFetched.current = false;
|
|
52
|
+
|
|
53
|
+
// Get species protected sites from all specified layers
|
|
54
|
+
Promise.all(
|
|
55
|
+
Object.values(urls).map((url) =>
|
|
56
|
+
fetch(url)
|
|
57
|
+
.then((response) => {
|
|
58
|
+
if (!isMounted) return { features: [] };
|
|
59
|
+
return response.status === 200 ? response.json() : { features: [] };
|
|
60
|
+
})
|
|
61
|
+
.catch(() => {
|
|
62
|
+
if (!isMounted) return { features: [] };
|
|
63
|
+
return { features: [] };
|
|
64
|
+
}),
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
.then((results) => {
|
|
68
|
+
if (!isMounted) return;
|
|
69
|
+
|
|
70
|
+
const validResults = results.filter((r) => !r.error);
|
|
46
71
|
dataFetched.current = true;
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
|
|
73
|
+
const allFeatures = validResults.reduce((acc, data) => {
|
|
74
|
+
return acc.concat(data.features || []);
|
|
75
|
+
}, []);
|
|
76
|
+
|
|
77
|
+
if (allFeatures.length > 0) {
|
|
78
|
+
// all features from all layers should have the same metadata
|
|
79
|
+
const metadataTemplate = validResults.find(
|
|
80
|
+
(r) => r.features && r.features.length > 0,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const features = esrijsonFormat.readFeatures({
|
|
84
|
+
...metadataTemplate,
|
|
85
|
+
features: allFeatures,
|
|
86
|
+
});
|
|
87
|
+
|
|
49
88
|
if (features.length > 0) {
|
|
50
89
|
vectorSource.addFeatures(features);
|
|
51
90
|
const vectorExtent = vectorSource.getExtent();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
91
|
+
|
|
92
|
+
if (!extent.isEmpty(vectorExtent)) {
|
|
93
|
+
let size = extent.getSize(vectorExtent);
|
|
94
|
+
setOptions({
|
|
95
|
+
...options,
|
|
96
|
+
extent: new extent.buffer(vectorExtent, size[0] * 0.1),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
57
99
|
}
|
|
58
100
|
}
|
|
101
|
+
})
|
|
102
|
+
.catch((error) => {
|
|
103
|
+
if (!isMounted) return;
|
|
104
|
+
|
|
105
|
+
dataFetched.current = false;
|
|
106
|
+
|
|
107
|
+
if (vectorSource) vectorSource.clear();
|
|
108
|
+
setOptions((currentOptions) => ({
|
|
109
|
+
...currentOptions,
|
|
110
|
+
extent: undefined,
|
|
111
|
+
}));
|
|
59
112
|
});
|
|
60
|
-
|
|
113
|
+
|
|
114
|
+
return () => {
|
|
115
|
+
isMounted = false;
|
|
116
|
+
};
|
|
61
117
|
/* eslint-disable-next-line */
|
|
62
118
|
}, [vectorSource, code_2000?.[0]]);
|
|
63
119
|
|
|
64
120
|
if (__SERVER__ || !vectorSource) return '';
|
|
121
|
+
|
|
65
122
|
return (
|
|
66
123
|
<div className="species-protected-sites-wrapper">
|
|
67
124
|
<div className="species-protected-sites">
|
|
@@ -111,4 +168,4 @@ const View = (props) => {
|
|
|
111
168
|
);
|
|
112
169
|
};
|
|
113
170
|
|
|
114
|
-
export default View;
|
|
171
|
+
export default withOpenLayers(View);
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import SpeciesProtectedSitesView from './View';
|
|
2
2
|
import getSchema from './schema';
|
|
3
3
|
|
|
4
|
-
export function getSpeciesProtectedSitesURL(code_2000) {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
export function getSpeciesProtectedSitesURL(code_2000, layers) {
|
|
5
|
+
const baseUrl =
|
|
6
|
+
'https://bio.discomap.eea.europa.eu/arcgis/rest/services/ProtectedSites/EUNIS_Website_Dyna_WM/MapServer';
|
|
7
|
+
const queryParams = encodeURI(
|
|
8
|
+
`?f=json&where=SPECIESCODE LIKE '%${code_2000.toUpperCase()}%'&returnGeometry=true&spatialRel=esriSpatialRelIntersects&outFields=SPECIESCODE,SITECODE,HABITATCODE,OBJECTID&outSR=102100`,
|
|
7
9
|
);
|
|
10
|
+
|
|
11
|
+
return layers.reduce((acc, layer) => {
|
|
12
|
+
acc[`layer${layer}`] = `${baseUrl}/${layer}/query${queryParams}`;
|
|
13
|
+
return acc;
|
|
14
|
+
}, {});
|
|
8
15
|
}
|
|
9
16
|
|
|
10
17
|
export default function applyConfig(config) {
|