@eeacms/volto-cca-policy 0.3.45 → 0.3.46

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,6 +4,17 @@ 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
+ ### [0.3.46](https://github.com/eea/volto-cca-policy/compare/0.3.45...0.3.46) - 21 May 2025
8
+
9
+ #### :house: Internal changes
10
+
11
+ - style: Automated code fix [eea-jenkins - [`ea4b8be`](https://github.com/eea/volto-cca-policy/commit/ea4b8beed2cb7426c3125b6edb85d3b1fadf66a1)]
12
+
13
+ #### :hammer_and_wrench: Others
14
+
15
+ - Dont' need this now [Tiberiu Ichim - [`eff27fb`](https://github.com/eea/volto-cca-policy/commit/eff27fb4022b445c6c298a1c59e36ecab661e91e)]
16
+ - Add actions customization [Tiberiu Ichim - [`69f9b00`](https://github.com/eea/volto-cca-policy/commit/69f9b00cb45149e9b4d06085f4688800cb4d1d9f)]
17
+ - Remove etag from server [Tiberiu Ichim - [`7d94455`](https://github.com/eea/volto-cca-policy/commit/7d94455440b69ebd97c0ef5cc3dd839687b13e54)]
7
18
  ### [0.3.45](https://github.com/eea/volto-cca-policy/compare/0.3.44...0.3.45) - 21 May 2025
8
19
 
9
20
  #### :rocket: New Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "0.3.45",
3
+ "version": "0.3.46",
4
4
  "description": "@eeacms/volto-cca-policy: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Html helper.
3
+ * @module helpers/Html
4
+ */
5
+
6
+ import React, { Component } from 'react';
7
+ import PropTypes from 'prop-types';
8
+ import Helmet from '@plone/volto/helpers/Helmet/Helmet';
9
+ import serialize from 'serialize-javascript';
10
+ import { join } from 'lodash';
11
+ import BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
12
+ import { runtimeConfig } from '@plone/volto/runtime_config';
13
+ import config from '@plone/volto/registry';
14
+
15
+ const CRITICAL_CSS_TEMPLATE = `function alter() {
16
+ document.querySelectorAll("head link[rel='prefetch']").forEach(function(el) { el.rel = 'stylesheet'});
17
+ }
18
+ if (window.addEventListener) {
19
+ window.addEventListener('DOMContentLoaded', alter, false)
20
+ } else {
21
+ window.onload=alter
22
+ }`;
23
+
24
+ export const loadReducers = (state = {}) => {
25
+ const { settings } = config;
26
+ return Object.assign(
27
+ {},
28
+ ...Object.keys(state).map((name) =>
29
+ settings.initialReducersBlacklist.includes(name)
30
+ ? {}
31
+ : { [name]: state[name] },
32
+ ),
33
+ );
34
+ };
35
+
36
+ /**
37
+ * Html class.
38
+ * Wrapper component containing HTML metadata and boilerplate tags.
39
+ * Used in server-side code only to wrap the string output of the
40
+ * rendered route component.
41
+ *
42
+ * The only thing this component doesn't (and can't) include is the
43
+ * HTML doctype declaration, which is added to the rendered output
44
+ * by the server.js file.
45
+ *
46
+ * Critical.css behaviour: when a file `public/critical.css` is present, the
47
+ * loading of stylesheets is changed. The styles in critical.css are inlined in
48
+ * the generated HTML, and the whole story needs to change completely: instead
49
+ * of treating stylesheets as priority for rendering, we want to defer their
50
+ * loading as much as possible. So we change the stylesheets to be prefetched
51
+ * and we switch their rel back to stylesheets at document ready event.
52
+ *
53
+ * @function Html
54
+ * @param {Object} props Component properties.
55
+ * @param {Object} props.assets Assets to be rendered.
56
+ * @param {Object} props.component Content to be rendered as child node.
57
+ * @param {Object} props.store Store object.
58
+ * @returns {string} Markup of the not found page.
59
+ */
60
+
61
+ /**
62
+ * Html class.
63
+ * @class Html
64
+ * @extends Component
65
+ */
66
+ class Html extends Component {
67
+ /**
68
+ * Property types.
69
+ * @property {Object} propTypes Property types.
70
+ * @static
71
+ */
72
+ static propTypes = {
73
+ extractor: PropTypes.shape({
74
+ getLinkElements: PropTypes.func.isRequired,
75
+ getScriptElements: PropTypes.func.isRequired,
76
+ getStyleElements: PropTypes.func.isRequired,
77
+ }).isRequired,
78
+ markup: PropTypes.string.isRequired,
79
+ store: PropTypes.shape({
80
+ getState: PropTypes.func,
81
+ }).isRequired,
82
+ nonce: PropTypes.string,
83
+ };
84
+
85
+ /**
86
+ * Render method.
87
+ * @method render
88
+ * @returns {string} Markup for the component.
89
+ */
90
+ render() {
91
+ const {
92
+ extractor,
93
+ markup,
94
+ store,
95
+ criticalCss,
96
+ apiPath,
97
+ publicURL,
98
+ nonce,
99
+ } = this.props;
100
+ const head = Helmet.rewind();
101
+ const bodyClass = join(BodyClass.rewind(), ' ');
102
+ const htmlAttributes = head.htmlAttributes.toComponent();
103
+
104
+ return (
105
+ <html lang={htmlAttributes.lang}>
106
+ <head>
107
+ <meta charSet="utf-8" />
108
+ {head.base.toComponent()}
109
+ {head.title.toComponent()}
110
+ {head.meta.toComponent()}
111
+ {head.link.toComponent()}
112
+ {head.script.toComponent()}
113
+
114
+ {React.createElement('script', {
115
+ nonce: nonce,
116
+ dangerouslySetInnerHTML: {
117
+ __html: `window.env = ${serialize(
118
+ {
119
+ ...runtimeConfig,
120
+ // Seamless mode requirement, the client need to know where the API is located
121
+ // if not set in the API_PATH
122
+ ...(apiPath && {
123
+ apiPath,
124
+ }),
125
+ ...(publicURL && {
126
+ publicURL,
127
+ }),
128
+ },
129
+ { space: 2 },
130
+ )};`,
131
+ },
132
+ })}
133
+
134
+ <link rel="icon" href="/favicon.ico" sizes="any" />
135
+ <link rel="icon" href="/icon.svg" type="image/svg+xml" />
136
+ <link
137
+ rel="apple-touch-icon"
138
+ sizes="180x180"
139
+ href="/apple-touch-icon.png"
140
+ />
141
+ <link rel="manifest" href="/site.webmanifest" />
142
+ <meta name="generator" content="Plone 6 - https://plone.org" />
143
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
144
+ <meta name="apple-mobile-web-app-capable" content="yes" />
145
+ {process.env.NODE_ENV === 'production' && criticalCss && (
146
+ <style
147
+ dangerouslySetInnerHTML={{ __html: this.props.criticalCss }}
148
+ />
149
+ )}
150
+ {/* Add the crossorigin while in development */}
151
+ {extractor.getLinkElements().map((elem) =>
152
+ React.cloneElement(elem, {
153
+ crossOrigin:
154
+ process.env.NODE_ENV === 'production' ? undefined : 'true',
155
+ rel: !criticalCss
156
+ ? elem.props.rel
157
+ : elem.props.as === 'style'
158
+ ? 'prefetch'
159
+ : elem.props.rel,
160
+ }),
161
+ )}
162
+ {/* Styles in development are loaded with Webpack's style-loader, in production,
163
+ they need to be static*/}
164
+ {process.env.NODE_ENV === 'production' ? (
165
+ criticalCss ? (
166
+ <>
167
+ <script
168
+ dangerouslySetInnerHTML={{
169
+ __html: CRITICAL_CSS_TEMPLATE,
170
+ }}
171
+ ></script>
172
+ {extractor.getStyleElements().map((elem) => (
173
+ <noscript>
174
+ {React.cloneElement(elem, {
175
+ rel: 'stylesheet',
176
+ crossOrigin:
177
+ process.env.NODE_ENV === 'production'
178
+ ? undefined
179
+ : 'true',
180
+ })}
181
+ </noscript>
182
+ ))}
183
+ </>
184
+ ) : (
185
+ extractor.getStyleElements()
186
+ )
187
+ ) : undefined}
188
+ </head>
189
+ <body className={bodyClass}>
190
+ <div role="navigation" aria-label="Toolbar" id="toolbar" />
191
+ <div id="main" dangerouslySetInnerHTML={{ __html: markup }} />
192
+ <div role="complementary" aria-label="Sidebar" id="sidebar" />
193
+ {React.createElement('script', {
194
+ nonce: nonce,
195
+ dangerouslySetInnerHTML: {
196
+ __html: `window.__data=${serialize(
197
+ loadReducers(store.getState()),
198
+ { space: 2 },
199
+ )};`,
200
+ },
201
+ charSet: 'UTF-8',
202
+ })}
203
+ {/* Add the crossorigin while in development */}
204
+ {this.props.extractScripts !== false
205
+ ? extractor.getScriptElements().map((elem) =>
206
+ React.cloneElement(elem, {
207
+ nonce: nonce,
208
+ crossOrigin:
209
+ process.env.NODE_ENV === 'production' ? undefined : 'true',
210
+ }),
211
+ )
212
+ : ''}
213
+ </body>
214
+ </html>
215
+ );
216
+ }
217
+ }
218
+
219
+ export default Html;
@@ -0,0 +1,3 @@
1
+ Customized for CSP support. Copy of https://github.com/plone/volto/blob/8b0f2af98ce0362f6975ce9c50137f6bd7cc3bb8/src/helpers/Html/Html.jsx Volto 17.x.x branch
2
+
3
+ Added formatting of json serialized strings
@@ -20,6 +20,7 @@ import { resetServerContext } from 'react-beautiful-dnd';
20
20
  import { CookiesProvider } from 'react-cookie';
21
21
  import cookiesMiddleware from 'universal-cookie-express';
22
22
  import debug from 'debug';
23
+ // import crypto from 'crypto';
23
24
 
24
25
  import routes from '@root/routes';
25
26
  import config from '@plone/volto/registry';
@@ -64,6 +65,18 @@ if (config.settings) {
64
65
  });
65
66
  }
66
67
 
68
+ // function buildCSPHeader(opts, nonce) {
69
+ // return Object.keys(opts)
70
+ // .sort()
71
+ // .reduce((acc, key) => {
72
+ // return [
73
+ // ...acc,
74
+ // `${key} ${opts[key].replaceAll('{nonce}', `'nonce-${nonce}'`)}`,
75
+ // ];
76
+ // }, [])
77
+ // .join('; ');
78
+ // }
79
+
67
80
  function reactIntlErrorHandler(error) {
68
81
  debug('i18n')(error);
69
82
  }
@@ -71,6 +84,7 @@ function reactIntlErrorHandler(error) {
71
84
  const supported = new locale.Locales(keys(languages), 'en');
72
85
 
73
86
  const server = express()
87
+ .set('etag', false)
74
88
  .disable('x-powered-by')
75
89
  .head('/*', function (req, res) {
76
90
  // Support for HEAD requests. Required by start-test utility in CI.
package/src/index.js CHANGED
@@ -555,6 +555,13 @@ const applyConfig = (config) => {
555
555
  ...config.settings.storeExtenders,
556
556
  ];
557
557
 
558
+ config.settings.initialReducersBlacklist = [
559
+ ...config.settings.initialReducersBlacklist,
560
+ 'intl',
561
+ // 'router',
562
+ // 'content',
563
+ ];
564
+
558
565
  config.widgets.vocabulary[
559
566
  'plone.app.vocabularies.Users'
560
567
  ] = SelectAutoCompleteWidget;
@@ -63,7 +63,6 @@ cca_build_runtime_mappings['op_cluster'] = {
63
63
 
64
64
  export default function installMainSearch(config) {
65
65
  const envConfig = ccaConfig;
66
-
67
66
  const pjson = require('@eeacms/volto-cca-policy/../package.json');
68
67
 
69
68
  envConfig.app_name = pjson.name;
@@ -221,7 +220,17 @@ export default function installMainSearch(config) {
221
220
  config.searchui.ccaSearch.host =
222
221
  process.env.RAZZLE_ES_PROXY_ADDR || getClientProxyAddress();
223
222
  }
223
+ let fieldsMatchAll = [
224
+ 'cca_climate_impacts.keyword',
225
+ 'cca_adaptation_sectors.keyword',
226
+ 'cca_adaptation_elements.keyword',
227
+ 'cca_key_type_measure.keyword',
228
+ ];
229
+ config.searchui.ccaSearch.facets.forEach((facet) => {
230
+ if (fieldsMatchAll.includes(facet.field)) {
231
+ facet.filterType = 'all';
232
+ }
233
+ });
224
234
 
225
- // console.log(config);
226
235
  return config;
227
236
  }