@eeacms/volto-clms-theme 1.1.37 → 1.1.39

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 (23) hide show
  1. package/CHANGELOG.md +20 -2
  2. package/package.json +3 -1
  3. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/AccordionFacet.jsx +3 -3
  4. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/CheckboxTreeFacet.jsx +3 -3
  5. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/CheckboxTreeParentFacet.jsx +3 -3
  6. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/DoubleRangeFacet.jsx +3 -20
  7. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/DoubleRangeSpatialFacet.jsx +3 -21
  8. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/utils.js +36 -0
  9. package/src/components/CLMSDatasetDetailView/DataSetInfoContent.jsx +20 -9
  10. package/src/components/CLMSDownloadCartView/AreaNaming.jsx +9 -9
  11. package/src/components/CLMSDownloadCartView/CLMSCartContent.jsx +37 -33
  12. package/src/components/CLMSDownloadCartView/CollectionNaming.jsx +9 -9
  13. package/src/components/CLMSDownloadCartView/FormatNaming.jsx +2 -2
  14. package/src/components/CLMSDownloadCartView/LayerNaming.jsx +6 -6
  15. package/src/components/CLMSDownloadCartView/TypeNaming.jsx +8 -8
  16. package/src/components/CLMSDownloadCartView/cartUtils.js +58 -55
  17. package/src/components/CLMSDownloadCartView/conversion.js +8 -2
  18. package/src/components/CLMSProfileView/CLMSNewsletterSubscriberView.jsx +3 -3
  19. package/src/components/CLMSProfileView/CLMSProfileView.jsx +1 -1
  20. package/src/components/CLMSSubscriptionView/SubscriptionView.jsx +8 -4
  21. package/src/components/CLMSSubscriptionView/subscription_utils.js +1 -1
  22. package/src/components/Widgets/DownloadableFilesTableWidget.jsx +11 -10
  23. package/src/customizations/volto/components/theme/Footer/Footer.jsx +35 -17
package/CHANGELOG.md CHANGED
@@ -4,11 +4,29 @@ 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.1.37](https://github.com/eea/volto-clms-theme/compare/1.1.36...1.1.37) - 30 August 2023
7
+ ### [1.1.39](https://github.com/eea/volto-clms-theme/compare/1.1.38...1.1.39) - 11 September 2023
8
+
9
+ #### :hammer_and_wrench: Others
10
+
11
+ - remove duplications [Ion Lizarazu - [`80b0a43`](https://github.com/eea/volto-clms-theme/commit/80b0a435926157d2a5d9f0ea2416431356f3d7a4)]
12
+ - Add expanded by default option to the search block facets [Ion Lizarazu - [`f0a30f8`](https://github.com/eea/volto-clms-theme/commit/f0a30f868eca3ab6860e8465647178bdb33c9eb8)]
13
+ - replace newsletter with CLMS updates and modify some footer stuff [Ion Lizarazu - [`1f7255a`](https://github.com/eea/volto-clms-theme/commit/1f7255a81001de686e23c29b36e7f4d855fe2285)]
14
+ ### [1.1.38](https://github.com/eea/volto-clms-theme/compare/1.1.37...1.1.38) - 7 September 2023
8
15
 
9
16
  #### :hammer_and_wrench: Others
10
17
 
11
- - margin left for nested uls [Mikel Larreategi - [`d439cd3`](https://github.com/eea/volto-clms-theme/commit/d439cd3c9528e2b2d5ff53cb606057b90bc5a712)]
18
+ - fix cart items concat function [Ion Lizarazu - [`4b72249`](https://github.com/eea/volto-clms-theme/commit/4b72249ef17a0cda22661809fce5be7c2d1f6649)]
19
+ - revert Jenkinsfile [Ion Lizarazu - [`64f6cd0`](https://github.com/eea/volto-clms-theme/commit/64f6cd08100357843b507c00d3286d7debe0ef04)]
20
+ - yarn.lock file [Ion Lizarazu - [`8444ad1`](https://github.com/eea/volto-clms-theme/commit/8444ad1606b3939e4609bdd186e5ace2252588a8)]
21
+ - packages.json versions order [Ion Lizarazu - [`4fd7a86`](https://github.com/eea/volto-clms-theme/commit/4fd7a86ab43238841b421e1ed10ebd52ab420a15)]
22
+ - downloadablefilestablewidget param modification [Ion Lizarazu - [`5dd794a`](https://github.com/eea/volto-clms-theme/commit/5dd794a33a8eddd042a753b7ab47e7d2a323b011)]
23
+ - add technical_documents_accordion_text field to the dataset view [Ion Lizarazu - [`96ed1e5`](https://github.com/eea/volto-clms-theme/commit/96ed1e5e2c2b501bd303bc76b333a70ad1614c16)]
24
+ - move Validation status below the description [Ion Lizarazu - [`3e45c25`](https://github.com/eea/volto-clms-theme/commit/3e45c255880f3fc182746d21752dc0a2fa974cb1)]
25
+ - fix [CLMS-2541] check if conversionTable[value] is not null [Ion Lizarazu - [`232df08`](https://github.com/eea/volto-clms-theme/commit/232df087fa32f88eb4da50e3db20abd8b7e0c4c5)]
26
+ - add to cart at the first position [Ion Lizarazu - [`1c648a6`](https://github.com/eea/volto-clms-theme/commit/1c648a66be0bcbfaf360d524096d1f37f801c131)]
27
+ - test: EN locales, pre-commit fix, feature PRs checks Refs #257193 [valentinab25 - [`b992431`](https://github.com/eea/volto-clms-theme/commit/b9924318282e7fb6f6ce0ff15ab24e5b1faec7f1)]
28
+ ### [1.1.37](https://github.com/eea/volto-clms-theme/compare/1.1.36...1.1.37) - 30 August 2023
29
+
12
30
  ### [1.1.36](https://github.com/eea/volto-clms-theme/compare/1.1.35...1.1.36) - 30 August 2023
13
31
 
14
32
  #### :hammer_and_wrench: Others
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-clms-theme",
3
- "version": "1.1.37",
3
+ "version": "1.1.39",
4
4
  "description": "volto-clms-theme: Volto theme for CLMS site",
5
5
  "main": "src/index.js",
6
6
  "author": "CodeSyntax for the European Environment Agency",
@@ -47,6 +47,7 @@
47
47
  "@eeacms/volto-tabs-block": "3.0.1",
48
48
  "@eeacms/volto-taxonomy": "3.0.1",
49
49
  "@fortawesome/fontawesome-svg-core": "1.2.35",
50
+ "@fortawesome/free-brands-svg-icons": "6.4.2",
50
51
  "@fortawesome/free-regular-svg-icons": "5.15.3",
51
52
  "@fortawesome/free-solid-svg-icons": "5.15.3",
52
53
  "@fortawesome/react-fontawesome": "0.1.14",
@@ -81,6 +82,7 @@
81
82
  "eslint-plugin-react-app": "^6.2.2",
82
83
  "husky": "7.0.4",
83
84
  "jsconfig": "^0.2.0",
85
+ "lint-staged": "*",
84
86
  "md5": "^2.3.0",
85
87
  "prettier": "2.0.5",
86
88
  "prettier-eslint": "^12.0.0",
@@ -1,10 +1,10 @@
1
1
  import { Checkbox, List } from 'semantic-ui-react';
2
2
  import React from 'react';
3
3
  import {
4
- selectFacetSchemaEnhancer,
5
4
  selectFacetStateToValue,
6
5
  selectFacetValueToQuery,
7
6
  } from '@plone/volto/components/manage/Blocks/Search/components/base';
7
+ import { enhanceExpandedByDefault } from './utils.js';
8
8
 
9
9
  const AccordionFacet = (props) => {
10
10
  const {
@@ -17,7 +17,7 @@ const AccordionFacet = (props) => {
17
17
  typeName,
18
18
  } = props;
19
19
  const facetValue = value;
20
- var [open, setOpen] = React.useState(false);
20
+ var [open, setOpen] = React.useState(facet.expandedByDefault ?? false);
21
21
  function isChoiceValue(isChecked, choiceValue) {
22
22
  return isChecked ? choiceValue : null;
23
23
  }
@@ -92,7 +92,7 @@ const AccordionFacet = (props) => {
92
92
  );
93
93
  };
94
94
 
95
- AccordionFacet.schemaEnhancer = selectFacetSchemaEnhancer;
95
+ AccordionFacet.schemaEnhancer = enhanceExpandedByDefault;
96
96
  AccordionFacet.stateToValue = selectFacetStateToValue;
97
97
  AccordionFacet.valueToQuery = selectFacetValueToQuery;
98
98
  export default AccordionFacet;
@@ -5,11 +5,11 @@ import { Checkbox, List } from 'semantic-ui-react';
5
5
  import { structure_taxonomy_terms } from '@eeacms/volto-clms-theme/components';
6
6
 
7
7
  import {
8
- selectFacetSchemaEnhancer,
9
8
  selectFacetStateToValue,
10
9
  selectFacetValueToQuery,
11
10
  } from '@plone/volto/components/manage/Blocks/Search/components/base';
12
11
  import { checkAllChildren } from './utils';
12
+ import { enhanceExpandedByDefault } from './utils.js';
13
13
 
14
14
  const hasAllChildrensSelected = (value, childrens) => {
15
15
  var result = true;
@@ -40,7 +40,7 @@ const CheckboxTreeFacet = (props) => {
40
40
  const { facet, choices, onChange, value, typeName } = props;
41
41
 
42
42
  const facetValue = value;
43
- var [open, setOpen] = useState(false);
43
+ var [open, setOpen] = useState(facet.expandedByDefault ?? false);
44
44
  let options = [];
45
45
  if (choices?.length > 0) {
46
46
  options = structure_taxonomy_terms(choices);
@@ -161,7 +161,7 @@ const CheckboxListParent = ({ option, key, onChange, value, id }) => {
161
161
  );
162
162
  };
163
163
 
164
- CheckboxTreeFacet.schemaEnhancer = selectFacetSchemaEnhancer;
164
+ CheckboxTreeFacet.schemaEnhancer = enhanceExpandedByDefault;
165
165
  CheckboxTreeFacet.stateToValue = selectFacetStateToValue;
166
166
  CheckboxTreeFacet.valueToQuery = selectFacetValueToQuery;
167
167
  export default CheckboxTreeFacet;
@@ -5,11 +5,11 @@ import { Checkbox, List } from 'semantic-ui-react';
5
5
  import { structure_taxonomy_terms } from '@eeacms/volto-clms-theme/components';
6
6
 
7
7
  import {
8
- selectFacetSchemaEnhancer,
9
8
  selectFacetStateToValue,
10
9
  selectFacetValueToQuery,
11
10
  } from '@plone/volto/components/manage/Blocks/Search/components/base';
12
11
  import { checkAllChildren, uncheckOptionAndChildren } from './utils';
12
+ import { enhanceExpandedByDefault } from './utils.js';
13
13
 
14
14
  const hasAllChildrensSelected = (value, childrens) => {
15
15
  var result = true;
@@ -39,7 +39,7 @@ const Wrapper = ({ typeName, children }) => {
39
39
  const CheckboxTreeParentFacet = (props) => {
40
40
  const { facet, choices, onChange, value, typeName } = props;
41
41
  const facetValue = value;
42
- var [open, setOpen] = useState(false);
42
+ var [open, setOpen] = useState(facet.expandedByDefault ?? false);
43
43
  let options = [];
44
44
  if (choices?.length > 0) {
45
45
  options = structure_taxonomy_terms(choices);
@@ -153,7 +153,7 @@ const CheckboxListParent = ({ option, key, onChange, value, id }) => {
153
153
  );
154
154
  };
155
155
 
156
- CheckboxTreeParentFacet.schemaEnhancer = selectFacetSchemaEnhancer;
156
+ CheckboxTreeParentFacet.schemaEnhancer = enhanceExpandedByDefault;
157
157
  CheckboxTreeParentFacet.stateToValue = selectFacetStateToValue;
158
158
  CheckboxTreeParentFacet.valueToQuery = selectFacetValueToQuery;
159
159
  export default CheckboxTreeParentFacet;
@@ -8,30 +8,12 @@ import {
8
8
  selectFacetStateToValue,
9
9
  selectFacetValueToQuery,
10
10
  } from '@plone/volto/components/manage/Blocks/Search/components/base';
11
-
12
- const doubleRangeFacetSchemaEnhancer = ({ schema, formData }) => {
13
- // adds (enables) the 'multiple' field after the 'type' dropdown
14
- let { fields } = schema.fieldsets[0];
15
- const pos = fields.indexOf('type') + 1;
16
- fields = [
17
- ...fields.slice(0, pos),
18
- 'step',
19
- 'multiple',
20
- ...fields.slice(pos, fields.length),
21
- ];
22
-
23
- schema.properties = {
24
- ...schema.properties,
25
- step: { title: 'Step', type: 'number', default: 1 },
26
- };
27
- schema.fieldsets[0].fields = fields;
28
- return schema;
29
- };
11
+ import { doubleRangeFacetSchemaEnhancer } from './utils.js';
30
12
 
31
13
  const DoubleRangeFacet = (props) => {
32
14
  const { facet, choices, onChange, value } = props;
33
15
  const facetValue = value;
34
- var [open, setOpen] = React.useState(false);
16
+ var [open, setOpen] = React.useState(facet.expandedByDefault ?? false);
35
17
 
36
18
  const convertToRange = (values) => {
37
19
  return {
@@ -111,6 +93,7 @@ const DoubleRangeFacet = (props) => {
111
93
  };
112
94
 
113
95
  DoubleRangeFacet.schemaEnhancer = doubleRangeFacetSchemaEnhancer;
96
+
114
97
  DoubleRangeFacet.stateToValue = selectFacetStateToValue;
115
98
  DoubleRangeFacet.valueToQuery = selectFacetValueToQuery;
116
99
  export default DoubleRangeFacet;
@@ -8,25 +8,7 @@ import {
8
8
  selectFacetStateToValue,
9
9
  selectFacetValueToQuery,
10
10
  } from '@plone/volto/components/manage/Blocks/Search/components/base';
11
-
12
- const doubleRangeSpatialFacetSchemaEnhancer = ({ schema, formData }) => {
13
- // adds (enables) the 'multiple' field after the 'type' dropdown
14
- let { fields } = schema.fieldsets[0];
15
- const pos = fields.indexOf('type') + 1;
16
- fields = [
17
- ...fields.slice(0, pos),
18
- 'step',
19
- 'multiple',
20
- ...fields.slice(pos, fields.length),
21
- ];
22
-
23
- schema.properties = {
24
- ...schema.properties,
25
- step: { title: 'Step', type: 'number', default: 1 },
26
- };
27
- schema.fieldsets[0].fields = fields;
28
- return schema;
29
- };
11
+ import { doubleRangeFacetSchemaEnhancer } from './utils.js';
30
12
 
31
13
  const mToKm = (m) => {
32
14
  return m >= 1000 ? Math.round((m / 1000) * 10) / 10 + 'km' : m + 'm';
@@ -82,7 +64,7 @@ const convertToRange = (values, step) => {
82
64
  const DoubleRangeSpatialFacet = (props) => {
83
65
  const { facet, choices, onChange, value } = props;
84
66
  const facetValue = value;
85
- var [open, setOpen] = React.useState(false);
67
+ var [open, setOpen] = React.useState(facet.expandedByDefault ?? false);
86
68
 
87
69
  const startingValues = convertToRange(choices, facet?.step);
88
70
 
@@ -156,7 +138,7 @@ const DoubleRangeSpatialFacet = (props) => {
156
138
  );
157
139
  };
158
140
 
159
- DoubleRangeSpatialFacet.schemaEnhancer = doubleRangeSpatialFacetSchemaEnhancer;
141
+ DoubleRangeSpatialFacet.schemaEnhancer = doubleRangeFacetSchemaEnhancer;
160
142
  DoubleRangeSpatialFacet.stateToValue = selectFacetStateToValue;
161
143
  DoubleRangeSpatialFacet.valueToQuery = selectFacetValueToQuery;
162
144
  export default DoubleRangeSpatialFacet;
@@ -21,3 +21,39 @@ export const uncheckOptionAndChildren = (value, option) => {
21
21
  }
22
22
  });
23
23
  };
24
+
25
+ export const enhanceExpandedByDefault = ({ schema, formData }) => {
26
+ return expandedByDefault(schema);
27
+ };
28
+
29
+ export const doubleRangeFacetSchemaEnhancer = ({ schema, formData }) => {
30
+ // adds (enables) the 'multiple' field after the 'type' dropdown
31
+ let { fields } = schema.fieldsets[0];
32
+ const pos = fields.indexOf('type') + 1;
33
+ fields = [
34
+ ...fields.slice(0, pos),
35
+ 'step',
36
+ 'multiple',
37
+ ...fields.slice(pos, fields.length),
38
+ ];
39
+
40
+ schema.properties = {
41
+ ...schema.properties,
42
+ step: { title: 'Step', type: 'number', default: 1 },
43
+ };
44
+ schema.fieldsets[0].fields = fields;
45
+ return expandedByDefault(schema);
46
+ };
47
+
48
+ export const expandedByDefault = (schema) => {
49
+ schema.properties = {
50
+ ...schema.properties,
51
+ expandedByDefault: {
52
+ title: 'Expanded by default',
53
+ type: 'boolean',
54
+ default: false,
55
+ },
56
+ };
57
+ schema.fieldsets[0].fields.push('expandedByDefault');
58
+ return schema;
59
+ };
@@ -106,15 +106,6 @@ const DataSetInfoContent = (props) => {
106
106
 
107
107
  return (
108
108
  <div>
109
- {validation?.data &&
110
- validation?.data !== '<p><br/></p>' &&
111
- validation?.data !== '<p></p>' && (
112
- <CclCitation
113
- title="Validation status"
114
- marginBottom={true}
115
- children={<StringToHTML string={validation.data} />}
116
- ></CclCitation>
117
- )}
118
109
  <CclInfoContainer>
119
110
  {props?.description ? (
120
111
  <CclInfoDescription
@@ -124,6 +115,15 @@ const DataSetInfoContent = (props) => {
124
115
  ''
125
116
  )}
126
117
  </CclInfoContainer>
118
+ {validation?.data &&
119
+ validation?.data !== '<p><br/></p>' &&
120
+ validation?.data !== '<p></p>' && (
121
+ <CclCitation
122
+ title="Validation status"
123
+ marginBottom={true}
124
+ children={<StringToHTML string={validation.data} />}
125
+ ></CclCitation>
126
+ )}
127
127
  {citation?.data &&
128
128
  citation?.data !== '<p><br/></p>' &&
129
129
  citation?.data !== '<p></p>' && (
@@ -314,6 +314,17 @@ const DataSetInfoContent = (props) => {
314
314
  duration={500}
315
315
  height={'auto'}
316
316
  >
317
+ {props.technical_documents_accordion_text?.data &&
318
+ props.technical_documents_accordion_text?.data !==
319
+ '<p><br/></p>' &&
320
+ props.technical_documents_accordion_text?.data !==
321
+ '<p></p>' && (
322
+ <StringToHTML
323
+ string={
324
+ props.technical_documents_accordion_text?.data
325
+ }
326
+ />
327
+ )}
317
328
  <CclRelatedListingView
318
329
  id={'dataset-info-technicals'}
319
330
  properties={{ ...props }}
@@ -1,7 +1,7 @@
1
1
  import { Label } from 'semantic-ui-react';
2
2
  export const AreaNaming = (areaProps) => {
3
3
  const { item } = areaProps;
4
- switch (item.area?.type) {
4
+ switch (item?.area?.type) {
5
5
  case 'polygon':
6
6
  return (
7
7
  <>
@@ -9,22 +9,22 @@ export const AreaNaming = (areaProps) => {
9
9
  <br />
10
10
  <span className="cart-bounding-boxes">
11
11
  <span className="cart-bounding-box-row">
12
- <Label>{`N: ${item.area.value[1].toFixed(1)}º`}</Label>&nbsp;
13
- <Label>{`E: ${item.area.value[2].toFixed(1)}º`}</Label>&nbsp;
12
+ <Label>{`N: ${item?.area.value[1].toFixed(1)}º`}</Label>&nbsp;
13
+ <Label>{`E: ${item?.area.value[2].toFixed(1)}º`}</Label>&nbsp;
14
14
  {/* </span>
15
15
  <span className="cart-bounding-box-row"> */}
16
- <Label>{`S: ${item.area.value[3].toFixed(1)}º`}</Label>&nbsp;
17
- <Label>{`W: ${item.area.value[0].toFixed(1)}º`}</Label>
16
+ <Label>{`S: ${item?.area.value[3].toFixed(1)}º`}</Label>&nbsp;
17
+ <Label>{`W: ${item?.area.value[0].toFixed(1)}º`}</Label>
18
18
  </span>
19
19
  </span>
20
20
  </>
21
21
  );
22
22
  case 'nuts':
23
- return item.area.valueName || item.area.value;
23
+ return item?.area.valueName || item?.area.value;
24
24
  case undefined:
25
- return item.area || item.file || '-';
26
- case typeof item.area === 'string':
27
- return item.area || item.file || '-';
25
+ return item?.area || item?.file || '-';
26
+ case typeof item?.area === 'string':
27
+ return item?.area || item?.file || '-';
28
28
  default:
29
29
  return '-';
30
30
  }
@@ -90,11 +90,11 @@ const CLMSCartContent = (props) => {
90
90
  }, [cartItems]);
91
91
  useEffect(() => {
92
92
  const array_ids =
93
- cart.length > 0 ? cart?.map((item) => item.unique_id) : [];
93
+ cart.length > 0 ? cart?.map((item) => item?.unique_id) : [];
94
94
  const newCart = cartItems.filter((item) =>
95
- array_ids.includes(item.unique_id),
95
+ array_ids.includes(item?.unique_id),
96
96
  );
97
- setCartItems(cleanDuplicatesEntries(newCart));
97
+
98
98
  let localsessionNutsIDList = [...new Set(getNutsIDList(cart))];
99
99
 
100
100
  if (
@@ -112,6 +112,8 @@ const CLMSCartContent = (props) => {
112
112
  projections,
113
113
  nutsnames.nutsnames,
114
114
  );
115
+ } else {
116
+ setCartItems(cleanDuplicatesEntries(newCart));
115
117
  }
116
118
  }, [cart, datasets_items, nutsnames]);
117
119
 
@@ -119,8 +121,8 @@ const CLMSCartContent = (props) => {
119
121
  if (checked && cartItems.length > 0) {
120
122
  setCartSelection(
121
123
  cartItems
122
- .filter((item) => item.task_in_progress === false)
123
- .map((item, key) => item.unique_id),
124
+ .filter((item) => item?.task_in_progress === false)
125
+ .map((item, key) => item?.unique_id),
124
126
  );
125
127
  } else {
126
128
  setCartSelection([]);
@@ -134,7 +136,7 @@ const CLMSCartContent = (props) => {
134
136
 
135
137
  const getSelectedCartItems = () => {
136
138
  return cartItems.filter(
137
- (item) => cartSelection.indexOf(item.unique_id) > -1,
139
+ (item) => cartSelection.indexOf(item?.unique_id) > -1,
138
140
  );
139
141
  };
140
142
 
@@ -190,7 +192,7 @@ const CLMSCartContent = (props) => {
190
192
  const body = getDownloadToolPostBody(selectedItems);
191
193
  const unique_ids =
192
194
  selectedItems.length > 0
193
- ? selectedItems.map((item) => item.unique_id)
195
+ ? selectedItems.map((item) => item?.unique_id)
194
196
  : [];
195
197
  dispatch(postDownloadtool(body, unique_ids));
196
198
  };
@@ -198,9 +200,9 @@ const CLMSCartContent = (props) => {
198
200
  const downloadModal = () => {
199
201
  let selectedItems = getSelectedCartItems();
200
202
  const hasPrepackaged =
201
- selectedItems.filter((item) => item.file_id).length > 0;
203
+ selectedItems.filter((item) => item?.file_id).length > 0;
202
204
  const hasMapSelection =
203
- selectedItems.filter((item) => !item.file_id).length > 0;
205
+ selectedItems.filter((item) => !item?.file_id).length > 0;
204
206
  if (!(hasMapSelection && hasPrepackaged)) {
205
207
  startDownloading();
206
208
  } else {
@@ -259,16 +261,16 @@ const CLMSCartContent = (props) => {
259
261
  <tr
260
262
  key={key}
261
263
  style={
262
- item.task_in_progress
264
+ item?.task_in_progress
263
265
  ? { opacity: 0.5, backgroundColor: '#f5f5f5' }
264
266
  : {}
265
267
  }
266
268
  >
267
269
  <td className="table-td-warning hidden-warning">
268
- {!!item.warning && (
270
+ {!!item?.warning && (
269
271
  <span
270
272
  className="info-icon"
271
- tooltip={item.warning}
273
+ tooltip={item?.warning}
272
274
  direction="up"
273
275
  >
274
276
  <FontAwesomeIcon
@@ -282,10 +284,10 @@ const CLMSCartContent = (props) => {
282
284
  <div className="ccl-form-group">
283
285
  <Checkbox
284
286
  onChange={(e, data) =>
285
- selectCart(item.unique_id, data.checked)
287
+ selectCart(item?.unique_id, data.checked)
286
288
  }
287
- checked={cartSelection.includes(item.unique_id)}
288
- disabled={item.task_in_progress}
289
+ checked={cartSelection.includes(item?.unique_id)}
290
+ disabled={item?.task_in_progress}
289
291
  />
290
292
  </div>
291
293
  </div>
@@ -293,11 +295,11 @@ const CLMSCartContent = (props) => {
293
295
  <td>
294
296
  <div className="mb-2">
295
297
  <strong>Name: </strong>
296
- {contentOrDash(item.name)}
298
+ {contentOrDash(item?.name)}
297
299
  </div>
298
300
  <div className="mb-2">
299
301
  <strong>Source: </strong>
300
- {contentOrDash(item.source)}
302
+ {contentOrDash(item?.source)}
301
303
  </div>
302
304
  <div className="mb-2">
303
305
  <strong>Area: </strong>
@@ -364,10 +366,10 @@ const CLMSCartContent = (props) => {
364
366
  )}
365
367
  </td>
366
368
  <td className="table-td-projections">
367
- {!item.file_id ? (
369
+ {!item?.file_id ? (
368
370
  <Select
369
371
  placeholder="Select projection"
370
- value={item.projection}
372
+ value={item?.projection}
371
373
  options={
372
374
  projections.length > 0 &&
373
375
  projections?.map((projection) => {
@@ -379,7 +381,7 @@ const CLMSCartContent = (props) => {
379
381
  })
380
382
  }
381
383
  onChange={(e, data) => {
382
- setProjectionValue(item.unique_id, data.value);
384
+ setProjectionValue(item?.unique_id, data.value);
383
385
  }}
384
386
  />
385
387
  ) : (
@@ -387,16 +389,18 @@ const CLMSCartContent = (props) => {
387
389
  )}
388
390
  </td>
389
391
  <td>
390
- {datasetTimeseries.datasets[item.dataset_uid]?.start ? (
392
+ {datasetTimeseries.datasets[item?.dataset_uid]
393
+ ?.start ? (
391
394
  <TimeseriesPicker
392
395
  start={
393
- datasetTimeseries.datasets[item.dataset_uid].start
396
+ datasetTimeseries.datasets[item?.dataset_uid]
397
+ .start
394
398
  }
395
399
  end={
396
- datasetTimeseries.datasets[item.dataset_uid].end
400
+ datasetTimeseries.datasets[item?.dataset_uid].end
397
401
  }
398
402
  period={
399
- datasetTimeseries.datasets[item.dataset_uid]
403
+ datasetTimeseries.datasets[item?.dataset_uid]
400
404
  .period
401
405
  }
402
406
  item={item}
@@ -408,9 +412,9 @@ const CLMSCartContent = (props) => {
408
412
  </td>
409
413
  <td className="text-end">
410
414
  <div style={{ display: 'flex' }}>
411
- {item.task_in_progress ? (
415
+ {item?.task_in_progress ? (
412
416
  <FontAwesomeIcon icon="spinner" spin />
413
- ) : !item.file_id ? (
417
+ ) : !item?.file_id ? (
414
418
  <span
415
419
  className="info-icon"
416
420
  tooltip="Add a duplicated row below"
@@ -419,7 +423,7 @@ const CLMSCartContent = (props) => {
419
423
  <button
420
424
  onClick={() => {
421
425
  duplicateCartItem(
422
- item.unique_id,
426
+ item?.unique_id,
423
427
  cartItems,
424
428
  setCartItems,
425
429
  updateCart,
@@ -442,7 +446,7 @@ const CLMSCartContent = (props) => {
442
446
  <></>
443
447
  )}
444
448
 
445
- {item.task_in_progress ? (
449
+ {item?.task_in_progress ? (
446
450
  <FontAwesomeIcon icon="spinner" spin />
447
451
  ) : (
448
452
  <span
@@ -452,7 +456,7 @@ const CLMSCartContent = (props) => {
452
456
  >
453
457
  <button
454
458
  onClick={() => {
455
- removeCartItem(item.unique_id);
459
+ removeCartItem(item?.unique_id);
456
460
  if (
457
461
  pagination.length === 1 &&
458
462
  currentPage > 1
@@ -559,8 +563,8 @@ const CLMSCartContent = (props) => {
559
563
  {[
560
564
  ...new Set(
561
565
  getSelectedCartItems()
562
- .filter((item) => item.file_id)
563
- .map((item) => item.name),
566
+ .filter((item) => item?.file_id)
567
+ .map((item) => item?.name),
564
568
  ),
565
569
  ]
566
570
  .sort()
@@ -574,8 +578,8 @@ const CLMSCartContent = (props) => {
574
578
  {[
575
579
  ...new Set(
576
580
  getSelectedCartItems()
577
- .filter((item) => !item.file_id)
578
- .map((item) => item.name),
581
+ .filter((item) => !item?.file_id)
582
+ .map((item) => item?.name),
579
583
  ),
580
584
  ].map((item, key) => (
581
585
  <li key={key}>{item}</li>
@@ -8,23 +8,23 @@ export const CollectionNaming = ({
8
8
  cartItems,
9
9
  setCartItems,
10
10
  }) => {
11
- if (item.file_id) {
11
+ if (item?.file_id) {
12
12
  return '-';
13
- } else if (!item.type) {
13
+ } else if (!item?.type) {
14
14
  return '-';
15
15
  }
16
16
  const this_type_collections = item?.type_options.filter(
17
17
  (o) =>
18
- o.name === item?.type_options.find((t_o) => t_o.id === item.type).name,
18
+ o.name === item?.type_options.find((t_o) => t_o.id === item?.type).name,
19
19
  );
20
20
  return this_type_collections.length > 1 ? (
21
21
  <Select
22
22
  placeholder="Select type"
23
23
  className="collection-selector"
24
24
  value={
25
- item.type
26
- ? item.type
27
- : item.type_options.length > 0 && item.type_options[0].id
25
+ item?.type
26
+ ? item?.type
27
+ : item?.type_options.length > 0 && item?.type_options[0].id
28
28
  }
29
29
  options={
30
30
  item?.type_options?.length > 0 &&
@@ -39,16 +39,16 @@ export const CollectionNaming = ({
39
39
  onChange={(e, data) => {
40
40
  const new_cartItems = [...cartItems];
41
41
  const objIndex = new_cartItems.findIndex(
42
- (obj) => obj.unique_id === item.unique_id,
42
+ (obj) => obj.unique_id === item?.unique_id,
43
43
  );
44
44
  new_cartItems[objIndex].type = data.value;
45
45
  const dataset = datasets_items
46
- ? datasets_items.find((req) => req.UID === item.dataset_uid)
46
+ ? datasets_items.find((req) => req.UID === item?.dataset_uid)
47
47
  : false;
48
48
  const format_item = dataset.dataset_download_information.items.find(
49
49
  (item) => item['@id'] === data.value,
50
50
  );
51
- new_cartItems[objIndex].format = format_item.full_format;
51
+ new_cartItems[objIndex].format = format_item?.full_format;
52
52
  setCartItems([...new_cartItems]);
53
53
  }}
54
54
  />
@@ -14,7 +14,7 @@ export const FormatNaming = ({
14
14
  originalFormatNaming(item),
15
15
  );
16
16
  const item_format_name = formatNaming(item);
17
- return !item.file_id ? (
17
+ return !item?.file_id ? (
18
18
  format_options.length > 1 ? (
19
19
  <Select
20
20
  placeholder="Select format"
@@ -23,7 +23,7 @@ export const FormatNaming = ({
23
23
  options={format_options}
24
24
  onChange={(e, data) => {
25
25
  const objIndex = cartItems.findIndex(
26
- (obj) => obj.unique_id === item.unique_id,
26
+ (obj) => obj.unique_id === item?.unique_id,
27
27
  );
28
28
  cartItems[objIndex].format = data.value;
29
29
  setCartItems([...cartItems]);
@@ -1,15 +1,15 @@
1
1
  import { Select } from 'semantic-ui-react';
2
2
  export const LayerNaming = ({ item, cartItems, setCartItems }) => {
3
- if (item.file_id) {
3
+ if (item?.file_id) {
4
4
  return '-';
5
- } else if (!item.type) {
5
+ } else if (!item?.type) {
6
6
  return '-';
7
7
  }
8
8
 
9
9
  const this_type_layers = item?.type_options.filter(
10
10
  (o) =>
11
11
  o.collection ===
12
- item?.type_options.find((t_o) => t_o.id === item.type).collection,
12
+ item?.type_options.find((t_o) => t_o.id === item?.type).collection,
13
13
  );
14
14
 
15
15
  return this_type_layers.length > 0 &&
@@ -18,8 +18,8 @@ export const LayerNaming = ({ item, cartItems, setCartItems }) => {
18
18
  placeholder="Select layer"
19
19
  className="layer-selector"
20
20
  value={
21
- item.layer
22
- ? item.layer
21
+ item?.layer
22
+ ? item?.layer
23
23
  : this_type_layers[0].layers.length > 0 &&
24
24
  this_type_layers[0].layers[0]
25
25
  }
@@ -36,7 +36,7 @@ export const LayerNaming = ({ item, cartItems, setCartItems }) => {
36
36
  onChange={(e, data) => {
37
37
  const new_cartItems = [...cartItems];
38
38
  const objIndex = new_cartItems.findIndex(
39
- (obj) => obj.unique_id === item.unique_id,
39
+ (obj) => obj.unique_id === item?.unique_id,
40
40
  );
41
41
  new_cartItems[objIndex].layer = data.value;
42
42
  setCartItems([...new_cartItems]);
@@ -10,15 +10,15 @@ export const TypeNaming = ({
10
10
  }) => {
11
11
  const types_options =
12
12
  item?.type_options?.length > 0
13
- ? [...new Set(item.type_options.map((ddi) => ddi.name))]
13
+ ? [...new Set(item?.type_options.map((ddi) => ddi.name))]
14
14
  : [];
15
- if (item.file_id) {
15
+ if (item?.file_id) {
16
16
  return (
17
17
  <span className={'tag tag-' + item?.type?.toLowerCase()}>
18
- {contentOrDash(item.type)}
18
+ {contentOrDash(item?.type)}
19
19
  </span>
20
20
  );
21
- } else if (!item.type) {
21
+ } else if (!item?.type) {
22
22
  return '-';
23
23
  } else {
24
24
  let defaultType = getCollectionByItem(item);
@@ -40,19 +40,19 @@ export const TypeNaming = ({
40
40
  onChange={(e, data) => {
41
41
  const new_cartItems = [...cartItems];
42
42
  const objIndex = new_cartItems.findIndex(
43
- (obj) => obj.unique_id === item.unique_id,
43
+ (obj) => obj.unique_id === item?.unique_id,
44
44
  );
45
- const first_type_id = item.type_options.filter(
45
+ const first_type_id = item?.type_options.filter(
46
46
  (t_o) => t_o.name === data.value,
47
47
  )[0].id;
48
48
  new_cartItems[objIndex].type = first_type_id;
49
49
  const dataset = datasets_items
50
- ? datasets_items.find((req) => req.UID === item.dataset_uid)
50
+ ? datasets_items.find((req) => req.UID === item?.dataset_uid)
51
51
  : false;
52
52
  const format_item = dataset.dataset_download_information.items.find(
53
53
  (item) => item['@id'] === first_type_id,
54
54
  );
55
- new_cartItems[objIndex].format = format_item.full_format;
55
+ new_cartItems[objIndex].format = format_item?.full_format;
56
56
  setCartItems([...new_cartItems]);
57
57
  }}
58
58
  />
@@ -13,7 +13,7 @@ export const originalFormatNaming = (item) => {
13
13
 
14
14
  export const getCollectionByItem = (item) => {
15
15
  return item?.type_options
16
- ? item.type_options.find((t_o) => t_o['id'] === item.type)
16
+ ? item?.type_options.find((t_o) => t_o['id'] === item?.type)
17
17
  : { id: '' };
18
18
  };
19
19
 
@@ -21,41 +21,41 @@ export const getDownloadToolPostBody = (selectedItems) => {
21
21
  const datasetList = selectedItems.map((item) => {
22
22
  let body_extras = {};
23
23
 
24
- if (item.file_id) {
25
- body_extras['FileID'] = item.file_id;
24
+ if (item?.file_id) {
25
+ body_extras['FileID'] = item?.file_id;
26
26
  } else {
27
- if (item.area?.type === 'polygon') {
28
- body_extras['BoundingBox'] = item.area.value;
27
+ if (item?.area?.type === 'polygon') {
28
+ body_extras['BoundingBox'] = item?.area.value;
29
29
  }
30
- if (item.area?.type === 'nuts') {
31
- body_extras['NUTS'] = item.area.value;
30
+ if (item?.area?.type === 'nuts') {
31
+ body_extras['NUTS'] = item?.area.value;
32
32
  }
33
- // if (item.timeExtent?.length > 0) {
33
+ // if (item?.timeExtent?.length > 0) {
34
34
  // body_extras['TemporalFilter'] = {
35
- // StartDate: item.timeExtent[0],
36
- // EndDate: item.timeExtent[1],
35
+ // StartDate: item?.timeExtent[0],
36
+ // EndDate: item?.timeExtent[1],
37
37
  // };
38
38
  // }
39
- if (item.format) {
39
+ if (item?.format) {
40
40
  body_extras['OutputFormat'] = formatNaming(item);
41
41
  }
42
- if (item.projection) {
43
- body_extras['OutputGCS'] = item.projection;
42
+ if (item?.projection) {
43
+ body_extras['OutputGCS'] = item?.projection;
44
44
  }
45
- if (item.type) {
46
- body_extras['DatasetDownloadInformationID'] = item.type;
45
+ if (item?.type) {
46
+ body_extras['DatasetDownloadInformationID'] = item?.type;
47
47
  }
48
- if (item.layer) {
49
- body_extras['Layer'] = item.layer;
48
+ if (item?.layer) {
49
+ body_extras['Layer'] = item?.layer;
50
50
  }
51
- if (item.TemporalFilter) {
51
+ if (item?.TemporalFilter) {
52
52
  body_extras['TemporalFilter'] = {
53
- StartDate: new Date(item.TemporalFilter?.StartDate).getTime(),
54
- EndDate: new Date(item.TemporalFilter?.EndDate).getTime(),
53
+ StartDate: new Date(item?.TemporalFilter?.StartDate).getTime(),
54
+ EndDate: new Date(item?.TemporalFilter?.EndDate).getTime(),
55
55
  };
56
56
  }
57
57
  }
58
- return { DatasetID: item.dataset_uid, ...body_extras };
58
+ return { DatasetID: item?.dataset_uid, ...body_extras };
59
59
  });
60
60
  return {
61
61
  Datasets: datasetList,
@@ -99,9 +99,9 @@ export const getCartObjectFromMapviewer = (
99
99
  dataset_data.dataset_download_information.items.forEach((item) => {
100
100
  type_options.push({
101
101
  id: item['@id'],
102
- name: item.name,
103
- full_format: item.full_format,
104
- collection: item.collection,
102
+ name: item?.name,
103
+ full_format: item?.full_format,
104
+ collection: item?.collection,
105
105
  layers: item?.layers || [],
106
106
  });
107
107
  });
@@ -149,8 +149,8 @@ export const duplicateCartItem = (
149
149
  unique_id: cartItems[itemIndex].unique_id + '-copy',
150
150
  },
151
151
  );
152
- while (cartItems.some((c_i) => c_i.unique_id === new_item.unique_id)) {
153
- new_item['unique_id'] = new_item.unique_id + '-copy';
152
+ while (cartItems.some((c_i) => c_i.unique_id === new_item?.unique_id)) {
153
+ new_item['unique_id'] = new_item?.unique_id + '-copy';
154
154
  }
155
155
  cartItems.splice(itemIndex + 1, 0, new_item);
156
156
  refreshCart(cartItems, setCartItems, updateCart);
@@ -182,40 +182,43 @@ export const concatRequestedCartItem = (
182
182
  projections,
183
183
  nutsnames,
184
184
  ) => {
185
- let newCartItems = [...cartItems];
186
- [...localSessionCart].reverse().forEach((localItem) => {
187
- const requestedItem = datasets_items
188
- ? datasets_items.find((req) => req.UID === localItem.UID)
189
- : false;
190
- if (requestedItem) {
191
- const file_data = requestedItem?.downloadable_files?.items.find(
192
- (item) => item['@id'] === localItem.file_id,
193
- );
194
- if (file_data) {
195
- newCartItems.push(
196
- getCartObjectFromPrepackaged(file_data, requestedItem),
197
- );
198
- setCartItems(cleanDuplicatesEntries(newCartItems));
199
- } else {
200
- newCartItems.push(
201
- getCartObjectFromMapviewer(
202
- localItem,
203
- requestedItem,
204
- projections,
205
- nutsnames,
206
- ),
207
- );
208
- setCartItems(cleanDuplicatesEntries(newCartItems));
209
- }
210
- }
211
- });
185
+ setCartItems(
186
+ cleanDuplicatesEntries(
187
+ [...localSessionCart]
188
+ .reverse()
189
+ .filter((localItem) => {
190
+ const requestedItem = datasets_items
191
+ ? datasets_items.find((req) => req.UID === localItem?.UID)
192
+ : false;
193
+ return requestedItem;
194
+ })
195
+ .map((localItem) => {
196
+ const requestedItem = datasets_items
197
+ ? datasets_items.find((req) => req.UID === localItem?.UID)
198
+ : false;
199
+ const file_data = requestedItem?.downloadable_files?.items.find(
200
+ (item) => item['@id'] === localItem?.file_id,
201
+ );
202
+ if (file_data) {
203
+ return getCartObjectFromPrepackaged(file_data, requestedItem);
204
+ } else {
205
+ return getCartObjectFromMapviewer(
206
+ localItem,
207
+ requestedItem,
208
+ projections,
209
+ nutsnames,
210
+ );
211
+ }
212
+ }),
213
+ ),
214
+ );
212
215
  };
213
216
 
214
217
  export const isChecked = (cartSelectionCh, cartItemsCh) => {
215
218
  return cartItemsCh.length > 0
216
219
  ? cartItemsCh
217
- .filter((item) => item.task_in_progress === false)
218
- .map((item, key) => item.unique_id)
220
+ .filter((item) => item?.task_in_progress === false)
221
+ .map((item, key) => item?.unique_id)
219
222
  .every(function (val) {
220
223
  return cartSelectionCh.indexOf(val) !== -1;
221
224
  })
@@ -1,6 +1,9 @@
1
1
  export const getAvailableConversion = (conversionTable, defaultValue) => {
2
2
  if (conversionTable) {
3
- if (conversionTable[defaultValue] === undefined) {
3
+ if (
4
+ conversionTable[defaultValue] === undefined ||
5
+ conversionTable[defaultValue] === null
6
+ ) {
4
7
  defaultValue = Object.keys(conversionTable)[0];
5
8
  }
6
9
  const keys = Object.keys(conversionTable[defaultValue]);
@@ -24,7 +27,10 @@ export const initializeIfNotCompatibleConversion = (
24
27
  conversionTable,
25
28
  defaultValue,
26
29
  ) => {
27
- if (conversionTable[defaultValue] === undefined) {
30
+ if (
31
+ conversionTable[defaultValue] === undefined ||
32
+ conversionTable[defaultValue] === null
33
+ ) {
28
34
  defaultValue = Object.keys(conversionTable)[0];
29
35
  }
30
36
  return defaultValue;
@@ -24,7 +24,7 @@ class CLMSNewsletterSubscriberView extends Component {
24
24
  this.handleClick = this.handleClick.bind(this);
25
25
  this.state = {
26
26
  download: false,
27
- headers: [{ label: 'Newsletter subscribers', key: 'email' }],
27
+ headers: [{ label: 'CLMS updates subscribers', key: 'email' }],
28
28
  };
29
29
  }
30
30
  componentDidMount() {
@@ -45,10 +45,10 @@ class CLMSNewsletterSubscriberView extends Component {
45
45
  <Container>
46
46
  <div>
47
47
  <h1 className="page-title">
48
- Download a list of newsletter subscribers
48
+ Download a list of CLMS updates subscribers
49
49
  </h1>
50
50
  <p>
51
- Click in the button below to download a list of all the newsletter
51
+ Click in the button below to download a list of all the CLMS updates
52
52
  subscribers.
53
53
  </p>
54
54
  <CclButton mode={'filled'} onClick={this.handleClick}>
@@ -69,7 +69,7 @@ class CLMSProfileView extends Component {
69
69
  </div>
70
70
  {(this.props.roles?.includes('Manager') ||
71
71
  this.props.roles?.includes('Site Administrator')) && (
72
- <div tabTitle="Newsletter subscribers">
72
+ <div tabTitle="CLMS updates subscribers">
73
73
  <CLMSNewsletterSubscriberView />
74
74
  </div>
75
75
  )}
@@ -275,7 +275,7 @@ class SubscriptionView extends Component {
275
275
  this.props.type === 'events'
276
276
  ? 'event'
277
277
  : this.props.type === 'newsletter'
278
- ? 'the newsletter'
278
+ ? 'the CLMS updates'
279
279
  : this.props.type,
280
280
  })}
281
281
  {this.props.isUnsubscribe === false &&
@@ -284,7 +284,7 @@ class SubscriptionView extends Component {
284
284
  this.props.type === 'events'
285
285
  ? 'event'
286
286
  : this.props.type === 'newsletter'
287
- ? 'the newsletter'
287
+ ? 'the CLMS updates'
288
288
  : this.props.type,
289
289
  })}{' '}
290
290
  {this.props.type !== 'newsletter' &&
@@ -320,7 +320,7 @@ class SubscriptionView extends Component {
320
320
  {
321
321
  type:
322
322
  this.props.type === 'newsletter'
323
- ? 'the newsletter'
323
+ ? 'the CLMS updates'
324
324
  : this.props.type === 'events'
325
325
  ? 'event'
326
326
  : this.props.type,
@@ -420,7 +420,11 @@ class SubscriptionView extends Component {
420
420
  }}
421
421
  >
422
422
  {'Click here if you would like to unsubscribe from our'}{' '}
423
- {this.props.type === 'events' ? 'event' : this.props.type}
423
+ {this.props.type === 'events'
424
+ ? 'event'
425
+ : this.props.type === 'newsletter'
426
+ ? 'CLMS updates'
427
+ : this.props.type}
424
428
  {this.props.type === 'newsletter' ? '' : ' notifications'}
425
429
  </Link>
426
430
  </>
@@ -1,6 +1,6 @@
1
1
  export const AVAILABLE_SUBSCRIPTIONS = [
2
2
  {
3
- title: 'Subscribe to the newsletter',
3
+ title: 'Subscribe to the CLMS updates',
4
4
  type: 'newsletter',
5
5
  back_url: 'newsletter',
6
6
  },
@@ -48,7 +48,16 @@ const DownloadableFilesTableWidget = (props) => {
48
48
  const { schema, uiSchema, ready } = data;
49
49
  const { setSchema, setUISchema, setSchemaHandler } = functions;
50
50
  const [edited, setEdited] = React.useState(false);
51
-
51
+ const table_value =
52
+ props.value?.items.length > 0
53
+ ? [
54
+ ...props.value?.items.map((i) =>
55
+ JSON.parse(orderKeysBy(['@id', ...uiSchema['ui:order']], i)),
56
+ ),
57
+ ]
58
+ : props.default?.items.length > 0
59
+ ? props.default?.items
60
+ : [];
52
61
  return (
53
62
  <>
54
63
  <div className="ui container">
@@ -137,15 +146,7 @@ const DownloadableFilesTableWidget = (props) => {
137
146
  schema={schema}
138
147
  csvexport={true}
139
148
  csvimport={true}
140
- value={
141
- [
142
- ...props.value?.items.map((i) =>
143
- JSON.parse(orderKeysBy(['@id', ...uiSchema['ui:order']], i)),
144
- ),
145
- ] ||
146
- props.default?.items ||
147
- []
148
- }
149
+ value={table_value}
149
150
  onChange={(id, value) =>
150
151
  props.onChange(id, {
151
152
  ...props.value,
@@ -2,28 +2,29 @@
2
2
  * Footer component.
3
3
  * @module components/theme/Footer/Footer
4
4
  */
5
-
6
5
  import React, { Component } from 'react';
7
6
  import { defineMessages, injectIntl } from 'react-intl';
7
+ import { connect } from 'react-redux';
8
+ import { Link } from 'react-router-dom';
9
+ import { ReactSVG } from 'react-svg';
10
+ import { toast } from 'react-toastify';
11
+ import { compose } from 'redux';
8
12
 
13
+ import { Toast } from '@plone/volto/components';
9
14
  import AtmosphereImage from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-icon-atmosphere.svg';
10
- import CclFooterColumn from '@eeacms/volto-clms-theme/components/CclFooterColumn/CclFooterColumn';
11
- import CclFooterMenu from '@eeacms/volto-clms-theme/components/CclTopMainMenu/CclFooterMenu';
12
15
  import ClimateImage from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-icon-climate.svg';
13
- import CopernicusImage from '@eeacms/volto-clms-theme/../theme/clms/img/copernicus_eu_logo_white.svg';
14
- import ECImage from '@eeacms/volto-clms-theme/../theme/clms/img/eea-logo.svg';
15
- import EEAImage from '@eeacms/volto-clms-theme/../theme/clms/img/ec-logo-white.svg';
16
16
  import EmergencyImage from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-icon-emergency.svg';
17
17
  import LandImage from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-icon-land.svg';
18
- import { Link } from 'react-router-dom';
19
18
  import MarineImage from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-icon-marine.svg';
20
- import { ReactSVG } from 'react-svg';
21
19
  import SecurityImage from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-icon-security.svg';
22
- import { Toast } from '@plone/volto/components';
23
- import { compose } from 'redux';
24
- import { connect } from 'react-redux';
20
+ import CopernicusImage from '@eeacms/volto-clms-theme/../theme/clms/img/copernicus_eu_logo_white.svg';
21
+ import EEAImage from '@eeacms/volto-clms-theme/../theme/clms/img/ec-logo-white.svg';
22
+ import ECImage from '@eeacms/volto-clms-theme/../theme/clms/img/eea-logo.svg';
23
+ import CclFooterColumn from '@eeacms/volto-clms-theme/components/CclFooterColumn/CclFooterColumn';
24
+ import CclFooterMenu from '@eeacms/volto-clms-theme/components/CclTopMainMenu/CclFooterMenu';
25
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
25
26
  import { subscribeTo } from '../../../../../actions';
26
- import { toast } from 'react-toastify';
27
+ import { faLinkedin } from '@fortawesome/free-brands-svg-icons';
27
28
  import validator from 'validator';
28
29
 
29
30
  const messages = defineMessages({
@@ -370,7 +371,7 @@ class Footer extends Component {
370
371
  </CclFooterColumn>
371
372
  <div className="ccl-footer-col">
372
373
  <div className="ccl-footer-form-title">
373
- Sign up to our newsletter
374
+ Sign up to CLMS updates
374
375
  </div>
375
376
  <form action="" className="ccl-footer-form">
376
377
  <div className="ccl-footer-newsletter">
@@ -435,7 +436,7 @@ class Footer extends Component {
435
436
  </div>
436
437
  <div className="ccl-footer-social">
437
438
  <a
438
- href="https://www.youtube.com/channel/UCpuwnbuwGG20enAdE50g6TA"
439
+ href="https://www.youtube.com/playlist?list=PL1_QSyumTz7CZQEZ-1foOTeTOelKDQmxu"
439
440
  target="_blank"
440
441
  rel="noreferrer"
441
442
  aria-label="Youtube"
@@ -458,8 +459,17 @@ class Footer extends Component {
458
459
  >
459
460
  <span className="ccl-icon-facebook"></span>
460
461
  </a>
462
+ <a
463
+ href="https://www.linkedin.com/showcase/copernicus-eea"
464
+ target="_blank"
465
+ rel="noreferrer"
466
+ aria-label="Linkedin"
467
+ >
468
+ <FontAwesomeIcon icon={faLinkedin} />
469
+ </a>
461
470
  </div>
462
471
  </div>
472
+
463
473
  <CclFooterColumn title={'Implemented by'}>
464
474
  <div className="footer-implemented footer-implemented-eea">
465
475
  <a
@@ -497,9 +507,17 @@ class Footer extends Component {
497
507
  wrapper="div"
498
508
  />
499
509
  </a>
500
- <span>
501
- {this.props.intl.formatMessage(messages.jointResearchCenter)}
502
- </span>
510
+ <a
511
+ href="https://joint-research-centre.ec.europa.eu/index_en"
512
+ target="_blank"
513
+ rel="noreferrer"
514
+ >
515
+ <span>
516
+ {this.props.intl.formatMessage(
517
+ messages.jointResearchCenter,
518
+ )}
519
+ </span>
520
+ </a>
503
521
  </div>
504
522
  {/* <div className="ccl-footer-col-title">
505
523
  {intl.formatMessage(messages.expertSupportProvidedBy)}