@eeacms/volto-n2k 0.1.1

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.
Files changed (233) hide show
  1. package/.coverage.babel.config.js +9 -0
  2. package/.release-it.json +17 -0
  3. package/CHANGELOG.md +155 -0
  4. package/DEVELOP.md +53 -0
  5. package/Jenkinsfile +209 -0
  6. package/LICENSE.md +9 -0
  7. package/README.md +62 -0
  8. package/bootstrap +41 -0
  9. package/cypress/fixtures/example.json +5 -0
  10. package/cypress/integration/block-basics.js +32 -0
  11. package/cypress/plugins/index.js +26 -0
  12. package/cypress/support/commands.js +315 -0
  13. package/cypress/support/index.js +53 -0
  14. package/cypress.json +12 -0
  15. package/jest-addon.config.js +36 -0
  16. package/package.json +57 -0
  17. package/src/actions.js +20 -0
  18. package/src/components/index.js +3 -0
  19. package/src/components/manage/Blocks/BodyClass/Edit.jsx +29 -0
  20. package/src/components/manage/Blocks/BodyClass/View.jsx +13 -0
  21. package/src/components/manage/Blocks/BodyClass/index.js +24 -0
  22. package/src/components/manage/Blocks/BodyClass/schema.js +19 -0
  23. package/src/components/manage/Blocks/BubbleChart/BubbleChart.jsx +101 -0
  24. package/src/components/manage/Blocks/BubbleChart/Chart.jsx +67 -0
  25. package/src/components/manage/Blocks/BubbleChart/ChartContext.jsx +3 -0
  26. package/src/components/manage/Blocks/BubbleChart/View.jsx +63 -0
  27. package/src/components/manage/Blocks/BubbleChart/index.js +17 -0
  28. package/src/components/manage/Blocks/BubbleChart/schema.js +124 -0
  29. package/src/components/manage/Blocks/BubbleChart/style.less +12 -0
  30. package/src/components/manage/Blocks/CarouselHorizontal/HorizontalView.jsx +221 -0
  31. package/src/components/manage/Blocks/CarouselHorizontal/index.js +19 -0
  32. package/src/components/manage/Blocks/CarouselHorizontal/schema.js +32 -0
  33. package/src/components/manage/Blocks/CddaShape/View.jsx +109 -0
  34. package/src/components/manage/Blocks/CddaShape/index.js +23 -0
  35. package/src/components/manage/Blocks/CddaShape/schema.js +19 -0
  36. package/src/components/manage/Blocks/CddaShape/style.less +14 -0
  37. package/src/components/manage/Blocks/ContactBlock/View.jsx +56 -0
  38. package/src/components/manage/Blocks/ContactBlock/icons/domain.svg +1 -0
  39. package/src/components/manage/Blocks/ContactBlock/icons/email.svg +1 -0
  40. package/src/components/manage/Blocks/ContactBlock/icons/location.svg +1 -0
  41. package/src/components/manage/Blocks/ContactBlock/index.js +17 -0
  42. package/src/components/manage/Blocks/ContactBlock/schema.js +57 -0
  43. package/src/components/manage/Blocks/ContactBlock/styles.less +31 -0
  44. package/src/components/manage/Blocks/ExplodedPiesChart/Pie.jsx +125 -0
  45. package/src/components/manage/Blocks/ExplodedPiesChart/View.jsx +80 -0
  46. package/src/components/manage/Blocks/ExplodedPiesChart/index.js +17 -0
  47. package/src/components/manage/Blocks/ExplodedPiesChart/schema.js +75 -0
  48. package/src/components/manage/Blocks/ExplodedPiesChart/style.less +80 -0
  49. package/src/components/manage/Blocks/ExploreHabitats/Edit.jsx +29 -0
  50. package/src/components/manage/Blocks/ExploreHabitats/View.jsx +177 -0
  51. package/src/components/manage/Blocks/ExploreHabitats/index.js +24 -0
  52. package/src/components/manage/Blocks/ExploreHabitats/schema.js +15 -0
  53. package/src/components/manage/Blocks/ExploreHabitats/style.less +15 -0
  54. package/src/components/manage/Blocks/ExploreSites/Edit.jsx +29 -0
  55. package/src/components/manage/Blocks/ExploreSites/View.jsx +175 -0
  56. package/src/components/manage/Blocks/ExploreSites/index.js +24 -0
  57. package/src/components/manage/Blocks/ExploreSites/schema.js +15 -0
  58. package/src/components/manage/Blocks/ExploreSites/style.less +15 -0
  59. package/src/components/manage/Blocks/ExploreSpecies/Edit.jsx +29 -0
  60. package/src/components/manage/Blocks/ExploreSpecies/View.jsx +177 -0
  61. package/src/components/manage/Blocks/ExploreSpecies/index.js +24 -0
  62. package/src/components/manage/Blocks/ExploreSpecies/schema.js +15 -0
  63. package/src/components/manage/Blocks/ExploreSpecies/style.less +15 -0
  64. package/src/components/manage/Blocks/HabitatClassification/View.jsx +30 -0
  65. package/src/components/manage/Blocks/HabitatClassification/index.js +17 -0
  66. package/src/components/manage/Blocks/HabitatClassification/schema.js +19 -0
  67. package/src/components/manage/Blocks/HabitatClassification/style.less +3 -0
  68. package/src/components/manage/Blocks/HabitatDistribution/View.jsx +97 -0
  69. package/src/components/manage/Blocks/HabitatDistribution/index.js +23 -0
  70. package/src/components/manage/Blocks/HabitatDistribution/schema.js +19 -0
  71. package/src/components/manage/Blocks/HabitatDistribution/style.less +5 -0
  72. package/src/components/manage/Blocks/HabitatProtectedSites/View.jsx +97 -0
  73. package/src/components/manage/Blocks/HabitatProtectedSites/index.js +23 -0
  74. package/src/components/manage/Blocks/HabitatProtectedSites/schema.js +19 -0
  75. package/src/components/manage/Blocks/HabitatProtectedSites/style.less +5 -0
  76. package/src/components/manage/Blocks/HabitatsBanner/View.jsx +39 -0
  77. package/src/components/manage/Blocks/HabitatsBanner/index.js +17 -0
  78. package/src/components/manage/Blocks/HabitatsBanner/schema.js +19 -0
  79. package/src/components/manage/Blocks/HabitatsBanner/style.less +49 -0
  80. package/src/components/manage/Blocks/ImageText/Edit.jsx +98 -0
  81. package/src/components/manage/Blocks/ImageText/View.jsx +66 -0
  82. package/src/components/manage/Blocks/ImageText/index.js +24 -0
  83. package/src/components/manage/Blocks/ImageText/schema.js +69 -0
  84. package/src/components/manage/Blocks/ImageText/styles.less +87 -0
  85. package/src/components/manage/Blocks/Landing/DefalutView.jsx +83 -0
  86. package/src/components/manage/Blocks/Landing/Edit.jsx +219 -0
  87. package/src/components/manage/Blocks/Landing/EditBlockWrapper.jsx +161 -0
  88. package/src/components/manage/Blocks/Landing/View.jsx +65 -0
  89. package/src/components/manage/Blocks/Landing/images/background.webp +0 -0
  90. package/src/components/manage/Blocks/Landing/images/coasts_and_seas.webp +0 -0
  91. package/src/components/manage/Blocks/Landing/images/forests.webp +0 -0
  92. package/src/components/manage/Blocks/Landing/images/grasslands.webp +0 -0
  93. package/src/components/manage/Blocks/Landing/images/hiker.webp +0 -0
  94. package/src/components/manage/Blocks/Landing/images/islands.webp +0 -0
  95. package/src/components/manage/Blocks/Landing/images/mountains.webp +0 -0
  96. package/src/components/manage/Blocks/Landing/images/natura2000.webp +0 -0
  97. package/src/components/manage/Blocks/Landing/images/natura2000_square.webp +0 -0
  98. package/src/components/manage/Blocks/Landing/images/peatlands.webp +0 -0
  99. package/src/components/manage/Blocks/Landing/images/people_and_nature.webp +0 -0
  100. package/src/components/manage/Blocks/Landing/images/rivers.webp +0 -0
  101. package/src/components/manage/Blocks/Landing/index.js +104 -0
  102. package/src/components/manage/Blocks/Landing/schema.js +62 -0
  103. package/src/components/manage/Blocks/Landing/style.less +174 -0
  104. package/src/components/manage/Blocks/List/View.jsx +37 -0
  105. package/src/components/manage/Blocks/List/index.js +17 -0
  106. package/src/components/manage/Blocks/List/schema.js +49 -0
  107. package/src/components/manage/Blocks/List/style.less +12 -0
  108. package/src/components/manage/Blocks/NavigationAnchors/Edit.jsx +33 -0
  109. package/src/components/manage/Blocks/NavigationAnchors/View.jsx +132 -0
  110. package/src/components/manage/Blocks/NavigationAnchors/assets/external.png +0 -0
  111. package/src/components/manage/Blocks/NavigationAnchors/index.js +23 -0
  112. package/src/components/manage/Blocks/NavigationAnchors/schema.js +76 -0
  113. package/src/components/manage/Blocks/NavigationAnchors/styles.less +104 -0
  114. package/src/components/manage/Blocks/SimpleDataTable/index.js +16 -0
  115. package/src/components/manage/Blocks/SimpleDataTable/templates/colored/View.jsx +178 -0
  116. package/src/components/manage/Blocks/SimpleDataTable/templates/colored/index.js +4 -0
  117. package/src/components/manage/Blocks/SimpleDataTable/templates/colored/schema.js +56 -0
  118. package/src/components/manage/Blocks/SimpleDataTable/templates/colored/style.less +54 -0
  119. package/src/components/manage/Blocks/SiteBanner/View.jsx +148 -0
  120. package/src/components/manage/Blocks/SiteBanner/index.js +17 -0
  121. package/src/components/manage/Blocks/SiteBanner/schema.js +19 -0
  122. package/src/components/manage/Blocks/SiteBanner/style.less +106 -0
  123. package/src/components/manage/Blocks/SiteHabitatsList/View.jsx +89 -0
  124. package/src/components/manage/Blocks/SiteHabitatsList/index.js +17 -0
  125. package/src/components/manage/Blocks/SiteHabitatsList/schema.js +19 -0
  126. package/src/components/manage/Blocks/SiteHabitatsList/style.less +70 -0
  127. package/src/components/manage/Blocks/SiteProtectedHabitats/View.jsx +47 -0
  128. package/src/components/manage/Blocks/SiteProtectedHabitats/images/background.webp +0 -0
  129. package/src/components/manage/Blocks/SiteProtectedHabitats/index.js +17 -0
  130. package/src/components/manage/Blocks/SiteProtectedHabitats/schema.js +19 -0
  131. package/src/components/manage/Blocks/SiteProtectedHabitats/style.less +90 -0
  132. package/src/components/manage/Blocks/SiteProtectedSpecies/View.jsx +55 -0
  133. package/src/components/manage/Blocks/SiteProtectedSpecies/images/background.webp +0 -0
  134. package/src/components/manage/Blocks/SiteProtectedSpecies/index.js +17 -0
  135. package/src/components/manage/Blocks/SiteProtectedSpecies/schema.js +19 -0
  136. package/src/components/manage/Blocks/SiteProtectedSpecies/style.less +90 -0
  137. package/src/components/manage/Blocks/SiteShape/View.jsx +107 -0
  138. package/src/components/manage/Blocks/SiteShape/index.js +23 -0
  139. package/src/components/manage/Blocks/SiteShape/schema.js +19 -0
  140. package/src/components/manage/Blocks/SiteShape/style.less +15 -0
  141. package/src/components/manage/Blocks/SiteSpeciesList/Filters/SortBy.jsx +52 -0
  142. package/src/components/manage/Blocks/SiteSpeciesList/Filters/SpeciesGroups.jsx +43 -0
  143. package/src/components/manage/Blocks/SiteSpeciesList/Filters/View.jsx +200 -0
  144. package/src/components/manage/Blocks/SiteSpeciesList/Filters/index.js +4 -0
  145. package/src/components/manage/Blocks/SiteSpeciesList/View.jsx +253 -0
  146. package/src/components/manage/Blocks/SiteSpeciesList/index.js +17 -0
  147. package/src/components/manage/Blocks/SiteSpeciesList/schema.js +19 -0
  148. package/src/components/manage/Blocks/SiteSpeciesList/style.less +264 -0
  149. package/src/components/manage/Blocks/SiteSpeciesList/utils.js +33 -0
  150. package/src/components/manage/Blocks/SlateLink/render.jsx +77 -0
  151. package/src/components/manage/Blocks/SlateLink/styles.less +22 -0
  152. package/src/components/manage/Blocks/SlateSVG/constants.js +1 -0
  153. package/src/components/manage/Blocks/SlateSVG/extensions.js +11 -0
  154. package/src/components/manage/Blocks/SlateSVG/index.js +47 -0
  155. package/src/components/manage/Blocks/SlateSVG/render.jsx +42 -0
  156. package/src/components/manage/Blocks/SlateSVG/schema.js +12 -0
  157. package/src/components/manage/Blocks/SlateSVG/styles.less +6 -0
  158. package/src/components/manage/Blocks/SpeciesBanner/View.jsx +109 -0
  159. package/src/components/manage/Blocks/SpeciesBanner/index.js +17 -0
  160. package/src/components/manage/Blocks/SpeciesBanner/schema.js +19 -0
  161. package/src/components/manage/Blocks/SpeciesBanner/style.less +115 -0
  162. package/src/components/manage/Blocks/SpeciesClassification/View.jsx +19 -0
  163. package/src/components/manage/Blocks/SpeciesClassification/index.js +17 -0
  164. package/src/components/manage/Blocks/SpeciesClassification/schema.js +19 -0
  165. package/src/components/manage/Blocks/SpeciesClassification/style.less +3 -0
  166. package/src/components/manage/Blocks/SpeciesDistribution/View.jsx +97 -0
  167. package/src/components/manage/Blocks/SpeciesDistribution/index.js +23 -0
  168. package/src/components/manage/Blocks/SpeciesDistribution/schema.js +19 -0
  169. package/src/components/manage/Blocks/SpeciesDistribution/style.less +5 -0
  170. package/src/components/manage/Blocks/SpeciesProtectedSites/View.jsx +97 -0
  171. package/src/components/manage/Blocks/SpeciesProtectedSites/index.js +23 -0
  172. package/src/components/manage/Blocks/SpeciesProtectedSites/schema.js +19 -0
  173. package/src/components/manage/Blocks/SpeciesProtectedSites/style.less +5 -0
  174. package/src/components/manage/Blocks/StackedBarChart/Chart.jsx +127 -0
  175. package/src/components/manage/Blocks/StackedBarChart/ChartContext.jsx +3 -0
  176. package/src/components/manage/Blocks/StackedBarChart/StackedBars.jsx +116 -0
  177. package/src/components/manage/Blocks/StackedBarChart/View.jsx +64 -0
  178. package/src/components/manage/Blocks/StackedBarChart/index.js +17 -0
  179. package/src/components/manage/Blocks/StackedBarChart/schema.js +25 -0
  180. package/src/components/manage/Blocks/StackedBarChart/style.less +37 -0
  181. package/src/components/manage/Blocks/TilesImages/Edit.jsx +32 -0
  182. package/src/components/manage/Blocks/TilesImages/View.jsx +37 -0
  183. package/src/components/manage/Blocks/TilesImages/index.js +23 -0
  184. package/src/components/manage/Blocks/TilesImages/schema.js +72 -0
  185. package/src/components/manage/Blocks/TilesImages/styles.less +57 -0
  186. package/src/components/theme/AppExtras/CopyPaste/CopyPaste.jsx +176 -0
  187. package/src/components/theme/AppExtras/CopyPaste/index.js +3 -0
  188. package/src/components/theme/AppExtras/CopyPaste/style.less +18 -0
  189. package/src/components/theme/AppExtras/MultilingualRedirector/MultilingualRedirector.jsx +35 -0
  190. package/src/components/theme/AppExtras/index.js +13 -0
  191. package/src/components/theme/Footer/Footer.jsx +209 -0
  192. package/src/components/theme/Header/Header.jsx +81 -0
  193. package/src/components/theme/LanguageSelector/LanguageSelector.jsx +79 -0
  194. package/src/components/theme/LanguageSelector/styles.less +44 -0
  195. package/src/components/theme/Navigation/Navigation.jsx +453 -0
  196. package/src/components/theme/Sitemap/Sitemap.jsx +152 -0
  197. package/src/fonts/OpenSans-Bold.ttf +0 -0
  198. package/src/fonts/OpenSans-Regular.ttf +0 -0
  199. package/src/fonts/OpenSans-Semibold.ttf +0 -0
  200. package/src/fonts/Rajdhani-Bold.ttf +0 -0
  201. package/src/fonts/Rajdhani-Regular.ttf +0 -0
  202. package/src/grid.js +78 -0
  203. package/src/helpers.js +148 -0
  204. package/src/hocs/index.js +6 -0
  205. package/src/hocs/useResizeObserver.jsx +26 -0
  206. package/src/hocs/withLocalStorage.jsx +37 -0
  207. package/src/hocs/withScreenSize.jsx +43 -0
  208. package/src/icons/home.svg +12 -0
  209. package/src/icons/info.svg +5 -0
  210. package/src/icons/n2k-logo-transparent.png +0 -0
  211. package/src/icons/n2k-logo.png +0 -0
  212. package/src/icons/natura2000.svg +142 -0
  213. package/src/icons/placeholders/Algae.png +0 -0
  214. package/src/icons/placeholders/Amphibians.png +0 -0
  215. package/src/icons/placeholders/Birds.png +0 -0
  216. package/src/icons/placeholders/Conifers.png +0 -0
  217. package/src/icons/placeholders/Fishes.png +0 -0
  218. package/src/icons/placeholders/Fungi.png +0 -0
  219. package/src/icons/placeholders/Mammals.png +0 -0
  220. package/src/icons/placeholders/Plants.png +0 -0
  221. package/src/icons/placeholders/Reptiles.png +0 -0
  222. package/src/icons/placeholders/default.png +0 -0
  223. package/src/index.js +163 -0
  224. package/src/less/globals.less +3 -0
  225. package/src/less/styles.less +691 -0
  226. package/src/less/variables.less +2 -0
  227. package/src/static/cca.svg +61 -0
  228. package/src/static/ec.png +0 -0
  229. package/src/static/eea.png +0 -0
  230. package/src/static/eu.jpg +0 -0
  231. package/src/static/forest.svg +100 -0
  232. package/src/static/wise.png +0 -0
  233. package/src/store.js +24 -0
@@ -0,0 +1,176 @@
1
+ import React from 'react';
2
+ import { connect } from 'react-redux';
3
+ import { compose } from 'redux';
4
+ import { Portal } from 'react-portal';
5
+ import { toast } from 'react-toastify';
6
+ import { Button } from 'semantic-ui-react';
7
+ import { getBaseUrl } from '@plone/volto/helpers';
8
+ import { updateContent } from '@plone/volto/actions';
9
+ import { Icon, Toast } from '@plone/volto/components';
10
+ import copySVG from '@plone/volto/icons/copy.svg';
11
+ import pasteSVG from '@plone/volto/icons/paste.svg';
12
+
13
+ import './style.less';
14
+
15
+ const TIMEOUT = 2000;
16
+
17
+ const CopyPaste = (props) => {
18
+ const [readyToRender, setReadyToRender] = React.useState(false);
19
+ const clock = React.useRef(null);
20
+ const time = React.useRef(0);
21
+ const toolbar = React.useRef(null);
22
+ const { content } = props;
23
+
24
+ const copyData = () => {
25
+ navigator.clipboard.writeText(
26
+ JSON.stringify({
27
+ blocks: content.blocks,
28
+ blocks_layout: content.blocks_layout,
29
+ }),
30
+ );
31
+ toast.success(
32
+ <Toast success title={'Success'} content={`Copied blocks`} />,
33
+ );
34
+ };
35
+
36
+ const pasteData = () => {
37
+ const message = [
38
+ '============= BRAKING CHANGE =============',
39
+ '\nAre you sure you want to paste from clipboard?',
40
+ '\nThis action will replace all the blocks with those from clipboard and will trigger SUBMIT !!!',
41
+ ];
42
+ navigator.clipboard.readText().then((text) => {
43
+ if (
44
+ // eslint-disable-next-line no-alert
45
+ window.confirm(message.join(''))
46
+ ) {
47
+ try {
48
+ const data = JSON.parse(text) || {};
49
+ const { blocks = {}, blocks_layout = {} } = data;
50
+ const blocksIds = Object.keys(blocks);
51
+ let valid = true;
52
+ if (
53
+ blocks_layout &&
54
+ blocks_layout.items &&
55
+ blocks_layout.items.length === blocksIds.length
56
+ ) {
57
+ blocks_layout.items.forEach((block) => {
58
+ if (valid && !blocksIds.includes(block)) {
59
+ valid = false;
60
+ }
61
+ });
62
+ }
63
+ if (valid) {
64
+ props.updateContent(getBaseUrl(props.pathname), data);
65
+ toast.success(
66
+ <Toast
67
+ success
68
+ title={'Success'}
69
+ content={'Blocks replaced successfully'}
70
+ />,
71
+ );
72
+ } else {
73
+ toast.error(
74
+ <Toast
75
+ error
76
+ title={'Error'}
77
+ content={'Your clipboard contains incompatible data'}
78
+ />,
79
+ );
80
+ }
81
+ } catch {
82
+ toast.error(
83
+ <Toast
84
+ error
85
+ title={'Error'}
86
+ content={'Your clipboard contains incompatible data'}
87
+ />,
88
+ );
89
+ }
90
+ }
91
+ });
92
+ };
93
+
94
+ React.useEffect(() => {
95
+ clock.current = setInterval(() => {
96
+ const element = document.querySelector('#toolbar .toolbar-actions');
97
+ if (element) {
98
+ setReadyToRender(true);
99
+ clearInterval(clock.current);
100
+ time.current = 0;
101
+ return;
102
+ }
103
+ if (time.current >= TIMEOUT) {
104
+ clearInterval(clock.current);
105
+ time.current = 0;
106
+ return;
107
+ }
108
+ time.current += 100;
109
+ }, 100);
110
+ return () => {
111
+ clearInterval(clock.current);
112
+ time.current = 0;
113
+ };
114
+ }, []);
115
+
116
+ if (!__CLIENT__ || !readyToRender) return '';
117
+
118
+ return (
119
+ <Portal node={document.querySelector('#toolbar .toolbar-actions')}>
120
+ <div
121
+ ref={toolbar}
122
+ id="__developer_tools"
123
+ onMouseEnter={(e) => {
124
+ if (
125
+ e.altKey &&
126
+ e.ctrlKey &&
127
+ toolbar.current &&
128
+ !toolbar.current.classList.contains('__dev_on')
129
+ ) {
130
+ toolbar.current.classList.add('__dev_on');
131
+ }
132
+ }}
133
+ onMouseLeave={(e) => {
134
+ if (
135
+ toolbar.current &&
136
+ toolbar.current.classList.contains('__dev_on')
137
+ ) {
138
+ toolbar.current.classList.remove('__dev_on');
139
+ }
140
+ }}
141
+ onFocus={() => {}}
142
+ >
143
+ <Button
144
+ className="copy"
145
+ aria-label="Copy blocks data"
146
+ title="Copy blocks data"
147
+ onClick={copyData}
148
+ >
149
+ <Icon name={copySVG} className="circled" size="30px" />
150
+ </Button>
151
+ <Button
152
+ className="paste"
153
+ aria-label="Paste blocks data"
154
+ title="Paste blocks data"
155
+ onClick={pasteData}
156
+ disabled={props.updateRequest.loading}
157
+ >
158
+ <Icon name={pasteSVG} className="circled" size="30px" />
159
+ </Button>
160
+ </div>
161
+ </Portal>
162
+ );
163
+ };
164
+
165
+ export default compose(
166
+ connect(
167
+ (state, props) => ({
168
+ content: state.content.data,
169
+ updateRequest: state.content.update,
170
+ pathname: props.location.pathname,
171
+ }),
172
+ {
173
+ updateContent,
174
+ },
175
+ ),
176
+ )(CopyPaste);
@@ -0,0 +1,3 @@
1
+ import CopyPaste from './CopyPaste';
2
+
3
+ export default CopyPaste;
@@ -0,0 +1,18 @@
1
+ #__developer_tools {
2
+ .ui.button {
3
+ color: #007eb1;
4
+ opacity: 0;
5
+ pointer-events: none;
6
+
7
+ &.disabled {
8
+ opacity: 0 !important;
9
+ }
10
+ }
11
+
12
+ &.__dev_on {
13
+ .ui.button {
14
+ opacity: 1;
15
+ pointer-events: all;
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,35 @@
1
+ import React from 'react';
2
+ import { Redirect } from 'react-router-dom';
3
+ import { useDispatch } from 'react-redux';
4
+ import cookie from 'react-cookie';
5
+ import config from '@plone/volto/registry';
6
+ import { changeLanguage } from '@plone/volto/actions';
7
+
8
+ const MultilingualRedirector = (props) => {
9
+ const { settings } = config;
10
+ const { pathname, children } = props;
11
+ const currentLanguage =
12
+ cookie.load('N2K_LANGUAGE') || settings.defaultLanguage;
13
+ const redirectToLanguage = settings.supportedLanguages.includes(
14
+ currentLanguage,
15
+ )
16
+ ? currentLanguage
17
+ : settings.defaultLanguage;
18
+ const dispatch = useDispatch();
19
+
20
+ React.useEffect(() => {
21
+ if (settings.isMultilingual && pathname === '/') {
22
+ import('~/../locales/' + redirectToLanguage + '.json').then((locale) => {
23
+ dispatch(changeLanguage(redirectToLanguage, locale.default));
24
+ });
25
+ }
26
+ }, [pathname, dispatch, redirectToLanguage, settings.isMultilingual]);
27
+
28
+ return pathname === '/' && settings.isMultilingual ? (
29
+ <Redirect to={`/${redirectToLanguage}`} />
30
+ ) : (
31
+ <>{children}</>
32
+ );
33
+ };
34
+
35
+ export default MultilingualRedirector;
@@ -0,0 +1,13 @@
1
+ import CopyPaste from './CopyPaste';
2
+
3
+ export default (config) => {
4
+ config.settings.appExtras = [
5
+ ...(config.settings.appExtras || []),
6
+ {
7
+ match: '/**/edit',
8
+ component: CopyPaste,
9
+ },
10
+ ];
11
+
12
+ return config;
13
+ };
@@ -0,0 +1,209 @@
1
+ /* eslint-disable react/jsx-no-target-blank */
2
+ /**
3
+ * Footer component.
4
+ * @module components/theme/Footer/Footer
5
+ */
6
+
7
+ import React from 'react';
8
+ import { Container, Segment, Grid } from 'semantic-ui-react';
9
+ import { Link } from 'react-router-dom';
10
+ import { FormattedMessage, injectIntl } from 'react-intl';
11
+ import LogoImage from '@plone/volto/components/theme/Logo/Logo.svg';
12
+
13
+ import { LazyLoadImage } from 'react-lazy-load-image-component';
14
+
15
+ import ecLogo from '../../../static/ec.png';
16
+ import eeaLogo from '../../../static/eea.png';
17
+ import fiseLogo from '../../../static/forest.svg';
18
+ import ccaLogo from '../../../static/cca.svg';
19
+ import wiseLogo from '../../../static/wise.png';
20
+
21
+ // const messages = defineMessages({
22
+ // copyright: {
23
+ // id: 'Copyright',
24
+ // defaultMessage: 'Copyright',
25
+ // },
26
+ // });
27
+
28
+ /**
29
+ * Component to display the footer.
30
+ * @function Footer
31
+ * @param {Object} intl Intl object
32
+ * @returns {string} Markup of the component
33
+ */
34
+ const Footer = ({ intl }) => (
35
+ <Segment role="contentinfo" vertical padded className="footerWrapper">
36
+ <Container>
37
+ <div className="footer-top-wrapper">
38
+ <Grid stackable>
39
+ <Grid.Row>
40
+ <Grid.Column mobile={16} tablet={10} computer={10}>
41
+ <ul className="footer-nav" id="footer_links">
42
+ <li>
43
+ <Link className="item" to="/natura2000">
44
+ <FormattedMessage id="home" defaultMessage="Home" />
45
+ </Link>
46
+ </li>
47
+ <li>
48
+ <a className="item" href={`mailto:bise@eea.europa.eu`}>
49
+ Contact
50
+ </a>
51
+ </li>
52
+ <li>
53
+ <Link className="item" to="/natura2000/sitemap">
54
+ <FormattedMessage id="sitemap" defaultMessage="Sitemap" />
55
+ </Link>
56
+ </li>
57
+ <li>
58
+ <Link
59
+ className="item"
60
+ to="/natura2000/legal-and-privacy-notice"
61
+ >
62
+ <FormattedMessage
63
+ id="legal_notice"
64
+ defaultMessage="Privacy and legal notice"
65
+ />
66
+ </Link>
67
+ </li>
68
+ <li>
69
+ <Link className="item" to="/natura2000/copyright-notice">
70
+ <FormattedMessage
71
+ id="copyright_notice"
72
+ defaultMessage="Copyright notice"
73
+ />
74
+ </Link>
75
+ </li>
76
+ </ul>
77
+ </Grid.Column>
78
+ <Grid.Column mobile={16} tablet={2} computer={2}>
79
+ <Link to="/">
80
+ <img
81
+ className="bise-footer"
82
+ src={LogoImage}
83
+ alt="BISE"
84
+ height={50}
85
+ width={150}
86
+ />
87
+ </Link>
88
+ </Grid.Column>
89
+ </Grid.Row>
90
+ </Grid>
91
+ </div>
92
+
93
+ <div className="site-info">
94
+ <Grid stackable>
95
+ <Grid.Row>
96
+ <Grid.Column
97
+ mobile={16}
98
+ tablet={16}
99
+ computer={5}
100
+ className="information"
101
+ >
102
+ <div>
103
+ <p>
104
+ The Biodiversity information system for Europe is a
105
+ partnership between the{' '}
106
+ <a
107
+ href="https://ec.europa.eu/"
108
+ target="_blank"
109
+ rel="noopener"
110
+ >
111
+ European Commission
112
+ </a>{' '}
113
+ and the{' '}
114
+ <a
115
+ href="https://www.eea.europa.eu/"
116
+ target="_blank"
117
+ rel="noopener"
118
+ >
119
+ European Environment Agency.
120
+ </a>
121
+ </p>{' '}
122
+ </div>
123
+ <div className="site-info-logos">
124
+ <a href="https://ec.europa.eu/" aria-label="European Comission">
125
+ <LazyLoadImage
126
+ className="footerLogo"
127
+ src={ecLogo}
128
+ title="European Commission"
129
+ alt="European Commission"
130
+ />
131
+ </a>
132
+ <a
133
+ href="https://www.eea.europa.eu/"
134
+ aria-label="European Environment Agency"
135
+ >
136
+ <LazyLoadImage
137
+ className="footerLogo"
138
+ src={eeaLogo}
139
+ title="European Environment Agency"
140
+ alt="European Environment Agency"
141
+ />
142
+ </a>
143
+ </div>
144
+ </Grid.Column>
145
+
146
+ <Grid.Column
147
+ mobile={16}
148
+ tablet={16}
149
+ computer={7}
150
+ className="other-information"
151
+ >
152
+ <div>
153
+ <p>Other European Information Systems</p>
154
+ </div>
155
+ <div className="footerLogos">
156
+ <a
157
+ href="https://water.europa.eu/"
158
+ aria-label="Water Information System for Europe"
159
+ >
160
+ <LazyLoadImage
161
+ className="footerLogo"
162
+ src={wiseLogo}
163
+ title="Water Information System for Europe"
164
+ alt="Water Information System for Europe"
165
+ />
166
+ </a>
167
+ <a
168
+ href="https://forest.eea.europa.eu/"
169
+ aria-label="Forest Information System for Europe"
170
+ >
171
+ <LazyLoadImage
172
+ className="footerLogo"
173
+ src={fiseLogo}
174
+ title="Forest Information System for Europe"
175
+ alt="Forest Information System for Europe"
176
+ />
177
+ </a>
178
+ <a
179
+ href="https://climate-adapt.eea.europa.eu/"
180
+ aria-label="Climate-Adapt"
181
+ >
182
+ <LazyLoadImage
183
+ className="footerLogo"
184
+ src={ccaLogo}
185
+ title="Climate-Adapt"
186
+ alt="Climate-Adapt"
187
+ />
188
+ </a>
189
+ </div>
190
+ </Grid.Column>
191
+ </Grid.Row>
192
+ </Grid>
193
+ </div>
194
+ </Container>
195
+ </Segment>
196
+ );
197
+
198
+ /**
199
+ * Property types.
200
+ * @property {Object} propTypes Property types.
201
+ * @static
202
+ */
203
+ Footer.propTypes = {
204
+ /**
205
+ * i18n object
206
+ */
207
+ };
208
+
209
+ export default injectIntl(Footer);
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Header component.
3
+ * @module components/theme/Header/Header
4
+ */
5
+
6
+ import React, { useEffect, useContext } from 'react';
7
+ import { withRouter } from 'react-router';
8
+ import { Container, Sticky } from 'semantic-ui-react';
9
+ import { connect } from 'react-redux';
10
+ import { Portal } from 'react-portal';
11
+ import config from '@plone/volto/registry';
12
+ import { Anontools } from '@plone/volto/components';
13
+ import { withLocalStorage } from '@eeacms/volto-n2k/hocs';
14
+ import Navigation from '../Navigation/Navigation';
15
+ import { StickyContext } from '~/components';
16
+
17
+ const Navbar = (props) => {
18
+ const currentLang = props.localStorage.get('N2K_LANGUAGE');
19
+
20
+ return (
21
+ <Container>
22
+ <div className="header-wrapper">
23
+ <div className="header">
24
+ <div className="logo-nav-wrapper">
25
+ <div className="tools-search-wrapper">
26
+ {currentLang ? (
27
+ <Navigation
28
+ isSticky={props.isSticky}
29
+ pathname={props.pathname}
30
+ />
31
+ ) : (
32
+ ''
33
+ )}
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </div>
38
+ {!props.token && (
39
+ <Portal node={__CLIENT__ && document.querySelector('#footer_links')}>
40
+ <Anontools />
41
+ </Portal>
42
+ )}
43
+ </Container>
44
+ );
45
+ };
46
+
47
+ const Header = (props) => {
48
+ const [isSticky, setIsSticky] = React.useState(false);
49
+ const { stickyRef } = useContext(StickyContext);
50
+
51
+ useEffect(() => {
52
+ if (!props.localStorage.get('N2K_LANGUAGE')) {
53
+ props.localStorage.set('N2K_LANGUAGE', config.settings.defaultLanguage);
54
+ }
55
+ /* eslint-disable-next-line */
56
+ }, []);
57
+
58
+ return props.location.pathname === '/natura2000' ? (
59
+ ''
60
+ ) : (
61
+ <>
62
+ <Sticky
63
+ context={stickyRef}
64
+ className="ui basic segment sticky-header-wrapper"
65
+ role="banner"
66
+ onStick={() => {
67
+ setIsSticky(true);
68
+ }}
69
+ onUnstick={() => {
70
+ setIsSticky(false);
71
+ }}
72
+ >
73
+ <Navbar {...props} isSticky={isSticky} />
74
+ </Sticky>
75
+ </>
76
+ );
77
+ };
78
+
79
+ export default connect((state) => ({
80
+ token: state.userSession.token,
81
+ }))(withRouter(withLocalStorage(Header)));
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Language selector component.
3
+ * @module components/LanguageSelector/LanguageSelector
4
+ */
5
+
6
+ import React from 'react';
7
+ import { withRouter, matchPath, generatePath } from 'react-router';
8
+ import { useSelector } from 'react-redux';
9
+ // import langmap from 'langmap';
10
+ import { flattenToAppURL } from '@plone/volto/helpers';
11
+ import { Dropdown } from 'semantic-ui-react';
12
+ import config from '@plone/volto/registry';
13
+ import { withLocalStorage } from '@eeacms/volto-n2k/hocs';
14
+ import { getN2kItems, pathExists } from '@eeacms/volto-n2k/helpers';
15
+ import './styles.less';
16
+
17
+ const LanguageSelector = (props) => {
18
+ const content = useSelector((state) => state.content);
19
+ const n2kItems = getN2kItems(props.navigation.items);
20
+ const localStorage = props.localStorage;
21
+ const pathname = props.location.pathname;
22
+ const currentLang = localStorage.get('N2K_LANGUAGE');
23
+ const match = matchPath(pathname, {
24
+ path: config.settings.multilingualPath,
25
+ exact: true,
26
+ strict: false,
27
+ });
28
+ const hasMultilingualSupport =
29
+ match && config.settings.supportedLanguages.includes(match.params.lang);
30
+ const translations = hasMultilingualSupport
31
+ ? config.settings.supportedLanguages.map((lang) => ({
32
+ path: generatePath(config.settings.multilingualPath, {
33
+ ...match.params,
34
+ lang,
35
+ }),
36
+ lang,
37
+ }))
38
+ : [];
39
+ const { settings } = config;
40
+ const supportedLanguagesOptions = settings.supportedLanguages.map((lang) => ({
41
+ key: lang,
42
+ value: lang,
43
+ text: lang,
44
+ }));
45
+
46
+ return (
47
+ <div className="language-selector">
48
+ <Dropdown
49
+ aria-label="Language selector"
50
+ disabled={content.get.loading}
51
+ placeholder="Select a language"
52
+ value={currentLang}
53
+ scrolling
54
+ options={supportedLanguagesOptions}
55
+ onChange={(e, data) => {
56
+ const lang = data.value;
57
+ const translation = translations.filter(
58
+ (item) => item.lang === lang,
59
+ )[0];
60
+
61
+ if (translation && translation.path) {
62
+ const exists = pathExists(translation.path, n2kItems);
63
+ if (exists) {
64
+ props.history.push(flattenToAppURL(translation.path));
65
+ } else {
66
+ props.history.push('/natura2000');
67
+ }
68
+ }
69
+
70
+ if (config.settings.supportedLanguages.includes(lang)) {
71
+ localStorage.set('N2K_LANGUAGE', lang);
72
+ }
73
+ }}
74
+ />
75
+ </div>
76
+ );
77
+ };
78
+
79
+ export default withRouter(withLocalStorage(LanguageSelector));
@@ -0,0 +1,44 @@
1
+ .language-selector {
2
+ .ui.dropdown {
3
+ &:not(.button) .text,
4
+ &:not(.button) .default.text {
5
+ color: #3b7f02;
6
+ font-family: OpenSans, 'Raleway', sans-serif;
7
+ text-transform: uppercase;
8
+
9
+ &:hover {
10
+ color: #7ac943;
11
+ }
12
+ }
13
+
14
+ .menu {
15
+ margin-top: 0.5rem;
16
+ margin-left: -0.6rem;
17
+
18
+ .item {
19
+ background: #fff !important;
20
+
21
+ .text {
22
+ color: #3b7f02;
23
+ font-family: OpenSans, 'Raleway', sans-serif;
24
+ font-size: 1rem;
25
+ font-weight: bold;
26
+ text-transform: uppercase;
27
+ }
28
+
29
+ &.active.selected {
30
+ background: #fff !important;
31
+
32
+ .text {
33
+ color: #3b7f02;
34
+ }
35
+
36
+ &::before {
37
+ display: none !important;
38
+ opacity: 0;
39
+ }
40
+ }
41
+ }
42
+ }
43
+ }
44
+ }