@eeacms/volto-n2k 1.2.1 → 1.2.3
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 +29 -7
- package/README.md +8 -8
- package/package.json +1 -1
- package/src/components/manage/Blocks/HabitatsBanner/View.jsx +12 -212
- package/src/components/manage/Blocks/HabitatsBanner/index.js +9 -0
- package/src/components/manage/Blocks/HabitatsBanner/variations/Default.jsx +208 -0
- package/src/components/manage/Blocks/SiteHabitatsList/View.jsx +6 -3
- package/src/components/manage/Blocks/TilesImages/index.js +47 -0
- package/src/components/manage/Blocks/TilesImages/variations/DataConnectedImageGallery/ImageGallery.jsx +172 -0
- package/src/components/manage/Blocks/TilesImages/variations/DataConnectedImageGallery/style.less +248 -0
- package/src/components/manage/Blocks/TilesImages/variations/Default/Default.jsx +37 -36
- package/src/helpers.js +8 -0
- /package/src/components/manage/Blocks/HabitatsBanner/{style.less → variations/style.less} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@ 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.2.3](https://github.com/eea/volto-n2k/compare/1.2.2...1.2.3) - 26 March 2026
|
|
8
|
+
|
|
9
|
+
#### :rocket: New Features
|
|
10
|
+
|
|
11
|
+
- feat(tilesImages): add Data connected Images variation [nileshgulia1 - [`1c92f16`](https://github.com/eea/volto-n2k/commit/1c92f167e1960b548ecbae908ab25ec0ce9042bf)]
|
|
12
|
+
- feat(): add red habitat banner listing variation for habitat banner refs#301670 [nileshgulia1 - [`2fa0b3a`](https://github.com/eea/volto-n2k/commit/2fa0b3ac0f585c022eb30e5e0c638903dc6b4135)]
|
|
13
|
+
|
|
14
|
+
#### :bug: Bug Fixes
|
|
15
|
+
|
|
16
|
+
- fix: images rendering [nileshgulia1 - [`d1e22b0`](https://github.com/eea/volto-n2k/commit/d1e22b007f0f42c0913b2f8359bfe672ac253651)]
|
|
17
|
+
- fix: remove unused imports [nileshgulia1 - [`df7de96`](https://github.com/eea/volto-n2k/commit/df7de96eecbf40ad3b095628172b391223393ce2)]
|
|
18
|
+
|
|
19
|
+
#### :house: Internal changes
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
#### :hammer_and_wrench: Others
|
|
23
|
+
|
|
24
|
+
- remove: habitats variation for Habitats Banner [nileshgulia1 - [`d160a38`](https://github.com/eea/volto-n2k/commit/d160a3806d3b68507d15c77054f764a2f3ce1962)]
|
|
25
|
+
- move arrows to left [nileshgulia1 - [`781c07d`](https://github.com/eea/volto-n2k/commit/781c07d384ea0e6060df124bb0412c724d651e40)]
|
|
26
|
+
- eslint . [nileshgulia1 - [`516da36`](https://github.com/eea/volto-n2k/commit/516da36ce3a95ee2f8cc9b3e630ddc2875034745)]
|
|
27
|
+
### [1.2.2](https://github.com/eea/volto-n2k/compare/1.2.1...1.2.2) - 23 February 2026
|
|
28
|
+
|
|
29
|
+
#### :house: Internal changes
|
|
30
|
+
|
|
31
|
+
- style: Automated code fix [eea-jenkins - [`dd7eb96`](https://github.com/eea/volto-n2k/commit/dd7eb969dbf212e8cc0e49d76dff0cedfcc26e53)]
|
|
32
|
+
|
|
33
|
+
#### :hammer_and_wrench: Others
|
|
34
|
+
|
|
35
|
+
- #286491 - refactor: move priority labels to shared helpers [Claudia Ifrim - [`4bee837`](https://github.com/eea/volto-n2k/commit/4bee8379fff1fd0b2984b2acb66c8272e7a6f1ff)]
|
|
7
36
|
### [1.2.1](https://github.com/eea/volto-n2k/compare/1.2.0...1.2.1) - 3 February 2026
|
|
8
37
|
|
|
9
38
|
#### :bug: Bug Fixes
|
|
@@ -157,7 +186,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
157
186
|
|
|
158
187
|
#### :house: Internal changes
|
|
159
188
|
|
|
160
|
-
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`e4f9fc8`](https://github.com/eea/volto-n2k/commit/e4f9fc800b753b97cca7c685bc47dd48804276f0)]
|
|
161
189
|
- chore: husky, lint-staged use fixed versions [valentinab25 - [`647d621`](https://github.com/eea/volto-n2k/commit/647d621d52400c50f5bc629b3ddc4f2121f14ffa)]
|
|
162
190
|
- chore:volto 16 in tests, update docs, fix stylelint overrides [valentinab25 - [`60d94b6`](https://github.com/eea/volto-n2k/commit/60d94b61ff8826abc57af9616793a1a247f585b5)]
|
|
163
191
|
|
|
@@ -172,11 +200,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
172
200
|
- try to use volto-spotlight theme in jenkins [Miu Razvan - [`ec0b952`](https://github.com/eea/volto-n2k/commit/ec0b9525b967f907922ae660bd9f520119cd80c1)]
|
|
173
201
|
- remove waitForResourceToLoad [ana-oprea - [`eaded9b`](https://github.com/eea/volto-n2k/commit/eaded9b9ecd1ca2eb78aa8dd65838c063d95db85)]
|
|
174
202
|
- update image size from 300 to 800 px [Claudia Ifrim - [`8d9270a`](https://github.com/eea/volto-n2k/commit/8d9270a09506278ceaea25e8a72abdf5b22fcc78)]
|
|
175
|
-
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`350f8a6`](https://github.com/eea/volto-n2k/commit/350f8a6928aafbf168472b572f8041a79f71f577)]
|
|
176
|
-
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`99b3a84`](https://github.com/eea/volto-n2k/commit/99b3a84a266710fadf7d430117359b741cadede8)]
|
|
177
|
-
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`050ac98`](https://github.com/eea/volto-n2k/commit/050ac982ec39e9a1b4885b665cdc118fca7b1283)]
|
|
178
|
-
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`3546040`](https://github.com/eea/volto-n2k/commit/35460409817f496fc752ab34e37d6d33a069b2e9)]
|
|
179
|
-
- test: [JENKINS] Improve cypress time [valentinab25 - [`06a4ab1`](https://github.com/eea/volto-n2k/commit/06a4ab151799b8cdf4a316dbcb0c323e0f568e30)]
|
|
180
203
|
- test: EN locales, pre-commit fix, feature PRs checks Refs #257193 [valentinab25 - [`4850d6a`](https://github.com/eea/volto-n2k/commit/4850d6a65349fe49dbe9244c30592ae38c9aeaba)]
|
|
181
204
|
- test: Update Makefile and docker-compose to align it with Jenkinsfile [valentinab25 - [`2c91856`](https://github.com/eea/volto-n2k/commit/2c9185688a2fe6b36e5eeb2963f6c8676e3c5628)]
|
|
182
205
|
### [1.0.33](https://github.com/eea/volto-n2k/compare/1.0.32...1.0.33) - 3 July 2023
|
|
@@ -433,7 +456,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
433
456
|
- Update [razvanMiu - [`42ab50e`](https://github.com/eea/volto-n2k/commit/42ab50e6681a47251d15ac06b836c6f8c27157fa)]
|
|
434
457
|
- Added bubble chart [razvanMiu - [`89fba5e`](https://github.com/eea/volto-n2k/commit/89fba5e5db41aa955ba2d0ed58c9f0042c461504)]
|
|
435
458
|
- Group species by id_eunis in species list [razvanMiu - [`543c957`](https://github.com/eea/volto-n2k/commit/543c9573b53acd8eecc9afbb6ae7beeddba53966)]
|
|
436
|
-
- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`2ca3e4c`](https://github.com/eea/volto-n2k/commit/2ca3e4c092211f92339791d71db81f5b4ca2d562)]
|
|
437
459
|
- update maps - species and habitats distribution maps [Claudia Ifrim - [`ad12eb1`](https://github.com/eea/volto-n2k/commit/ad12eb141907d6f28444f1eafc3f687735d2a68d)]
|
|
438
460
|
- update format for common name and author [Claudia Ifrim - [`26b7a2f`](https://github.com/eea/volto-n2k/commit/26b7a2f3d20c7701b57fb24f39fc7dfeceec3ce8)]
|
|
439
461
|
- update format for species name (common / scientific) [Claudia Ifrim - [`abdedcf`](https://github.com/eea/volto-n2k/commit/abdedcfe645665031dedf050fd2c5cdde8c14a50)]
|
package/README.md
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
[](https://github.com/eea/volto-n2k/releases)
|
|
4
4
|
|
|
5
5
|
[](https://ci.eionet.europa.eu/view/Github/job/volto-addons/job/volto-n2k/job/master/display/redirect)
|
|
6
|
-
[](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-n2k
|
|
6
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k)
|
|
7
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k)
|
|
8
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k)
|
|
9
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k)
|
|
10
10
|
|
|
11
11
|
[](https://ci.eionet.europa.eu/view/Github/job/volto-addons/job/volto-n2k/job/develop/display/redirect)
|
|
12
|
-
[](https://sonarqube.eea.europa.eu/api/project_badges/measure?project=volto-n2k
|
|
12
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k&branch=develop)
|
|
13
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k&branch=develop)
|
|
14
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k&branch=develop)
|
|
15
|
+
[](https://sonarqube.eea.europa.eu/dashboard?id=volto-n2k&branch=develop)
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
[Volto](https://github.com/plone/volto) add-on
|
package/package.json
CHANGED
|
@@ -1,216 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import arrowLeft from '@eeacms/volto-n2k/icons/arrow-left.svg';
|
|
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';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { withBlockExtensions } from '@plone/volto/helpers/Extensions';
|
|
3
|
+
import config from '@plone/volto/registry';
|
|
12
4
|
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
function View(props) {
|
|
6
|
+
const { mode = 'view', variation } = props;
|
|
15
7
|
|
|
16
|
-
const
|
|
17
|
-
|
|
8
|
+
const variations =
|
|
9
|
+
config.blocks?.blocksConfig['habitats_banner']?.variations || [];
|
|
10
|
+
const defaultVariation = variations.filter((item) => item.isDefault)?.[0];
|
|
11
|
+
const Template = variation?.template ?? defaultVariation?.template ?? null;
|
|
18
12
|
|
|
19
|
-
|
|
20
|
-
let parsedSource = replaceQueryParam(source, 'x', 800);
|
|
21
|
-
parsedSource = replaceQueryParam(parsedSource, 'y', 800);
|
|
22
|
-
|
|
23
|
-
return parsedSource;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const ViewComponent = (props) => {
|
|
27
|
-
const swiperEl = useRef();
|
|
28
|
-
const previewEl = useRef();
|
|
29
|
-
const [activeSlide, setActiveSlide] = useState(0);
|
|
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],
|
|
43
|
-
);
|
|
44
|
-
const habitat_pictures = useMemo(
|
|
45
|
-
() => props.providers_data?.[habitat_pictures_provider] || {},
|
|
46
|
-
[props.providers_data, habitat_pictures_provider],
|
|
47
|
-
);
|
|
48
|
-
|
|
49
|
-
const {
|
|
50
|
-
code_2000 = [],
|
|
51
|
-
scientific_name = [],
|
|
52
|
-
habitat_prioriy = [],
|
|
53
|
-
} = habitat;
|
|
54
|
-
const { attribution_copyright = [] } = habitat_pictures;
|
|
55
|
-
|
|
56
|
-
const priorityLabel = useMemo(() => {
|
|
57
|
-
const priority = habitat_prioriy[0];
|
|
58
|
-
|
|
59
|
-
if (priority === 0) {
|
|
60
|
-
return 'Conditional priority';
|
|
61
|
-
}
|
|
62
|
-
if (priority === null) {
|
|
63
|
-
return '';
|
|
64
|
-
}
|
|
65
|
-
if (priority === 1) {
|
|
66
|
-
return 'Priority habitat';
|
|
67
|
-
}
|
|
68
|
-
}, [habitat_prioriy]);
|
|
69
|
-
|
|
70
|
-
const pictures = useMemo(
|
|
71
|
-
() => habitat_pictures?.['WebURL'] || [],
|
|
72
|
-
[habitat_pictures],
|
|
73
|
-
);
|
|
74
|
-
const pictures_length = useMemo(
|
|
75
|
-
() => pictures.filter((picture) => !!picture)?.length,
|
|
76
|
-
[pictures],
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
const handleSliderPrevious = useCallback(() => {
|
|
80
|
-
swiperEl.current.slidePrev();
|
|
81
|
-
if (previewEl.current?.[0]) {
|
|
82
|
-
previewEl.current[0].slidePrev();
|
|
83
|
-
}
|
|
84
|
-
if (previewEl.current?.[1]) {
|
|
85
|
-
previewEl.current[1].slidePrev();
|
|
86
|
-
}
|
|
87
|
-
setActiveSlide(swiperEl.current.realIndex);
|
|
88
|
-
}, []);
|
|
89
|
-
|
|
90
|
-
const handleSliderNext = useCallback(() => {
|
|
91
|
-
swiperEl.current.slideNext();
|
|
92
|
-
if (previewEl.current?.[0]) {
|
|
93
|
-
previewEl.current[0].slideNext();
|
|
94
|
-
}
|
|
95
|
-
if (previewEl.current?.[1]) {
|
|
96
|
-
previewEl.current[1].slideNext();
|
|
97
|
-
}
|
|
98
|
-
setActiveSlide(swiperEl.current.realIndex);
|
|
99
|
-
}, []);
|
|
100
|
-
|
|
101
|
-
if (!habitat_provider && props.mode === 'edit') {
|
|
102
|
-
return 'Habitat banner block, habitat provider undefined';
|
|
103
|
-
}
|
|
104
|
-
if (!habitat_pictures_provider && props.mode === 'edit') {
|
|
105
|
-
return 'Habitat banner block, habitat pictures provider undefined';
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
return (
|
|
109
|
-
<div className="habitat-banner-details">
|
|
110
|
-
<div className="habitat-details">
|
|
111
|
-
<div className="habitat-metadata">
|
|
112
|
-
<h2 className="name">{scientific_name[0]}</h2>
|
|
113
|
-
<p className="info">
|
|
114
|
-
Habitats Directive Annex I code {code_2000[0]}
|
|
115
|
-
</p>
|
|
116
|
-
<p className="info" style={{ marginTop: '1rem' }}>
|
|
117
|
-
{priorityLabel}
|
|
118
|
-
</p>
|
|
119
|
-
</div>
|
|
120
|
-
{pictures_length > 0 && (
|
|
121
|
-
<div className={cx('carousel one-slide')}>
|
|
122
|
-
<div
|
|
123
|
-
className={cx('arrows', { 'arrows-hidden': pictures_length < 2 })}
|
|
124
|
-
>
|
|
125
|
-
{pictures_length > 1 && (
|
|
126
|
-
<>
|
|
127
|
-
<button
|
|
128
|
-
className="swiper-button image-swiper-button-prev"
|
|
129
|
-
onClick={handleSliderPrevious}
|
|
130
|
-
>
|
|
131
|
-
<Icon
|
|
132
|
-
className="icon-left"
|
|
133
|
-
color="#000"
|
|
134
|
-
name={arrowLeft}
|
|
135
|
-
size="32px"
|
|
136
|
-
/>
|
|
137
|
-
</button>
|
|
138
|
-
<button
|
|
139
|
-
className="swiper-button image-swiper-button-next"
|
|
140
|
-
onClick={handleSliderNext}
|
|
141
|
-
>
|
|
142
|
-
<Icon
|
|
143
|
-
className="icon-right"
|
|
144
|
-
color="#000"
|
|
145
|
-
name={arrowRight}
|
|
146
|
-
size="32px"
|
|
147
|
-
/>
|
|
148
|
-
</button>
|
|
149
|
-
</>
|
|
150
|
-
)}
|
|
151
|
-
{!!attribution_copyright[activeSlide] && (
|
|
152
|
-
<p title={attribution_copyright[activeSlide]}>
|
|
153
|
-
{attribution_copyright[activeSlide]}
|
|
154
|
-
</p>
|
|
155
|
-
)}
|
|
156
|
-
</div>
|
|
157
|
-
{__CLIENT__ && (
|
|
158
|
-
<SwiperLoader>
|
|
159
|
-
{() => {
|
|
160
|
-
return (
|
|
161
|
-
<SwiperReactLoader>
|
|
162
|
-
{({ Swiper, SwiperSlide }) => {
|
|
163
|
-
return (
|
|
164
|
-
<>
|
|
165
|
-
<Swiper
|
|
166
|
-
loop={true}
|
|
167
|
-
allowTouchMove={false}
|
|
168
|
-
initialSlide={0}
|
|
169
|
-
slidesPerView={1}
|
|
170
|
-
spaceBetween={0}
|
|
171
|
-
onBeforeInit={(swiper) => {
|
|
172
|
-
swiperEl.current = swiper;
|
|
173
|
-
}}
|
|
174
|
-
>
|
|
175
|
-
{pictures.map((source, index) => (
|
|
176
|
-
<SwiperSlide key={source}>
|
|
177
|
-
<img
|
|
178
|
-
src={getSource(source)}
|
|
179
|
-
alt={pictures[index]}
|
|
180
|
-
/>
|
|
181
|
-
</SwiperSlide>
|
|
182
|
-
))}
|
|
183
|
-
</Swiper>
|
|
184
|
-
</>
|
|
185
|
-
);
|
|
186
|
-
}}
|
|
187
|
-
</SwiperReactLoader>
|
|
188
|
-
);
|
|
189
|
-
}}
|
|
190
|
-
</SwiperLoader>
|
|
191
|
-
)}
|
|
192
|
-
</div>
|
|
193
|
-
)}
|
|
194
|
-
</div>
|
|
195
|
-
</div>
|
|
196
|
-
);
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const ViewCompose = compose(
|
|
200
|
-
connectToMultipleProviders((props) => ({
|
|
201
|
-
providers: [
|
|
202
|
-
{
|
|
203
|
-
provider_url: props.data?.habitat_provider,
|
|
204
|
-
},
|
|
205
|
-
{ provider_url: props.data?.habitat_pictures_provider },
|
|
206
|
-
],
|
|
207
|
-
})),
|
|
208
|
-
)(ViewComponent);
|
|
209
|
-
|
|
210
|
-
export default function View(props) {
|
|
211
|
-
return (
|
|
212
|
-
<VisibilitySensor Placeholder={() => <div>loading.... </div>}>
|
|
213
|
-
<ViewCompose {...props} />
|
|
214
|
-
</VisibilitySensor>
|
|
215
|
-
);
|
|
13
|
+
return <Template {...props} mode={mode} />;
|
|
216
14
|
}
|
|
15
|
+
|
|
16
|
+
export default withBlockExtensions(View);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import worldSVG from '@plone/volto/icons/world.svg';
|
|
2
2
|
import Edit from './Edit';
|
|
3
3
|
import View from './View';
|
|
4
|
+
import DefaultVariation from './variations/Default';
|
|
4
5
|
|
|
5
6
|
export default function applyConfig(config) {
|
|
6
7
|
config.blocks.blocksConfig.habitats_banner = {
|
|
@@ -19,6 +20,14 @@ export default function applyConfig(config) {
|
|
|
19
20
|
view: [],
|
|
20
21
|
},
|
|
21
22
|
blockHasOwnFocusManagement: false,
|
|
23
|
+
variations: [
|
|
24
|
+
{
|
|
25
|
+
id: 'default',
|
|
26
|
+
title: 'Default',
|
|
27
|
+
isDefault: true,
|
|
28
|
+
template: DefaultVariation,
|
|
29
|
+
},
|
|
30
|
+
],
|
|
22
31
|
};
|
|
23
32
|
return config;
|
|
24
33
|
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { VisibilitySensor } from '@eeacms/volto-datablocks/components';
|
|
2
|
+
import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
|
|
3
|
+
import { replaceQueryParam, priorityLabels } from '@eeacms/volto-n2k/helpers';
|
|
4
|
+
import arrowLeft from '@eeacms/volto-n2k/icons/arrow-left.svg';
|
|
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
|
+
|
|
13
|
+
import 'swiper/css';
|
|
14
|
+
import './style.less';
|
|
15
|
+
|
|
16
|
+
const SwiperLoader = loadable.lib(() => import('swiper'));
|
|
17
|
+
const SwiperReactLoader = loadable.lib(() => import('swiper/react'));
|
|
18
|
+
|
|
19
|
+
const getSource = (source) => {
|
|
20
|
+
let parsedSource = replaceQueryParam(source, 'x', 800);
|
|
21
|
+
parsedSource = replaceQueryParam(parsedSource, 'y', 800);
|
|
22
|
+
|
|
23
|
+
return parsedSource;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const Default = (props) => {
|
|
27
|
+
const swiperEl = useRef();
|
|
28
|
+
const previewEl = useRef();
|
|
29
|
+
const [activeSlide, setActiveSlide] = useState(0);
|
|
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],
|
|
43
|
+
);
|
|
44
|
+
const habitat_pictures = useMemo(
|
|
45
|
+
() => props.providers_data?.[habitat_pictures_provider] || {},
|
|
46
|
+
[props.providers_data, habitat_pictures_provider],
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const {
|
|
50
|
+
code_2000 = [],
|
|
51
|
+
scientific_name = [],
|
|
52
|
+
habitat_prioriy = [],
|
|
53
|
+
} = habitat;
|
|
54
|
+
const { attribution_copyright = [] } = habitat_pictures;
|
|
55
|
+
|
|
56
|
+
const priorityLabel = useMemo(() => {
|
|
57
|
+
const priority = habitat_prioriy[0];
|
|
58
|
+
|
|
59
|
+
return priorityLabels.habitat_prioriy[priority] ?? '';
|
|
60
|
+
}, [habitat_prioriy]);
|
|
61
|
+
|
|
62
|
+
const pictures = useMemo(
|
|
63
|
+
() => habitat_pictures?.['WebURL'] || [],
|
|
64
|
+
[habitat_pictures],
|
|
65
|
+
);
|
|
66
|
+
const pictures_length = useMemo(
|
|
67
|
+
() => pictures.filter((picture) => !!picture)?.length,
|
|
68
|
+
[pictures],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const handleSliderPrevious = useCallback(() => {
|
|
72
|
+
swiperEl.current.slidePrev();
|
|
73
|
+
if (previewEl.current?.[0]) {
|
|
74
|
+
previewEl.current[0].slidePrev();
|
|
75
|
+
}
|
|
76
|
+
if (previewEl.current?.[1]) {
|
|
77
|
+
previewEl.current[1].slidePrev();
|
|
78
|
+
}
|
|
79
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
const handleSliderNext = useCallback(() => {
|
|
83
|
+
swiperEl.current.slideNext();
|
|
84
|
+
if (previewEl.current?.[0]) {
|
|
85
|
+
previewEl.current[0].slideNext();
|
|
86
|
+
}
|
|
87
|
+
if (previewEl.current?.[1]) {
|
|
88
|
+
previewEl.current[1].slideNext();
|
|
89
|
+
}
|
|
90
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
91
|
+
}, []);
|
|
92
|
+
|
|
93
|
+
if (!habitat_provider && props.mode === 'edit') {
|
|
94
|
+
return 'Habitat banner block, habitat provider undefined';
|
|
95
|
+
}
|
|
96
|
+
if (!habitat_pictures_provider && props.mode === 'edit') {
|
|
97
|
+
return 'Habitat banner block, habitat pictures provider undefined';
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return (
|
|
101
|
+
<div className="habitat-banner-details">
|
|
102
|
+
<div className="habitat-details">
|
|
103
|
+
<div className="habitat-metadata">
|
|
104
|
+
<h2 className="name">{scientific_name[0]}</h2>
|
|
105
|
+
<p className="info">
|
|
106
|
+
Habitats Directive Annex I code {code_2000[0]}
|
|
107
|
+
</p>
|
|
108
|
+
<p className="info" style={{ marginTop: '1rem' }}>
|
|
109
|
+
{priorityLabel}
|
|
110
|
+
</p>
|
|
111
|
+
</div>
|
|
112
|
+
{pictures_length > 0 && (
|
|
113
|
+
<div className={cx('carousel one-slide')}>
|
|
114
|
+
<div
|
|
115
|
+
className={cx('arrows', { 'arrows-hidden': pictures_length < 2 })}
|
|
116
|
+
>
|
|
117
|
+
{pictures_length > 1 && (
|
|
118
|
+
<>
|
|
119
|
+
<button
|
|
120
|
+
className="swiper-button image-swiper-button-prev"
|
|
121
|
+
onClick={handleSliderPrevious}
|
|
122
|
+
>
|
|
123
|
+
<Icon
|
|
124
|
+
className="icon-left"
|
|
125
|
+
color="#000"
|
|
126
|
+
name={arrowLeft}
|
|
127
|
+
size="32px"
|
|
128
|
+
/>
|
|
129
|
+
</button>
|
|
130
|
+
<button
|
|
131
|
+
className="swiper-button image-swiper-button-next"
|
|
132
|
+
onClick={handleSliderNext}
|
|
133
|
+
>
|
|
134
|
+
<Icon
|
|
135
|
+
className="icon-right"
|
|
136
|
+
color="#000"
|
|
137
|
+
name={arrowRight}
|
|
138
|
+
size="32px"
|
|
139
|
+
/>
|
|
140
|
+
</button>
|
|
141
|
+
</>
|
|
142
|
+
)}
|
|
143
|
+
{!!attribution_copyright[activeSlide] && (
|
|
144
|
+
<p title={attribution_copyright[activeSlide]}>
|
|
145
|
+
{attribution_copyright[activeSlide]}
|
|
146
|
+
</p>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
{__CLIENT__ && (
|
|
150
|
+
<SwiperLoader>
|
|
151
|
+
{() => {
|
|
152
|
+
return (
|
|
153
|
+
<SwiperReactLoader>
|
|
154
|
+
{({ Swiper, SwiperSlide }) => {
|
|
155
|
+
return (
|
|
156
|
+
<>
|
|
157
|
+
<Swiper
|
|
158
|
+
loop={true}
|
|
159
|
+
allowTouchMove={false}
|
|
160
|
+
initialSlide={0}
|
|
161
|
+
slidesPerView={1}
|
|
162
|
+
spaceBetween={0}
|
|
163
|
+
onBeforeInit={(swiper) => {
|
|
164
|
+
swiperEl.current = swiper;
|
|
165
|
+
}}
|
|
166
|
+
>
|
|
167
|
+
{pictures.map((source, index) => (
|
|
168
|
+
<SwiperSlide key={source}>
|
|
169
|
+
<img
|
|
170
|
+
src={getSource(source)}
|
|
171
|
+
alt={pictures[index]}
|
|
172
|
+
/>
|
|
173
|
+
</SwiperSlide>
|
|
174
|
+
))}
|
|
175
|
+
</Swiper>
|
|
176
|
+
</>
|
|
177
|
+
);
|
|
178
|
+
}}
|
|
179
|
+
</SwiperReactLoader>
|
|
180
|
+
);
|
|
181
|
+
}}
|
|
182
|
+
</SwiperLoader>
|
|
183
|
+
)}
|
|
184
|
+
</div>
|
|
185
|
+
)}
|
|
186
|
+
</div>
|
|
187
|
+
</div>
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const ViewCompose = compose(
|
|
192
|
+
connectToMultipleProviders((props) => ({
|
|
193
|
+
providers: [
|
|
194
|
+
{
|
|
195
|
+
provider_url: props.data?.habitat_provider,
|
|
196
|
+
},
|
|
197
|
+
{ provider_url: props.data?.habitat_pictures_provider },
|
|
198
|
+
],
|
|
199
|
+
})),
|
|
200
|
+
)(Default);
|
|
201
|
+
|
|
202
|
+
export default function View(props) {
|
|
203
|
+
return (
|
|
204
|
+
<VisibilitySensor Placeholder={() => <div>loading.... </div>}>
|
|
205
|
+
<ViewCompose {...props} />
|
|
206
|
+
</VisibilitySensor>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Link } from 'react-router-dom';
|
|
3
3
|
import { Container, Pagination, Grid } from 'semantic-ui-react';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
getObjectByIndex,
|
|
6
|
+
photoPlaceholders,
|
|
7
|
+
priorityLabels,
|
|
8
|
+
} from '@eeacms/volto-n2k/helpers';
|
|
5
9
|
import { Filters } from './Filters';
|
|
6
10
|
|
|
7
11
|
import './style.less';
|
|
8
|
-
import { filtersLabels } from './utils';
|
|
9
12
|
|
|
10
13
|
const getCurrentPageLength = (pagination, arr) => {
|
|
11
14
|
const totalPages = Math.ceil(pagination.totalItems / pagination.itemsPerPage);
|
|
@@ -17,7 +20,7 @@ const getCurrentPageLength = (pagination, arr) => {
|
|
|
17
20
|
};
|
|
18
21
|
|
|
19
22
|
function getPriorityString(priority) {
|
|
20
|
-
return
|
|
23
|
+
return priorityLabels.habitat_prioriy[priority] || '';
|
|
21
24
|
}
|
|
22
25
|
|
|
23
26
|
const View = (props) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import TilesImagesEdit from './Edit';
|
|
2
2
|
import ImageGallery from './variations/ImageGallery/ImageGallery';
|
|
3
|
+
import DataConnectedImageGallery from './variations/DataConnectedImageGallery/ImageGallery';
|
|
3
4
|
import DefaultView from './variations/Default/Default';
|
|
4
5
|
import TilesImagesView from './View';
|
|
5
6
|
import worldSVG from '@plone/volto/icons/world.svg';
|
|
@@ -33,7 +34,53 @@ export default function applyConfig(config) {
|
|
|
33
34
|
title: 'ImageGallery',
|
|
34
35
|
template: ImageGallery,
|
|
35
36
|
},
|
|
37
|
+
{
|
|
38
|
+
id: 'dataConnectedImageGallery',
|
|
39
|
+
isDefault: false,
|
|
40
|
+
title: 'Data Connected ImageGallery',
|
|
41
|
+
template: DataConnectedImageGallery,
|
|
42
|
+
schemaEnhancer: ({ schema, intl, formData }) => {
|
|
43
|
+
schema.fieldsets = schema.fieldsets.map((fieldset) =>
|
|
44
|
+
fieldset.id === 'default'
|
|
45
|
+
? {
|
|
46
|
+
...fieldset,
|
|
47
|
+
fields: fieldset.fields.filter((field) => field !== 'theme'),
|
|
48
|
+
}
|
|
49
|
+
: fieldset,
|
|
50
|
+
);
|
|
51
|
+
schema.fieldsets.push({
|
|
52
|
+
id: 'data_query',
|
|
53
|
+
title: 'Data query',
|
|
54
|
+
fields: [
|
|
55
|
+
'has_data_query_by_context',
|
|
56
|
+
'has_data_query_by_provider',
|
|
57
|
+
'data_query',
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
schema.properties.images.widget = 'url';
|
|
61
|
+
schema.properties.has_data_query_by_context = {
|
|
62
|
+
title: 'Has data_query by context',
|
|
63
|
+
type: 'boolean',
|
|
64
|
+
description:
|
|
65
|
+
'This flag will denote whether or not the connector will be filtered by data_query applied on the page',
|
|
66
|
+
defaultValue: true,
|
|
67
|
+
};
|
|
68
|
+
schema.properties.has_data_query_by_provider = {
|
|
69
|
+
title: 'Has data_query by provider',
|
|
70
|
+
type: 'boolean',
|
|
71
|
+
description:
|
|
72
|
+
'This flag will denote whether or not the connector will be filtered by data_query applied on the connector itself',
|
|
73
|
+
defaultValue: true,
|
|
74
|
+
};
|
|
75
|
+
schema.properties.data_query = {
|
|
76
|
+
title: 'Data query',
|
|
77
|
+
widget: 'data_query',
|
|
78
|
+
};
|
|
79
|
+
return schema;
|
|
80
|
+
},
|
|
81
|
+
},
|
|
36
82
|
],
|
|
37
83
|
};
|
|
84
|
+
|
|
38
85
|
return config;
|
|
39
86
|
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { VisibilitySensor } from '@eeacms/volto-datablocks/components';
|
|
2
|
+
import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
|
|
3
|
+
import { replaceQueryParam } from '@eeacms/volto-n2k/helpers';
|
|
4
|
+
import arrowLeft from '@eeacms/volto-n2k/icons/arrow-left.svg';
|
|
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
|
+
|
|
13
|
+
import 'swiper/css';
|
|
14
|
+
import './style.less';
|
|
15
|
+
|
|
16
|
+
const SwiperLoader = loadable.lib(() => import('swiper'));
|
|
17
|
+
const SwiperReactLoader = loadable.lib(() => import('swiper/react'));
|
|
18
|
+
|
|
19
|
+
const getSource = (source) => {
|
|
20
|
+
let parsedSource = replaceQueryParam(source, 'x', 800);
|
|
21
|
+
parsedSource = replaceQueryParam(parsedSource, 'y', 800);
|
|
22
|
+
|
|
23
|
+
return parsedSource;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const RedHabitats = (props) => {
|
|
27
|
+
const swiperEl = useRef();
|
|
28
|
+
const previewEl = useRef();
|
|
29
|
+
const [activeSlide, setActiveSlide] = useState(0);
|
|
30
|
+
|
|
31
|
+
const habitat_pictures_provider = useMemo(
|
|
32
|
+
() => flattenToAppURL(props.data.images),
|
|
33
|
+
[props.data.images],
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const habitat_pictures = useMemo(
|
|
37
|
+
() => props.providers_data?.[habitat_pictures_provider] || {},
|
|
38
|
+
[props.providers_data, habitat_pictures_provider],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const { attribution_copyright = [] } = habitat_pictures;
|
|
42
|
+
|
|
43
|
+
const pictures = useMemo(
|
|
44
|
+
() => habitat_pictures?.['WebURL'] || [],
|
|
45
|
+
[habitat_pictures],
|
|
46
|
+
);
|
|
47
|
+
const pictures_length = useMemo(
|
|
48
|
+
() => pictures.filter((picture) => !!picture)?.length,
|
|
49
|
+
[pictures],
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const handleSliderPrevious = useCallback(() => {
|
|
53
|
+
swiperEl.current.slidePrev();
|
|
54
|
+
if (previewEl.current?.[0]) {
|
|
55
|
+
previewEl.current[0].slidePrev();
|
|
56
|
+
}
|
|
57
|
+
if (previewEl.current?.[1]) {
|
|
58
|
+
previewEl.current[1].slidePrev();
|
|
59
|
+
}
|
|
60
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
61
|
+
}, []);
|
|
62
|
+
|
|
63
|
+
const handleSliderNext = useCallback(() => {
|
|
64
|
+
swiperEl.current.slideNext();
|
|
65
|
+
if (previewEl.current?.[0]) {
|
|
66
|
+
previewEl.current[0].slideNext();
|
|
67
|
+
}
|
|
68
|
+
if (previewEl.current?.[1]) {
|
|
69
|
+
previewEl.current[1].slideNext();
|
|
70
|
+
}
|
|
71
|
+
setActiveSlide(swiperEl.current.realIndex);
|
|
72
|
+
}, []);
|
|
73
|
+
|
|
74
|
+
if (!habitat_pictures_provider && props.mode === 'edit') {
|
|
75
|
+
return ' habitat pictures provider undefined';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<div className="habitat-banner-details">
|
|
80
|
+
<div className="habitat-details">
|
|
81
|
+
{pictures_length > 0 && (
|
|
82
|
+
<div className={cx('carousel one-slide')}>
|
|
83
|
+
<div
|
|
84
|
+
className={cx('arrows', { 'arrows-hidden': pictures_length < 2 })}
|
|
85
|
+
>
|
|
86
|
+
{pictures_length > 1 && (
|
|
87
|
+
<>
|
|
88
|
+
<button
|
|
89
|
+
className="swiper-button image-swiper-button-prev"
|
|
90
|
+
onClick={handleSliderPrevious}
|
|
91
|
+
>
|
|
92
|
+
<Icon
|
|
93
|
+
className="icon-left"
|
|
94
|
+
color="#000"
|
|
95
|
+
name={arrowLeft}
|
|
96
|
+
size="32px"
|
|
97
|
+
/>
|
|
98
|
+
</button>
|
|
99
|
+
<button
|
|
100
|
+
className="swiper-button image-swiper-button-next"
|
|
101
|
+
onClick={handleSliderNext}
|
|
102
|
+
>
|
|
103
|
+
<Icon
|
|
104
|
+
className="icon-right"
|
|
105
|
+
color="#000"
|
|
106
|
+
name={arrowRight}
|
|
107
|
+
size="32px"
|
|
108
|
+
/>
|
|
109
|
+
</button>
|
|
110
|
+
</>
|
|
111
|
+
)}
|
|
112
|
+
{!!attribution_copyright[activeSlide] && (
|
|
113
|
+
<p title={attribution_copyright[activeSlide]}>
|
|
114
|
+
{attribution_copyright[activeSlide]}
|
|
115
|
+
</p>
|
|
116
|
+
)}
|
|
117
|
+
</div>
|
|
118
|
+
{__CLIENT__ && (
|
|
119
|
+
<SwiperLoader>
|
|
120
|
+
{() => {
|
|
121
|
+
return (
|
|
122
|
+
<SwiperReactLoader>
|
|
123
|
+
{({ Swiper, SwiperSlide }) => {
|
|
124
|
+
return (
|
|
125
|
+
<>
|
|
126
|
+
<Swiper
|
|
127
|
+
loop={true}
|
|
128
|
+
allowTouchMove={false}
|
|
129
|
+
initialSlide={0}
|
|
130
|
+
slidesPerView={1}
|
|
131
|
+
spaceBetween={0}
|
|
132
|
+
onBeforeInit={(swiper) => {
|
|
133
|
+
swiperEl.current = swiper;
|
|
134
|
+
}}
|
|
135
|
+
>
|
|
136
|
+
{pictures.map((source, index) => (
|
|
137
|
+
<SwiperSlide key={source}>
|
|
138
|
+
<img
|
|
139
|
+
src={getSource(source)}
|
|
140
|
+
alt={pictures[index]}
|
|
141
|
+
/>
|
|
142
|
+
</SwiperSlide>
|
|
143
|
+
))}
|
|
144
|
+
</Swiper>
|
|
145
|
+
</>
|
|
146
|
+
);
|
|
147
|
+
}}
|
|
148
|
+
</SwiperReactLoader>
|
|
149
|
+
);
|
|
150
|
+
}}
|
|
151
|
+
</SwiperLoader>
|
|
152
|
+
)}
|
|
153
|
+
</div>
|
|
154
|
+
)}
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const ViewCompose = compose(
|
|
161
|
+
connectToMultipleProviders((props) => ({
|
|
162
|
+
providers: [{ provider_url: props.data?.images }],
|
|
163
|
+
})),
|
|
164
|
+
)(RedHabitats);
|
|
165
|
+
|
|
166
|
+
export default function View(props) {
|
|
167
|
+
return (
|
|
168
|
+
<VisibilitySensor Placeholder={() => <div>loading.... </div>}>
|
|
169
|
+
<ViewCompose {...props} />
|
|
170
|
+
</VisibilitySensor>
|
|
171
|
+
);
|
|
172
|
+
}
|
package/src/components/manage/Blocks/TilesImages/variations/DataConnectedImageGallery/style.less
ADDED
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
@type: extra;
|
|
2
|
+
@element: custom;
|
|
3
|
+
|
|
4
|
+
@import (multiple, reference, optional) '../../theme.config';
|
|
5
|
+
|
|
6
|
+
@{view} {
|
|
7
|
+
.habitat-banner-details {
|
|
8
|
+
&::before {
|
|
9
|
+
.full-width();
|
|
10
|
+
position: absolute;
|
|
11
|
+
z-index: -1;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.carousel {
|
|
15
|
+
.half-width(960px);
|
|
16
|
+
|
|
17
|
+
@media @mobile {
|
|
18
|
+
width: calc(@pageFullWidth - 2rem) !important;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@{edit} {
|
|
25
|
+
.habitat-banner-details {
|
|
26
|
+
&::before {
|
|
27
|
+
.full-width-edit();
|
|
28
|
+
position: absolute;
|
|
29
|
+
z-index: -1;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.carousel {
|
|
33
|
+
.half-width-edit(960px);
|
|
34
|
+
|
|
35
|
+
@media @mobile {
|
|
36
|
+
width: calc(@pageFullWidthEdit - 2rem) !important;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
div#view .habitat-banner-details .ui.container > * {
|
|
43
|
+
margin-top: 0;
|
|
44
|
+
margin-bottom: 0;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.habitat-banner-details {
|
|
48
|
+
position: relative;
|
|
49
|
+
padding: 0;
|
|
50
|
+
margin-bottom: 1rem;
|
|
51
|
+
color: #fff !important;
|
|
52
|
+
font-family: 'RajdhaniB', 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
|
53
|
+
|
|
54
|
+
&::before {
|
|
55
|
+
display: block;
|
|
56
|
+
height: 100%;
|
|
57
|
+
background-color: transparent;
|
|
58
|
+
content: '';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
.habitat-details {
|
|
62
|
+
display: flex;
|
|
63
|
+
align-items: center;
|
|
64
|
+
justify-content: space-between;
|
|
65
|
+
|
|
66
|
+
.habitat-metadata {
|
|
67
|
+
display: flex;
|
|
68
|
+
width: 50%;
|
|
69
|
+
height: 320px !important;
|
|
70
|
+
flex: 0 0 50%;
|
|
71
|
+
flex-direction: column;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
word-wrap: break-word;
|
|
74
|
+
|
|
75
|
+
.name {
|
|
76
|
+
margin-top: 0 !important;
|
|
77
|
+
margin-bottom: 0 !important;
|
|
78
|
+
color: #fff !important;
|
|
79
|
+
font-family: inherit;
|
|
80
|
+
|
|
81
|
+
font-family: RajdhaniB, 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
|
82
|
+
font-size: 40px;
|
|
83
|
+
line-height: 40px;
|
|
84
|
+
text-transform: uppercase;
|
|
85
|
+
|
|
86
|
+
> * {
|
|
87
|
+
font-family: RajdhaniB, 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.info {
|
|
92
|
+
margin-bottom: 0;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
h3 {
|
|
96
|
+
margin-top: 0 !important;
|
|
97
|
+
margin-bottom: 0 !important;
|
|
98
|
+
color: #fff !important;
|
|
99
|
+
font-family: inherit;
|
|
100
|
+
font-size: 32px;
|
|
101
|
+
line-height: 32px;
|
|
102
|
+
text-transform: uppercase;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
h4 {
|
|
106
|
+
margin-top: 0 !important;
|
|
107
|
+
margin-bottom: 0 !important;
|
|
108
|
+
color: #fff !important;
|
|
109
|
+
font-family: inherit;
|
|
110
|
+
font-size: 32px;
|
|
111
|
+
line-height: 32px;
|
|
112
|
+
text-transform: uppercase;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.info,
|
|
116
|
+
.info > * {
|
|
117
|
+
font-family: 'RajdhaniR', 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
|
118
|
+
font-size: 18px;
|
|
119
|
+
font-weight: 600;
|
|
120
|
+
line-height: 18px;
|
|
121
|
+
|
|
122
|
+
a {
|
|
123
|
+
color: #fff;
|
|
124
|
+
|
|
125
|
+
&:hover {
|
|
126
|
+
color: #fff;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.carousel {
|
|
133
|
+
display: flex;
|
|
134
|
+
height: 320px;
|
|
135
|
+
|
|
136
|
+
p {
|
|
137
|
+
font-family: 'RajdhaniB', 'Helvetica Neue', Arial, Helvetica, sans-serif;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
img {
|
|
141
|
+
width: 100%;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
&.one-slide .swiper {
|
|
145
|
+
width: 100%;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
&.two-slides .swiper {
|
|
149
|
+
width: 50%;
|
|
150
|
+
|
|
151
|
+
@media @mobile {
|
|
152
|
+
width: 100%;
|
|
153
|
+
|
|
154
|
+
&.preview.preview-one {
|
|
155
|
+
display: none;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
&.three-slides .swiper {
|
|
161
|
+
width: 33.33%;
|
|
162
|
+
|
|
163
|
+
@media @tablet {
|
|
164
|
+
width: 50%;
|
|
165
|
+
|
|
166
|
+
&.preview.preview-two {
|
|
167
|
+
display: none;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@media @mobile {
|
|
172
|
+
width: 100%;
|
|
173
|
+
|
|
174
|
+
&.preview.preview-two,
|
|
175
|
+
&.preview.preview-one {
|
|
176
|
+
display: none;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.swiper {
|
|
182
|
+
&.preview .swiper-slide {
|
|
183
|
+
filter: grayscale(100%);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
img {
|
|
187
|
+
display: block;
|
|
188
|
+
width: 100%;
|
|
189
|
+
height: 100%;
|
|
190
|
+
object-fit: contain;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
.arrows {
|
|
195
|
+
position: absolute;
|
|
196
|
+
z-index: 2;
|
|
197
|
+
bottom: 0;
|
|
198
|
+
left: 0;
|
|
199
|
+
display: flex;
|
|
200
|
+
width: 100%;
|
|
201
|
+
align-items: center;
|
|
202
|
+
|
|
203
|
+
button {
|
|
204
|
+
padding: 0;
|
|
205
|
+
border: none;
|
|
206
|
+
margin: 0;
|
|
207
|
+
background-color: transparent;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.icon {
|
|
211
|
+
display: block;
|
|
212
|
+
width: 32px;
|
|
213
|
+
background-color: #fff;
|
|
214
|
+
cursor: pointer;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
p {
|
|
218
|
+
overflow: hidden;
|
|
219
|
+
width: 100%;
|
|
220
|
+
padding: 0.25rem 0.25rem 0.25rem 1rem;
|
|
221
|
+
margin: 0;
|
|
222
|
+
backdrop-filter: brightness(0.5);
|
|
223
|
+
text-overflow: ellipsis;
|
|
224
|
+
white-space: nowrap;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
&:not(.arrows-hidden) {
|
|
228
|
+
p {
|
|
229
|
+
width: calc(100% - 64px);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
@media @mobile {
|
|
236
|
+
flex-flow: column;
|
|
237
|
+
|
|
238
|
+
.habitat-metadata {
|
|
239
|
+
width: 100%;
|
|
240
|
+
margin-top: 2rem;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.carousel {
|
|
244
|
+
margin: 0 1rem 1rem 1rem;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
@@ -12,42 +12,43 @@ const DefaultView = (props) => {
|
|
|
12
12
|
return (
|
|
13
13
|
<div className={cx('tiles-images', mode, data.theme || 'light')}>
|
|
14
14
|
{mode === 'edit' && !images.length ? <p>Tiles images block</p> : ''}
|
|
15
|
-
{
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
'
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
{copyright
|
|
38
|
-
|
|
39
|
-
<Copyright
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
15
|
+
{Array.isArray(images) &&
|
|
16
|
+
images.map((image) => {
|
|
17
|
+
const { copyright } = image;
|
|
18
|
+
return (
|
|
19
|
+
<p
|
|
20
|
+
key={`tile-${image.title}`}
|
|
21
|
+
className={cx('p-image', {
|
|
22
|
+
'with-border': data.hasBorder ?? true,
|
|
23
|
+
'rounded-border': data.rounded ?? true,
|
|
24
|
+
})}
|
|
25
|
+
>
|
|
26
|
+
<UniversalLink href={image.link || '#'} title={image.title}>
|
|
27
|
+
<>
|
|
28
|
+
<img
|
|
29
|
+
src={`${image.image}/@@images/image/mini`}
|
|
30
|
+
alt={image.title}
|
|
31
|
+
style={
|
|
32
|
+
data.size
|
|
33
|
+
? { width: `${data.size}px`, height: `${data.size}px` }
|
|
34
|
+
: {}
|
|
35
|
+
}
|
|
36
|
+
/>
|
|
37
|
+
<div className={`copyright-wrapper ${'left'}`}>
|
|
38
|
+
{copyright ? (
|
|
39
|
+
<Copyright copyrightPosition={'left'}>
|
|
40
|
+
<Copyright.Icon>@</Copyright.Icon>
|
|
41
|
+
<Copyright.Text>{copyright}</Copyright.Text>
|
|
42
|
+
</Copyright>
|
|
43
|
+
) : (
|
|
44
|
+
''
|
|
45
|
+
)}
|
|
46
|
+
</div>
|
|
47
|
+
</>
|
|
48
|
+
</UniversalLink>
|
|
49
|
+
</p>
|
|
50
|
+
);
|
|
51
|
+
})}
|
|
51
52
|
</div>
|
|
52
53
|
);
|
|
53
54
|
};
|
package/src/helpers.js
CHANGED
|
@@ -30,6 +30,14 @@ export const photoPlaceholders = {
|
|
|
30
30
|
default: defaultPNG,
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
export const priorityLabels = {
|
|
34
|
+
habitat_prioriy: {
|
|
35
|
+
1: 'Priority habitat',
|
|
36
|
+
0: 'Conditional priority',
|
|
37
|
+
'-1': '',
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
33
41
|
export const getObjectByIndex = (provider_data, index) => {
|
|
34
42
|
const obj = {};
|
|
35
43
|
const keys = Object.keys(provider_data);
|
|
File without changes
|