@eeacms/volto-n2k 1.0.20 → 1.0.22

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,11 +4,16 @@ 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.20](https://github.com/eea/volto-n2k/compare/1.0.19...1.0.20) - 15 March 2023
7
+ ### [1.0.22](https://github.com/eea/volto-n2k/compare/1.0.21...1.0.22) - 29 March 2023
8
8
 
9
9
  #### :hammer_and_wrench: Others
10
10
 
11
- - update layer for species and habitats [Claudia Ifrim - [`b2262fc`](https://github.com/eea/volto-n2k/commit/b2262fcb7416208ba3ce5368bbd50bda2e0e58f6)]
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)]
13
+ ### [1.0.21](https://github.com/eea/volto-n2k/compare/1.0.20...1.0.21) - 22 March 2023
14
+
15
+ ### [1.0.20](https://github.com/eea/volto-n2k/compare/1.0.19...1.0.20) - 22 March 2023
16
+
12
17
  ### [1.0.19](https://github.com/eea/volto-n2k/compare/1.0.18...1.0.19) - 7 March 2023
13
18
 
14
19
  ### [1.0.18](https://github.com/eea/volto-n2k/compare/1.0.17...1.0.18) - 25 February 2023
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-n2k",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "volto-n2k: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -16,15 +16,13 @@
16
16
  "@eeacms/volto-datablocks",
17
17
  "@eeacms/volto-openlayers-map",
18
18
  "@eeacms/volto-resize-helper",
19
- "@eeacms/volto-tabs-block",
20
- "@eeacms/volto-bise"
19
+ "@eeacms/volto-tabs-block"
21
20
  ],
22
21
  "repository": {
23
22
  "type": "git",
24
23
  "url": "git@github.com:eea/volto-n2k.git"
25
24
  },
26
25
  "dependencies": {
27
- "@eeacms/volto-bise": "*",
28
26
  "@eeacms/volto-datablocks": "*",
29
27
  "@eeacms/volto-openlayers-map": "*",
30
28
  "@eeacms/volto-resize-helper": "*",
@@ -1,3 +1,3 @@
1
- export { default as Header } from '@eeacms/volto-n2k/components/theme/Header/Header';
2
- export { default as Footer } from '@eeacms/volto-n2k/components/theme/Footer/Footer';
1
+ // export { default as Header } from '@eeacms/volto-n2k/components/theme/Header/Header';
2
+ // export { default as Footer } from '@eeacms/volto-n2k/components/theme/Footer/Footer';
3
3
  export { default as Sitemap } from '@eeacms/volto-n2k/components/theme/Sitemap/Sitemap';
@@ -11,6 +11,7 @@ import cx from 'classnames';
11
11
  import 'slick-carousel/slick/slick.css';
12
12
  import 'slick-carousel/slick/slick-theme.css';
13
13
  import '@eeacms/volto-tabs-block/less/carousel.less';
14
+ import './styles.less';
14
15
 
15
16
  const Slider = loadable(() => import('react-slick'));
16
17
 
@@ -27,8 +28,11 @@ const Dots = (props) => {
27
28
  >
28
29
  <button
29
30
  aria-label={`Select slide ${index + 1}`}
31
+ tabIndex={0}
30
32
  onClick={() => {
31
- slider.current.slickGoTo(index);
33
+ if (slider.current) {
34
+ slider.current.slickGoTo(index);
35
+ }
32
36
  }}
33
37
  />
34
38
  </li>
@@ -56,7 +60,12 @@ const ArrowsGroup = (props) => {
56
60
  <button
57
61
  aria-label="Previous slide"
58
62
  className="slick-arrow slick-prev"
59
- onClick={slider.current.slickPrev}
63
+ onClick={() => {
64
+ if (slider.current) {
65
+ slider.current.slickPrev();
66
+ }
67
+ }}
68
+ tabIndex={0}
60
69
  >
61
70
  <Icon name={leftArrowSVG} size="50px" />
62
71
  </button>
@@ -67,7 +76,12 @@ const ArrowsGroup = (props) => {
67
76
  <button
68
77
  aria-label="Next slide"
69
78
  className="slick-arrow slick-next"
70
- onClick={slider.current.slickNext}
79
+ onClick={() => {
80
+ if (slider.current) {
81
+ slider.current.slickNext();
82
+ }
83
+ }}
84
+ tabIndex={0}
71
85
  >
72
86
  {currentSlide === 0 && props.learnMore ? (
73
87
  <p className="learn-more">{props.learnMore}</p>
@@ -88,8 +102,9 @@ const ArrowsGroup = (props) => {
88
102
  const View = (props) => {
89
103
  const slider = React.useRef(null);
90
104
  const img = React.useRef(null);
91
- const [imgHeight, setImgHeight] = React.useState(0);
105
+ // const [imgHeight, setImgHeight] = React.useState(0);
92
106
  const [hashlinkOnMount, setHashlinkOnMount] = React.useState(false);
107
+ const blockId = props.id;
93
108
  const {
94
109
  activeTab = null,
95
110
  data = {},
@@ -100,7 +115,6 @@ const View = (props) => {
100
115
  setActiveTab = () => {},
101
116
  } = props;
102
117
  const activeTabIndex = tabsList.indexOf(activeTab);
103
- // const tabData = tabs[activeTab] || {};
104
118
  const uiContainer = data.align === 'full' ? 'ui container' : false;
105
119
  const image = data.image || null;
106
120
 
@@ -120,28 +134,28 @@ const View = (props) => {
120
134
  },
121
135
  };
122
136
 
123
- const panes = tabsList.map((tab, index) => {
124
- return {
125
- id: tab,
126
- renderItem: (
127
- <React.Fragment key={`slide-${tab}`}>
128
- <RenderBlocks {...props} metadata={metadata} content={tabs[tab]} />
129
- {index === 0 ? (
130
- <div
131
- className="divider"
132
- style={{ height: `${imgHeight - 80}px` }}
133
- />
134
- ) : (
135
- ''
136
- )}
137
- </React.Fragment>
138
- ),
139
- };
140
- });
137
+ // const panes = tabsList.map((tab, index) => {
138
+ // return {
139
+ // id: tab,
140
+ // renderItem: (
141
+ // <React.Fragment key={`slide-${tab}`}>
142
+ // <RenderBlocks {...props} metadata={metadata} content={tabs[tab]} />
143
+ // {index === 0 ? (
144
+ // <div
145
+ // className="divider"
146
+ // style={{ height: `${imgHeight - 80}px` }}
147
+ // />
148
+ // ) : (
149
+ // ''
150
+ // )}
151
+ // </React.Fragment>
152
+ // ),
153
+ // };
154
+ // });
141
155
 
142
- const updateImageHeight = () => {
143
- setImgHeight(img.current?.height || 0);
144
- };
156
+ // const updateImageHeight = () => {
157
+ // setImgHeight(img.current?.height || 0);
158
+ // };
145
159
 
146
160
  React.useEffect(() => {
147
161
  const urlHash = props.location.hash.substring(1) || '';
@@ -177,21 +191,54 @@ const View = (props) => {
177
191
  /* eslint-disable-next-line */
178
192
  }, [hashlink.counter]);
179
193
 
180
- React.useEffect(() => {
181
- updateImageHeight();
182
- img.current.onload = () => {
183
- updateImageHeight();
184
- };
185
- window.addEventListener('resize', updateImageHeight);
186
- return () => {
187
- window.removeEventListener('resize', updateImageHeight);
194
+ const panes = tabsList.map((tab, index) => {
195
+ return {
196
+ id: tab,
197
+ renderItem: (
198
+ <RenderBlocks
199
+ key={`slide-${tab}`}
200
+ {...props}
201
+ metadata={metadata}
202
+ content={tabs[tab]}
203
+ />
204
+ ),
188
205
  };
189
- /* eslint-disable-next-line */
190
- }, []);
206
+ });
207
+
208
+ // React.useEffect(() => {
209
+ // updateImageHeight();
210
+ // img.current.onload = () => {
211
+ // updateImageHeight();
212
+ // };
213
+ // window.addEventListener('resize', updateImageHeight);
214
+ // return () => {
215
+ // window.removeEventListener('resize', updateImageHeight);
216
+ // };
217
+ // /* eslint-disable-next-line */
218
+ // }, []);
219
+
220
+ // console.log('HERE RERENDER');
191
221
 
192
222
  return (
193
223
  <>
194
- <Slider {...settings} ref={slider} className={cx(uiContainer)}>
224
+ <Slider
225
+ {...settings}
226
+ ref={slider}
227
+ className={cx(uiContainer, 'tabs-accessibility')}
228
+ accessibility={true}
229
+ afterChange={() => {
230
+ if (
231
+ document
232
+ .getElementById(blockId)
233
+ ?.getElementsByClassName('slick-slider')?.length > 0
234
+ ) {
235
+ document
236
+ .getElementById(blockId)
237
+ .getElementsByClassName('slick-current')[0]
238
+ .focus();
239
+ }
240
+ }}
241
+ >
195
242
  {panes.length ? panes.map((pane) => pane.renderItem) : ''}
196
243
  </Slider>
197
244
  <img
@@ -0,0 +1,32 @@
1
+ @import (multiple, reference, optional) '../../theme.config';
2
+ @type: extra;
3
+ @element: custom;
4
+
5
+ .slick-image {
6
+ position: absolute;
7
+ bottom: 0;
8
+ left: 0;
9
+ width: 600px;
10
+ pointer-events: none;
11
+ }
12
+
13
+ @media only screen and (min-width: @mobileBreakpoint) {
14
+ .slick-image {
15
+ width: 450px !important;
16
+ transform: translateX(-40%) translateY(5%) !important;
17
+ }
18
+ }
19
+
20
+ @media only screen and (min-width: @tabletBreakpoint) {
21
+ .slick-image {
22
+ width: 500px !important;
23
+ transform: translateX(-25%) translateY(5%) !important;
24
+ }
25
+ }
26
+
27
+ @media only screen and (min-width: @computerBreakpoint) {
28
+ .slick-image {
29
+ width: 600px !important;
30
+ transform: translateX(-20%) translateY(5%) !important;
31
+ }
32
+ }
@@ -1,9 +1,10 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { connect } from 'react-redux';
3
3
  import { generatePath } from 'react-router';
4
+ import Cookies from 'universal-cookie';
4
5
  import { Grid } from 'semantic-ui-react';
6
+ import config from '@plone/volto/registry';
5
7
  import { UniversalLink } from '@plone/volto/components';
6
- import { withLocalStorage } from '@eeacms/volto-n2k/hocs';
7
8
  import hiker from './images/hiker.webp';
8
9
  import { tiles, tileProps, getStyle } from './index';
9
10
 
@@ -11,15 +12,25 @@ function removeTrailingSlash(str) {
11
12
  return str.replace(/\/+$/, '');
12
13
  }
13
14
 
15
+ function getLanguage() {
16
+ if (__SERVER__) {
17
+ return config.settings.eea.defaultLanguage;
18
+ }
19
+ const cookies = new Cookies();
20
+
21
+ if (!cookies.get('LANGUAGE')) {
22
+ cookies.set('LANGUAGE', config.settings.eea.defaultLanguage || '');
23
+ }
24
+
25
+ return cookies.get('LANGUAGE');
26
+ }
27
+
14
28
  const DefaultView = (props) => {
15
- const currentLang = props.localStorage.get('N2K_LANGUAGE');
29
+ const language = getLanguage();
16
30
 
17
31
  useEffect(() => {
18
- if (
19
- props.location?.pathname &&
20
- removeTrailingSlash(props.location.pathname) === '/natura2000'
21
- ) {
22
- props.history.push(`/natura2000/${currentLang || 'en'}`);
32
+ if (removeTrailingSlash(props.location?.pathname || '') === '/natura2000') {
33
+ props.history.push(`/natura2000/${language || 'en'}`);
23
34
  }
24
35
  /* eslint-disable-next-line */
25
36
  }, []);
@@ -59,10 +70,10 @@ const DefaultView = (props) => {
59
70
  mobile="7"
60
71
  >
61
72
  <Grid style={{ justifyContent: 'space-around' }}>
62
- {currentLang
73
+ {language
63
74
  ? tiles.map((item, index) => {
64
75
  const link = generatePath(item.link, {
65
- lang: currentLang,
76
+ lang: language,
66
77
  });
67
78
  return (
68
79
  <Grid.Column
@@ -93,6 +104,5 @@ const DefaultView = (props) => {
93
104
  };
94
105
 
95
106
  export default connect((state) => ({
96
- navigation: state.navigation,
97
107
  screen: state.screen,
98
- }))(withLocalStorage(DefaultView));
108
+ }))(DefaultView);
@@ -73,13 +73,13 @@ export const tileProps = {
73
73
  export const getStyle = (props) => {
74
74
  if (!props.screen) return {};
75
75
  if (!props.screen.width || !props.screen.height) return {};
76
+ const height =
77
+ props.screen.height -
78
+ props.screen.browserToolbarHeight -
79
+ props.screen.content.offsetTop;
76
80
  return {
77
- minHeight: (
78
- props.screen.height - props.screen.browserToolbarHeight
79
- ).toPixel(),
80
- maxHeight: (
81
- props.screen.height - props.screen.browserToolbarHeight
82
- ).toPixel(),
81
+ minHeight: `${height}px`,
82
+ maxHeight: `${height}px`,
83
83
  };
84
84
  };
85
85
 
@@ -2,14 +2,10 @@
2
2
  @type: extra;
3
3
  @element: custom;
4
4
 
5
- div#view .ui.container > {
6
- .landing-page-wrapper {
7
- margin-bottom: 0;
8
- }
9
- }
10
-
11
- .landing-page-wrapper {
5
+ .landing-page-wrapper,
6
+ [class~='view-defaultview'] [id='page-document'] .landing-page-wrapper {
12
7
  position: relative;
8
+ max-width: 100vw !important;
13
9
  padding-top: 4rem;
14
10
  background-image: url('./images/background.webp');
15
11
  background-repeat: no-repeat;
@@ -24,6 +20,7 @@ div#view .ui.container > {
24
20
  }
25
21
 
26
22
  .ui.grid.landing-page {
23
+ position: relative;
27
24
  z-index: 1;
28
25
  max-height: inherit;
29
26
 
@@ -32,7 +29,6 @@ div#view .ui.container > {
32
29
  scrollbar-width: none; /* Firefox */
33
30
 
34
31
  > .row {
35
- z-index: 1;
36
32
  justify-content: space-between;
37
33
  padding-bottom: 5rem;
38
34
  }
@@ -44,7 +40,7 @@ div#view .ui.container > {
44
40
 
45
41
  .landing-page-description {
46
42
  margin-bottom: 3rem;
47
- color: #fff !important;
43
+ color: #fff;
48
44
 
49
45
  p {
50
46
  font-size: 20px;
@@ -65,17 +61,18 @@ div#view .ui.container > {
65
61
  .item a {
66
62
  display: flex;
67
63
  flex-flow: column;
64
+ align-items: center;
65
+ justify-content: center;
68
66
  }
69
67
 
70
68
  .item img.image {
71
69
  width: 100%;
72
- // max-width: 200px;
73
70
  }
74
71
 
75
72
  .item p.description {
76
73
  position: relative;
77
74
  margin-top: 1rem;
78
- color: #fff !important;
75
+ color: #fff;
79
76
  font-size: 0.9em;
80
77
  font-weight: bold;
81
78
  }
@@ -95,7 +92,7 @@ div#view .ui.container > {
95
92
  border: 1px solid #78c0d7bf;
96
93
  border-bottom: 1px solid #fff;
97
94
  margin-top: -45px;
98
- background-color: #fff !important;
95
+ background-color: #fff;
99
96
 
100
97
  .ui.basic.button {
101
98
  padding: 3px;
@@ -144,31 +141,53 @@ div#view .ui.container > {
144
141
  }
145
142
 
146
143
  .slick-image {
147
- z-index: 0 !important;
144
+ position: absolute;
145
+ z-index: 0;
146
+ bottom: 0;
147
+ left: 0;
148
148
  pointer-events: none;
149
149
  }
150
150
  }
151
151
 
152
- // @media only screen and (max-width: @largeMonitorBreakpoint + @offset) {
153
- // .natura2000-theme {
154
- // .landing-page-wrapper {
155
- // .ui.grid.landing-page {
156
- // > .row {
157
- // justify-content: flex-end;
158
- // }
159
- // }
160
- // }
161
- // }
162
- // }
163
-
164
- @media only screen and (max-width: @largestTabletScreen) {
165
- .natura2000-theme {
166
- .landing-page-wrapper {
167
- .ui.grid.landing-page {
168
- > .row {
169
- justify-content: flex-end;
170
- }
152
+ @media only screen and (min-width: @mobileBreakpoint) {
153
+ .landing-page-wrapper {
154
+ .item a img.image {
155
+ max-width: 280px;
156
+ }
157
+
158
+ .ui.grid.landing-page {
159
+ > .row {
160
+ justify-content: flex-end !important;
171
161
  }
172
162
  }
163
+
164
+ .slick-image {
165
+ width: 450px !important;
166
+ transform: translateX(-40%) translateY(5%) !important;
167
+ }
168
+ }
169
+ }
170
+
171
+ @media only screen and (min-width: @tabletBreakpoint) {
172
+ .landing-page-wrapper {
173
+ .ui.grid.landing-page {
174
+ > .row {
175
+ justify-content: flex-end !important;
176
+ }
177
+ }
178
+
179
+ .slick-image {
180
+ width: 500px !important;
181
+ transform: translateX(-25%) translateY(5%) !important;
182
+ }
183
+ }
184
+ }
185
+
186
+ @media only screen and (min-width: @computerBreakpoint) {
187
+ .landing-page-wrapper {
188
+ .slick-image {
189
+ width: 600px !important;
190
+ transform: translateX(-20%) translateY(5%) !important;
191
+ }
173
192
  }
174
193
  }
@@ -1,11 +1,10 @@
1
- import React, { useState, useEffect, useContext, useRef } from 'react';
1
+ import React, { useState, useEffect, useRef } from 'react';
2
2
  import { connect } from 'react-redux';
3
3
  import { withRouter } from 'react-router';
4
4
  import { Menu, Container, Sticky } from 'semantic-ui-react';
5
5
  import qs from 'querystring';
6
6
  import cx from 'classnames';
7
7
  import { UniversalLink } from '@plone/volto/components';
8
- import { StickyContext } from '@eeacms/volto-bise/components';
9
8
  import { withHashLink } from '@eeacms/volto-n2k/hocs';
10
9
  import './styles.less';
11
10
 
@@ -20,8 +19,8 @@ const formatLink = (str, obj) => {
20
19
 
21
20
  const View = (props) => {
22
21
  const [activeHash, setActiveHash] = useState();
22
+ const [height, setHeight] = useState();
23
23
  const [offsetHeight, setOffsetHeight] = useState(0);
24
- const { stickyRef } = useContext(StickyContext);
25
24
  const anchorsRef = useRef();
26
25
  const { data = {}, screen = {} } = props;
27
26
  const links = data.links || [];
@@ -39,18 +38,24 @@ const View = (props) => {
39
38
 
40
39
  const onScroll = () => {
41
40
  const top = document.documentElement.scrollTop;
42
- const offsetHeight = anchorsRef.current?.offsetHeight + 10;
43
- let activeHash,
41
+ const offsetHeight = anchorsRef.current?.offsetHeight + 16;
42
+ let newActiveHash,
44
43
  maxTop = 0;
45
44
  hashList.forEach((hash) => {
46
45
  const hashTop = document.getElementById(hash)?.offsetTop;
47
46
  if (top >= hashTop - offsetHeight && top >= maxTop) {
48
47
  maxTop = top;
49
- activeHash = hash;
48
+ newActiveHash = hash;
50
49
  }
51
50
  });
52
- setActiveHash(activeHash);
53
- setOffsetHeight(offsetHeight - 11);
51
+ if (newActiveHash !== activeHash) {
52
+ setActiveHash(newActiveHash);
53
+ }
54
+ setOffsetHeight(offsetHeight);
55
+ setHeight(
56
+ document.querySelector('.eea.header .fixed-container > .ui.sticky')
57
+ ?.offsetHeight,
58
+ );
54
59
  };
55
60
 
56
61
  useEffect(() => {
@@ -65,7 +70,7 @@ const View = (props) => {
65
70
  return (
66
71
  <Sticky
67
72
  active={sticky && screen.page?.width > 765}
68
- context={stickyRef}
73
+ context={__CLIENT__ && document.querySelector('.content-area')}
69
74
  className={cx('sticky-navigation-anchors', {
70
75
  'full-width': sticky,
71
76
  'is-sticky': sticky,
@@ -73,6 +78,7 @@ const View = (props) => {
73
78
  >
74
79
  <div
75
80
  className={cx('navigation-anchors', data.className)}
81
+ style={{ ...(height ? { height: `${height}px` } : {}) }}
76
82
  ref={anchorsRef}
77
83
  >
78
84
  <Container>
@@ -1,3 +1,7 @@
1
+ #site-details {
2
+ margin-top: 0;
3
+ }
4
+
1
5
  .site-banner {
2
6
  padding: 1.5em 0;
3
7
  background-color: #00a390;
@@ -105,8 +105,8 @@ const View = (props) => {
105
105
  />
106
106
  </Map>
107
107
  </div>
108
- <Container className="map-info-notice">
109
- <Message>
108
+ <Message className="map-info-notice">
109
+ <Container>
110
110
  <p>
111
111
  The designations employed and the presentation of material on this
112
112
  map do not imply the expression of any opinion whatsoever on the
@@ -114,8 +114,8 @@ const View = (props) => {
114
114
  country, territory, city or area or of its authorities, or
115
115
  concerning the delimitation of its frontiers or boundaries.
116
116
  </p>
117
- </Message>
118
- </Container>
117
+ </Container>
118
+ </Message>
119
119
  </div>
120
120
  );
121
121
  };
@@ -38,6 +38,7 @@ div#view .site-species-list .species-list .ui.container > * {
38
38
  .ui.button.dropdown,
39
39
  button {
40
40
  border: 1px solid #0000001f;
41
+ margin-bottom: 0;
41
42
  background-color: #fff !important;
42
43
  color: #000;
43
44
  cursor: pointer;
@@ -191,7 +192,7 @@ div#view .site-species-list .species-list .ui.container > * {
191
192
  border-top-right-radius: 10px;
192
193
 
193
194
  @media only screen and (max-width: 767px) {
194
- margin-left: 1rem;
195
+ margin-left: 0.625rem;
195
196
  border-bottom-left-radius: 10px;
196
197
  border-bottom-right-radius: 10;
197
198
  border-top-left-radius: 0;
@@ -12,6 +12,7 @@ const View = (props) => {
12
12
  {mode === 'edit' && !images.length ? <p>Tiles images block</p> : ''}
13
13
  {images.map((image) => (
14
14
  <p
15
+ key={`tile-${image.title}`}
15
16
  className={cx('p-image', {
16
17
  'with-border': data.hasBorder ?? true,
17
18
  'rounded-border': data.rounded ?? true,