@eeacms/volto-clms-theme 1.0.103 → 1.0.106

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 (27) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/package.json +1 -1
  3. package/src/components/Blocks/CclSubscriptionBlock/SubscriptionEdit.jsx +2 -2
  4. package/src/components/Blocks/CclSubscriptionBlock/SubscriptionView.jsx +12 -1
  5. package/src/components/Blocks/CclSubscriptionBlock/schema.js +5 -1
  6. package/src/components/Blocks/CustomTemplates/VoltoFormBlock/VocabularyWidget.jsx +69 -0
  7. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/FilterList.jsx +1 -1
  8. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/RightModalFacets.jsx +1 -2
  9. package/src/components/Blocks/CustomTemplates/VoltoSearchBlock/SearchInput.jsx +59 -0
  10. package/src/components/Blocks/customBlocks.js +39 -0
  11. package/src/components/CLMSDownloadCartView/CLMSCartContent.jsx +23 -5
  12. package/src/components/CLMSLoginView/CLMSLogin.css +17 -0
  13. package/src/components/CLMSLoginView/CLMSLogin.jsx +64 -0
  14. package/src/components/CLMSMeetingView/CLMSMeetingView.jsx +149 -1
  15. package/src/components/CLMSNewsItemView/CLMSNewsItemView.jsx +147 -0
  16. package/src/components/CclCard/CclCard.jsx +9 -19
  17. package/src/components/CclCard/cards.less +10 -1
  18. package/src/components/CclModal/CclModal.jsx +1 -1
  19. package/src/components/Widgets/DatasetDownloadInformationWidget.jsx +1 -1
  20. package/src/components/Widgets/ImageWidget.jsx +239 -0
  21. package/src/components/Widgets/taxonomyUtils.js +24 -1
  22. package/src/customizations/volto/components/manage/Widgets/EmailWidget.jsx +124 -0
  23. package/src/customizations/volto/components/theme/Footer/Footer.jsx +3 -11
  24. package/src/customizations/volto/components/theme/Login/Login.jsx +325 -0
  25. package/src/index.js +19 -1
  26. package/theme/clms/css/header.css +1 -0
  27. package/theme/clms/css/maps.less +5 -4
package/CHANGELOG.md CHANGED
@@ -4,8 +4,46 @@ 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.106](https://github.com/eea/volto-clms-theme/compare/1.0.105...1.0.106)
8
+
9
+ - new field types for form [`a452429`](https://github.com/eea/volto-clms-theme/commit/a452429eff799806d58e05e3e4164bc885d6eeb9)
10
+ - handle SelectWidget choices until the vocabulary is loaded [`0614fb5`](https://github.com/eea/volto-clms-theme/commit/0614fb584f52571d15e37fbe921e0694594a01f4)
11
+ - EmailWidget fix and ImageWidget created for form block [`fc1d16b`](https://github.com/eea/volto-clms-theme/commit/fc1d16baf2466dec09d835147fc3df839811e409)
12
+ - lint fix [`af5f960`](https://github.com/eea/volto-clms-theme/commit/af5f9605ec147cb010245a58696087abaed55c35)
13
+ - EmailWidget override for correct anguage and size limitation [`8a6c253`](https://github.com/eea/volto-clms-theme/commit/8a6c253f590fcf753d1a274e8ab7767f366d8c1e)
14
+ - number of current filters [`195cc43`](https://github.com/eea/volto-clms-theme/commit/195cc43d351d0e9793a0f462ecf8bdf9433a1def)
15
+ - subscription modal block [`30db876`](https://github.com/eea/volto-clms-theme/commit/30db876826dd53db6bbb11507de11af10a71a4eb)
16
+
17
+ #### [1.0.105](https://github.com/eea/volto-clms-theme/compare/1.0.104...1.0.105)
18
+
19
+ > 11 July 2022
20
+
21
+ - Develop [`#275`](https://github.com/eea/volto-clms-theme/pull/275)
22
+ - File card [`#274`](https://github.com/eea/volto-clms-theme/pull/274)
23
+ - sort items taxonomy items [`#272`](https://github.com/eea/volto-clms-theme/pull/272)
24
+ - Changes in download cart [`#271`](https://github.com/eea/volto-clms-theme/pull/271)
25
+ - related products and datasets added to news and meeting views and login-plone route created [`5704a1a`](https://github.com/eea/volto-clms-theme/commit/5704a1a766148746162b60efaf232ea90dc20cf4)
26
+ - sort items according to the lowercased label and put those with special meaning at the end [`6410abe`](https://github.com/eea/volto-clms-theme/commit/6410abe096f60dcad54dced2026c9df9b7946d68)
27
+ - lint fix [`1264a7a`](https://github.com/eea/volto-clms-theme/commit/1264a7adfe8d679fea1bd821ad087add20f4271d)
28
+ - footer newsletter subscription change, global search maxLength change from 8000 to 200 and /login design change [`a09d24a`](https://github.com/eea/volto-clms-theme/commit/a09d24adbb6fa053fb2a2cc0071506b906593b42)
29
+ - show Collection on download cart, add dropdown selection to it and remove from Type [`3a13417`](https://github.com/eea/volto-clms-theme/commit/3a13417b92c15187fe0e91ca891ccf9f8b0ed3f1)
30
+ - change form label [`c512a2e`](https://github.com/eea/volto-clms-theme/commit/c512a2e1048c977847cedc8379f58f42adebba18)
31
+
32
+ #### [1.0.104](https://github.com/eea/volto-clms-theme/compare/1.0.103...1.0.104)
33
+
34
+ > 30 June 2022
35
+
36
+ - Develop [`#270`](https://github.com/eea/volto-clms-theme/pull/270)
37
+ - use a combined vocabulary of Products and Datasets [`9f9d0c6`](https://github.com/eea/volto-clms-theme/commit/9f9d0c693a1e870614eb8adc07c58657d9d72a06)
38
+ - allow multiple values [`1edb5dd`](https://github.com/eea/volto-clms-theme/commit/1edb5dd166f31ade19bdcae0b7fa92836dbad420)
39
+ - Products Vocabulary for volto-form-block CLMS-747 [`3f48358`](https://github.com/eea/volto-clms-theme/commit/3f48358dab6a3c20a8367bf4be93c94af6c86350)
40
+ - CLMS-935 and input limitation at 8000 [`9971910`](https://github.com/eea/volto-clms-theme/commit/9971910fbe3c291faed7c0c7d458ae34597e7dc4)
41
+
7
42
  #### [1.0.103](https://github.com/eea/volto-clms-theme/compare/1.0.102...1.0.103)
8
43
 
44
+ > 29 June 2022
45
+
46
+ - Develop [`#269`](https://github.com/eea/volto-clms-theme/pull/269)
9
47
  - footer button disabled if email is not valid and privacy check is not clicked [`ab6a061`](https://github.com/eea/volto-clms-theme/commit/ab6a06174dd3cd5fb38bd5ae35cc530a7d3baf4e)
10
48
  - download table change and home product block fix [`480d83f`](https://github.com/eea/volto-clms-theme/commit/480d83f1772b3cdfe9b2906edfc7505dac420c8e)
11
49
  - rename Sort on selection texts CLMS-745 [`2e2f8c6`](https://github.com/eea/volto-clms-theme/commit/2e2f8c60bce7c09844f4e8f17d79f91de47d134b)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-clms-theme",
3
- "version": "1.0.103",
3
+ "version": "1.0.106",
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",
@@ -1,4 +1,4 @@
1
- import { SubscriptionView } from '@eeacms/volto-clms-theme/components/CLMSSubscriptionView';
1
+ import CclButton from '@eeacms/volto-clms-theme/components/CclButton/CclButton';
2
2
  import { SidebarPortal } from '@plone/volto/components';
3
3
  import { SubscriptionSchema } from './schema';
4
4
  import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
@@ -16,7 +16,7 @@ const SubscriptionBlockEdit = (props) => {
16
16
  aria-hidden="true"
17
17
  />
18
18
  </div>
19
- <SubscriptionView type={data.type || 'events'} />
19
+ <CclButton mode={'filled'}>{data.title || 'Text example...'}</CclButton>
20
20
  <SidebarPortal selected={selected}>
21
21
  <InlineForm
22
22
  schema={SubscriptionSchema()}
@@ -1,9 +1,20 @@
1
1
  import { SubscriptionView } from '@eeacms/volto-clms-theme/components/CLMSSubscriptionView';
2
+ import CclModal from '@eeacms/volto-clms-theme/components/CclModal/CclModal';
3
+ import CclButton from '@eeacms/volto-clms-theme/components/CclButton/CclButton';
2
4
 
3
5
  const SubscriptionBlockView = (props) => {
4
6
  const { data } = props;
5
7
 
6
- return <SubscriptionView type={data.type || 'events'} />;
8
+ return (
9
+ <CclModal
10
+ trigger={
11
+ <CclButton mode={'filled'}>{data.title || 'Text example...'}</CclButton>
12
+ }
13
+ size="small"
14
+ >
15
+ <SubscriptionView type={data.type || 'events'} />
16
+ </CclModal>
17
+ );
7
18
  };
8
19
 
9
20
  export default SubscriptionBlockView;
@@ -4,7 +4,7 @@ export const SubscriptionSchema = () => ({
4
4
  {
5
5
  id: 'default',
6
6
  title: 'Default',
7
- fields: ['type'],
7
+ fields: ['type', 'title'],
8
8
  },
9
9
  ],
10
10
  properties: {
@@ -16,6 +16,10 @@ export const SubscriptionSchema = () => ({
16
16
  ['newsletter', 'newsletter'],
17
17
  ],
18
18
  },
19
+ title: {
20
+ title: 'Title',
21
+ type: 'string',
22
+ },
19
23
  },
20
24
  required: ['product'],
21
25
  });
@@ -0,0 +1,69 @@
1
+ import React, { useEffect } from 'react';
2
+ import SelectWidget from '@plone/volto/components/manage/Widgets/SelectWidget';
3
+ import { useIntl, defineMessages } from 'react-intl';
4
+ import { getVocabulary } from '@plone/volto/actions';
5
+ import { useDispatch, useSelector } from 'react-redux';
6
+
7
+ const messages = defineMessages({
8
+ select_a_value: {
9
+ id: 'form_select_a_value',
10
+ defaultMessage: 'Select a value',
11
+ },
12
+ });
13
+
14
+ const VocabularyWidget = ({
15
+ name,
16
+ label,
17
+ description,
18
+ value,
19
+ onChange,
20
+ disabled,
21
+ invalid,
22
+ title,
23
+ required,
24
+ vocabulary,
25
+ isMulti,
26
+ }) => {
27
+ const intl = useIntl();
28
+ const dispatch = useDispatch();
29
+ useEffect(() => {
30
+ dispatch(
31
+ getVocabulary({
32
+ vocabNameOrURL: vocabulary,
33
+ size: -1,
34
+ }),
35
+ );
36
+ }, [dispatch, vocabulary]);
37
+ const vocabItems = useSelector((state) => state.vocabularies[vocabulary]);
38
+ return (
39
+ <SelectWidget
40
+ id={name}
41
+ name={name}
42
+ title={title}
43
+ required={required}
44
+ description={description}
45
+ getVocabulary={() => {}}
46
+ getVocabularyTokenTitle={() => {}}
47
+ choices={
48
+ vocabItems?.loaded
49
+ ? [
50
+ ...vocabItems.items.map((item) => {
51
+ return [item.label, item.label];
52
+ }),
53
+ ]
54
+ : []
55
+ }
56
+ value={value}
57
+ onChange={onChange}
58
+ placeholder={intl.formatMessage(messages.select_a_value)}
59
+ aria-label={intl.formatMessage(messages.select_a_value)}
60
+ classNamePrefix="react-select"
61
+ isDisabled={disabled}
62
+ invalid={invalid}
63
+ isMulti={isMulti}
64
+ {...(invalid === 'true' ? { className: 'is-invalid' } : {})}
65
+ />
66
+ );
67
+ };
68
+
69
+ export default VocabularyWidget;
@@ -25,7 +25,7 @@ const FilterList = (props) => {
25
25
  (v) =>
26
26
  v[1] &&
27
27
  baseFacets.length > 0 &&
28
- !baseFacets.map((bf) => bf.field?.value).includes(v[0]),
28
+ baseFacets.map((bf) => bf.field?.value).includes(v[0]),
29
29
  ),
30
30
  );
31
31
 
@@ -2,11 +2,10 @@ import { Button, Grid, Segment } from 'semantic-ui-react';
2
2
  import {
3
3
  Facets,
4
4
  SearchDetails,
5
- SearchInput,
6
5
  SortOn,
7
6
  } from '@plone/volto/components/manage/Blocks/Search/components';
8
7
  import { defineMessages, useIntl } from 'react-intl';
9
-
8
+ import SearchInput from './SearchInput';
10
9
  import FilterList from './FilterList';
11
10
  import CclFiltersModal from '@eeacms/volto-clms-theme/components/CclFiltersModal/CclFiltersModal';
12
11
  import { Icon } from '@plone/volto/components';
@@ -0,0 +1,59 @@
1
+ import React, { useEffect } from 'react';
2
+ import { Button, Input } from 'semantic-ui-react';
3
+ import { defineMessages, useIntl } from 'react-intl';
4
+ import { Icon } from '@plone/volto/components';
5
+ import loupeSVG from '@plone/volto/icons/zoom.svg';
6
+
7
+ const messages = defineMessages({
8
+ search: {
9
+ id: 'Search',
10
+ defaultMessage: 'Search',
11
+ },
12
+ });
13
+
14
+ const SearchInput = (props) => {
15
+ const {
16
+ data,
17
+ searchText,
18
+ setSearchText,
19
+ isLive,
20
+ onTriggerSearch,
21
+ ...rest
22
+ } = props;
23
+ const intl = useIntl();
24
+
25
+ useEffect(() => {
26
+ onTriggerSearch(rest.searchedText);
27
+ setSearchText(rest.searchedText);
28
+ }, [rest.searchedText, onTriggerSearch, setSearchText]);
29
+
30
+ return (
31
+ <div className="search-input">
32
+ <Input
33
+ maxLength="200"
34
+ id={`${props.id}-searchtext`}
35
+ value={searchText}
36
+ placeholder={
37
+ data.searchInputPrompt || intl.formatMessage(messages.search)
38
+ }
39
+ fluid
40
+ onKeyPress={(event) => {
41
+ if (isLive || event.key === 'Enter') onTriggerSearch(searchText);
42
+ }}
43
+ onChange={(event, { value }) => {
44
+ setSearchText(value);
45
+ if (isLive) {
46
+ onTriggerSearch(searchText);
47
+ }
48
+ }}
49
+ />
50
+ {isLive && (
51
+ <Button basic icon className="search-input-live-icon-button">
52
+ <Icon name={loupeSVG} />
53
+ </Button>
54
+ )}
55
+ </div>
56
+ );
57
+ };
58
+
59
+ export default SearchInput;
@@ -59,11 +59,13 @@ import SubscriptionBlockView from '@eeacms/volto-clms-theme/components/Blocks/Cc
59
59
  import SubscriptionBlockEdit from '@eeacms/volto-clms-theme/components/Blocks/CclSubscriptionBlock/SubscriptionEdit';
60
60
  import containerSVG from '@plone/volto/icons/apps.svg';
61
61
  import customIdFieldSchema from '@eeacms/volto-clms-theme/components/Blocks/CustomTemplates/VoltoFormBlock/customIdFieldSchema';
62
+ import VocabularyWidget from '@eeacms/volto-clms-theme/components/Blocks/CustomTemplates/VoltoFormBlock/VocabularyWidget';
62
63
  import downSVG from '@plone/volto/icons/down-key.svg';
63
64
  import homeBand from '@plone/volto/icons/image-wide.svg';
64
65
  import linkSVG from '@plone/volto/icons/link.svg';
65
66
  import navSVG from '@plone/volto/icons/nav.svg';
66
67
  import upSVG from '@plone/volto/icons/up-key.svg';
68
+ import ImageWidget from '@eeacms/volto-clms-theme/components/Widgets/ImageWidget';
67
69
 
68
70
  export const customGroupBlocksOrder = [
69
71
  {
@@ -462,6 +464,43 @@ const customBlocks = (config) => ({
462
464
  form: {
463
465
  ...config.blocks.blocksConfig.form,
464
466
  fieldSchema: customIdFieldSchema,
467
+ additionalFields: [
468
+ {
469
+ id: 'product_vocabulary',
470
+ label: 'Products Vocabulary',
471
+ component: (props) =>
472
+ VocabularyWidget({
473
+ ...props,
474
+ vocabulary: 'clms.types.ProductsAndDatasetsVocabulary',
475
+ isMulti: true,
476
+ }),
477
+ },
478
+ {
479
+ id: 'topic_vocabulary',
480
+ label: 'Topics Vocabulary',
481
+ component: (props) =>
482
+ VocabularyWidget({
483
+ ...props,
484
+ vocabulary: 'clms.types.TopicsVocabulary',
485
+ isMulti: true,
486
+ }),
487
+ },
488
+ {
489
+ id: 'spatial_coverage_vocabulary',
490
+ label: 'Spatial Coverage Vocabulary',
491
+ component: (props) =>
492
+ VocabularyWidget({
493
+ ...props,
494
+ vocabulary: 'clms.types.UseCaseSpatialCoverageVocabulary',
495
+ isMulti: true,
496
+ }),
497
+ },
498
+ {
499
+ id: 'image_field_widget',
500
+ label: 'Image Field Widget',
501
+ component: ImageWidget,
502
+ },
503
+ ],
465
504
  },
466
505
  });
467
506
 
@@ -214,6 +214,24 @@ const CLMSCartContent = (props) => {
214
214
  };
215
215
 
216
216
  const TypeNaming = (typeProps) => {
217
+ const { item } = typeProps;
218
+ if (item.file_id) {
219
+ return (
220
+ <span className={'tag tag-' + item?.type?.toLowerCase()}>
221
+ {contentOrDash(item.type)}
222
+ </span>
223
+ );
224
+ } else if (!item.type) {
225
+ return '-';
226
+ } else {
227
+ let values = item.type_options.filter((myitem) => {
228
+ return myitem['id'] === item.type;
229
+ });
230
+ return values.length > 0 ? values[0].name : '.';
231
+ }
232
+ };
233
+
234
+ const CollectionNaming = (typeProps) => {
217
235
  const { item } = typeProps;
218
236
  if (item.file_id) {
219
237
  return (
@@ -237,11 +255,7 @@ const CLMSCartContent = (props) => {
237
255
  return {
238
256
  key: option.id,
239
257
  value: option.id,
240
- text:
241
- option.name +
242
- ((option.collection !== undefined &&
243
- ' (' + option.collection + ')') ||
244
- ''),
258
+ text: (option.collection === undefined && '-') || option.collection,
245
259
  };
246
260
  })}
247
261
  onChange={(e, data) => {
@@ -290,6 +304,7 @@ const CLMSCartContent = (props) => {
290
304
  <th>Source</th>
291
305
  <th>Area</th>
292
306
  <th>Type</th>
307
+ <th>Collection</th>
293
308
  <th>Format</th>
294
309
  <th>Projection</th>
295
310
  <th></th>
@@ -346,6 +361,9 @@ const CLMSCartContent = (props) => {
346
361
  <td>
347
362
  <TypeNaming item={item} />
348
363
  </td>
364
+ <td>
365
+ <CollectionNaming item={item} />
366
+ </td>
349
367
  <td className="table-td-format">
350
368
  {!item.file_id ? (
351
369
  <Select
@@ -0,0 +1,17 @@
1
+ .header-login-link {
2
+ color: white;
3
+ }
4
+
5
+ .green-login-link {
6
+ color: #a0b128bf;
7
+ cursor: pointer;
8
+ }
9
+
10
+ .login {
11
+ margin-top: 3rem;
12
+ }
13
+
14
+ .login-button {
15
+ margin-top: 3rem;
16
+ margin-bottom: 3rem;
17
+ }
@@ -0,0 +1,64 @@
1
+ import React, { useEffect } from 'react';
2
+ import { useSelector } from 'react-redux';
3
+ import config from '@plone/volto/registry';
4
+ import { toPublicURL } from '@plone/volto/helpers/Url/Url';
5
+ import './CLMSLogin.css';
6
+
7
+ /**
8
+ * Login Modal component doc.
9
+ * @function CclLoginModal
10
+ * @example <CclLoginModal />
11
+ *
12
+ */
13
+ function CLMSLoginView(props) {
14
+ const registryRecords = useSelector((state) => state.registry.records);
15
+ const [loginUrl, setLoginUrl] = React.useState('');
16
+ const registry_key = config.settings?.registry?.login_url || null;
17
+
18
+ useEffect(() => {
19
+ if (registryRecords && registry_key in registryRecords) {
20
+ setLoginUrl(
21
+ registryRecords[registry_key] + '?came_from=' + window.location.href,
22
+ );
23
+ }
24
+ }, [registryRecords, registry_key]);
25
+
26
+ return (
27
+ <>
28
+ <div className="ccl-container login">
29
+ <h1 className="page-title">Registration / Login</h1>
30
+ <div className="modal-login-text">
31
+ <p>
32
+ This site uses EU Login to handle user registration and login. You
33
+ can read more about this service in the{' '}
34
+ <a href="https://ecas.ec.europa.eu/cas/about.html">
35
+ EU Login site help
36
+ </a>
37
+ .
38
+ </p>
39
+ <p>
40
+ {' '}
41
+ When you clik on the following link, you will be sent to EU Login
42
+ and after a successful login there you will be redirected back to
43
+ this site.
44
+ </p>
45
+ <p>
46
+ If you have any issues or questions, please contact us using the
47
+ <a href="/en/contact-service-helpdesk"> helpdesk</a>.
48
+ </p>
49
+ </div>
50
+ </div>
51
+ <div className="login-button">
52
+ <div className="modal-buttons">
53
+ <a
54
+ href={toPublicURL(loginUrl) || '#'}
55
+ className="ccl-button ccl-button-green"
56
+ >
57
+ Login using EU Login
58
+ </a>
59
+ </div>
60
+ </div>
61
+ </>
62
+ );
63
+ }
64
+ export default CLMSLoginView;
@@ -1,7 +1,7 @@
1
1
  import './meetingstyles.less';
2
2
 
3
3
  import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
4
- import { Header, Image, Message, Segment } from 'semantic-ui-react';
4
+ import { Header, Image, Message, Segment, Grid } from 'semantic-ui-react';
5
5
  import { Icon, Toast } from '@plone/volto/components';
6
6
  import {
7
7
  Recurrence,
@@ -20,6 +20,9 @@ import { postMeetingRegister } from '../../actions';
20
20
  import { toast } from 'react-toastify';
21
21
  import { LightGalleryListing } from './CclLightGallery';
22
22
  import CclListingCards from '@eeacms/volto-clms-theme/components/Blocks/CustomTemplates/VoltoListingBlock/CclListingCards';
23
+ import config from '@plone/volto/registry';
24
+ import AnimateHeight from 'react-animate-height';
25
+ import { Accordion } from 'semantic-ui-react';
23
26
 
24
27
  export const CLMSMeetingView = (props) => {
25
28
  const { content, intl } = props;
@@ -182,6 +185,36 @@ export const CLMSMeetingView = (props) => {
182
185
  intl.formatMessage(messages.no_fullname_customfield),
183
186
  );
184
187
 
188
+ const [activeIndex, setActiveIndex] = React.useState([99]);
189
+
190
+ const handleClick = ({ index }) => {
191
+ const newIndex =
192
+ activeIndex.indexOf(index) === -1
193
+ ? [...activeIndex, index]
194
+ : activeIndex.filter((item) => item !== index);
195
+
196
+ setActiveIndex(newIndex);
197
+ };
198
+
199
+ const [activeDatasetIndex, setActiveDatasetIndex] = React.useState([99]);
200
+
201
+ const handleDatasetClick = ({ datasetindex }) => {
202
+ const newDatasetIndex =
203
+ activeDatasetIndex.indexOf(datasetindex) === -1
204
+ ? [...activeDatasetIndex, datasetindex]
205
+ : activeDatasetIndex.filter((item) => item !== datasetindex);
206
+
207
+ setActiveDatasetIndex(newDatasetIndex);
208
+ };
209
+
210
+ const titleIcons = config.blocks?.blocksConfig?.accordion?.titleIcons;
211
+
212
+ function iconName(iconData, iTitleIcons) {
213
+ return iconData?.right_arrows
214
+ ? iTitleIcons.rightPosition
215
+ : iTitleIcons.leftPosition;
216
+ }
217
+
185
218
  return (
186
219
  <div className="ccl-container">
187
220
  <h1 className="page-title">{content.title}</h1>
@@ -399,6 +432,121 @@ export const CLMSMeetingView = (props) => {
399
432
  linkHref={`${files['@id']}/@@download/file`}
400
433
  />
401
434
  )}
435
+ <div className="dataset-info-documents dropdown">
436
+ <div className="accordion-block"></div>
437
+ {content?.products?.length > 0 && (
438
+ <Accordion fluid styled>
439
+ <Accordion.Title
440
+ as={'h2'}
441
+ onClick={() => handleClick({ index: 0 })}
442
+ className={'accordion-title align-arrow-right'}
443
+ >
444
+ {activeIndex.includes(0) ? (
445
+ <Icon
446
+ name={iconName(content, titleIcons.opened)}
447
+ size="24px"
448
+ />
449
+ ) : (
450
+ <Icon
451
+ name={iconName(content, titleIcons.closed)}
452
+ size="24px"
453
+ />
454
+ )}
455
+ <span>Related products</span>
456
+ </Accordion.Title>
457
+ <Accordion.Content active={activeIndex.includes(0)}>
458
+ <AnimateHeight animateOpacity duration={500} height={'auto'}>
459
+ <ul>
460
+ {content.products.map((product, key) => (
461
+ <li key={key}>
462
+ <Grid columns={2}>
463
+ <Grid.Column width={2}>
464
+ {product.image_field && (
465
+ <img
466
+ src={
467
+ product.image_field
468
+ ? `${product['@id']}/@@images/image`
469
+ : 'https://eu-copernicus.github.io/copernicus-component-library/assets/images/image_placeholder.jpg'
470
+ }
471
+ alt={
472
+ product.image_field
473
+ ? product.image?.filename
474
+ : 'Placeholder'
475
+ }
476
+ />
477
+ )}
478
+ </Grid.Column>
479
+ <Grid.Column width={10}>
480
+ <a href={product['@id']}>
481
+ <strong>{product.title}</strong>
482
+ </a>
483
+ <p>{product.description}</p>
484
+ </Grid.Column>
485
+ </Grid>
486
+ </li>
487
+ ))}
488
+ </ul>
489
+ </AnimateHeight>
490
+ </Accordion.Content>
491
+ </Accordion>
492
+ )}
493
+ {content?.datasets?.length > 0 && (
494
+ <Accordion fluid styled>
495
+ <Accordion.Title
496
+ as={'h2'}
497
+ onClick={() => handleDatasetClick({ datasetindex: 0 })}
498
+ className={'accordion-title align-arrow-right'}
499
+ >
500
+ {activeDatasetIndex.includes(0) ? (
501
+ <Icon
502
+ name={iconName(content, titleIcons.opened)}
503
+ size="24px"
504
+ />
505
+ ) : (
506
+ <Icon
507
+ name={iconName(content, titleIcons.closed)}
508
+ size="24px"
509
+ />
510
+ )}
511
+ <span>Related datasets</span>
512
+ </Accordion.Title>
513
+ <Accordion.Content active={activeDatasetIndex.includes(0)}>
514
+ <AnimateHeight animateOpacity duration={500} height={'auto'}>
515
+ <ul>
516
+ {content.datasets.map((dataset, key) => (
517
+ <li key={key}>
518
+ <Grid columns={2}>
519
+ <Grid.Column width={2}>
520
+ {dataset.image_field && (
521
+ <img
522
+ src={
523
+ dataset.image_field
524
+ ? `${dataset['@id']}/@@images/image`
525
+ : 'https://eu-copernicus.github.io/copernicus-component-library/assets/images/image_placeholder.jpg'
526
+ }
527
+ alt={
528
+ dataset.image_field
529
+ ? dataset.image?.filename
530
+ : 'Placeholder'
531
+ }
532
+ />
533
+ )}
534
+ </Grid.Column>
535
+ <Grid.Column width={10}>
536
+ <a href={dataset['@id']}>
537
+ <strong>{dataset.title}</strong>
538
+ </a>
539
+ <p>{dataset.description}</p>
540
+ </Grid.Column>
541
+ </Grid>
542
+ </li>
543
+ ))}
544
+ </ul>
545
+ </AnimateHeight>
546
+ </Accordion.Content>
547
+ </Accordion>
548
+ )}
549
+ </div>
402
550
  </Segment>
403
551
  </div>
404
552
  );