@eeacms/volto-cca-policy 0.3.90 → 0.3.92
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 +24 -2
- package/locales/bg/LC_MESSAGES/volto.po +8 -1
- package/locales/cs/LC_MESSAGES/volto.po +8 -1
- package/locales/da/LC_MESSAGES/volto.po +8 -1
- package/locales/de/LC_MESSAGES/volto.po +8 -1
- package/locales/eea.climateadapt.pot +3 -0
- package/locales/el/LC_MESSAGES/volto.po +8 -1
- package/locales/en/LC_MESSAGES/volto.po +8 -0
- package/locales/es/LC_MESSAGES/volto.po +8 -1
- package/locales/et/LC_MESSAGES/volto.po +8 -1
- package/locales/fi/LC_MESSAGES/volto.po +8 -1
- package/locales/fr/LC_MESSAGES/volto.po +31 -24
- package/locales/ga/LC_MESSAGES/volto.po +8 -1
- package/locales/hr/LC_MESSAGES/volto.po +8 -1
- package/locales/hu/LC_MESSAGES/volto.po +8 -1
- package/locales/is/LC_MESSAGES/volto.po +8 -1
- package/locales/it/LC_MESSAGES/volto.po +8 -1
- package/locales/lt/LC_MESSAGES/volto.po +8 -1
- package/locales/lv/LC_MESSAGES/volto.po +20 -13
- package/locales/mt/LC_MESSAGES/volto.po +8 -1
- package/locales/nl/LC_MESSAGES/volto.po +9 -2
- package/locales/nn/LC_MESSAGES/volto.po +8 -1
- package/locales/pl/LC_MESSAGES/volto.po +8 -1
- package/locales/pt/LC_MESSAGES/volto.po +8 -1
- package/locales/ro/LC_MESSAGES/volto.po +9 -2
- package/locales/sk/LC_MESSAGES/volto.po +8 -1
- package/locales/sl/LC_MESSAGES/volto.po +8 -1
- package/locales/sv/LC_MESSAGES/volto.po +8 -1
- package/locales/tr/LC_MESSAGES/volto.po +8 -1
- package/locales/volto.pot +4 -1
- package/package.json +1 -1
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyFilters.jsx +5 -5
- package/src/customizations/volto/components/theme/View/README.md +9 -1
- package/src/customizations/volto/components/theme/View/View.jsx +26 -12
- package/src/customizations/volto/middleware/api.js +28 -8
- package/src/customizations/volto/server.jsx +5 -1
- package/src/messages.js +96 -0
|
@@ -93,7 +93,7 @@ export default function CaseStudyFilters(props) {
|
|
|
93
93
|
{Object.entries(filters?.sectors || {}).map(
|
|
94
94
|
([value, label], index) => (
|
|
95
95
|
<Checkbox
|
|
96
|
-
label={intl.formatMessage({ id: label })}
|
|
96
|
+
label={intl.formatMessage({ id: label.trim() })}
|
|
97
97
|
value={value}
|
|
98
98
|
checked={activeFilters.sectors.includes(value)}
|
|
99
99
|
name="sectors"
|
|
@@ -119,7 +119,7 @@ export default function CaseStudyFilters(props) {
|
|
|
119
119
|
{Object.entries(filters?.impacts || {}).map(
|
|
120
120
|
([value, label], index) => (
|
|
121
121
|
<Checkbox
|
|
122
|
-
label={intl.formatMessage({ id: label })}
|
|
122
|
+
label={intl.formatMessage({ id: label.trim() })}
|
|
123
123
|
checked={activeFilters.impacts.includes(value)}
|
|
124
124
|
value={value}
|
|
125
125
|
name="impacts"
|
|
@@ -145,10 +145,10 @@ export default function CaseStudyFilters(props) {
|
|
|
145
145
|
{Object.entries(filters?.measures || {}).map(
|
|
146
146
|
([key, values], index) => (
|
|
147
147
|
<div className="subcategory" key={'ktm' + index}>
|
|
148
|
-
<h4>{intl.formatMessage({ id: key })}</h4>
|
|
148
|
+
<h4>{intl.formatMessage({ id: key.trim() })}</h4>
|
|
149
149
|
{Object.entries(values).map(([_, valData]) => (
|
|
150
150
|
<Checkbox
|
|
151
|
-
label={intl.formatMessage({ id: valData.value })}
|
|
151
|
+
label={intl.formatMessage({ id: valData.value.trim() })}
|
|
152
152
|
value={valData.key}
|
|
153
153
|
checked={activeFilters.measures.includes(valData.key)}
|
|
154
154
|
name="measures"
|
|
@@ -175,7 +175,7 @@ export default function CaseStudyFilters(props) {
|
|
|
175
175
|
{Object.entries(filters?.elements || {}).map(
|
|
176
176
|
([value, label], index) => (
|
|
177
177
|
<Checkbox
|
|
178
|
-
label={intl.formatMessage({ id: label })}
|
|
178
|
+
label={intl.formatMessage({ id: label.trim() })}
|
|
179
179
|
value={value}
|
|
180
180
|
checked={activeFilters.elements.includes(value)}
|
|
181
181
|
name="elements"
|
|
@@ -1 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
# View Customizations
|
|
2
|
+
|
|
3
|
+
## Changes
|
|
4
|
+
|
|
5
|
+
1. **API URL stripping**: Removes `++api++` from URLs
|
|
6
|
+
2. **Link redirect handling**: Supports 301/302 redirects for Link content types
|
|
7
|
+
- Checks `@components.redirect` from backend serializer
|
|
8
|
+
- Sets correct HTTP status code for SSR (301 vs 302)
|
|
9
|
+
- Backwards compatible with error-based redirects
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
Tags,
|
|
19
19
|
Toolbar,
|
|
20
20
|
} from '@plone/volto/components';
|
|
21
|
+
import { AlternateHrefLangs } from '@plone/volto/components/theme/AlternateHrefLangs/AlternateHrefLangs';
|
|
21
22
|
import { listActions, getContent } from '@plone/volto/actions';
|
|
22
23
|
import {
|
|
23
24
|
BodyClass,
|
|
@@ -98,6 +99,8 @@ class View extends Component {
|
|
|
98
99
|
* Error type
|
|
99
100
|
*/
|
|
100
101
|
status: PropTypes.number,
|
|
102
|
+
code: PropTypes.number,
|
|
103
|
+
url: PropTypes.string,
|
|
101
104
|
}),
|
|
102
105
|
};
|
|
103
106
|
|
|
@@ -203,23 +206,33 @@ class View extends Component {
|
|
|
203
206
|
*/
|
|
204
207
|
render() {
|
|
205
208
|
const { views } = config;
|
|
206
|
-
if (this.props.error && this.props.error.code === 301) {
|
|
207
|
-
// const base = typeof window !== 'undefined' ? window.location.origin : '';
|
|
208
209
|
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
// customization
|
|
211
|
+
const redirectData =
|
|
212
|
+
this.props.content?.['@components']?.redirect ||
|
|
213
|
+
([301, 302].includes(this.props.error?.code) && {
|
|
214
|
+
url: this.props.error.url,
|
|
215
|
+
status: this.props.error.code,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
if (redirectData) {
|
|
219
|
+
const redirect = flattenToAppURL(redirectData.url)
|
|
220
|
+
.replace('/++api++', '')
|
|
211
221
|
.replaceAll('//', '/')
|
|
212
222
|
.split('?')[0];
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
223
|
+
const targetUrl = `${redirect}${this.props.location.search}`;
|
|
224
|
+
|
|
225
|
+
if (this.props.staticContext) {
|
|
226
|
+
this.props.staticContext.error_code = redirectData.status || 302;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const shouldPush = redirectData.status === 302;
|
|
217
230
|
|
|
218
|
-
|
|
219
|
-
|
|
231
|
+
return <Redirect to={targetUrl} push={shouldPush} />;
|
|
232
|
+
}
|
|
233
|
+
// end of customization
|
|
220
234
|
|
|
221
|
-
|
|
222
|
-
} else if (this.props.error && !this.props.connectionRefused) {
|
|
235
|
+
if (this.props.error && !this.props.connectionRefused) {
|
|
223
236
|
let FoundView;
|
|
224
237
|
if (this.props.error.status === undefined) {
|
|
225
238
|
// For some reason, while development and if CORS is in place and the
|
|
@@ -247,6 +260,7 @@ class View extends Component {
|
|
|
247
260
|
return (
|
|
248
261
|
<div id="view">
|
|
249
262
|
<ContentMetadataTags content={this.props.content} />
|
|
263
|
+
<AlternateHrefLangs content={this.props.content} />
|
|
250
264
|
{/* Body class if displayName in component is set */}
|
|
251
265
|
<BodyClass
|
|
252
266
|
className={
|
|
@@ -50,10 +50,7 @@ export function addExpandersToPath(path, type, isAnonymous) {
|
|
|
50
50
|
} = qs.parseUrl(path, { decode: false });
|
|
51
51
|
|
|
52
52
|
const expandersFromConfig = apiExpanders
|
|
53
|
-
.filter((expand) =>
|
|
54
|
-
const res = matchPath(url, expand.match) && expand[type];
|
|
55
|
-
return res;
|
|
56
|
-
})
|
|
53
|
+
.filter((expand) => matchPath(url, expand.match) && expand[type])
|
|
57
54
|
.map((expand) => expand[type]);
|
|
58
55
|
|
|
59
56
|
const expandMerge = compact(
|
|
@@ -70,7 +67,15 @@ export function addExpandersToPath(path, type, isAnonymous) {
|
|
|
70
67
|
|
|
71
68
|
const querystringFromConfig = apiExpanders
|
|
72
69
|
.filter((expand) => matchPath(url, expand.match) && expand[type])
|
|
73
|
-
.reduce((acc, expand) =>
|
|
70
|
+
.reduce((acc, expand) => {
|
|
71
|
+
let querystring = expand?.['querystring'];
|
|
72
|
+
// The querystring accepts being a function to be able to take other
|
|
73
|
+
// config parameters
|
|
74
|
+
if (typeof querystring === 'function') {
|
|
75
|
+
querystring = querystring(config);
|
|
76
|
+
}
|
|
77
|
+
return { ...acc, ...querystring };
|
|
78
|
+
}, {});
|
|
74
79
|
|
|
75
80
|
const queryMerge = { ...query, ...querystringFromConfig };
|
|
76
81
|
|
|
@@ -128,6 +133,13 @@ const apiMiddlewareFactory =
|
|
|
128
133
|
const { settings } = config;
|
|
129
134
|
|
|
130
135
|
const isAnonymous = !getState().userSession.token;
|
|
136
|
+
// const token = getState().userSession.token;
|
|
137
|
+
// let isAnonymous = true;
|
|
138
|
+
// if (token) {
|
|
139
|
+
// const tokenExpiration = jwtDecode(token).exp;
|
|
140
|
+
// const currentTime = new Date().getTime() / 1000;
|
|
141
|
+
// isAnonymous = !token || currentTime > tokenExpiration;
|
|
142
|
+
// }
|
|
131
143
|
|
|
132
144
|
if (typeof action === 'function') {
|
|
133
145
|
return action(dispatch, getState);
|
|
@@ -310,15 +322,23 @@ const apiMiddlewareFactory =
|
|
|
310
322
|
}
|
|
311
323
|
|
|
312
324
|
// Redirect
|
|
313
|
-
|
|
325
|
+
// customization
|
|
326
|
+
else if (error?.code === 301 || error?.code === 302) {
|
|
327
|
+
const redirectUrl =
|
|
328
|
+
error.response?.body?.url || error.response?.body?.location;
|
|
329
|
+
|
|
314
330
|
next({
|
|
315
331
|
...rest,
|
|
316
|
-
error
|
|
332
|
+
error: {
|
|
333
|
+
...error,
|
|
334
|
+
url: redirectUrl,
|
|
335
|
+
},
|
|
317
336
|
statusCode: error.code,
|
|
318
337
|
connectionRefused: false,
|
|
319
338
|
type: SET_APIERROR,
|
|
320
339
|
});
|
|
321
340
|
}
|
|
341
|
+
// end of customization
|
|
322
342
|
|
|
323
343
|
// Redirect
|
|
324
344
|
else if (error?.code === 408) {
|
|
@@ -337,7 +357,7 @@ const apiMiddlewareFactory =
|
|
|
337
357
|
...rest,
|
|
338
358
|
error,
|
|
339
359
|
statusCode: error.response,
|
|
340
|
-
message: error.response
|
|
360
|
+
message: error.response?.body?.message,
|
|
341
361
|
connectionRefused: false,
|
|
342
362
|
type: SET_APIERROR,
|
|
343
363
|
});
|
|
@@ -321,7 +321,11 @@ server.get('/*', (req, res) => {
|
|
|
321
321
|
}
|
|
322
322
|
|
|
323
323
|
if (context.url) {
|
|
324
|
-
|
|
324
|
+
// customization
|
|
325
|
+
// Use error_code if set (for Link redirects with specific status)
|
|
326
|
+
const redirectStatus = context.error_code || 302;
|
|
327
|
+
res.redirect(redirectStatus, flattenToAppURL(context.url));
|
|
328
|
+
// end of customization
|
|
325
329
|
} else if (context.error_code) {
|
|
326
330
|
res.set({
|
|
327
331
|
'Cache-Control': 'no-cache',
|
package/src/messages.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { defineMessages } from 'react-intl';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
placeholderClimateSearch: {
|
|
4
|
+
id: 'Search the Climate-ADAPT database',
|
|
5
|
+
defaultMessage: 'Search the Climate-ADAPT database',
|
|
6
|
+
},
|
|
7
|
+
placeholderObservatorySearch: {
|
|
8
|
+
id: 'Search the Observatory Resource Catalogue...',
|
|
9
|
+
defaultMessage: 'Search the Observatory Resource Catalogue...',
|
|
10
|
+
},
|
|
11
|
+
placeholderMissionSearch: {
|
|
12
|
+
id: 'Search the EU Mission on Adaptation',
|
|
13
|
+
defaultMessage: 'Search the EU Mission on Adaptation',
|
|
14
|
+
},
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export const messagesList = defineMessages({
|
|
18
|
+
a1def: {
|
|
19
|
+
id: 'Governance and Institutional',
|
|
20
|
+
defaultMessage: 'Governance and Institutional',
|
|
21
|
+
},
|
|
22
|
+
a1: {
|
|
23
|
+
id: 'Policy Instruments',
|
|
24
|
+
defaultMessage: 'Policy Instruments',
|
|
25
|
+
},
|
|
26
|
+
a2: {
|
|
27
|
+
id: 'Management and planning',
|
|
28
|
+
defaultMessage: 'Management and planning',
|
|
29
|
+
},
|
|
30
|
+
a3: {
|
|
31
|
+
id: 'Coordination cooperation and networks',
|
|
32
|
+
defaultMessage: 'Coordination cooperation and networks',
|
|
33
|
+
},
|
|
34
|
+
b1def: {
|
|
35
|
+
id: 'Economic and Finance',
|
|
36
|
+
defaultMessage: 'Economic and Finance',
|
|
37
|
+
},
|
|
38
|
+
b1: {
|
|
39
|
+
id: 'Financing incentive instruments',
|
|
40
|
+
defaultMessage: 'Financing incentive instruments',
|
|
41
|
+
},
|
|
42
|
+
b2: {
|
|
43
|
+
id: 'Insurance and risk sharing instruments',
|
|
44
|
+
defaultMessage: 'Insurance and risk sharing instruments',
|
|
45
|
+
},
|
|
46
|
+
c1def: {
|
|
47
|
+
id: 'Physical and technological',
|
|
48
|
+
defaultMessage: 'Physical and technological',
|
|
49
|
+
},
|
|
50
|
+
c1: {
|
|
51
|
+
id: 'Grey options',
|
|
52
|
+
defaultMessage: 'Grey options',
|
|
53
|
+
},
|
|
54
|
+
c2: {
|
|
55
|
+
id: 'Technological options',
|
|
56
|
+
defaultMessage: 'Technological options',
|
|
57
|
+
},
|
|
58
|
+
d1def: {
|
|
59
|
+
id: 'Nature based Solutions and Ecosystem based approaches',
|
|
60
|
+
defaultMessage: 'Nature based Solutions and Ecosystem based approaches',
|
|
61
|
+
},
|
|
62
|
+
d1: {
|
|
63
|
+
id: 'Green options',
|
|
64
|
+
defaultMessage: 'Green options',
|
|
65
|
+
},
|
|
66
|
+
d2: {
|
|
67
|
+
id: 'Blue options',
|
|
68
|
+
defaultMessage: 'Blue options',
|
|
69
|
+
},
|
|
70
|
+
e1def: {
|
|
71
|
+
id: 'Knowledge and behavioural change',
|
|
72
|
+
defaultMessage: 'Knowledge and behavioural change',
|
|
73
|
+
},
|
|
74
|
+
e1: {
|
|
75
|
+
id: 'Information and awareness raising',
|
|
76
|
+
defaultMessage: 'Information and awareness raising',
|
|
77
|
+
},
|
|
78
|
+
e2: {
|
|
79
|
+
id: 'Capacity building empowering and lifestyle practices',
|
|
80
|
+
defaultMessage: 'Capacity building empowering and lifestyle practices',
|
|
81
|
+
},
|
|
82
|
+
e3: {
|
|
83
|
+
id: 'Capacity building empowering and lifestyle practices',
|
|
84
|
+
defaultMessage: 'Capacity building empowering and lifestyle practices',
|
|
85
|
+
},
|
|
86
|
+
healthImpacts: {
|
|
87
|
+
id: 'Health Impacts',
|
|
88
|
+
defaultMessage: 'Health Impacts',
|
|
89
|
+
},
|
|
90
|
+
types: {
|
|
91
|
+
id: 'Types',
|
|
92
|
+
defaultMessage: 'Types',
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
export default messages;
|