@eeacms/volto-cca-policy 1.0.6 → 1.0.8

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 (124) hide show
  1. package/CHANGELOG.md +65 -1
  2. package/locales/bg/LC_MESSAGES/volto.po +63 -63
  3. package/locales/cs/LC_MESSAGES/volto.po +63 -63
  4. package/locales/da/LC_MESSAGES/volto.po +63 -63
  5. package/locales/de/LC_MESSAGES/volto.po +63 -63
  6. package/locales/el/LC_MESSAGES/volto.po +63 -63
  7. package/locales/en/LC_MESSAGES/volto.po +63 -63
  8. package/locales/es/LC_MESSAGES/volto.po +63 -63
  9. package/locales/et/LC_MESSAGES/volto.po +63 -63
  10. package/locales/fi/LC_MESSAGES/volto.po +63 -63
  11. package/locales/fr/LC_MESSAGES/volto.po +63 -63
  12. package/locales/ga/LC_MESSAGES/volto.po +63 -63
  13. package/locales/hr/LC_MESSAGES/volto.po +63 -63
  14. package/locales/hu/LC_MESSAGES/volto.po +63 -63
  15. package/locales/is/LC_MESSAGES/volto.po +63 -63
  16. package/locales/it/LC_MESSAGES/volto.po +63 -63
  17. package/locales/lt/LC_MESSAGES/volto.po +63 -63
  18. package/locales/lv/LC_MESSAGES/volto.po +63 -63
  19. package/locales/mt/LC_MESSAGES/volto.po +63 -63
  20. package/locales/nl/LC_MESSAGES/volto.po +63 -63
  21. package/locales/nn/LC_MESSAGES/volto.po +63 -63
  22. package/locales/pl/LC_MESSAGES/volto.po +63 -63
  23. package/locales/pt/LC_MESSAGES/volto.po +63 -63
  24. package/locales/ro/LC_MESSAGES/volto.po +63 -63
  25. package/locales/sk/LC_MESSAGES/volto.po +63 -63
  26. package/locales/sl/LC_MESSAGES/volto.po +63 -63
  27. package/locales/sv/LC_MESSAGES/volto.po +63 -63
  28. package/locales/tr/LC_MESSAGES/volto.po +63 -63
  29. package/locales/volto.pot +64 -64
  30. package/package.json +2 -2
  31. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.jsx +3 -2
  32. package/src/components/index.js +26 -10
  33. package/src/components/manage/Blocks/CollectionStatistics/CollectionStatsEdit.jsx +1 -1
  34. package/src/components/manage/Blocks/CountryMapHeatIndex/View.jsx +2 -2
  35. package/src/components/manage/Blocks/CountryMapObservatory/CountryMapObservatoryOLView.jsx +2 -2
  36. package/src/components/manage/Blocks/CountryMapProfile/OLView.jsx +2 -2
  37. package/src/components/{theme → manage}/Widgets/GeolocationWidget.jsx +1 -1
  38. package/src/components/{theme → manage}/Widgets/GeolocationWidget.test.jsx +1 -1
  39. package/src/components/{theme → manage}/Widgets/ImageWidget.jsx +2 -2
  40. package/src/components/manage/Widgets/ImageWidget.test.jsx +187 -0
  41. package/src/components/{theme → manage}/Widgets/PromotionalImageWidget.test.jsx +9 -3
  42. package/src/components/manage/Widgets/VisualizationsWidget.jsx +151 -0
  43. package/src/components/manage/Widgets/visualizations.less +60 -0
  44. package/src/components/theme/Content/Fields/BooleanField.jsx +7 -0
  45. package/src/components/theme/Content/Fields/HTMLField.jsx +14 -0
  46. package/src/components/theme/Content/Fields/TextField.jsx +12 -0
  47. package/src/components/theme/Content/Fields/VocabularyField.jsx +26 -0
  48. package/src/components/theme/Content/Fields/index.js +4 -0
  49. package/src/components/theme/Content/Sections/ContentBannerTitle.jsx +26 -0
  50. package/src/{helpers → components/theme/Content/Sections}/ContentMetadata.jsx +11 -312
  51. package/src/components/theme/Content/Sections/ContentRelatedItems.jsx +35 -0
  52. package/src/components/theme/Content/Sections/DocumentsList.jsx +80 -0
  53. package/src/components/theme/Content/Sections/EventDetails.jsx +90 -0
  54. package/src/components/theme/Content/Sections/GeographicMetadata.jsx +83 -0
  55. package/src/components/theme/Content/Sections/ImageGallery/index.js +1 -0
  56. package/src/components/theme/Content/Sections/ItemLogo.jsx +29 -0
  57. package/src/components/theme/Content/Sections/LinkedMetadataItemList.jsx +63 -0
  58. package/src/components/theme/Content/Sections/LinksList.jsx +48 -0
  59. package/src/components/theme/Content/Sections/MetadataItemList.jsx +43 -0
  60. package/src/components/theme/Content/Sections/PublicationDateInfo.jsx +62 -0
  61. package/src/components/theme/Content/Sections/PublishedModifiedInfo.jsx +33 -0
  62. package/src/components/theme/Content/Sections/ReferenceInfo.jsx +137 -0
  63. package/src/components/theme/Content/Sections/ShareInfoButton.jsx +24 -0
  64. package/src/components/theme/Content/Sections/SubjectTags.jsx +19 -0
  65. package/src/components/theme/Content/Sections/Versioning/index.js +3 -0
  66. package/src/components/theme/Content/Sections/geographicMetadataUtils.js +177 -0
  67. package/src/components/theme/Content/Sections/index.js +17 -0
  68. package/src/components/theme/Content/index.js +20 -0
  69. package/src/components/theme/Views/AdaptationOptionView.jsx +6 -8
  70. package/src/components/theme/Views/AdaptationOptionView.test.jsx +5 -8
  71. package/src/components/theme/Views/C3SIndicatorView.jsx +5 -5
  72. package/src/components/theme/Views/CaseStudyView.jsx +6 -8
  73. package/src/components/theme/Views/CcaEventView.jsx +4 -4
  74. package/src/components/theme/Views/DatabaseItemView.jsx +79 -40
  75. package/src/components/theme/Views/DatabaseItemView.test.jsx +98 -38
  76. package/src/components/theme/Views/EventView.jsx +3 -3
  77. package/src/components/theme/Views/ExtendedToolView.jsx +6 -8
  78. package/src/components/theme/Views/ExtendedToolView.test.jsx +10 -16
  79. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/MissionSignatoryProfileView.jsx +5 -2
  80. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/MissionSignatoryProfileView.test.jsx +2 -2
  81. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/ActionTab.jsx +1 -2
  82. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/ActionTab.test.jsx +3 -0
  83. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/AssessmentTab.jsx +1 -2
  84. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/AssessmentTab.test.jsx +11 -1
  85. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/GovernanceTab.jsx +1 -2
  86. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/PlanningTab.jsx +1 -2
  87. package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/PlanningTab.test.jsx +11 -1
  88. package/src/components/theme/Views/NewsItemView.jsx +5 -2
  89. package/src/components/theme/Views/ProjectView.jsx +4 -6
  90. package/src/constants.js +7 -0
  91. package/src/helpers/countryMap.js +1 -4
  92. package/src/helpers/embed.js +11 -0
  93. package/src/helpers/index.js +13 -101
  94. package/src/helpers/string.js +4 -0
  95. package/src/hocs/index.js +1 -0
  96. package/src/{helpers/clientOnly.jsx → hocs/withClientOnly.jsx} +1 -1
  97. package/src/index.js +5 -3
  98. package/src/search/queryUtils.js +64 -0
  99. package/src/components/theme/ShareInfoButton/ShareInfoButton.jsx +0 -26
  100. package/src/components/theme/Widgets/ImageWidget.test.jsx +0 -90
  101. package/src/helpers/Utils.jsx +0 -620
  102. /package/src/components/manage/{TransparentOverlay.jsx → Blocks/CollectionStatistics/TransparentOverlay.jsx} +0 -0
  103. /package/src/components/{theme → manage}/Widgets/GeocharsWidget.jsx +0 -0
  104. /package/src/components/{theme → manage}/Widgets/GeolocationWidgetMapContainer.jsx +0 -0
  105. /package/src/components/{theme → manage}/Widgets/PromotionalImageWidget.jsx +0 -0
  106. /package/src/components/{theme → manage}/Widgets/RASTWidgetView.jsx +0 -0
  107. /package/src/components/{theme → manage}/Widgets/__mocks__/GeolocationWidgetMapContainer.jsx +0 -0
  108. /package/src/components/{theme → manage}/Widgets/utils.js +0 -0
  109. /package/src/components/theme/{ImageGallery → Content/Sections/ImageGallery}/ImageGallery.jsx +0 -0
  110. /package/src/components/theme/{ImageGallery → Content/Sections/ImageGallery}/ImageGallery.test.jsx +0 -0
  111. /package/src/components/theme/{ImageGallery → Content/Sections/ImageGallery}/styles.less +0 -0
  112. /package/src/components/theme/{Views → Content/Sections/Versioning}/ArchivedVersionListing.jsx +0 -0
  113. /package/src/components/theme/{Views → Content/Sections/Versioning}/ArchivedVersionListing.test.jsx +0 -0
  114. /package/src/components/theme/{Views → Content/Sections/Versioning}/ArchivedVersionNotice.jsx +0 -0
  115. /package/src/components/theme/{Views → Content/Sections/Versioning}/ArchivedVersionNotice.test.jsx +0 -0
  116. /package/src/components/theme/{Views → Content/Sections/Versioning}/VersionsGroup.jsx +0 -0
  117. /package/src/components/theme/{Views → Content/Sections/Versioning}/VersionsGroup.test.jsx +0 -0
  118. /package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/ItemsSection.jsx +0 -0
  119. /package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/ItemsSection.test.jsx +0 -0
  120. /package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/NoDataReported.jsx +0 -0
  121. /package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/NoDataReported.test.jsx +0 -0
  122. /package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/StatisticSection.jsx +0 -0
  123. /package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/StatisticSection.test.jsx +0 -0
  124. /package/src/components/theme/{MissionSignatoryProfile → Views/MissionSignatoryProfile}/TabSections/GovernanceTab.test.jsx +0 -0
@@ -19,22 +19,19 @@ jest.mock('@eeacms/volto-cca-policy/components', () => ({
19
19
  ))}
20
20
  </div>
21
21
  ),
22
- PortalMessage: () => <div data-testid="portal-message" />,
23
- ShareInfoButton: () => <div data-testid="share-info" />,
24
- }));
25
-
26
- jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
22
+ ContentBannerTitle: () => <div data-testid="banner-title" />,
23
+ ContentMetadata: () => <div data-testid="content-metadata" />,
27
24
  HTMLField: ({ value, className }) => (
28
25
  <div data-testid={className ? `html-${className}` : 'html-field'}>
29
26
  {value?.data ?? value ?? ''}
30
27
  </div>
31
28
  ),
32
- ContentMetadata: () => <div data-testid="content-metadata" />,
33
- PublishedModifiedInfo: () => <div data-testid="published-modified" />,
34
- BannerTitle: () => <div data-testid="banner-title" />,
35
29
  LinksList: ({ value }) => (
36
30
  <div data-testid="links-list">{(value || []).join(',')}</div>
37
31
  ),
32
+ PortalMessage: () => <div data-testid="portal-message" />,
33
+ PublishedModifiedInfo: () => <div data-testid="published-modified" />,
34
+ ShareInfoButton: () => <div data-testid="share-info" />,
38
35
  }));
39
36
 
40
37
  jest.mock('@eeacms/volto-eea-design-system/ui', () => ({
@@ -1,11 +1,12 @@
1
1
  import React, { useState, useEffect } from 'react';
2
2
  import spinner from '@eeacms/volto-cca-policy/../theme//assets/images/spinner.svg';
3
3
  import {
4
+ ContentBannerTitle,
5
+ ContentMetadata,
4
6
  HTMLField,
5
- BannerTitle,
6
7
  LogoWrapper,
7
- ContentMetadata,
8
- } from '@eeacms/volto-cca-policy/helpers';
8
+ PortalMessage,
9
+ } from '@eeacms/volto-cca-policy/components';
9
10
  import {
10
11
  Icon,
11
12
  Grid,
@@ -15,7 +16,6 @@ import {
15
16
  Container,
16
17
  Accordion,
17
18
  } from 'semantic-ui-react';
18
- import { PortalMessage } from '@eeacms/volto-cca-policy/components';
19
19
  import { Link } from 'react-router-dom';
20
20
  import { FormattedMessage } from 'react-intl';
21
21
  import { useSelector } from 'react-redux';
@@ -215,7 +215,7 @@ function C3SIndicatorView(props) {
215
215
 
216
216
  return (
217
217
  <div className="db-item-view c3sindicator-view">
218
- <BannerTitle
218
+ <ContentBannerTitle
219
219
  content={{ ...content, image: '' }}
220
220
  data={{
221
221
  info: [{ description: '' }],
@@ -1,16 +1,14 @@
1
1
  import {
2
- ImageGallery,
3
- PortalMessage,
4
- ShareInfoButton,
5
- } from '@eeacms/volto-cca-policy/components';
6
- import {
7
- BannerTitle,
2
+ ContentBannerTitle,
8
3
  ContentMetadata,
9
4
  DocumentsList,
10
5
  HTMLField,
6
+ ImageGallery,
11
7
  LinksList,
8
+ PortalMessage,
12
9
  PublishedModifiedInfo,
13
- } from '@eeacms/volto-cca-policy/helpers';
10
+ ShareInfoButton,
11
+ } from '@eeacms/volto-cca-policy/components';
14
12
  import React, { Fragment } from 'react';
15
13
  import AnchorLink from 'react-anchor-link-smooth-scroll';
16
14
  import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
@@ -360,7 +358,7 @@ function CaseStudyView(props) {
360
358
 
361
359
  return (
362
360
  <div className="db-item-view case-study-view">
363
- <BannerTitle
361
+ <ContentBannerTitle
364
362
  content={{ ...content, image: '' }}
365
363
  data={{
366
364
  info: [{ description: '' }],
@@ -2,11 +2,11 @@ import React from 'react';
2
2
  import { useIntl, defineMessages, FormattedMessage } from 'react-intl';
3
3
  import { Grid, Container, Segment } from 'semantic-ui-react';
4
4
  import {
5
- HTMLField,
6
- EventDetails,
7
5
  DocumentsList,
8
- } from '@eeacms/volto-cca-policy/helpers';
9
- import { PortalMessage } from '@eeacms/volto-cca-policy/components';
6
+ EventDetails,
7
+ HTMLField,
8
+ PortalMessage,
9
+ } from '@eeacms/volto-cca-policy/components';
10
10
  import { filterBlocks } from '@eeacms/volto-cca-policy/utils';
11
11
  import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';
12
12
 
@@ -3,8 +3,20 @@ import { FormattedMessage } from 'react-intl';
3
3
  import { PrivacyProtection } from '@eeacms/volto-embed';
4
4
  import { Container, Divider, Grid } from 'semantic-ui-react';
5
5
  import {
6
- ShareInfoButton,
6
+ ArchivedVersionListing,
7
+ ArchivedVersionNotice,
8
+ ContentBannerTitle,
9
+ ContentMetadata,
10
+ ContentRelatedItems,
11
+ DocumentsList,
12
+ ExternalLink,
13
+ HTMLField,
14
+ ItemLogo,
7
15
  PortalMessage,
16
+ PublishedModifiedInfo,
17
+ ReferenceInfo,
18
+ ShareInfoButton,
19
+ // VersionsGroup, // commented out - relatedItems already shows versions
8
20
  } from '@eeacms/volto-cca-policy/components';
9
21
  import { fixEmbedURL } from '@eeacms/volto-cca-policy/helpers';
10
22
  import {
@@ -17,31 +29,19 @@ import {
17
29
  INDICATOR,
18
30
  CONTENT_TYPE_LABELS,
19
31
  } from '@eeacms/volto-cca-policy/constants';
20
- import {
21
- HTMLField,
22
- ReferenceInfo,
23
- ContentMetadata,
24
- PublishedModifiedInfo,
25
- ItemLogo,
26
- ContentRelatedItems,
27
- DocumentsList,
28
- ExternalLink,
29
- BannerTitle,
30
- } from '@eeacms/volto-cca-policy/helpers';
31
- import {
32
- ArchivedVersionNotice,
33
- ArchivedVersionListing,
34
- // VersionsGroup, // commented out - relatedItems already shows versions
35
- } from '@eeacms/volto-cca-policy/components';
36
32
 
37
33
  const SHARE_EEA = ['https://cmshare.eea.eu', 'shareit.eea.europa.eu'];
38
34
 
39
- const MaybeFlourishVisualization = ({ content }) => {
40
- const { map_graphs } = content;
35
+ const getVisualizationEmbedCode = (visualization) =>
36
+ visualization?.embed_code || visualization?.map_graphs || '';
41
37
 
38
+ const MaybeFlourishVisualization = ({ visualization }) => {
39
+ const embedCode = getVisualizationEmbedCode(visualization);
42
40
  // https://helpcenter.flourish.studio/hc/en-us/articles/8761537208463-How-to-embed-Flourish-charts-in-your-CMS
43
- const flourishPath = getDataSrcFromEmbedCode(map_graphs);
41
+ const flourishPath = getDataSrcFromEmbedCode(embedCode);
44
42
  const flourishUrl = buildFlourishUrl(flourishPath);
43
+ const height = visualization?.height || '980';
44
+ const title = visualization?.title || 'Interactive or visual content';
45
45
 
46
46
  return !!flourishPath ? (
47
47
  <PrivacyProtection
@@ -51,10 +51,10 @@ const MaybeFlourishVisualization = ({ content }) => {
51
51
  }}
52
52
  >
53
53
  <iframe
54
- height="980"
54
+ height={height}
55
55
  width="100%"
56
56
  src={flourishUrl}
57
- title="Interactive or visual content"
57
+ title={title}
58
58
  className="flourish-embed-iframe"
59
59
  sandbox="allow-same-origin allow-forms allow-scripts allow-downloads allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation"
60
60
  ></iframe>
@@ -77,10 +77,11 @@ function getFirstIframeSrc(htmlString) {
77
77
  }
78
78
  }
79
79
 
80
- const MaybeIframeVisualization = ({ content }) => {
81
- const { map_graphs, map_graphs_height } = content;
82
- const url = getFirstIframeSrc(map_graphs || '');
83
- const height = map_graphs_height || 800;
80
+ const MaybeIframeVisualization = ({ visualization }) => {
81
+ const embedCode = getVisualizationEmbedCode(visualization);
82
+ const url = getFirstIframeSrc(embedCode);
83
+ const height = visualization?.height || 800;
84
+ const title = visualization?.title || 'Interactive or visual content';
84
85
  const [isClient, setIsClient] = React.useState();
85
86
 
86
87
  React.useEffect(() => setIsClient(true), []);
@@ -98,7 +99,7 @@ const MaybeIframeVisualization = ({ content }) => {
98
99
  height={height}
99
100
  width="100%"
100
101
  src={url}
101
- title="Interactive or visual content"
102
+ title={title}
102
103
  className="flourish-embed-iframe"
103
104
  sandbox="allow-same-origin allow-forms allow-scripts allow-downloads allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation"
104
105
  ></iframe>
@@ -106,6 +107,43 @@ const MaybeIframeVisualization = ({ content }) => {
106
107
  );
107
108
  };
108
109
 
110
+ const Visualization = ({ visualization }) => (
111
+ <>
112
+ {visualization?.title && <h2>{visualization.title}</h2>}
113
+ <MaybeFlourishVisualization visualization={visualization} />
114
+ <MaybeIframeVisualization visualization={visualization} />
115
+ </>
116
+ );
117
+
118
+ const Visualizations = ({ visualizations }) => (
119
+ <>
120
+ {visualizations.map((visualization, index) => (
121
+ <Visualization
122
+ key={`visualization-${index}`}
123
+ visualization={visualization}
124
+ />
125
+ ))}
126
+ </>
127
+ );
128
+
129
+ const getVisualizations = (content) => {
130
+ const visualizations = Array.isArray(content?.visualizations)
131
+ ? content.visualizations.filter((item) => item?.embed_code)
132
+ : [];
133
+
134
+ return content?.map_graphs
135
+ ? [
136
+ ...visualizations,
137
+ {
138
+ title: '',
139
+ embed_code: content.map_graphs,
140
+ height: content.map_graphs_height,
141
+ full_width: content.map_graphs_full_width,
142
+ },
143
+ ]
144
+ : visualizations;
145
+ };
146
+
109
147
  const BottomInfo = (props) => {
110
148
  const { content } = props;
111
149
  const { organisational_websites, organisational_contact_information } =
@@ -161,9 +199,14 @@ const DatabaseItemView = (props) => {
161
199
  } = content;
162
200
  const item_title = acronym ? title + ' (' + acronym + ')' : title;
163
201
  const subtitle = CONTENT_TYPE_LABELS[type] ?? '';
164
- const hasVisualization = !!content?.map_graphs?.length;
165
- const isFullWidthVisualization =
166
- hasVisualization && content?.map_graphs_full_width;
202
+ const visualizations = getVisualizations(content);
203
+ const columnVisualizations = visualizations.filter(
204
+ (visualization) => !visualization.full_width,
205
+ );
206
+ const fullWidthVisualizations = visualizations.filter(
207
+ (visualization) => visualization.full_width,
208
+ );
209
+ const hasFullWidthVisualizations = !!fullWidthVisualizations.length;
167
210
 
168
211
  const is_cmshare_video = SHARE_EEA.some((domain) =>
169
212
  content?.embed_url?.includes(domain),
@@ -171,7 +214,7 @@ const DatabaseItemView = (props) => {
171
214
 
172
215
  return (
173
216
  <div className="db-item-view">
174
- <BannerTitle
217
+ <ContentBannerTitle
175
218
  content={{ ...content, image: '', title: item_title }}
176
219
  data={{
177
220
  info: [{ description: '' }],
@@ -256,14 +299,11 @@ const DatabaseItemView = (props) => {
256
299
  </>
257
300
  )}
258
301
 
259
- {hasVisualization && !isFullWidthVisualization && (
260
- <>
261
- <MaybeFlourishVisualization {...props} />
262
- <MaybeIframeVisualization {...props} />
263
- </>
302
+ {!!columnVisualizations.length && (
303
+ <Visualizations visualizations={columnVisualizations} />
264
304
  )}
265
305
 
266
- {!isFullWidthVisualization && <BottomInfo {...props} />}
306
+ {!hasFullWidthVisualizations && <BottomInfo {...props} />}
267
307
  </Grid.Column>
268
308
 
269
309
  <Grid.Column
@@ -277,12 +317,11 @@ const DatabaseItemView = (props) => {
277
317
  </Grid.Column>
278
318
  </Grid.Row>
279
319
 
280
- {isFullWidthVisualization && (
320
+ {hasFullWidthVisualizations && (
281
321
  <>
282
322
  <Grid.Row>
283
323
  <Grid.Column mobile={12} tablet={12} computer={12}>
284
- <MaybeFlourishVisualization {...props} />
285
- <MaybeIframeVisualization {...props} />
324
+ <Visualizations visualizations={fullWidthVisualizations} />
286
325
  </Grid.Column>
287
326
  </Grid.Row>
288
327
  <Grid.Row>
@@ -17,6 +17,58 @@ config.blocks = {
17
17
 
18
18
  const mockStore = configureStore();
19
19
 
20
+ const baseContent = {
21
+ title: 'My DatabaseItemView',
22
+ long_description: {
23
+ 'content-type': null,
24
+ data: '<p>Nam commodo suscipit quam. Praesent egestas neque eu enim. Quisque rutrum.</p>',
25
+ encoding: 'utf-8',
26
+ },
27
+ publication_date: '2022-06-24',
28
+ geochars:
29
+ '{\r\n "geoElements":{"element":"GLOBAL",\r\n "macrotrans":null,"biotrans":null,"countries":[],\r\n "subnational":[],"city":""}}',
30
+ keywords: ['keyword 1', 'keyword 2'],
31
+ websites: ['https://example.org/'],
32
+ contributions: [
33
+ {
34
+ title: 'Contributor 1',
35
+ url: '/contributor-1',
36
+ },
37
+ {
38
+ title: 'Contributor 2',
39
+ url: '/contributor-2',
40
+ },
41
+ ],
42
+ };
43
+
44
+ const visualizationEmbedCode =
45
+ '<div class="flourish-embed" data-src="visualisation/12345"></div>';
46
+
47
+ const renderDatabaseItemView = (content = baseContent) => {
48
+ const store = mockStore({
49
+ userSession: { token: '1234' },
50
+ intl: {
51
+ locale: 'en',
52
+ messages: {},
53
+ },
54
+ });
55
+
56
+ return renderer.create(
57
+ <Provider store={store}>
58
+ <MemoryRouter>
59
+ <DatabaseItemView content={content} />
60
+ </MemoryRouter>
61
+ </Provider>,
62
+ );
63
+ };
64
+
65
+ const findColumnByClassName = (component, className) =>
66
+ component.root.findAll(
67
+ (node) =>
68
+ typeof node.props.className === 'string' &&
69
+ node.props.className.includes(className),
70
+ )[0];
71
+
20
72
  jest.mock('semantic-ui-react', () => ({
21
73
  ...jest.requireActual('semantic-ui-react'),
22
74
  }));
@@ -29,46 +81,54 @@ jest.mock('@eeacms/volto-embed', () => {
29
81
 
30
82
  describe('DatabaseItemView', () => {
31
83
  it('should render the component', () => {
32
- const content = {
33
- title: 'My DatabaseItemView',
34
- long_description: {
35
- 'content-type': null,
36
- data: '<p>Nam commodo suscipit quam. Praesent egestas neque eu enim. Quisque rutrum.</p>',
37
- encoding: 'utf-8',
38
- },
39
- publication_date: '2022-06-24',
40
- geochars:
41
- '{\r\n "geoElements":{"element":"GLOBAL",\r\n "macrotrans":null,"biotrans":null,"countries":[],\r\n "subnational":[],"city":""}}',
42
- keywords: ['keyword 1', 'keyword 2'],
43
- websites: ['https://example.org/'],
44
- contributions: [
45
- {
46
- title: 'Contributor 1',
47
- url: '/contributor-1',
48
- },
49
- {
50
- title: 'Contributor 2',
51
- url: '/contributor-2',
52
- },
53
- ],
54
- };
55
-
56
- const store = mockStore({
57
- userSession: { token: '1234' },
58
- intl: {
59
- locale: 'en',
60
- messages: {},
61
- },
84
+ const component = renderDatabaseItemView();
85
+ const json = component.toJSON();
86
+ expect(json).toMatchSnapshot();
87
+ });
88
+
89
+ it('renders the visualizations field in the left column by default', () => {
90
+ const component = renderDatabaseItemView({
91
+ ...baseContent,
92
+ map_graphs: visualizationEmbedCode,
62
93
  });
94
+ const colLeft = findColumnByClassName(component, 'col-left');
95
+ const fullWidthColumns = component.root.findAll(
96
+ (node) => node.props.computer === 12,
97
+ );
63
98
 
64
- const component = renderer.create(
65
- <Provider store={store}>
66
- <MemoryRouter>
67
- <DatabaseItemView content={content} />
68
- </MemoryRouter>
69
- </Provider>,
99
+ expect(colLeft.findAllByType('iframe')).toHaveLength(1);
100
+ expect(component.root.findByType('iframe').props.src).toBe(
101
+ 'https://flo.uri.sh/visualisation/12345/embed',
70
102
  );
71
- const json = component.toJSON();
72
- expect(json).toMatchSnapshot();
103
+ expect(fullWidthColumns).toHaveLength(0);
104
+ });
105
+
106
+ it('renders the visualizations field full width when enabled', () => {
107
+ const component = renderDatabaseItemView({
108
+ ...baseContent,
109
+ map_graphs: visualizationEmbedCode,
110
+ map_graphs_full_width: true,
111
+ });
112
+ const colLeft = findColumnByClassName(component, 'col-left');
113
+ const fullWidthColumn = component.root.findAll(
114
+ (node) => node.props.computer === 12,
115
+ )[0];
116
+
117
+ expect(colLeft.findAllByType('iframe')).toHaveLength(0);
118
+ expect(fullWidthColumn.findAllByType('iframe')).toHaveLength(1);
119
+ });
120
+
121
+ it('does not render a visualization when the visualizations field is empty', () => {
122
+ const component = renderDatabaseItemView({
123
+ ...baseContent,
124
+ map_graphs: '',
125
+ map_graphs_full_width: true,
126
+ });
127
+
128
+ expect(component.root.findAllByType('iframe')).toHaveLength(0);
129
+ const fullWidthColumns = component.root.findAll(
130
+ (node) => node.props.computer === 12,
131
+ );
132
+ expect(fullWidthColumns).toHaveLength(0);
73
133
  });
74
134
  });
@@ -2,12 +2,12 @@ import React from 'react';
2
2
  import { Grid, Container, Segment } from 'semantic-ui-react';
3
3
  import RenderBlocks from '@plone/volto/components/theme/View/RenderBlocks';
4
4
  import {
5
- SubjectTags,
6
5
  EventDetails,
7
6
  HTMLField,
8
- } from '@eeacms/volto-cca-policy/helpers';
7
+ PortalMessage,
8
+ SubjectTags,
9
+ } from '@eeacms/volto-cca-policy/components';
9
10
  import { filterBlocks } from '@eeacms/volto-cca-policy/utils';
10
- import { PortalMessage } from '@eeacms/volto-cca-policy/components';
11
11
 
12
12
  function EventView(props) {
13
13
  const { content } = props;
@@ -1,17 +1,15 @@
1
1
  import { Button, Container, Grid, Icon } from 'semantic-ui-react';
2
2
  import {
3
+ BooleanField,
3
4
  CompareToolsPanel,
4
- PortalMessage,
5
- } from '@eeacms/volto-cca-policy/components';
6
- import {
5
+ ContentMetadata,
6
+ DocumentsList,
7
7
  HTMLField,
8
+ ItemLogo,
9
+ PortalMessage,
8
10
  TextField,
9
- BooleanField,
10
11
  VocabularyField,
11
- ContentMetadata,
12
- ItemLogo,
13
- DocumentsList,
14
- } from '@eeacms/volto-cca-policy/helpers';
12
+ } from '@eeacms/volto-cca-policy/components';
15
13
  import { defineMessages, useIntl } from 'react-intl';
16
14
  import config from '@plone/volto/registry';
17
15
  import { useCompareTools } from '../CompareTools/utils';
@@ -12,14 +12,19 @@ jest.mock('../CompareTools/utils', () => ({
12
12
  }));
13
13
 
14
14
  jest.mock('@eeacms/volto-cca-policy/components', () => ({
15
+ BooleanField: ({ label, value, yesLabel, noLabel }) => (
16
+ <div>
17
+ <span>{label}</span>
18
+ <span>{value ? yesLabel : noLabel}</span>
19
+ </div>
20
+ ),
15
21
  CompareToolsPanel: () => <div data-testid="compare-tools-panel" />,
16
- PortalMessage: () => <div data-testid="portal-message" />,
17
- }));
18
-
19
- jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
22
+ ContentMetadata: () => <div data-testid="content-metadata" />,
23
+ DocumentsList: () => <div data-testid="documents-list" />,
20
24
  HTMLField: ({ value }) =>
21
25
  value ? <div dangerouslySetInnerHTML={{ __html: value }} /> : null,
22
-
26
+ ItemLogo: () => <div data-testid="item-logo" />,
27
+ PortalMessage: () => <div data-testid="portal-message" />,
23
28
  TextField: ({ label, value }) =>
24
29
  value !== null && value !== undefined && value !== '' ? (
25
30
  <div>
@@ -28,13 +33,6 @@ jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
28
33
  </div>
29
34
  ) : null,
30
35
 
31
- BooleanField: ({ label, value, yesLabel, noLabel }) => (
32
- <div>
33
- <span>{label}</span>
34
- <span>{value ? yesLabel : noLabel}</span>
35
- </div>
36
- ),
37
-
38
36
  VocabularyField: ({ label, values = [], asList }) =>
39
37
  values.length > 0 ? (
40
38
  <div>
@@ -50,10 +48,6 @@ jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
50
48
  )}
51
49
  </div>
52
50
  ) : null,
53
-
54
- ContentMetadata: () => <div data-testid="content-metadata" />,
55
- ItemLogo: () => <div data-testid="item-logo" />,
56
- DocumentsList: () => <div data-testid="documents-list" />,
57
51
  }));
58
52
 
59
53
  jest.mock('@plone/volto/registry', () => ({
@@ -2,7 +2,10 @@ import React from 'react';
2
2
  import { Link } from 'react-router-dom';
3
3
  import { Tab, Container, Divider, Button, Icon } from 'semantic-ui-react';
4
4
  import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
5
- import { BannerTitle, HTMLField } from '@eeacms/volto-cca-policy/helpers';
5
+ import {
6
+ ContentBannerTitle,
7
+ HTMLField,
8
+ } from '@eeacms/volto-cca-policy/components';
6
9
  import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
7
10
 
8
11
  import GovernanceTab from './TabSections/GovernanceTab';
@@ -55,7 +58,7 @@ const MissionSignatoryProfileView = ({ content }) => {
55
58
 
56
59
  return (
57
60
  <Container>
58
- <BannerTitle
61
+ <ContentBannerTitle
59
62
  content={{ ...content, image: signatoryData?.image }}
60
63
  data={{
61
64
  info: [{ description: '' }],
@@ -12,8 +12,8 @@ jest.mock('./TabSections/AssessmentTab', () => () => (
12
12
  jest.mock('./TabSections/PlanningTab', () => () => <div>Mocked Planning</div>);
13
13
  jest.mock('./TabSections/ActionTab', () => () => <div>Mocked Action</div>);
14
14
 
15
- jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
16
- BannerTitle: ({ children }) => <div>{children}</div>,
15
+ jest.mock('@eeacms/volto-cca-policy/components', () => ({
16
+ ContentBannerTitle: ({ children }) => <div>{children}</div>,
17
17
  HTMLField: ({ value }) => (
18
18
  <div dangerouslySetInnerHTML={{ __html: value?.data }} />
19
19
  ),
@@ -1,7 +1,6 @@
1
1
  import { Tab, Grid } from 'semantic-ui-react';
2
2
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
3
- import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
4
- import { AccordionList } from '@eeacms/volto-cca-policy/components';
3
+ import { AccordionList, HTMLField } from '@eeacms/volto-cca-policy/components';
5
4
  import { formatTextToHTML, isEmpty } from '@eeacms/volto-cca-policy/utils';
6
5
  import NoDataReported from '../NoDataReported';
7
6
  import ItemsSection from '../ItemsSection';
@@ -23,6 +23,9 @@ jest.mock('@eeacms/volto-cca-policy/components', () => ({
23
23
  ))}
24
24
  </div>
25
25
  ),
26
+ HTMLField: ({ value }) => (
27
+ <div dangerouslySetInnerHTML={{ __html: value?.data }} />
28
+ ),
26
29
  }));
27
30
 
28
31
  describe('ActionTab', () => {
@@ -1,7 +1,6 @@
1
1
  import { Tab, Segment } from 'semantic-ui-react';
2
2
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
3
- import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
4
- import { AccordionList } from '@eeacms/volto-cca-policy/components';
3
+ import { AccordionList, HTMLField } from '@eeacms/volto-cca-policy/components';
5
4
  import { isEmpty, formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
6
5
  import NoDataReported from '../NoDataReported';
7
6
  import ItemsSection from '../ItemsSection';
@@ -6,7 +6,17 @@ jest.mock('@eeacms/volto-eea-design-system/ui', () => ({
6
6
  Callout: ({ children }) => <div>{children}</div>,
7
7
  }));
8
8
 
9
- jest.mock('@eeacms/volto-cca-policy/helpers', () => ({
9
+ jest.mock('@eeacms/volto-cca-policy/components', () => ({
10
+ AccordionList: ({ accordions }) => (
11
+ <div>
12
+ {accordions.map((item, index) => (
13
+ <div key={index}>
14
+ <div>{item.title}</div>
15
+ <div>{item.content}</div>
16
+ </div>
17
+ ))}
18
+ </div>
19
+ ),
10
20
  HTMLField: ({ value }) => <div>{value.data}</div>,
11
21
  }));
12
22
 
@@ -1,8 +1,7 @@
1
1
  import { Tab } from 'semantic-ui-react';
2
2
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
3
- import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
4
3
  import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
5
- import { AccordionList } from '@eeacms/volto-cca-policy/components';
4
+ import { AccordionList, HTMLField } from '@eeacms/volto-cca-policy/components';
6
5
  import StatisticSection from '../StatisticSection';
7
6
 
8
7
  const GovernanceTab = ({ result, general_text }) => {
@@ -1,13 +1,12 @@
1
1
  import React from 'react';
2
2
  import { Tab, Message, Segment, Grid } from 'semantic-ui-react';
3
3
  import { Callout } from '@eeacms/volto-eea-design-system/ui';
4
- import { HTMLField } from '@eeacms/volto-cca-policy/helpers';
5
4
  import {
6
5
  isEmpty,
7
6
  formatTextToHTML,
8
7
  extractPlanNameAndURL,
9
8
  } from '@eeacms/volto-cca-policy/utils';
10
- import { AccordionList } from '@eeacms/volto-cca-policy/components';
9
+ import { AccordionList, HTMLField } from '@eeacms/volto-cca-policy/components';
11
10
  import NoDataReported from '../NoDataReported';
12
11
  import ItemsSection from '../ItemsSection';
13
12