@eeacms/volto-n2k 1.2.2 → 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 +20 -8
- package/package.json +1 -1
- package/src/components/manage/Blocks/HabitatsBanner/View.jsx +12 -204
- 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/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/components/manage/Blocks/HabitatsBanner/{style.less → variations/style.less} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,12 +4,31 @@ 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)]
|
|
7
27
|
### [1.2.2](https://github.com/eea/volto-n2k/compare/1.2.1...1.2.2) - 23 February 2026
|
|
8
28
|
|
|
9
29
|
#### :house: Internal changes
|
|
10
30
|
|
|
11
31
|
- style: Automated code fix [eea-jenkins - [`dd7eb96`](https://github.com/eea/volto-n2k/commit/dd7eb969dbf212e8cc0e49d76dff0cedfcc26e53)]
|
|
12
|
-
- chore: [JENKINSFILE] use sonarqube branches [EEA Jenkins - [`0e3a176`](https://github.com/eea/volto-n2k/commit/0e3a176b5013e874fd769549c7c43dacdfee07d2)]
|
|
13
32
|
|
|
14
33
|
#### :hammer_and_wrench: Others
|
|
15
34
|
|
|
@@ -167,7 +186,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
167
186
|
|
|
168
187
|
#### :house: Internal changes
|
|
169
188
|
|
|
170
|
-
- chore: [JENKINS] Refactor automated testing [valentinab25 - [`e4f9fc8`](https://github.com/eea/volto-n2k/commit/e4f9fc800b753b97cca7c685bc47dd48804276f0)]
|
|
171
189
|
- chore: husky, lint-staged use fixed versions [valentinab25 - [`647d621`](https://github.com/eea/volto-n2k/commit/647d621d52400c50f5bc629b3ddc4f2121f14ffa)]
|
|
172
190
|
- chore:volto 16 in tests, update docs, fix stylelint overrides [valentinab25 - [`60d94b6`](https://github.com/eea/volto-n2k/commit/60d94b61ff8826abc57af9616793a1a247f585b5)]
|
|
173
191
|
|
|
@@ -182,11 +200,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
182
200
|
- try to use volto-spotlight theme in jenkins [Miu Razvan - [`ec0b952`](https://github.com/eea/volto-n2k/commit/ec0b9525b967f907922ae660bd9f520119cd80c1)]
|
|
183
201
|
- remove waitForResourceToLoad [ana-oprea - [`eaded9b`](https://github.com/eea/volto-n2k/commit/eaded9b9ecd1ca2eb78aa8dd65838c063d95db85)]
|
|
184
202
|
- update image size from 300 to 800 px [Claudia Ifrim - [`8d9270a`](https://github.com/eea/volto-n2k/commit/8d9270a09506278ceaea25e8a72abdf5b22fcc78)]
|
|
185
|
-
- test: [JENKINS] Use java17 for sonarqube scanner [valentinab25 - [`350f8a6`](https://github.com/eea/volto-n2k/commit/350f8a6928aafbf168472b572f8041a79f71f577)]
|
|
186
|
-
- test: [JENKINS] Run cypress in started frontend container [valentinab25 - [`99b3a84`](https://github.com/eea/volto-n2k/commit/99b3a84a266710fadf7d430117359b741cadede8)]
|
|
187
|
-
- test: [JENKINS] Add cpu limit on cypress docker [valentinab25 - [`050ac98`](https://github.com/eea/volto-n2k/commit/050ac982ec39e9a1b4885b665cdc118fca7b1283)]
|
|
188
|
-
- test: [JENKINS] Increase shm-size to cypress docker [valentinab25 - [`3546040`](https://github.com/eea/volto-n2k/commit/35460409817f496fc752ab34e37d6d33a069b2e9)]
|
|
189
|
-
- test: [JENKINS] Improve cypress time [valentinab25 - [`06a4ab1`](https://github.com/eea/volto-n2k/commit/06a4ab151799b8cdf4a316dbcb0c323e0f568e30)]
|
|
190
203
|
- test: EN locales, pre-commit fix, feature PRs checks Refs #257193 [valentinab25 - [`4850d6a`](https://github.com/eea/volto-n2k/commit/4850d6a65349fe49dbe9244c30592ae38c9aeaba)]
|
|
191
204
|
- test: Update Makefile and docker-compose to align it with Jenkinsfile [valentinab25 - [`2c91856`](https://github.com/eea/volto-n2k/commit/2c9185688a2fe6b36e5eeb2963f6c8676e3c5628)]
|
|
192
205
|
### [1.0.33](https://github.com/eea/volto-n2k/compare/1.0.32...1.0.33) - 3 July 2023
|
|
@@ -443,7 +456,6 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
|
|
|
443
456
|
- Update [razvanMiu - [`42ab50e`](https://github.com/eea/volto-n2k/commit/42ab50e6681a47251d15ac06b836c6f8c27157fa)]
|
|
444
457
|
- Added bubble chart [razvanMiu - [`89fba5e`](https://github.com/eea/volto-n2k/commit/89fba5e5db41aa955ba2d0ed58c9f0042c461504)]
|
|
445
458
|
- Group species by id_eunis in species list [razvanMiu - [`543c957`](https://github.com/eea/volto-n2k/commit/543c9573b53acd8eecc9afbb6ae7beeddba53966)]
|
|
446
|
-
- Add Sonarqube tag using frontend addons list [EEA Jenkins - [`2ca3e4c`](https://github.com/eea/volto-n2k/commit/2ca3e4c092211f92339791d71db81f5b4ca2d562)]
|
|
447
459
|
- update maps - species and habitats distribution maps [Claudia Ifrim - [`ad12eb1`](https://github.com/eea/volto-n2k/commit/ad12eb141907d6f28444f1eafc3f687735d2a68d)]
|
|
448
460
|
- update format for common name and author [Claudia Ifrim - [`26b7a2f`](https://github.com/eea/volto-n2k/commit/26b7a2f3d20c7701b57fb24f39fc7dfeceec3ce8)]
|
|
449
461
|
- update format for species name (common / scientific) [Claudia Ifrim - [`abdedcf`](https://github.com/eea/volto-n2k/commit/abdedcfe645665031dedf050fd2c5cdde8c14a50)]
|
package/package.json
CHANGED
|
@@ -1,208 +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
|
-
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
|
-
)(ViewComponent);
|
|
201
|
-
|
|
202
|
-
export default function View(props) {
|
|
203
|
-
return (
|
|
204
|
-
<VisibilitySensor Placeholder={() => <div>loading.... </div>}>
|
|
205
|
-
<ViewCompose {...props} />
|
|
206
|
-
</VisibilitySensor>
|
|
207
|
-
);
|
|
13
|
+
return <Template {...props} mode={mode} />;
|
|
208
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,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
|
};
|
|
File without changes
|