@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,253 @@
1
+ import React from 'react';
2
+ import { Link } from 'react-router-dom';
3
+ import { Container, Pagination, Grid } from 'semantic-ui-react';
4
+ import { getObjectByIndex } from '@eeacms/volto-n2k/helpers';
5
+ import { Filters } from './Filters';
6
+ import { photoPlaceholders } from '@eeacms/volto-n2k/helpers';
7
+ import { getPopulationString, getLabelString } from './utils';
8
+
9
+ import './style.less';
10
+
11
+ const getCurrentPageLength = (pagination, arr) => {
12
+ const totalPages = Math.ceil(pagination.totalItems / pagination.itemsPerPage);
13
+ if (arr.length < pagination.itemsPerPage) return arr.length;
14
+ if (totalPages === pagination.activePage) {
15
+ return arr.length - (pagination.activePage - 1) * pagination.itemsPerPage;
16
+ }
17
+ return pagination.itemsPerPage;
18
+ };
19
+
20
+ const View = (props) => {
21
+ const {
22
+ provider_data = {},
23
+ placeholder = 'This site does not host any protected species',
24
+ } = props;
25
+ const dataReady = React.useRef(false);
26
+ const [activeSpeciesGroup, setActiveSpeciesGroup] = React.useState('All');
27
+ const [filters, setFilters] = React.useState({});
28
+ const [species, setSpecies] = React.useState([]);
29
+ const [filteredSpecies, setFilteredSpecies] = React.useState([]);
30
+ const [pagination, setPagination] = React.useState({
31
+ activePage: 1,
32
+ totalItems: 0,
33
+ itemsPerPage: 10,
34
+ });
35
+ const [sortBy, setSortBy] = React.useState(['scientific_name', 'ASC']);
36
+
37
+ const getSortedSpecies = (species = []) => {
38
+ const property = sortBy[0];
39
+ const order = sortBy[1];
40
+
41
+ return species.sort((a, b) => {
42
+ const a_value = a[0][property];
43
+ const b_value = b[0][property];
44
+ if (a_value < b_value) return order === 'ASC' ? -1 : 1;
45
+ if (a_value > b_value) return order === 'ASC' ? 1 : -1;
46
+ return 0;
47
+ });
48
+ };
49
+
50
+ const getFilteredSpecies = (species = []) => {
51
+ const activeFilters = {
52
+ ...filters,
53
+ ...(activeSpeciesGroup !== 'All'
54
+ ? { species_group_name: [activeSpeciesGroup] }
55
+ : {}),
56
+ };
57
+
58
+ const filteredSpecies = species.filter((items, index) => {
59
+ let itemsHaveFilter = true;
60
+ Object.keys(activeFilters).forEach((filter) => {
61
+ let specimenHasFilter = false;
62
+ items.forEach((item) => {
63
+ if (activeFilters[filter].includes(item[filter])) {
64
+ specimenHasFilter = true;
65
+ }
66
+ });
67
+ if (!specimenHasFilter) {
68
+ itemsHaveFilter = false;
69
+ }
70
+ });
71
+ return itemsHaveFilter;
72
+ });
73
+
74
+ setPagination({
75
+ ...pagination,
76
+ activePage: 1,
77
+ totalItems: filteredSpecies.length,
78
+ });
79
+
80
+ return filteredSpecies;
81
+ };
82
+
83
+ React.useEffect(() => {
84
+ dataReady.current = false;
85
+ const speciesIndex = {};
86
+ const newSpecies = [];
87
+ if (provider_data.scientific_name?.length) {
88
+ provider_data.scientific_name.forEach((_, index) => {
89
+ const specimen = getObjectByIndex(provider_data, index);
90
+ if (!(speciesIndex[specimen.id_eunis] >= 0)) {
91
+ speciesIndex[specimen.id_eunis] = index;
92
+ }
93
+ if (!newSpecies[speciesIndex[specimen.id_eunis]]) {
94
+ newSpecies[speciesIndex[specimen.id_eunis]] = [];
95
+ }
96
+ newSpecies[speciesIndex[specimen.id_eunis]].push(specimen);
97
+ });
98
+ }
99
+ setSpecies(getSortedSpecies(newSpecies.filter((species) => species)));
100
+ /* eslint-disable-next-line */
101
+ }, [JSON.stringify(provider_data)]);
102
+
103
+ React.useEffect(() => {
104
+ const filteredSpecies = getSortedSpecies(getFilteredSpecies([...species]));
105
+ setFilteredSpecies(filteredSpecies);
106
+ /* eslint-disable-next-line */
107
+ }, [species, sortBy, activeSpeciesGroup, filters]);
108
+
109
+ return (
110
+ <div className="site-species-list full-width">
111
+ {props.mode !== 'edit' && species.length ? (
112
+ <Filters
113
+ {...props}
114
+ activeSpeciesGroup={activeSpeciesGroup}
115
+ activeFilters={filters}
116
+ filteredSpecies={filteredSpecies}
117
+ pagination={pagination}
118
+ sortBy={sortBy}
119
+ species={species}
120
+ setActiveSpeciesGroup={setActiveSpeciesGroup}
121
+ setActiveFilters={setFilters}
122
+ setPagination={setPagination}
123
+ setSortBy={setSortBy}
124
+ />
125
+ ) : (
126
+ ''
127
+ )}
128
+
129
+ <div className="species-list">
130
+ <Container>
131
+ {filteredSpecies.length ? (
132
+ Array.from(
133
+ {
134
+ length: getCurrentPageLength(pagination, filteredSpecies),
135
+ },
136
+ (v, k) =>
137
+ k + (pagination.activePage - 1) * pagination.itemsPerPage,
138
+ ).map((index) => {
139
+ const speciesData = filteredSpecies[index][0];
140
+
141
+ return (
142
+ <Grid
143
+ className="species"
144
+ key={`${index}-${speciesData.id_eunis}`}
145
+ columns="12"
146
+ >
147
+ <Grid.Row>
148
+ <Grid.Column
149
+ mobile={12}
150
+ tablet={3}
151
+ computer={2}
152
+ className="species-photo"
153
+ >
154
+ <img
155
+ src={
156
+ speciesData.picture_url ||
157
+ photoPlaceholders[speciesData.species_group_name] ||
158
+ photoPlaceholders.Birds
159
+ }
160
+ alt={speciesData.species_group_name}
161
+ />
162
+ </Grid.Column>
163
+ <Grid.Column
164
+ mobile={12}
165
+ tablet={9}
166
+ computer={10}
167
+ className="species-details"
168
+ >
169
+ <div className="metadata">
170
+ <div className="name">
171
+ <Link
172
+ as="h3"
173
+ to={`/natura2000/species/s/${speciesData.id_eunis}`}
174
+ >
175
+ {speciesData.common_name
176
+ ? speciesData.common_name + ' '
177
+ : ''}
178
+ <em>{speciesData.scientific_name}</em>
179
+ <span className="code-2000">
180
+ {' '}
181
+ - {speciesData.code_2000 || 'NA'}
182
+ </span>
183
+ </Link>
184
+ </div>
185
+ {filteredSpecies[index].map((specimen, index) => (
186
+ <p
187
+ className="specimen-data"
188
+ key={`specimen-${index}-${specimen.id_eunis}`}
189
+ >
190
+ {getLabelString(
191
+ 'population_type',
192
+ specimen.population_type,
193
+ )}
194
+ {getPopulationString(
195
+ specimen.lower_bound,
196
+ specimen.upper_bound,
197
+ ', ',
198
+ )}
199
+ {getLabelString(
200
+ 'counting_unit',
201
+ specimen.counting_unit,
202
+ ', ',
203
+ )}
204
+ {getLabelString(
205
+ 'abundance_category',
206
+ specimen.abundance_category,
207
+ ', ',
208
+ )}
209
+ </p>
210
+ ))}
211
+ </div>
212
+ <div className="footer-metadata">
213
+ <p className="orange">
214
+ {speciesData.EU_threat_name || 'Not reported'} (IUCN
215
+ European Red List)
216
+ </p>
217
+ <p className="green">
218
+ Appears in {speciesData.appears_number_sites} sites
219
+ </p>
220
+ </div>
221
+ </Grid.Column>
222
+ </Grid.Row>
223
+ </Grid>
224
+ );
225
+ })
226
+ ) : species.length ? (
227
+ <div className="empty">No results</div>
228
+ ) : (
229
+ ''
230
+ )}
231
+ {!species?.length ? <div className="empty">{placeholder}</div> : ''}
232
+ {pagination.totalItems > 0 ? (
233
+ <Pagination
234
+ activePage={pagination.activePage}
235
+ totalPages={Math.ceil(
236
+ pagination.totalItems / pagination.itemsPerPage,
237
+ )}
238
+ onPageChange={(e, data) => {
239
+ setPagination({ ...pagination, activePage: data.activePage });
240
+ }}
241
+ prevItem={null}
242
+ nextItem={null}
243
+ />
244
+ ) : (
245
+ ''
246
+ )}
247
+ </Container>
248
+ </div>
249
+ </div>
250
+ );
251
+ };
252
+
253
+ export default View;
@@ -0,0 +1,17 @@
1
+ import SiteSpeciesList from './View';
2
+ import getSchema from './schema';
3
+
4
+ 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
+ site_species_list: {
10
+ view: SiteSpeciesList,
11
+ getSchema: getSchema,
12
+ title: 'Site species list',
13
+ },
14
+ },
15
+ };
16
+ return config;
17
+ };
@@ -0,0 +1,19 @@
1
+ const getSchema = (props) => {
2
+ return {
3
+ title: 'Site species list',
4
+
5
+ fieldsets: [
6
+ {
7
+ id: 'default',
8
+ title: 'Default',
9
+ fields: [],
10
+ },
11
+ ],
12
+
13
+ properties: {},
14
+
15
+ required: [],
16
+ };
17
+ };
18
+
19
+ export default getSchema;
@@ -0,0 +1,264 @@
1
+ div#view .site-species-list .species-group-filter .ui.container > *,
2
+ div#view .site-species-list .species-filters .ui.container > *,
3
+ div#view .site-species-list .species-list .ui.container > * {
4
+ margin-bottom: 0;
5
+ }
6
+
7
+ .site-species-list {
8
+ margin-top: -1.5rem;
9
+
10
+ .species-filters {
11
+ .ui.container {
12
+ display: flex;
13
+ justify-content: space-between;
14
+
15
+ .active-filters {
16
+ .ui.label.active-filter {
17
+ display: inline-flex;
18
+ flex-flow: row;
19
+ align-items: center;
20
+ border: 1px solid #c5c5c5;
21
+ border-radius: 18px;
22
+ color: #000;
23
+ font-weight: 400;
24
+
25
+ svg.icon {
26
+ margin-right: 0;
27
+ margin-left: 0.5rem;
28
+ cursor: pointer;
29
+ }
30
+ }
31
+ }
32
+
33
+ .toolbar {
34
+ display: flex;
35
+ flex-flow: row;
36
+ justify-content: center;
37
+
38
+ .ui.button.dropdown,
39
+ button {
40
+ border: 1px solid #0000001f;
41
+ background-color: #fff;
42
+ color: #000;
43
+ cursor: pointer;
44
+ }
45
+ }
46
+ }
47
+
48
+ .species-groups {
49
+ margin-bottom: 1rem;
50
+ background-color: #04a87d;
51
+
52
+ .ui.container {
53
+ display: flex;
54
+ align-items: center;
55
+ justify-content: center;
56
+ overflow-x: auto;
57
+
58
+ @media only screen and (max-width: 765px) {
59
+ justify-content: flex-start;
60
+ }
61
+
62
+ button.species-group {
63
+ padding: 1rem;
64
+ border: none;
65
+ background-color: transparent;
66
+ color: #fff;
67
+ cursor: pointer;
68
+ font-size: 14px;
69
+ text-transform: uppercase;
70
+
71
+ &.active,
72
+ &:hover {
73
+ padding-bottom: calc(1rem - 3px);
74
+ border-bottom: 3px solid #fff;
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ .ui.sidebar {
81
+ background-color: #fff;
82
+
83
+ &.right.visible {
84
+ box-shadow: 0px 0px 13px -5px #000000;
85
+ }
86
+
87
+ .sidebar-header {
88
+ display: flex;
89
+ flex-flow: row;
90
+ align-items: center;
91
+ justify-content: space-between;
92
+ padding: 2rem 1rem;
93
+ background-color: #04a87d;
94
+
95
+ .title {
96
+ margin-bottom: 0;
97
+ color: #fff;
98
+ font-size: 20px;
99
+ font-weight: bold;
100
+ }
101
+
102
+ .clear-button {
103
+ border: none;
104
+ background-color: transparent;
105
+ cursor: pointer;
106
+ }
107
+ }
108
+
109
+ .filters {
110
+ padding: 2rem 0;
111
+
112
+ .filter {
113
+ padding: 0 1rem 1rem 1rem;
114
+ border-bottom: 2px solid #e0e0e0;
115
+ margin-bottom: 2rem;
116
+
117
+ .header {
118
+ padding: 0;
119
+ margin-bottom: 2rem;
120
+ background-color: transparent;
121
+
122
+ .title {
123
+ color: #000;
124
+ font-weight: 600;
125
+
126
+ .reset-button {
127
+ border: none;
128
+ margin-left: 1rem;
129
+ background-color: transparent;
130
+ color: #04a87d;
131
+ cursor: pointer;
132
+
133
+ &:hover {
134
+ opacity: 0.8;
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ .checkbox-wrapper {
141
+ display: flex;
142
+ align-items: center;
143
+ justify-content: space-between;
144
+ margin-bottom: 1rem;
145
+
146
+ .count {
147
+ color: #636363;
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ .species-list {
156
+ .ui.grid.species {
157
+ margin-top: 0;
158
+ margin-right: 0;
159
+ margin-bottom: 0;
160
+
161
+ .row {
162
+ padding: 1rem 0;
163
+ }
164
+
165
+ .species-photo {
166
+ overflow: hidden;
167
+ padding-right: 0;
168
+
169
+ img {
170
+ width: 100%;
171
+ height: 100%;
172
+ border-bottom-left-radius: 10px;
173
+ border-top-left-radius: 10px;
174
+ object-fit: cover;
175
+
176
+ @media only screen and (max-width: 767px) {
177
+ border-bottom-left-radius: 0;
178
+ border-top-left-radius: 10px;
179
+ border-top-right-radius: 10px;
180
+ }
181
+ }
182
+ }
183
+
184
+ .species-details {
185
+ display: flex;
186
+ flex-flow: column;
187
+ justify-content: space-between;
188
+ padding: 0;
189
+ background-color: #fff;
190
+ border-bottom-right-radius: 10px;
191
+ border-top-right-radius: 10px;
192
+
193
+ @media only screen and (max-width: 767px) {
194
+ margin-left: 1rem;
195
+ border-bottom-left-radius: 10px;
196
+ border-bottom-right-radius: 10;
197
+ border-top-left-radius: 0;
198
+ border-top-right-radius: 0;
199
+ }
200
+
201
+ .metadata {
202
+ padding: 0 2rem;
203
+ padding-top: 1rem;
204
+ margin-bottom: 1rem;
205
+
206
+ .name {
207
+ margin-bottom: 1rem;
208
+
209
+ a {
210
+ color: #013c60;
211
+ font-size: 25px;
212
+ font-weight: 400;
213
+ }
214
+
215
+ .code-2000 {
216
+ color: #0f8f22;
217
+ }
218
+ }
219
+
220
+ .specimen-data:not(:last-child) {
221
+ margin-bottom: 0.5rem;
222
+ }
223
+ }
224
+
225
+ .footer-metadata {
226
+ display: flex;
227
+ padding: 1rem 2rem;
228
+ border-top: 1px solid #e8e8e8;
229
+
230
+ p:not(.last-child) {
231
+ margin-right: 1rem;
232
+ }
233
+
234
+ .orange {
235
+ color: #ff9300;
236
+ }
237
+
238
+ .green {
239
+ color: #0f8f22;
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ .ui.pagination.menu {
246
+ width: 100%;
247
+ justify-content: center;
248
+ background-color: transparent;
249
+
250
+ .item {
251
+ &.active {
252
+ color: #013c60;
253
+ font-weight: bold;
254
+ }
255
+ }
256
+ }
257
+
258
+ .empty {
259
+ margin-top: 3rem;
260
+ margin-bottom: 3rem !important;
261
+ text-align: left;
262
+ }
263
+ }
264
+ }
@@ -0,0 +1,33 @@
1
+ export const filtersLabels = {
2
+ population_type: {
3
+ p: 'Permanent',
4
+ r: 'Reproducing',
5
+ c: 'Concentration',
6
+ w: 'Wintering',
7
+ getTitle: () => 'Population type',
8
+ },
9
+ counting_unit: {
10
+ i: 'Individuals',
11
+ p: 'Pairs',
12
+ getTitle: () => 'Unit',
13
+ },
14
+ abundance_category: {
15
+ C: 'Common',
16
+ R: 'Rare',
17
+ V: 'Very rare',
18
+ P: 'Present',
19
+ getTitle: () => 'Abundance',
20
+ },
21
+ };
22
+
23
+ export const getPopulationString = (min, max, prefix = '') => {
24
+ return `${prefix}Population: min: ${min || 'not reported'}, max: ${
25
+ max || 'not reported'
26
+ }`;
27
+ };
28
+
29
+ export const getLabelString = (label, key, prefix = '') => {
30
+ return `${prefix}${filtersLabels[label].getTitle()}: ${
31
+ filtersLabels[label]?.[key]?.toLowerCase() || key || 'not reported'
32
+ }`;
33
+ };
@@ -0,0 +1,77 @@
1
+ import React from 'react';
2
+ import { UniversalLink } from '@plone/volto/components';
3
+ import { withRouter } from 'react-router';
4
+ import { useSelector } from 'react-redux';
5
+ import { withHashLink } from 'volto-slate/hooks';
6
+ import qs from 'querystring';
7
+ import './styles.less';
8
+
9
+ const formatLink = (str, obj) => {
10
+ let newStr = str;
11
+ if (!str || typeof str !== 'string') return str;
12
+ Object.keys(obj || {}).forEach((key) => {
13
+ newStr = newStr.replace(new RegExp(`\\$${key}`, 'g'), obj[key]);
14
+ });
15
+ return newStr;
16
+ };
17
+
18
+ export const LinkElement = withHashLink(
19
+ withRouter(
20
+ ({ attributes, children, element, location, match, mode, setHashLink }) => {
21
+ // TODO: handle title on internal links
22
+ let url = element.url;
23
+ const { link } = element.data || {};
24
+ const route_parameters = useSelector((state) => state.route_parameters);
25
+ const params = {
26
+ ...match.params,
27
+ ...(route_parameters || {}),
28
+ ...qs.parse(location.search.replace('?', '')),
29
+ };
30
+ const internal_link = formatLink(
31
+ link?.internal?.internal_link?.[0]?.['@id'],
32
+ params,
33
+ );
34
+ const external_link = formatLink(link?.external?.external_link, params);
35
+ const email = link?.email;
36
+ const internal_hash = link?.hash?.internal_hash?.[0]?.['id'];
37
+ const href = internal_hash
38
+ ? `#${internal_hash}`
39
+ : email
40
+ ? `mailto:${email.email_address}${
41
+ email.email_subject ? `?subject=${email.email_subject}` : ''
42
+ }`
43
+ : external_link || internal_link || url;
44
+
45
+ const { title } = element?.data || {};
46
+
47
+ return mode === 'view' ? (
48
+ <>
49
+ {internal_hash ? (
50
+ <a
51
+ href={`#${internal_hash}`}
52
+ title={title}
53
+ onClick={(event) => {
54
+ event.preventDefault();
55
+ setHashLink(internal_hash, link.hash.internal_hash[0]);
56
+ }}
57
+ >
58
+ {children}
59
+ </a>
60
+ ) : (
61
+ <UniversalLink
62
+ href={href || '#'}
63
+ openLinkInNewTab={link?.external?.target === '_blank'}
64
+ title={title}
65
+ >
66
+ {children}
67
+ </UniversalLink>
68
+ )}
69
+ </>
70
+ ) : (
71
+ <span {...attributes} className="slate-editor-link">
72
+ {children}
73
+ </span>
74
+ );
75
+ },
76
+ ),
77
+ );
@@ -0,0 +1,22 @@
1
+ @type: 'extra';
2
+ @element: 'custom';
3
+
4
+ @import (multiple, reference, optional) '../../theme.config';
5
+
6
+ .slate-editor-link {
7
+ color: @linkColor;
8
+ }
9
+
10
+ button.hash-link {
11
+ padding: 0;
12
+ border: none;
13
+ background: transparent;
14
+ color: @linkColor;
15
+ cursor: pointer;
16
+ text-decoration: @linkUnderline;
17
+ }
18
+
19
+ button.hash-link:hover {
20
+ color: @linkHoverColor;
21
+ text-decoration: @linkHoverUnderline;
22
+ }
@@ -0,0 +1 @@
1
+ export const SLATESVG = 'slatesvg';
@@ -0,0 +1,11 @@
1
+ import { SLATESVG } from './constants';
2
+
3
+ export const withSlateSvg = (editor) => {
4
+ const { isInline } = editor;
5
+
6
+ editor.isInline = (element) => {
7
+ return element.type === SLATESVG ? true : isInline(element);
8
+ };
9
+
10
+ return editor;
11
+ };