@eeacms/volto-n2k 1.0.22 → 1.0.23

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 CHANGED
@@ -4,12 +4,21 @@ 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.0.22](https://github.com/eea/volto-n2k/compare/1.0.21...1.0.22) - 29 March 2023
7
+ ### [1.0.23](https://github.com/eea/volto-n2k/compare/1.0.22...1.0.23) - 12 April 2023
8
+
9
+ #### :house: Internal changes
10
+
11
+ - style(HabitatsBanner): reorganize CSS properties and remove unused CSS properties [Miu Razvan - [`682ccc6`](https://github.com/eea/volto-n2k/commit/682ccc630e7f83d8084ec25cd5782315330af4ee)]
8
12
 
9
13
  #### :hammer_and_wrench: Others
10
14
 
11
- - update [Miu Razvan - [`e9a407f`](https://github.com/eea/volto-n2k/commit/e9a407fe51e6f0664f4d2d8aafd32042c9650302)]
12
- - update [Miu Razvan - [`930c7d3`](https://github.com/eea/volto-n2k/commit/930c7d3af8c8541dd83616b4131f0c1639495d70)]
15
+ - update [Miu Razvan - [`3b1f4bb`](https://github.com/eea/volto-n2k/commit/3b1f4bb0ab47baae9bf316c86f4ccaa8494a1a4d)]
16
+ - fix navigation icons svg [tedw87 - [`233255d`](https://github.com/eea/volto-n2k/commit/233255d5dcb655ef12e0ffbfdc64619f186884a5)]
17
+ - update [Miu Razvan - [`9009bc2`](https://github.com/eea/volto-n2k/commit/9009bc2bb08ddaf160bcacd57f9eefec4a487319)]
18
+ - update [Miu Razvan - [`baac43c`](https://github.com/eea/volto-n2k/commit/baac43cabbd61c44ae6513af774bffb0030a0450)]
19
+ - add habitats carousel [tedw87 - [`41861d1`](https://github.com/eea/volto-n2k/commit/41861d172884f04ef0b53ea4035c1051224dcf4e)]
20
+ ### [1.0.22](https://github.com/eea/volto-n2k/compare/1.0.21...1.0.22) - 29 March 2023
21
+
13
22
  ### [1.0.21](https://github.com/eea/volto-n2k/compare/1.0.20...1.0.21) - 22 March 2023
14
23
 
15
24
  ### [1.0.20](https://github.com/eea/volto-n2k/compare/1.0.19...1.0.20) - 22 March 2023
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-n2k",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "description": "volto-n2k: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -33,7 +33,8 @@
33
33
  "react-stickynode": "^4.0.0",
34
34
  "react-use-localstorage": "^3.5.3",
35
35
  "resize-observer-polyfill": "1.5.1",
36
- "slick-carousel": "1.8.1"
36
+ "slick-carousel": "1.8.1",
37
+ "swiper": "9.1.1"
37
38
  },
38
39
  "devDependencies": {
39
40
  "@cypress/code-coverage": "^3.10.0",
@@ -18,7 +18,7 @@ export default (config) => {
18
18
  addPermission: [],
19
19
  view: [],
20
20
  },
21
- blockHasOwnFocusManagement: true,
21
+ blockHasOwnFocusManagement: false,
22
22
  };
23
23
  return config;
24
24
  };
@@ -0,0 +1,49 @@
1
+ import React, { useMemo } from 'react';
2
+ import { compose } from 'redux';
3
+ import { SidebarPortal } from '@plone/volto/components';
4
+ import BlockDataForm from '@plone/volto/components/manage/Form/BlockDataForm';
5
+ import { VisibilitySensor } from '@eeacms/volto-datablocks/components';
6
+ import { connectToProviderData } from '@eeacms/volto-datablocks/hocs';
7
+ import getSchema from './schema';
8
+ import View from './View';
9
+ import './style.less';
10
+
11
+ const Edit = (props) => {
12
+ const schema = useMemo(() => getSchema(props), [props]);
13
+
14
+ return (
15
+ <>
16
+ <View {...props} mode="edit" />
17
+
18
+ <SidebarPortal selected={props.selected}>
19
+ <BlockDataForm
20
+ schema={schema}
21
+ title={schema.title}
22
+ onChangeField={(id, value) => {
23
+ props.onChangeBlock(props.block, {
24
+ ...props.data,
25
+ [id]: value,
26
+ });
27
+ }}
28
+ onChangeBlock={props.onChangeBlock}
29
+ formData={props.data}
30
+ block={props.block}
31
+ />
32
+ </SidebarPortal>
33
+ </>
34
+ );
35
+ };
36
+
37
+ const EditWrapper = compose(
38
+ connectToProviderData((props) => ({
39
+ provider_url: props.data?.provider_url,
40
+ })),
41
+ )(Edit);
42
+
43
+ export default (props) => {
44
+ return (
45
+ <VisibilitySensor>
46
+ <EditWrapper {...props} />
47
+ </VisibilitySensor>
48
+ );
49
+ };
@@ -1,30 +1,49 @@
1
- import React from 'react';
2
- import { Container } from 'semantic-ui-react';
1
+ import React, { useState } from 'react';
2
+ import loadable from '@loadable/component';
3
+ import { compose } from 'redux';
4
+ import { VisibilitySensor } from '@eeacms/volto-datablocks/components';
5
+ import { connectToMultipleProviders } from '@eeacms/volto-datablocks/hocs';
6
+ import arrowLeft from './chevron-left-square-fill-svgrepo-com.svg';
7
+ import arrowRight from './chevron-right-square-fill-svgrepo-com.svg';
3
8
  import './style.less';
4
9
 
5
- const View = (props) => {
6
- const provider_data = props.provider_data || {};
10
+ const SwiperLoader = loadable.lib(() => import('swiper'));
11
+ const SwiperReactLoader = loadable.lib(() => import('swiper/react'));
12
+
13
+ const _View = (props) => {
14
+ const [activeSlide, setActiveSlide] = useState(0);
15
+ const { providers = [] } = props.data;
16
+ const habitat = props.providers_data?.[providers[0]?.provider_url] || {};
17
+ const habitat_pictures =
18
+ props.providers_data?.[providers[1]?.provider_url] || {};
19
+
7
20
  const {
8
- code_2000 = [],
21
+ code_2000,
9
22
  // habitat_description = [],
10
23
  // habitat_type = [],
11
24
  // number_countries = [],
12
25
  // number_sites = [],
13
- scientific_name = [],
14
- } = provider_data;
26
+ scientific_name,
27
+ } = habitat;
28
+
29
+ const pictures = habitat_pictures?.['WebURL'] || [];
30
+ const picture_names = habitat_pictures?.['filename'] || [];
31
+ const copyright = habitat_pictures?.['attribution_copyright'] || [];
32
+
33
+ if (!code_2000 && props.mode === 'edit') {
34
+ return 'Habitat banner block (code_2000 undefined)';
35
+ }
36
+ if (!code_2000) return null;
15
37
 
16
- if (!code_2000[0]) return '';
17
38
  return (
18
- <div className="habitat-banner-details full-width">
19
- <Container>
20
- <div className="habitat-details">
21
- <div className="habitat-metadata">
22
- <h2 className="name">{scientific_name[0]}</h2>
23
- <p className="info">
24
- Habitats Directive Annex I code&nbsp;&nbsp;&nbsp;{code_2000[0]}
25
- </p>
26
- <br />
27
- {/* {number_sites[0] && (
39
+ <div className="habitat-banner-details">
40
+ <div className="habitat-details">
41
+ <div className="habitat-metadata">
42
+ <h2 className="name">{scientific_name[0]}</h2>
43
+ <p className="info">
44
+ Habitats Directive Annex I code&nbsp;&nbsp;&nbsp;{code_2000[0]}
45
+ </p>
46
+ {/* {number_sites[0] && (
28
47
  <>
29
48
  <h3 style={{ marginBottom: '0.15rem' }}>{number_sites[0]}</h3>
30
49
  <h4 className="radjhan-normal">
@@ -32,11 +51,86 @@ const View = (props) => {
32
51
  </h4>
33
52
  </>
34
53
  )} */}
35
- </div>
36
54
  </div>
37
- </Container>
55
+ {pictures?.length > 0 && (
56
+ <div className="carousel">
57
+ <div className="arrows">
58
+ <div className="swiper-button image-swiper-button-prev">
59
+ <img
60
+ className="icon icon-left"
61
+ src={arrowLeft}
62
+ alt="left arrow"
63
+ />
64
+ {/* <Icon className="icon-left" name={arrowSVG} size="24px" /> */}
65
+ </div>
66
+ <div className="swiper-button image-swiper-button-next">
67
+ <img
68
+ className="icon icon-right"
69
+ src={arrowRight}
70
+ alt="right arrow"
71
+ />
72
+ {/* <Icon className="icon-right" name={arrowSVG} size="24px" /> */}
73
+ </div>
74
+ <p>{copyright[activeSlide]}</p>
75
+ </div>
76
+ <SwiperLoader>
77
+ {({ Navigation, Pagination }) => {
78
+ return (
79
+ <SwiperReactLoader>
80
+ {({ Swiper, SwiperSlide }) => {
81
+ return (
82
+ <Swiper
83
+ modules={[Navigation, Pagination]}
84
+ navigation={{
85
+ prevEl: '.image-swiper-button-prev',
86
+ nextEl: '.image-swiper-button-next',
87
+ }}
88
+ slidesPerView={3}
89
+ spaceBetween={0}
90
+ loop={true}
91
+ breakpoints={{
92
+ 320: {
93
+ slidesPerView: 1,
94
+ spaceBetween: 0,
95
+ },
96
+ 1200: {
97
+ slidesPerView: 3,
98
+ spaceBetween: 0,
99
+ },
100
+ }}
101
+ onSlideChange={(swiper) => {
102
+ setActiveSlide(swiper.activeIndex);
103
+ }}
104
+ >
105
+ {pictures.map((source, index) => (
106
+ <SwiperSlide>
107
+ <img src={source} alt={picture_names[index]} />
108
+ </SwiperSlide>
109
+ ))}
110
+ </Swiper>
111
+ );
112
+ }}
113
+ </SwiperReactLoader>
114
+ );
115
+ }}
116
+ </SwiperLoader>
117
+ </div>
118
+ )}
119
+ </div>
38
120
  </div>
39
121
  );
40
122
  };
41
123
 
42
- export default View;
124
+ const View = compose(
125
+ connectToMultipleProviders((props) => ({
126
+ providers: props.data?.providers,
127
+ })),
128
+ )(_View);
129
+
130
+ export default (props) => {
131
+ return (
132
+ <VisibilitySensor Placeholder={() => <div>loading....&nbsp;</div>}>
133
+ <View {...props} />
134
+ </VisibilitySensor>
135
+ );
136
+ };
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 24.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{fill-rule:evenodd;clip-rule:evenodd;}
7
+ </style>
8
+ <path class="st0" d="M32,0H0v32h32V0z M12,16l10.1,10.1l-2.5,2.5L7,16L19.6,3.4l2.5,2.5L12,16z"/>
9
+ </svg>
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 24.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 32 32" style="enable-background:new 0 0 32 32;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{fill-rule:evenodd;clip-rule:evenodd;}
7
+ </style>
8
+ <path class="st0" d="M0,32h32V0L0,0L0,32z M9.9,5.9l2.5-2.5L25,16L12.4,28.6l-2.5-2.5L20,16L9.9,5.9z"/>
9
+ </svg>
@@ -1,17 +1,24 @@
1
- import HabitatsBannerView from './View';
2
- import getSchema from './schema';
1
+ import worldSVG from '@plone/volto/icons/world.svg';
2
+ import Edit from './Edit';
3
+ import View from './View';
3
4
 
4
5
  export default (config) => {
5
- config.blocks.blocksConfig.custom_connected_block = {
6
- ...config.blocks.blocksConfig.custom_connected_block,
7
- blocks: {
8
- ...config.blocks.blocksConfig.custom_connected_block.blocks,
9
- habitats_banner: {
10
- view: HabitatsBannerView,
11
- getSchema: getSchema,
12
- title: 'Habitat banner',
13
- },
6
+ config.blocks.blocksConfig.habitats_banner = {
7
+ id: 'habitats_banner',
8
+ title: 'Habitats banner',
9
+ icon: worldSVG,
10
+ group: 'natura_2000',
11
+ edit: Edit,
12
+ view: View,
13
+ restricted: false,
14
+ mostUsed: false,
15
+ sidebarTab: 1,
16
+ blocks: {},
17
+ security: {
18
+ addPermission: [],
19
+ view: [],
14
20
  },
21
+ blockHasOwnFocusManagement: false,
15
22
  };
16
23
  return config;
17
24
  };
@@ -1,18 +1,77 @@
1
+ const SourceSchema = {
2
+ title: 'Source',
3
+
4
+ fieldsets: [
5
+ {
6
+ id: 'default',
7
+ title: 'Default',
8
+ fields: ['source', 'source_link'],
9
+ },
10
+ ],
11
+
12
+ properties: {
13
+ source: {
14
+ type: 'string',
15
+ title: 'Source',
16
+ },
17
+ source_link: {
18
+ type: 'string',
19
+ title: 'Link',
20
+ },
21
+ },
22
+
23
+ required: ['source'],
24
+ };
25
+
26
+ const DataProvidersSchema = {
27
+ title: 'Data provider',
28
+ fieldsets: [{ id: 'default', title: 'Default', fields: ['provider_url'] }],
29
+ properties: {
30
+ provider_url: {
31
+ title: 'Provider url',
32
+ widget: 'object_by_path',
33
+ },
34
+ },
35
+ };
36
+
1
37
  const getSchema = (props) => {
2
38
  return {
3
- title: 'Habitats banner',
4
-
39
+ title: 'Habitats Banner',
5
40
  fieldsets: [
6
41
  {
7
42
  id: 'default',
8
43
  title: 'Default',
9
- fields: [],
44
+ fields: ['providers', 'allowedParams'],
45
+ },
46
+ {
47
+ id: 'sources',
48
+ title: 'Sources',
49
+ fields: ['sources'],
10
50
  },
11
51
  ],
12
52
 
13
- properties: {},
53
+ properties: {
54
+ providers: {
55
+ title: 'Data provider',
56
+ schema: DataProvidersSchema,
57
+ widget: 'object_list',
58
+ },
59
+ allowedParams: {
60
+ title: 'Allowed params',
61
+ type: 'array',
62
+ creatable: true,
63
+ items: {
64
+ choices: [],
65
+ },
66
+ },
67
+ sources: {
68
+ title: 'Sources',
69
+ schema: SourceSchema,
70
+ widget: 'object_list',
71
+ },
72
+ },
14
73
 
15
- required: [],
74
+ required: ['url'],
16
75
  };
17
76
  };
18
77
 
@@ -1,30 +1,81 @@
1
+ @type: extra;
2
+ @element: custom;
3
+
4
+ @import (multiple, reference, optional) '../../theme.config';
5
+
6
+ @import 'swiper/swiper.less';
7
+ @import 'swiper/modules/navigation/navigation.less';
8
+ @import 'swiper/modules/pagination/pagination.less';
9
+
10
+ @{view} {
11
+ .habitat-banner-details {
12
+ &::before {
13
+ .full-width();
14
+ position: absolute;
15
+ z-index: -1;
16
+ }
17
+
18
+ .carousel {
19
+ .half-width(960px);
20
+
21
+ @media @mobile {
22
+ width: calc(@pageFullWidth - 2rem) !important;
23
+ }
24
+ }
25
+ }
26
+ }
27
+
28
+ @{edit} {
29
+ .habitat-banner-details {
30
+ &::before {
31
+ .full-width-edit();
32
+ position: absolute;
33
+ z-index: -1;
34
+ }
35
+
36
+ .carousel {
37
+ .half-width-edit(960px);
38
+
39
+ @media @mobile {
40
+ width: calc(@pageFullWidthEdit - 2rem) !important;
41
+ }
42
+ }
43
+ }
44
+ }
45
+
1
46
  div#view .habitat-banner-details .ui.container > * {
2
47
  margin-bottom: 0;
3
48
  }
4
49
 
5
50
  .habitat-banner-details {
6
- padding: 1.5em 0;
7
- background-color: #00a390;
51
+ position: relative;
52
+ padding: 0;
8
53
  color: #fff !important;
9
54
  font-family: 'RajdhaniB', 'Helvetica Neue', Arial, Helvetica, sans-serif;
10
55
 
56
+ &::before {
57
+ display: block;
58
+ height: 100%;
59
+ background-color: #00a390;
60
+ content: '';
61
+ }
62
+
11
63
  .habitat-details {
12
64
  display: flex;
13
- align-items: flex-start;
65
+ align-items: center;
14
66
  justify-content: space-between;
15
- gap: 1rem;
16
-
17
- @media only screen and (max-width: 765px) {
18
- flex-flow: column;
19
-
20
- .habitat-metadata {
21
- margin-bottom: 1rem;
22
- }
23
- }
24
67
 
25
68
  .habitat-metadata {
69
+ display: flex;
70
+ width: 50%;
71
+ flex: 0 0 50%;
72
+ flex-direction: column;
73
+ justify-content: center;
74
+ margin: 4rem 0;
75
+ word-wrap: break-word;
76
+
26
77
  .name {
27
- margin-top: 0.5em !important;
78
+ margin-top: 0 !important;
28
79
  margin-bottom: 0 !important;
29
80
  color: #fff !important;
30
81
  font-family: inherit;
@@ -39,6 +90,10 @@ div#view .habitat-banner-details .ui.container > * {
39
90
  }
40
91
  }
41
92
 
93
+ .info {
94
+ margin-bottom: 0;
95
+ }
96
+
42
97
  h3 {
43
98
  margin-top: 0 !important;
44
99
  margin-bottom: 0 !important;
@@ -68,10 +123,77 @@ div#view .habitat-banner-details .ui.container > * {
68
123
  }
69
124
  }
70
125
 
71
- img {
72
- max-height: 200px;
73
- border-radius: 10px;
74
- filter: drop-shadow(-2px 2px 3px rgba(0, 0, 0, 0.4));
126
+ .carousel {
127
+ p {
128
+ font-family: 'RajdhaniB', 'Helvetica Neue', Arial, Helvetica, sans-serif;
129
+ }
130
+
131
+ img {
132
+ width: 100%;
133
+ }
134
+
135
+ .swiper {
136
+ img {
137
+ display: block;
138
+ // max-height: 300px;
139
+ width: 100%;
140
+ height: 300px;
141
+ object-fit: cover;
142
+ }
143
+ }
144
+
145
+ .arrows {
146
+ position: absolute;
147
+ z-index: 1;
148
+ bottom: 0;
149
+ left: 0;
150
+ display: flex;
151
+ width: 100%;
152
+ align-items: center;
153
+
154
+ .icon {
155
+ display: block;
156
+ width: 32px;
157
+ background-color: #fff;
158
+ cursor: pointer;
159
+ }
160
+
161
+ p {
162
+ overflow: hidden;
163
+ width: calc(100% - 64px);
164
+ padding: 0.25rem 0.25rem 0.25rem 1rem;
165
+ margin: 0;
166
+ backdrop-filter: brightness(0.5);
167
+ text-overflow: ellipsis;
168
+ white-space: nowrap;
169
+ }
170
+ }
171
+ }
172
+
173
+ .swiper {
174
+ z-index: 0;
175
+ width: 100%;
176
+
177
+ .swiper-slide:not(.swiper-slide-active) {
178
+ filter: grayscale(100%);
179
+ }
180
+
181
+ .swiper-slide {
182
+ transition: filter 0.5s;
183
+ }
184
+ }
185
+
186
+ @media @mobile {
187
+ flex-flow: column;
188
+
189
+ .habitat-metadata {
190
+ width: 100%;
191
+ margin-top: 2rem;
192
+ }
193
+
194
+ .carousel {
195
+ margin: 0 1rem 1rem 1rem;
196
+ }
75
197
  }
76
198
  }
77
199
  }
@@ -75,8 +75,9 @@ export const getStyle = (props) => {
75
75
  if (!props.screen.width || !props.screen.height) return {};
76
76
  const height =
77
77
  props.screen.height -
78
- props.screen.browserToolbarHeight -
79
- props.screen.content.offsetTop;
78
+ props.screen.content.offsetTop -
79
+ props.screen.browserToolbarHeight;
80
+
80
81
  return {
81
82
  minHeight: `${height}px`,
82
83
  maxHeight: `${height}px`,
@@ -11,12 +11,10 @@
11
11
  background-repeat: no-repeat;
12
12
  background-size: cover;
13
13
 
14
- &:not(.edit) {
15
- overflow-y: hidden;
14
+ overflow-y: hidden;
16
15
 
17
- .ui.grid.landing-page {
18
- overflow-y: auto;
19
- }
16
+ .ui.grid.landing-page {
17
+ overflow-y: auto;
20
18
  }
21
19
 
22
20
  .ui.grid.landing-page {
@@ -69,7 +69,7 @@ const View = (props) => {
69
69
 
70
70
  return (
71
71
  <Sticky
72
- active={sticky && screen.page?.width > 765}
72
+ active={sticky && screen.page?.width > 767}
73
73
  context={__CLIENT__ && document.querySelector('.content-area')}
74
74
  className={cx('sticky-navigation-anchors', {
75
75
  'full-width': sticky,
@@ -15,6 +15,8 @@ div#view .ui.container > .sticky-navigation-anchors {
15
15
  }
16
16
 
17
17
  .sticky-navigation-anchors {
18
+ z-index: 5 !important;
19
+
18
20
  &.is-sticky {
19
21
  .navigation-anchors {
20
22
  background-color: #fff !important;