@eeacms/volto-clms-theme 1.0.111 → 1.0.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,8 +4,19 @@ All notable changes to this project will be documented in this file. Dates are d
4
4
 
5
5
  Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
6
 
7
+ #### [1.0.112](https://github.com/eea/volto-clms-theme/compare/1.0.111...1.0.112)
8
+
9
+ - import fields [`#284`](https://github.com/eea/volto-clms-theme/pull/284)
10
+ - search filters checkbox unification [`0cd48bc`](https://github.com/eea/volto-clms-theme/commit/0cd48bc9a873ec1b3c4a082c4ec3519fbc3cef6d)
11
+ - check also childless parents CLMS-987 [`641a887`](https://github.com/eea/volto-clms-theme/commit/641a887e9e36f0f2e04aa8eb5362065ed53380a3)
12
+ - User profile form changes [`a7f7a63`](https://github.com/eea/volto-clms-theme/commit/a7f7a63a288f35037fc42a7af6761071c889e7ad)
13
+ - added UniversalLink to relatedItems [`46cb0c5`](https://github.com/eea/volto-clms-theme/commit/46cb0c5e6abb6658d0ec8108ba1eb1cf136d5e2f)
14
+
7
15
  #### [1.0.111](https://github.com/eea/volto-clms-theme/compare/1.0.110...1.0.111)
8
16
 
17
+ > 2 August 2022
18
+
19
+ - Develop [`#283`](https://github.com/eea/volto-clms-theme/pull/283)
9
20
  - bump accordion block [`f64f037`](https://github.com/eea/volto-clms-theme/commit/f64f037cbcb1200f15d70590beaf4131f7bf464d)
10
21
  - Use Case view [`c60b74f`](https://github.com/eea/volto-clms-theme/commit/c60b74f110f98faff7d15a42167e45e410efeec1)
11
22
  - textWidget limit to 1000 characters and textAreaWidget show error with more than 8000 characters [`662f035`](https://github.com/eea/volto-clms-theme/commit/662f035fa9ecd7b61b7bb8aa17acb0ce89718df8)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-clms-theme",
3
- "version": "1.0.111",
3
+ "version": "1.0.112",
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",
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Post meeting register actions.
3
+ * @module actions/postImportGeonetwork
4
+ */
5
+ export const POST_IMPORT_WMS_FIELDS = 'POST_IMPORT_WMS_FIELDS';
6
+
7
+ /**
8
+ * Post import geonetwork.
9
+ * @function postImportWMSFields
10
+ * @returns {Object} Get extra items action.
11
+ */
12
+ export function postImportWMSFields(url, id, type) {
13
+ return {
14
+ type: POST_IMPORT_WMS_FIELDS,
15
+ request: {
16
+ op: 'post',
17
+ path: `${url}/@import-wms-fields`,
18
+ },
19
+ };
20
+ }
@@ -87,3 +87,8 @@ export {
87
87
  POST_IMPORT_WMS_LAYERS,
88
88
  postImportWMSLayers,
89
89
  } from './import_wms_layers/import_wms_layers';
90
+
91
+ export {
92
+ POST_IMPORT_WMS_FIELDS,
93
+ postImportWMSFields,
94
+ } from './import_wms_fields/import_wms_fields';
@@ -1,6 +1,5 @@
1
1
  import { defineMessages, useIntl } from 'react-intl';
2
2
 
3
- import { Link } from 'react-router-dom';
4
3
  import React from 'react';
5
4
 
6
5
  const messages = defineMessages({
@@ -14,20 +13,10 @@ const messages = defineMessages({
14
13
  },
15
14
  });
16
15
 
17
- function hasProtocol(url) {
18
- if (url) {
19
- return url.startsWith('https://') || url.startsWith('http://')
20
- ? true
21
- : false;
22
- }
23
- return false;
24
- }
25
-
26
16
  const CclHomeSearchBlockView = (props) => {
27
17
  const { data, searchText } = props;
28
18
  var SearchText = searchText || '';
29
19
  const intl = useIntl();
30
- let url = data?.link?.[0]?.['@id'];
31
20
 
32
21
  function handleChange(event) {
33
22
  SearchText = event.target.value;
@@ -68,14 +57,6 @@ const CclHomeSearchBlockView = (props) => {
68
57
  </button>
69
58
  </form>
70
59
  </div>
71
- <div className="home-datasets-text">
72
- <span>{intl.formatMessage(messages.countText, { count: 999 })}</span>
73
- {url && hasProtocol(url) ? (
74
- <a href={url}>{data.linkText}</a>
75
- ) : (
76
- <Link to={url}>{data.linkText}</Link>
77
- )}
78
- </div>
79
60
  </div>
80
61
  </div>
81
62
  );
@@ -4,7 +4,7 @@ export const HomeSearchSchema = () => ({
4
4
  {
5
5
  id: 'default',
6
6
  title: 'Default',
7
- fields: ['title', 'linkText', 'link'],
7
+ fields: ['title'],
8
8
  },
9
9
  ],
10
10
  properties: {
@@ -12,19 +12,6 @@ export const HomeSearchSchema = () => ({
12
12
  title: 'Title',
13
13
  type: 'string',
14
14
  },
15
- linkText: {
16
- title: 'Link text',
17
- description: 'Text for the link to the catalogue',
18
- type: 'string',
19
- },
20
- link: {
21
- title: 'Link',
22
- description: 'Select site content or paste external url',
23
- widget: 'object_browser',
24
- mode: 'link',
25
- selectedItemAttrs: ['Title', 'Description', '@type', '@id'],
26
- allowExternals: true,
27
- },
28
15
  },
29
16
  required: ['title'],
30
17
  });
@@ -1,4 +1,4 @@
1
- import { Checkbox } from 'semantic-ui-react';
1
+ import { Checkbox, List } from 'semantic-ui-react';
2
2
  import React from 'react';
3
3
  import {
4
4
  selectFacetSchemaEnhancer,
@@ -47,38 +47,46 @@ const AccordionFacet = (props) => {
47
47
  <legend className="ccl-form-legend">{facet.title}</legend>
48
48
  </div>
49
49
  <Wrapper typeName={typeName}>
50
- {choices.map((choice, i) => (
51
- <div
52
- className={
53
- typeName === 'checkbox' ? 'ccl-form-group' : 'filters-tag'
54
- }
55
- key={choice.value}
56
- >
57
- <Checkbox
58
- disabled={isEditMode}
59
- label={choice.label}
60
- radio={!isMulti}
61
- checked={
62
- isMulti
63
- ? !!facetValue?.find((f) => f.value === choice.value)
64
- : facetValue && facetValue.value === choice.value
65
- }
66
- onChange={(e, { checked }) =>
67
- onChange(
68
- facet.field.value,
69
- isMulti
70
- ? [
71
- ...facetValue
72
- .filter((f) => f.value !== choice.value)
73
- .map((f) => f.value),
74
- ...(checked ? [choice.value] : []),
75
- ]
76
- : isChoiceValue(checked, choice.value),
77
- )
78
- }
79
- />
80
- </div>
81
- ))}
50
+ <List>
51
+ {choices.map((choice, i) => (
52
+ <List.Item
53
+ key={choice.value}
54
+ style={{
55
+ paddingLeft: '15px',
56
+ paddingBottom: '15px',
57
+ paddingTop: '10px',
58
+ }}
59
+ >
60
+ <List.Content>
61
+ <List.Header>
62
+ <Checkbox
63
+ disabled={isEditMode}
64
+ label={choice.label}
65
+ radio={!isMulti}
66
+ checked={
67
+ isMulti
68
+ ? !!facetValue?.find((f) => f.value === choice.value)
69
+ : facetValue && facetValue.value === choice.value
70
+ }
71
+ onChange={(e, { checked }) =>
72
+ onChange(
73
+ facet.field.value,
74
+ isMulti
75
+ ? [
76
+ ...facetValue
77
+ .filter((f) => f.value !== choice.value)
78
+ .map((f) => f.value),
79
+ ...(checked ? [choice.value] : []),
80
+ ]
81
+ : isChoiceValue(checked, choice.value),
82
+ )
83
+ }
84
+ />
85
+ </List.Header>
86
+ </List.Content>
87
+ </List.Item>
88
+ ))}
89
+ </List>
82
90
  </Wrapper>
83
91
  </fieldset>
84
92
  );
@@ -10,6 +10,7 @@ import {
10
10
  selectFacetStateToValue,
11
11
  selectFacetValueToQuery,
12
12
  } from '@plone/volto/components/manage/Blocks/Search/components/base';
13
+ import { checkAllChildren } from './utils';
13
14
 
14
15
  const hasAllChildrensSelected = (value, childrens) => {
15
16
  var result = true;
@@ -24,20 +25,21 @@ const hasAllChildrensSelected = (value, childrens) => {
24
25
  return result;
25
26
  };
26
27
 
27
- const checkAllChildren = (value, childrens) => {
28
- if (!childrens || childrens.length === 0) {
29
- return value;
28
+ const Wrapper = ({ typeName, children }) => {
29
+ if (typeName === 'checkbox') {
30
+ return <div className="ccl-form">{children}</div>;
31
+ } else if (typeName === 'label') {
32
+ return (
33
+ <div>
34
+ <div className="filters-tag-container">{children}</div>
35
+ </div>
36
+ );
30
37
  }
31
- childrens.forEach((ch) => {
32
- if (value.filter((v) => v.value === ch.value).length === 0) {
33
- value.push(ch);
34
- }
35
- });
36
- return value;
37
38
  };
38
39
 
39
40
  const CheckboxTreeFacet = (props) => {
40
- const { facet, choices, onChange, value } = props;
41
+ const { facet, choices, onChange, value, typeName } = props;
42
+
41
43
  const facetValue = value;
42
44
  var [open, setOpen] = useState(false);
43
45
  let options = [];
@@ -56,7 +58,7 @@ const CheckboxTreeFacet = (props) => {
56
58
  >
57
59
  <legend className="ccl-form-legend">{facet.title}</legend>
58
60
  </div>
59
- <div>
61
+ <Wrapper typeName={typeName}>
60
62
  <List>
61
63
  {options.map((option) => (
62
64
  <CheckboxListParent
@@ -68,7 +70,7 @@ const CheckboxTreeFacet = (props) => {
68
70
  />
69
71
  ))}
70
72
  </List>
71
- </div>
73
+ </Wrapper>
72
74
  </fieldset>
73
75
  );
74
76
  };
@@ -88,9 +90,7 @@ const CheckboxListParent = ({ option, key, onChange, value, id }) => {
88
90
  checked
89
91
  ? onChange(id, [
90
92
  // if this option has children, check them all
91
- ...checkAllChildren(value, option.childrens).map(
92
- (f) => f.value,
93
- ),
93
+ ...checkAllChildren(value, option).map((f) => f.value),
94
94
  ])
95
95
  : onChange(id, [
96
96
  ...value
@@ -10,6 +10,7 @@ import {
10
10
  selectFacetStateToValue,
11
11
  selectFacetValueToQuery,
12
12
  } from '@plone/volto/components/manage/Blocks/Search/components/base';
13
+ import { checkAllChildren } from './utils';
13
14
 
14
15
  const hasAllChildrensSelected = (value, childrens) => {
15
16
  var result = true;
@@ -24,20 +25,20 @@ const hasAllChildrensSelected = (value, childrens) => {
24
25
  return result;
25
26
  };
26
27
 
27
- const checkAllChildren = (value, childrens) => {
28
- if (!childrens || childrens.length === 0) {
29
- return value;
28
+ const Wrapper = ({ typeName, children }) => {
29
+ if (typeName === 'checkbox') {
30
+ return <div className="ccl-form">{children}</div>;
31
+ } else if (typeName === 'label') {
32
+ return (
33
+ <div>
34
+ <div className="filters-tag-container">{children}</div>
35
+ </div>
36
+ );
30
37
  }
31
- childrens.forEach((ch) => {
32
- if (value.filter((v) => v.value === ch.value).length === 0) {
33
- value.push(ch);
34
- }
35
- });
36
- return value;
37
38
  };
38
39
 
39
40
  const CheckboxTreeParentFacet = (props) => {
40
- const { facet, choices, onChange, value } = props;
41
+ const { facet, choices, onChange, value, typeName } = props;
41
42
  const facetValue = value;
42
43
  var [open, setOpen] = useState(false);
43
44
  let options = [];
@@ -56,7 +57,7 @@ const CheckboxTreeParentFacet = (props) => {
56
57
  >
57
58
  <legend className="ccl-form-legend">{facet.title}</legend>
58
59
  </div>
59
- <div>
60
+ <Wrapper typeName={typeName}>
60
61
  <List>
61
62
  {options.map((option) => (
62
63
  <CheckboxListParent
@@ -68,7 +69,7 @@ const CheckboxTreeParentFacet = (props) => {
68
69
  />
69
70
  ))}
70
71
  </List>
71
- </div>
72
+ </Wrapper>
72
73
  </fieldset>
73
74
  );
74
75
  };
@@ -85,12 +86,10 @@ const CheckboxListParent = ({ option, key, onChange, value, id }) => {
85
86
  key={option.value}
86
87
  name={`field-${option.value}`}
87
88
  onChange={(event, { checked }) => {
88
- checked
89
+ return checked
89
90
  ? onChange(id, [
90
91
  // if this option has children, check them all
91
- ...checkAllChildren(value, option.childrens).map(
92
- (f) => f.value,
93
- ),
92
+ ...checkAllChildren(value, option).map((f) => f.value),
94
93
  ])
95
94
  : onChange(id, [
96
95
  ...value
@@ -0,0 +1,11 @@
1
+ export const checkAllChildren = (value, option) => {
2
+ if (!option?.childrens || option.childrens.length === 0) {
3
+ return [...value, { label: option.label, value: option.value }];
4
+ }
5
+ option.childrens.forEach((ch) => {
6
+ if (value.filter((v) => v.value === ch.value).length === 0) {
7
+ value.push(ch);
8
+ }
9
+ });
10
+ return value;
11
+ };
@@ -328,7 +328,7 @@ const customBlocks = (config) => ({
328
328
  {
329
329
  id: 'doubleRangeFacet',
330
330
  title: 'Double Range',
331
- view: DoubleRangeFacet,
331
+ view: WithType(DoubleRangeFacet, 'range'),
332
332
  isDefault: false,
333
333
  schemaEnhancer: DoubleRangeFacet.schemaEnhancer,
334
334
  stateToValue: DoubleRangeFacet.stateToValue,
@@ -338,7 +338,7 @@ const customBlocks = (config) => ({
338
338
  {
339
339
  id: 'checkboxTreeFacet',
340
340
  title: 'Checkbox Tree',
341
- view: CheckboxTreeFacet,
341
+ view: WithType(CheckboxTreeFacet, 'checkbox'),
342
342
  isDefault: false,
343
343
  schemaEnhancer: CheckboxTreeFacet.schemaEnhancer,
344
344
  stateToValue: CheckboxTreeFacet.stateToValue,
@@ -348,7 +348,7 @@ const customBlocks = (config) => ({
348
348
  {
349
349
  id: 'checkboxTreeParentFacet',
350
350
  title: 'Checkbox Tree Parents',
351
- view: CheckboxTreeParentFacet,
351
+ view: WithType(CheckboxTreeParentFacet, 'checkbox'),
352
352
  isDefault: false,
353
353
  schemaEnhancer: CheckboxTreeParentFacet.schemaEnhancer,
354
354
  stateToValue: CheckboxTreeParentFacet.stateToValue,
@@ -11,7 +11,11 @@ import {
11
11
  } from '@eeacms/volto-clms-theme/components/CLMSDatasetDetailView';
12
12
  import { Modal, Segment } from 'semantic-ui-react';
13
13
  import { connect, useDispatch, useSelector } from 'react-redux';
14
- import { postImportGeonetwork, postImportWMSLayers } from '../../actions';
14
+ import {
15
+ postImportGeonetwork,
16
+ postImportWMSLayers,
17
+ postImportWMSFields,
18
+ } from '../../actions';
15
19
 
16
20
  import CclButton from '@eeacms/volto-clms-theme/components/CclButton/CclButton';
17
21
  import CclTabs from '@eeacms/volto-clms-theme/components/CclTab/CclTabs';
@@ -37,6 +41,7 @@ const CLMSDatasetDetailView = ({ content, token }) => {
37
41
  (state) => state.geonetwork_importation,
38
42
  );
39
43
  const wms_layers_importation = useSelector((state) => state.importWMSLayers);
44
+ const wms_fields_importation = useSelector((state) => state.importWMSFields);
40
45
  const user = useSelector((state) => state.users?.user);
41
46
  React.useEffect(() => {
42
47
  dispatch(getUser(token));
@@ -50,6 +55,10 @@ const CLMSDatasetDetailView = ({ content, token }) => {
50
55
  dispatch(postImportWMSLayers(location.pathname));
51
56
  }
52
57
 
58
+ function handleWMSFieldimport() {
59
+ dispatch(postImportWMSFields(location.pathname));
60
+ }
61
+
53
62
  const [open, setOpen] = React.useState({});
54
63
  const locale = useSelector((state) => state.intl.locale);
55
64
 
@@ -282,6 +291,100 @@ const CLMSDatasetDetailView = ({ content, token }) => {
282
291
  </Segment.Group>
283
292
  )}
284
293
 
294
+ {user?.roles && user.roles.includes('Manager') && (
295
+ <Segment.Group compact horizontal>
296
+ <Segment
297
+ padded={'very'}
298
+ color={'olive'}
299
+ key={'wms-fields-import'}
300
+ loading={wms_fields_importation?.loading}
301
+ circular
302
+ >
303
+ <Modal
304
+ onClose={() => {
305
+ setOpen({ ...open, 'wms-fields-import': false });
306
+ }}
307
+ onOpen={() => {
308
+ setOpen({ ...open, 'wms-fields-import': true });
309
+ }}
310
+ open={open['wms-fields-import']}
311
+ trigger={
312
+ <CclButton>
313
+ <FormattedMessage
314
+ id="Import WMS Fields"
315
+ defaultMessage="Import WMS Fields"
316
+ />
317
+ </CclButton>
318
+ }
319
+ className={'modal-clms'}
320
+ >
321
+ <div className={'modal-clms-background'}>
322
+ <div className={'modal-clms-container'}>
323
+ <div className={'modal-close modal-clms-close'}>
324
+ <span
325
+ className="ccl-icon-close"
326
+ aria-label="Close"
327
+ onClick={() => {
328
+ setOpen({ ...open, 'wms-fields-import': false });
329
+ }}
330
+ onKeyDown={() => {
331
+ setOpen({ ...open, 'wms-fields-import': false });
332
+ }}
333
+ tabIndex="0"
334
+ role="button"
335
+ ></span>
336
+ </div>
337
+ <div className="modal-login-text">
338
+ <h1>
339
+ <FormattedMessage
340
+ id="Import WMS Fields"
341
+ defaultMessage="Import WMS Fields"
342
+ />
343
+ </h1>
344
+ This action will import the WMS Fields from the view service
345
+ defined in the dataset if this WMS service is Arcgis based
346
+ <br />
347
+ <br />
348
+ </div>
349
+ <CclButton
350
+ onClick={() => {
351
+ handleWMSFieldimport();
352
+ setOpen({ ...open, 'wms-fields-import': false });
353
+ }}
354
+ mode="filled"
355
+ >
356
+ <FormattedMessage
357
+ id="Import data"
358
+ defaultMessage="Import data"
359
+ />
360
+ </CclButton>
361
+ </div>
362
+ </div>
363
+ </Modal>
364
+ {wms_fields_importation?.imported_wms_fields?.status && (
365
+ <p>
366
+ {wms_fields_importation?.loaded &&
367
+ wms_fields_importation?.error === null && (
368
+ <strong>
369
+ {' '}
370
+ {wms_fields_importation?.imported_wms_fields?.message}
371
+ </strong>
372
+ )}
373
+ </p>
374
+ )}
375
+ {wms_fields_importation?.imported_wms_fields?.status ===
376
+ 'error' && (
377
+ <p>
378
+ <strong>
379
+ {' '}
380
+ {wms_fields_importation?.imported_wms_fields?.message}
381
+ </strong>
382
+ </p>
383
+ )}
384
+ </Segment>
385
+ </Segment.Group>
386
+ )}
387
+
285
388
  <CclTabs routing={true}>
286
389
  <div tabTitle="General Info">{DataSetInfoContent(content)}</div>
287
390
  <div tabTitle="Use cases">{RelatedUseCases(content)}</div>
@@ -45,7 +45,6 @@ const CLMSNewsItemView = (props) => {
45
45
  ? iTitleIcons.rightPosition
46
46
  : iTitleIcons.leftPosition;
47
47
  }
48
-
49
48
  return (
50
49
  <div className="ccl-container">
51
50
  {hasBlocksData(content) && content.blocks_layout?.items?.length > 4 ? (
@@ -1,5 +1,6 @@
1
1
  import { Grid, Image } from 'semantic-ui-react';
2
2
  import PlaceHolder from '@eeacms/volto-clms-theme/../theme/clms/img/ccl-thumbnail-placeholder.jpg';
3
+ import { UniversalLink } from '@plone/volto/components';
3
4
 
4
5
  const CLMSRelatedItems = (props) => {
5
6
  const { items } = props;
@@ -24,9 +25,12 @@ const CLMSRelatedItems = (props) => {
24
25
  )}
25
26
  </Grid.Column>
26
27
  <Grid.Column width={9}>
27
- <a href={item['@id']}>
28
+ <UniversalLink href={`${item['@id']}`}>
29
+ <strong>{item?.title}</strong>
30
+ </UniversalLink>
31
+ {/* <a href={item['@id']}>
28
32
  <strong>{item.title}</strong>
29
- </a>
33
+ </a> */}
30
34
  {item?.description && <p>{item.description}</p>}
31
35
  </Grid.Column>
32
36
  </Grid>
@@ -24,8 +24,16 @@ import validator from 'validator';
24
24
 
25
25
  const messages = defineMessages({
26
26
  subscribeToThe: {
27
- id: '{subscribe_or_unsubscribe} to receive the {type}',
28
- defaultMessage: '{subscribe_or_unsubscribe} to receive the {type}',
27
+ id: 'subscribe to receive the {type}',
28
+ defaultMessage: 'Subscribe to receive the {type}',
29
+ },
30
+ unsubscribeFromThe: {
31
+ id: 'unsubscribe from the {type}',
32
+ defaultMessage: 'Unsubscribe from the {type}',
33
+ },
34
+ notifications: {
35
+ id: 'notifications',
36
+ defaultMessage: 'notifications',
29
37
  },
30
38
  emailTitle: {
31
39
  id: 'E-mail',
@@ -33,7 +41,7 @@ const messages = defineMessages({
33
41
  },
34
42
  emailDescription: {
35
43
  id: 'We will use this address to send you the {type}',
36
- defaultMessage: 'We will use this address to send you the {type}',
44
+ defaultMessage: 'We will use this address to send you the {type} ',
37
45
  },
38
46
  saved: {
39
47
  id: 'Changes saved',
@@ -65,7 +73,8 @@ const messages = defineMessages({
65
73
  },
66
74
  invalid_email: {
67
75
  id: 'The entered email address is not valid',
68
- defaultMessage: 'The entered email address is not valid',
76
+ defaultMessage:
77
+ 'You must agree privacy policy and enter a valid email address',
69
78
  },
70
79
  subscribe: {
71
80
  id: 'Subscribe',
@@ -79,6 +88,14 @@ const messages = defineMessages({
79
88
  id: 'Write your email in the field',
80
89
  defaultMessage: 'Write your email in the field',
81
90
  },
91
+ agreePrivacyPolicy: {
92
+ id: 'agreePrivacyPolicy',
93
+ defaultMessage: 'I agree to the ',
94
+ },
95
+ agreePrivacyPolicyLinkText: {
96
+ id: 'agreePrivacyPolicyLinkText',
97
+ defaultMessage: 'privacy policy.',
98
+ },
82
99
  });
83
100
 
84
101
  /**
@@ -100,18 +117,26 @@ class SubscriptionView extends Component {
100
117
  super(props);
101
118
  this.handleChange = this.handleChange.bind(this);
102
119
  this.onSubmit = this.onSubmit.bind(this);
120
+ this.handleInputChange = this.handleInputChange.bind(this);
103
121
  this.state = {
104
122
  value: '',
105
123
  type_conf: null,
124
+ inputValue: false,
106
125
  };
107
126
  }
108
127
 
109
128
  componentDidMount() {
110
129
  const type_conf = getSubscriptionConfig(this.props.type);
111
- this.setState({ type_conf });
130
+ this.setState({ type_conf, inputValue: this.state.inputValue });
112
131
  this.props.getExtraBreadcrumbItems([]);
113
132
  }
114
133
 
134
+ handleInputChange() {
135
+ this.setState({
136
+ inputValue: !this.state.inputValue,
137
+ });
138
+ }
139
+
115
140
  handleChange(event) {
116
141
  this.setState({
117
142
  value: event.target.value,
@@ -213,19 +238,28 @@ class SubscriptionView extends Component {
213
238
  {this.state.type_conf ? (
214
239
  <Container>
215
240
  <h1 className="page-title">
216
- {this.props.intl.formatMessage(messages.subscribeToThe, {
217
- type: this.props.type,
218
- subscribe_or_unsubscribe: this.props.isUnsubscribe
219
- ? this.props.intl.formatMessage(messages.unsubscribe)
220
- : this.props.intl.formatMessage(messages.subscribe),
221
- })}
241
+ {this.props.isUnsubscribe && this.props.type !== 'newsletter'
242
+ ? this.props.intl.formatMessage(messages.unsubscribeFromThe, {
243
+ type: this.props.type,
244
+ }) +
245
+ ' ' +
246
+ this.props.intl.formatMessage(messages.notifications)
247
+ : this.props.isUnsubscribe && this.props.type === 'newsletter'
248
+ ? this.props.intl.formatMessage(messages.unsubscribeFromThe, {
249
+ type: this.props.type,
250
+ })
251
+ : this.props.intl.formatMessage(messages.subscribeToThe, {
252
+ type: this.props.type,
253
+ })}
222
254
  </h1>
223
255
  <Form
224
256
  className="ccl-form user-form contact-form"
225
257
  size={'large'}
226
258
  onSubmit={
227
259
  validator.isEmail(this.state.value)
228
- ? this.onSubmit
260
+ ? this.state.inputValue === true
261
+ ? this.onSubmit
262
+ : this.invalidEmailErrorToast
229
263
  : this.invalidEmailErrorToast
230
264
  }
231
265
  >
@@ -238,11 +272,20 @@ class SubscriptionView extends Component {
238
272
  {this.props.intl.formatMessage(messages.emailTitle)}
239
273
  </label>
240
274
  <span className="label-required">*</span>
241
- <p>
242
- {this.props.intl.formatMessage(messages.emailDescription, {
243
- type: this.props.type,
244
- })}
245
- </p>
275
+ {this.props.isUnsubscribe ? (
276
+ ''
277
+ ) : (
278
+ <p>
279
+ {this.props.intl.formatMessage(
280
+ messages.emailDescription,
281
+ {
282
+ type: this.props.type,
283
+ },
284
+ )}
285
+ {this.props.type !== 'newsletter' &&
286
+ this.props.intl.formatMessage(messages.notifications)}
287
+ </p>
288
+ )}
246
289
  <Form.Group inline widths="equal">
247
290
  <Form.Input
248
291
  maxLength={8000}
@@ -264,6 +307,34 @@ class SubscriptionView extends Component {
264
307
  </Form.Group>
265
308
  </div>
266
309
  </div>
310
+ {!this.props.isUnsubscribe && (
311
+ <div className="ccl-form footer-privacy-check ccl-profile-privacy">
312
+ <div className="ccl-form-group">
313
+ <input
314
+ type="checkbox"
315
+ id="footer_privacy"
316
+ name="footerPrivacy"
317
+ value={this.state.inputValue}
318
+ onClick={this.handleInputChange}
319
+ className="ccl-checkbox ccl-form-check-input"
320
+ required={true}
321
+ />
322
+ <label
323
+ className="ccl-form-check-label"
324
+ htmlFor="footer_privacy"
325
+ >
326
+ {this.props.intl.formatMessage(
327
+ messages.agreePrivacyPolicy,
328
+ )}
329
+ <Link to={`/${this.props.lang}/personal-data-protection`}>
330
+ {this.props.intl.formatMessage(
331
+ messages.agreePrivacyPolicyLinkText,
332
+ )}
333
+ </Link>
334
+ </label>
335
+ </div>
336
+ </div>
337
+ )}
267
338
  </Form>
268
339
  {!this.props.isUnsubscribe && (
269
340
  <>
@@ -272,7 +343,8 @@ class SubscriptionView extends Component {
272
343
  pathname: `/${this.props.intl.locale}/unsubscribe/${this.props.type}`,
273
344
  }}
274
345
  >
275
- UNSUBSCRIBE
346
+ {'Click here if you would like to unsubscribe from our'}{' '}
347
+ {this.props.type} {'notifications'}
276
348
  </Link>
277
349
  </>
278
350
  )}
@@ -289,6 +361,7 @@ export default compose(
289
361
  injectIntl,
290
362
  connect(
291
363
  (state, props) => ({
364
+ lang: state.intl.locale,
292
365
  loaded: state.subscription.loaded,
293
366
  loading: state.subscription.loading,
294
367
  error: state.subscription.error,
@@ -1,16 +1,16 @@
1
1
  export const AVAILABLE_SUBSCRIPTIONS = [
2
2
  {
3
- title: 'Subscribe to our newsletter',
3
+ title: 'Subscribe to the newsletter',
4
4
  type: 'newsletter',
5
5
  back_url: 'newsletter',
6
6
  },
7
7
  {
8
- title: 'Subscribe to our news',
8
+ title: 'Subscribe to news notifications',
9
9
  type: 'news',
10
10
  back_url: 'newsitem',
11
11
  },
12
12
  {
13
- title: 'Subscribe to our events',
13
+ title: 'Subscribe to event notifications',
14
14
  type: 'events',
15
15
  back_url: 'event',
16
16
  },
@@ -34,12 +34,25 @@ const ItemSchema = {
34
34
  type: 'string',
35
35
  default: '',
36
36
  },
37
+ fields: {
38
+ title: 'Fields to be shown in the mapviewer',
39
+ description: 'Enter the JSON representing the fields',
40
+ type: 'text',
41
+ default: '',
42
+ },
37
43
  },
38
44
  fieldsets: [
39
45
  {
40
46
  id: 'default',
41
47
  title: 'Layer',
42
- fields: ['id', 'title', 'default_active', 'hide', 'static_legend_url'],
48
+ fields: [
49
+ 'id',
50
+ 'title',
51
+ 'default_active',
52
+ 'hide',
53
+ 'static_legend_url',
54
+ 'fields',
55
+ ],
43
56
  },
44
57
  ],
45
58
  required: [],
@@ -135,7 +135,7 @@ class Footer extends Component {
135
135
  componentDidMount() {
136
136
  this.setState({
137
137
  value: '',
138
- inputValue: false,
138
+ inputValue: this.state.inputValue,
139
139
  lang: this.props.intl.locale,
140
140
  });
141
141
  }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @module reducers/import_wms_fields
3
+ */
4
+
5
+ import { POST_IMPORT_WMS_FIELDS } from '../../actions';
6
+
7
+ const initialState = {
8
+ error: null,
9
+ loaded: false,
10
+ loading: false,
11
+ imported_wms_fields: {},
12
+ };
13
+
14
+ export const importWMSFieldsReducer = (state = initialState, action = {}) => {
15
+ switch (action?.type) {
16
+ case `${POST_IMPORT_WMS_FIELDS}_PENDING`:
17
+ return {
18
+ ...state,
19
+ error: null,
20
+ loaded: false,
21
+ loading: true,
22
+ imported_wms_fields: {},
23
+ };
24
+ case `${POST_IMPORT_WMS_FIELDS}_FAIL`:
25
+ return {
26
+ ...state,
27
+ error: action.error,
28
+ loaded: false,
29
+ loading: false,
30
+ imported_wms_fields: {},
31
+ };
32
+
33
+ case `${POST_IMPORT_WMS_FIELDS}_SUCCESS`:
34
+ return {
35
+ ...state,
36
+ error: null,
37
+ loaded: true,
38
+ loading: false,
39
+ imported_wms_fields: action.result,
40
+ };
41
+ default:
42
+ return state;
43
+ }
44
+ };
@@ -16,6 +16,7 @@ import { subscribeToReducer } from './subscription/subscription_reducer';
16
16
  import tokens from './tokens/tokens';
17
17
  import { userschemaReducer } from './userschema/userschema';
18
18
  import { importWMSLayersReducer } from './import_wms_layers/import_wms_layers_reducer';
19
+ import { importWMSFieldsReducer } from './import_wms_fields/import_wms_fields_reducer';
19
20
 
20
21
  /**
21
22
  * Root reducer.
@@ -41,6 +42,7 @@ const reducers = {
41
42
  newsletter_subscribers: newsletterSubscribersReducer,
42
43
  subscription: subscribeToReducer,
43
44
  importWMSLayers: importWMSLayersReducer,
45
+ importWMSFields: importWMSFieldsReducer,
44
46
  };
45
47
 
46
48
  export default reducers;
@@ -702,6 +702,11 @@ body:not(.contenttype-lrf:not(.section-cart):not(.section-profile))
702
702
  margin-bottom: 2rem;
703
703
  }
704
704
 
705
+ .ccl-profile-privacy {
706
+ margin-top: 2rem;
707
+ margin-bottom: 2rem;
708
+ }
709
+
705
710
  .user-form .ccl-form-label {
706
711
  display: inline-block;
707
712
  font-size: 1.125rem;