@eeacms/volto-cca-policy 1.0.36 → 1.0.38
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 +40 -14
- package/locales/bg/LC_MESSAGES/volto.po +30 -9
- package/locales/cs/LC_MESSAGES/volto.po +30 -9
- package/locales/da/LC_MESSAGES/volto.po +30 -9
- package/locales/de/LC_MESSAGES/volto.po +30 -9
- package/locales/el/LC_MESSAGES/volto.po +30 -9
- package/locales/en/LC_MESSAGES/volto.po +30 -9
- package/locales/es/LC_MESSAGES/volto.po +30 -9
- package/locales/et/LC_MESSAGES/volto.po +30 -9
- package/locales/fi/LC_MESSAGES/volto.po +30 -9
- package/locales/fr/LC_MESSAGES/volto.po +30 -9
- package/locales/ga/LC_MESSAGES/volto.po +30 -9
- package/locales/hr/LC_MESSAGES/volto.po +30 -9
- package/locales/hu/LC_MESSAGES/volto.po +30 -9
- package/locales/is/LC_MESSAGES/volto.po +30 -9
- package/locales/it/LC_MESSAGES/volto.po +30 -9
- package/locales/lt/LC_MESSAGES/volto.po +30 -9
- package/locales/lv/LC_MESSAGES/volto.po +30 -9
- package/locales/mt/LC_MESSAGES/volto.po +30 -9
- package/locales/nl/LC_MESSAGES/volto.po +30 -9
- package/locales/nn/LC_MESSAGES/volto.po +30 -9
- package/locales/pl/LC_MESSAGES/volto.po +30 -9
- package/locales/pt/LC_MESSAGES/volto.po +30 -9
- package/locales/ro/LC_MESSAGES/volto.po +30 -9
- package/locales/sk/LC_MESSAGES/volto.po +30 -9
- package/locales/sl/LC_MESSAGES/volto.po +30 -9
- package/locales/sv/LC_MESSAGES/volto.po +30 -9
- package/locales/tr/LC_MESSAGES/volto.po +30 -9
- package/locales/volto.pot +22 -1
- package/package.json +1 -1
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapState.jsx +72 -0
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapState.test.jsx +46 -0
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.jsx +20 -1
- package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.test.jsx +88 -0
- package/src/components/Search/NavigatorCatalogue/NavigatorGeographicCoverageFacet.jsx +47 -39
- package/src/components/Search/NavigatorCatalogue/NavigatorGeographicCoverageFacet.test.jsx +65 -1
- package/src/components/Search/NavigatorCatalogue/utils.js +24 -0
- package/src/components/Search/NavigatorGuide/NavigatorGuideContentView.test.jsx +67 -0
- package/src/components/theme/CompareTools/CompareToolsView.test.jsx +59 -0
- package/src/components/theme/Footer/Footer.jsx +137 -0
- package/src/customizations/volto/components/theme/App/App.jsx +1 -1
- package/src/messages.js +20 -0
- package/theme/globals/navigator.less +79 -1
|
@@ -3,7 +3,9 @@ import {
|
|
|
3
3
|
getColorForCount,
|
|
4
4
|
normalizeCountryName,
|
|
5
5
|
buildCountryCounts,
|
|
6
|
+
clearMapIncompatibleGeographicFilters,
|
|
6
7
|
filterCountryCounts,
|
|
8
|
+
hasMapIncompatibleGeographicSelection,
|
|
7
9
|
mapLegendItems,
|
|
8
10
|
setCountryFilter,
|
|
9
11
|
} from './utils';
|
|
@@ -185,6 +187,92 @@ describe('filterCountryCounts', () => {
|
|
|
185
187
|
});
|
|
186
188
|
});
|
|
187
189
|
|
|
190
|
+
describe('hasMapIncompatibleGeographicSelection', () => {
|
|
191
|
+
it('allows no geographic selection and country selections', () => {
|
|
192
|
+
expect(hasMapIncompatibleGeographicSelection()).toBe(false);
|
|
193
|
+
expect(hasMapIncompatibleGeographicSelection([])).toBe(false);
|
|
194
|
+
expect(
|
|
195
|
+
hasMapIncompatibleGeographicSelection([
|
|
196
|
+
{
|
|
197
|
+
field: 'cca_geographic_countries.keyword',
|
|
198
|
+
values: [],
|
|
199
|
+
type: 'any',
|
|
200
|
+
},
|
|
201
|
+
]),
|
|
202
|
+
).toBe(false);
|
|
203
|
+
expect(
|
|
204
|
+
hasMapIncompatibleGeographicSelection([
|
|
205
|
+
{
|
|
206
|
+
field: 'cca_geographic_countries.keyword',
|
|
207
|
+
values: ['Germany'],
|
|
208
|
+
type: 'any',
|
|
209
|
+
},
|
|
210
|
+
]),
|
|
211
|
+
).toBe(false);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('rejects Global, Europe, and transnational selections', () => {
|
|
215
|
+
expect(
|
|
216
|
+
hasMapIncompatibleGeographicSelection([
|
|
217
|
+
{
|
|
218
|
+
field: 'cca_navigator_geographic_scope',
|
|
219
|
+
values: ['Global', 'Europe'],
|
|
220
|
+
type: 'any',
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
field: 'cca_geographic_transnational_region.keyword',
|
|
224
|
+
values: ['Alpine Space'],
|
|
225
|
+
type: 'any',
|
|
226
|
+
},
|
|
227
|
+
]),
|
|
228
|
+
).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
describe('clearMapIncompatibleGeographicFilters', () => {
|
|
233
|
+
it('clears only map-incompatible geographic filters', () => {
|
|
234
|
+
const searchContext = {
|
|
235
|
+
filters: [
|
|
236
|
+
{
|
|
237
|
+
field: 'cca_navigator_geographic_scope',
|
|
238
|
+
values: ['Europe'],
|
|
239
|
+
type: 'any',
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
field: 'cca_geographic_transnational_region.keyword',
|
|
243
|
+
values: ['Alpine Space'],
|
|
244
|
+
type: 'any',
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
field: 'cca_geographic_countries.keyword',
|
|
248
|
+
values: ['Germany'],
|
|
249
|
+
type: 'any',
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
field: 'cca_climate_impacts.keyword',
|
|
253
|
+
values: ['Flooding'],
|
|
254
|
+
type: 'any',
|
|
255
|
+
},
|
|
256
|
+
],
|
|
257
|
+
removeFilter: jest.fn(),
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
clearMapIncompatibleGeographicFilters(searchContext);
|
|
261
|
+
|
|
262
|
+
expect(searchContext.removeFilter).toHaveBeenCalledTimes(2);
|
|
263
|
+
expect(searchContext.removeFilter).toHaveBeenCalledWith(
|
|
264
|
+
'cca_navigator_geographic_scope',
|
|
265
|
+
null,
|
|
266
|
+
'any',
|
|
267
|
+
);
|
|
268
|
+
expect(searchContext.removeFilter).toHaveBeenCalledWith(
|
|
269
|
+
'cca_geographic_transnational_region.keyword',
|
|
270
|
+
null,
|
|
271
|
+
'any',
|
|
272
|
+
);
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
|
|
188
276
|
describe('mapLegendItems', () => {
|
|
189
277
|
it('has 5 legend items', () => {
|
|
190
278
|
expect(mapLegendItems).toHaveLength(5);
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { Button, Card, Icon } from 'semantic-ui-react';
|
|
3
3
|
import { defineMessages, useIntl } from 'react-intl';
|
|
4
4
|
import { Term } from '@eeacms/search/components';
|
|
5
|
-
import { useSearchContext } from '@eeacms/search/lib/hocs';
|
|
5
|
+
import { useSearchContext, useViews } from '@eeacms/search/lib/hocs';
|
|
6
6
|
import { markSelectedFacetValuesFromFilters } from '@eeacms/search/lib/search/helpers';
|
|
7
7
|
import {
|
|
8
8
|
CHARACTERISATION_FIELD,
|
|
@@ -70,6 +70,7 @@ const FacetOption = ({ field, option, onChange }) => {
|
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
const ExpandableFacetGroup = ({
|
|
73
|
+
defaultOpen = false,
|
|
73
74
|
field,
|
|
74
75
|
id,
|
|
75
76
|
label,
|
|
@@ -78,11 +79,11 @@ const ExpandableFacetGroup = ({
|
|
|
78
79
|
onChange,
|
|
79
80
|
}) => {
|
|
80
81
|
const hasSelection = options.some(({ selected }) => selected);
|
|
81
|
-
const [isOpen, setIsOpen] = React.useState(hasSelection);
|
|
82
|
+
const [isOpen, setIsOpen] = React.useState(hasSelection || defaultOpen);
|
|
82
83
|
|
|
83
84
|
React.useEffect(() => {
|
|
84
|
-
if (hasSelection) setIsOpen(true);
|
|
85
|
-
}, [hasSelection]);
|
|
85
|
+
if (hasSelection || defaultOpen) setIsOpen(true);
|
|
86
|
+
}, [defaultOpen, hasSelection]);
|
|
86
87
|
|
|
87
88
|
return (
|
|
88
89
|
<div className="navigator-geographic-facet-group">
|
|
@@ -119,16 +120,10 @@ const ExpandableFacetGroup = ({
|
|
|
119
120
|
);
|
|
120
121
|
};
|
|
121
122
|
|
|
122
|
-
const NavigatorActiveFilters = ({ filters, onRemove }) => {
|
|
123
|
+
const NavigatorActiveFilters = ({ fields, filters, onRemove }) => {
|
|
123
124
|
const intl = useIntl();
|
|
124
|
-
const geographicFields = [
|
|
125
|
-
CHARACTERISATION_FIELD,
|
|
126
|
-
TRANSNATIONAL_REGION_FIELD,
|
|
127
|
-
COUNTRIES_FIELD,
|
|
128
|
-
];
|
|
129
125
|
const activeFilters = filters.filter(
|
|
130
|
-
({ field, values }) =>
|
|
131
|
-
geographicFields.includes(field) && values?.length > 0,
|
|
126
|
+
({ field, values }) => fields.includes(field) && values?.length > 0,
|
|
132
127
|
);
|
|
133
128
|
|
|
134
129
|
if (!activeFilters.length) return null;
|
|
@@ -190,6 +185,8 @@ const NavigatorGeographicCoverageFacet = ({
|
|
|
190
185
|
}) => {
|
|
191
186
|
const intl = useIntl();
|
|
192
187
|
const { addFilter, facets, filters = [], removeFilter } = useSearchContext();
|
|
188
|
+
const { activeViewId } = useViews();
|
|
189
|
+
const isMapView = activeViewId === 'map';
|
|
193
190
|
const transnationalOptions = getFacetOptions(
|
|
194
191
|
facets,
|
|
195
192
|
filters,
|
|
@@ -219,6 +216,7 @@ const NavigatorGeographicCoverageFacet = ({
|
|
|
219
216
|
}
|
|
220
217
|
|
|
221
218
|
clearFilter(CHARACTERISATION_FIELD);
|
|
219
|
+
if (isMapView) clearFilter(TRANSNATIONAL_REGION_FIELD);
|
|
222
220
|
addFilter(field, option.value, 'any');
|
|
223
221
|
};
|
|
224
222
|
|
|
@@ -226,25 +224,28 @@ const NavigatorGeographicCoverageFacet = ({
|
|
|
226
224
|
<fieldset
|
|
227
225
|
className={`sui-facet searchlib-multiterm-facet navigator-geographic-facet ${className}`}
|
|
228
226
|
>
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
227
|
+
{!isMapView && (
|
|
228
|
+
<div className="sui-multi-checkbox-facet navigator-geographic-facet-direct-options">
|
|
229
|
+
{options.map((option) => {
|
|
230
|
+
const directOption = {
|
|
231
|
+
...option,
|
|
232
|
+
selected:
|
|
233
|
+
option.selected || selectedDirectValues.includes(option.value),
|
|
234
|
+
};
|
|
236
235
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
236
|
+
return (
|
|
237
|
+
<FacetOption
|
|
238
|
+
key={valueAsText(option.value)}
|
|
239
|
+
field={CHARACTERISATION_FIELD}
|
|
240
|
+
option={directOption}
|
|
241
|
+
onChange={updateDirectFilter}
|
|
242
|
+
/>
|
|
243
|
+
);
|
|
244
|
+
})}
|
|
245
|
+
</div>
|
|
246
|
+
)}
|
|
247
247
|
<ExpandableFacetGroup
|
|
248
|
+
defaultOpen={isMapView}
|
|
248
249
|
field={COUNTRIES_FIELD}
|
|
249
250
|
id="navigator-geographic-countries"
|
|
250
251
|
label={intl.formatMessage(countriesLabel)}
|
|
@@ -252,17 +253,24 @@ const NavigatorGeographicCoverageFacet = ({
|
|
|
252
253
|
options={countryOptions}
|
|
253
254
|
onChange={(option) => updateChildFilter(COUNTRIES_FIELD, option)}
|
|
254
255
|
/>
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
256
|
+
{!isMapView && (
|
|
257
|
+
<ExpandableFacetGroup
|
|
258
|
+
field={TRANSNATIONAL_REGION_FIELD}
|
|
259
|
+
id="navigator-geographic-transnational-regions"
|
|
260
|
+
label={intl.formatMessage(transnationalRegionsLabel)}
|
|
261
|
+
emptyMessage={intl.formatMessage(messages.noOptionsAvailable)}
|
|
262
|
+
options={transnationalOptions}
|
|
263
|
+
onChange={(option) =>
|
|
264
|
+
updateChildFilter(TRANSNATIONAL_REGION_FIELD, option)
|
|
265
|
+
}
|
|
266
|
+
/>
|
|
267
|
+
)}
|
|
265
268
|
<NavigatorActiveFilters
|
|
269
|
+
fields={[
|
|
270
|
+
CHARACTERISATION_FIELD,
|
|
271
|
+
TRANSNATIONAL_REGION_FIELD,
|
|
272
|
+
COUNTRIES_FIELD,
|
|
273
|
+
]}
|
|
266
274
|
filters={filters}
|
|
267
275
|
onRemove={(field, value, type) => removeFilter(field, value, type)}
|
|
268
276
|
/>
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import '@testing-library/jest-dom';
|
|
3
3
|
import { fireEvent, render, screen } from '@testing-library/react';
|
|
4
4
|
import { IntlProvider } from 'react-intl';
|
|
5
|
-
import { useSearchContext } from '@eeacms/search/lib/hocs';
|
|
5
|
+
import { useSearchContext, useViews } from '@eeacms/search/lib/hocs';
|
|
6
6
|
import NavigatorGeographicCoverageFacet from './NavigatorGeographicCoverageFacet';
|
|
7
7
|
import {
|
|
8
8
|
CHARACTERISATION_FIELD,
|
|
@@ -15,9 +15,11 @@ jest.mock('@eeacms/search/components', () => ({
|
|
|
15
15
|
}));
|
|
16
16
|
jest.mock('@eeacms/search/lib/hocs', () => ({
|
|
17
17
|
useSearchContext: jest.fn(),
|
|
18
|
+
useViews: jest.fn(),
|
|
18
19
|
}));
|
|
19
20
|
|
|
20
21
|
const renderFacet = ({
|
|
22
|
+
activeViewId = 'listing',
|
|
21
23
|
detailedOptions = true,
|
|
22
24
|
filters = [],
|
|
23
25
|
onRemove = jest.fn(),
|
|
@@ -26,6 +28,8 @@ const renderFacet = ({
|
|
|
26
28
|
const addFilter = jest.fn();
|
|
27
29
|
const removeFilter = jest.fn();
|
|
28
30
|
|
|
31
|
+
useViews.mockReturnValue({ activeViewId });
|
|
32
|
+
|
|
29
33
|
useSearchContext.mockReturnValue({
|
|
30
34
|
addFilter,
|
|
31
35
|
removeFilter,
|
|
@@ -190,4 +194,64 @@ describe('NavigatorGeographicCoverageFacet', () => {
|
|
|
190
194
|
screen.getByRole('button', { name: 'Transnational regions' }),
|
|
191
195
|
).toBeEnabled();
|
|
192
196
|
});
|
|
197
|
+
|
|
198
|
+
it('shows only countries in the map view', () => {
|
|
199
|
+
renderFacet({ activeViewId: 'map' });
|
|
200
|
+
|
|
201
|
+
expect(screen.queryByLabelText('Europe')).not.toBeInTheDocument();
|
|
202
|
+
expect(screen.queryByLabelText('Global')).not.toBeInTheDocument();
|
|
203
|
+
expect(screen.getByRole('button', { name: 'Countries' })).toHaveAttribute(
|
|
204
|
+
'aria-expanded',
|
|
205
|
+
'true',
|
|
206
|
+
);
|
|
207
|
+
expect(screen.getByLabelText('Germany')).toBeVisible();
|
|
208
|
+
expect(
|
|
209
|
+
screen.queryByRole('button', { name: 'Transnational regions' }),
|
|
210
|
+
).not.toBeInTheDocument();
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('clears hidden geographic filters when selecting a country on the map', () => {
|
|
214
|
+
const { addFilter, removeFilter } = renderFacet({
|
|
215
|
+
activeViewId: 'map',
|
|
216
|
+
filters: [
|
|
217
|
+
{
|
|
218
|
+
field: TRANSNATIONAL_REGION_FIELD,
|
|
219
|
+
values: ['Alpine Space'],
|
|
220
|
+
type: 'any',
|
|
221
|
+
},
|
|
222
|
+
],
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
fireEvent.click(screen.getByLabelText('Germany'));
|
|
226
|
+
|
|
227
|
+
expect(removeFilter).toHaveBeenCalledWith(
|
|
228
|
+
CHARACTERISATION_FIELD,
|
|
229
|
+
null,
|
|
230
|
+
'any',
|
|
231
|
+
);
|
|
232
|
+
expect(removeFilter).toHaveBeenCalledWith(
|
|
233
|
+
TRANSNATIONAL_REGION_FIELD,
|
|
234
|
+
null,
|
|
235
|
+
'any',
|
|
236
|
+
);
|
|
237
|
+
expect(addFilter).toHaveBeenCalledWith(COUNTRIES_FIELD, 'Germany', 'any');
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it('shows hidden active geographic filters in the map view', () => {
|
|
241
|
+
renderFacet({
|
|
242
|
+
activeViewId: 'map',
|
|
243
|
+
detailedOptions: false,
|
|
244
|
+
filters: [
|
|
245
|
+
{
|
|
246
|
+
field: CHARACTERISATION_FIELD,
|
|
247
|
+
values: ['Europe'],
|
|
248
|
+
type: 'any',
|
|
249
|
+
},
|
|
250
|
+
],
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
expect(screen.queryByLabelText('Europe')).not.toBeInTheDocument();
|
|
254
|
+
expect(screen.getByText('Active filters:')).toBeInTheDocument();
|
|
255
|
+
expect(screen.getByText('Europe')).toBeInTheDocument();
|
|
256
|
+
});
|
|
193
257
|
});
|
|
@@ -61,6 +61,30 @@ export const filterCountryCounts = (countryCounts, filters) => {
|
|
|
61
61
|
);
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
+
const mapIncompatibleGeographicFields = new Set([
|
|
65
|
+
'cca_navigator_geographic_scope',
|
|
66
|
+
'cca_geographic_transnational_region.keyword',
|
|
67
|
+
]);
|
|
68
|
+
|
|
69
|
+
export const hasMapIncompatibleGeographicSelection = (filters) =>
|
|
70
|
+
Boolean(
|
|
71
|
+
filters?.find(
|
|
72
|
+
({ field, values }) =>
|
|
73
|
+
mapIncompatibleGeographicFields.has(field) && values?.length > 0,
|
|
74
|
+
),
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
export const clearMapIncompatibleGeographicFilters = (searchContext) => {
|
|
78
|
+
searchContext?.filters
|
|
79
|
+
?.filter(
|
|
80
|
+
({ field, values }) =>
|
|
81
|
+
mapIncompatibleGeographicFields.has(field) && values?.length > 0,
|
|
82
|
+
)
|
|
83
|
+
.forEach(({ field, type = 'any' }) =>
|
|
84
|
+
searchContext.removeFilter(field, null, type),
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
|
|
64
88
|
export const setCountryFilter = (searchContext, countryName) => {
|
|
65
89
|
searchContext?.setFilter(
|
|
66
90
|
'cca_geographic_countries.keyword',
|
|
@@ -268,3 +268,70 @@ describe('NavigatorGuideContentView climate hazards', () => {
|
|
|
268
268
|
).toHaveTextContent('Flooding');
|
|
269
269
|
});
|
|
270
270
|
});
|
|
271
|
+
|
|
272
|
+
describe('NavigatorGuideContentView actions', () => {
|
|
273
|
+
beforeEach(() => {
|
|
274
|
+
jest.clearAllMocks();
|
|
275
|
+
useSelector.mockReturnValue('en');
|
|
276
|
+
useSearchDriver.mockReturnValue(undefined);
|
|
277
|
+
useGuideFacetOptions.mockReturnValue({
|
|
278
|
+
'cca_adaptation_sectors.keyword': ['Water'],
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
it('removes a selected option from the current step', () => {
|
|
283
|
+
const removeFilter = jest.fn();
|
|
284
|
+
useAtom.mockReturnValue([0, jest.fn()]);
|
|
285
|
+
useHistory.mockReturnValue({ push: jest.fn() });
|
|
286
|
+
|
|
287
|
+
renderGuide(
|
|
288
|
+
{ title: 'Guide tool', href: '/tools/guide-tool' },
|
|
289
|
+
{
|
|
290
|
+
removeFilter,
|
|
291
|
+
facets: {
|
|
292
|
+
'cca_adaptation_sectors.keyword': [
|
|
293
|
+
{ data: [{ value: 'Water', count: 4 }] },
|
|
294
|
+
],
|
|
295
|
+
},
|
|
296
|
+
},
|
|
297
|
+
);
|
|
298
|
+
|
|
299
|
+
fireEvent.click(screen.getByText('Water'));
|
|
300
|
+
|
|
301
|
+
expect(removeFilter).toHaveBeenCalledWith(
|
|
302
|
+
'cca_adaptation_sectors.keyword',
|
|
303
|
+
'Water',
|
|
304
|
+
'all',
|
|
305
|
+
);
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
it('opens catalogue results with only supported Guide filters', () => {
|
|
309
|
+
const history = { push: jest.fn() };
|
|
310
|
+
useAtom.mockReturnValue([0, jest.fn()]);
|
|
311
|
+
useHistory.mockReturnValue(history);
|
|
312
|
+
|
|
313
|
+
renderGuide(
|
|
314
|
+
{ title: 'Guide tool', href: '/tools/guide-tool' },
|
|
315
|
+
{
|
|
316
|
+
filters: [
|
|
317
|
+
{
|
|
318
|
+
field: 'cca_adaptation_sectors.keyword',
|
|
319
|
+
values: ['Water'],
|
|
320
|
+
type: 'all',
|
|
321
|
+
},
|
|
322
|
+
{ field: 'unrelated.keyword', values: ['Ignored'], type: 'any' },
|
|
323
|
+
],
|
|
324
|
+
},
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
fireEvent.click(screen.getByRole('button', { name: 'Skip to results' }));
|
|
328
|
+
|
|
329
|
+
expect(history.push).toHaveBeenCalledWith(
|
|
330
|
+
expect.objectContaining({
|
|
331
|
+
pathname: '/en/navigator/tool-catalogue',
|
|
332
|
+
search: expect.any(String),
|
|
333
|
+
}),
|
|
334
|
+
);
|
|
335
|
+
expect(history.push.mock.calls[0][0].search).not.toContain('unrelated');
|
|
336
|
+
});
|
|
337
|
+
});
|
|
@@ -12,6 +12,7 @@ import { useAtom } from 'jotai';
|
|
|
12
12
|
import { useDispatch, useSelector } from 'react-redux';
|
|
13
13
|
import { useHistory, useLocation } from 'react-router-dom';
|
|
14
14
|
import CompareToolsView from './CompareToolsView';
|
|
15
|
+
import { exportComparisonTable } from '../../Search/NavigatorCatalogue/utils';
|
|
15
16
|
import { fetchResultsByUid } from './utils';
|
|
16
17
|
|
|
17
18
|
jest.mock('jotai', () => ({
|
|
@@ -62,6 +63,11 @@ jest.mock('./utils', () => ({
|
|
|
62
63
|
getPathname: (url) => url?.split('?')[0] || '',
|
|
63
64
|
}));
|
|
64
65
|
|
|
66
|
+
jest.mock('../../Search/NavigatorCatalogue/utils', () => ({
|
|
67
|
+
...jest.requireActual('../../Search/NavigatorCatalogue/utils'),
|
|
68
|
+
exportComparisonTable: jest.fn(),
|
|
69
|
+
}));
|
|
70
|
+
|
|
65
71
|
describe('CompareToolsView', () => {
|
|
66
72
|
beforeEach(() => {
|
|
67
73
|
jest.clearAllMocks();
|
|
@@ -246,4 +252,57 @@ describe('CompareToolsView', () => {
|
|
|
246
252
|
expect(thumbnail.querySelector('img')).not.toBeInTheDocument();
|
|
247
253
|
expect(thumbnail.querySelector('.ri-file-line')).toBeInTheDocument();
|
|
248
254
|
});
|
|
255
|
+
|
|
256
|
+
it('removes a tool from the selection and URL', async () => {
|
|
257
|
+
const setSelectedTools = jest.fn();
|
|
258
|
+
const history = { push: jest.fn() };
|
|
259
|
+
useAtom.mockReturnValue([[], setSelectedTools]);
|
|
260
|
+
useHistory.mockReturnValue(history);
|
|
261
|
+
|
|
262
|
+
render(
|
|
263
|
+
<IntlProvider locale="en">
|
|
264
|
+
<CompareToolsView />
|
|
265
|
+
</IntlProvider>,
|
|
266
|
+
);
|
|
267
|
+
await screen.findByRole('table', { name: 'Compare tools' });
|
|
268
|
+
|
|
269
|
+
fireEvent.click(
|
|
270
|
+
screen.getByRole('button', {
|
|
271
|
+
name: 'Remove Tool one from comparison',
|
|
272
|
+
}),
|
|
273
|
+
);
|
|
274
|
+
|
|
275
|
+
const updateSelection = setSelectedTools.mock.calls[0][0];
|
|
276
|
+
expect(updateSelection([{ uid: 'one' }, { uid: 'two' }])).toEqual([
|
|
277
|
+
{ uid: 'two' },
|
|
278
|
+
]);
|
|
279
|
+
expect(history.push).toHaveBeenCalledWith({
|
|
280
|
+
pathname: '/en/navigator/compare',
|
|
281
|
+
search: '?uid=two',
|
|
282
|
+
hash: '',
|
|
283
|
+
state: {},
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
it('exports comparison data with only applicable table options', async () => {
|
|
288
|
+
render(
|
|
289
|
+
<IntlProvider locale="en">
|
|
290
|
+
<CompareToolsView />
|
|
291
|
+
</IntlProvider>,
|
|
292
|
+
);
|
|
293
|
+
await screen.findByRole('table', { name: 'Compare tools' });
|
|
294
|
+
|
|
295
|
+
fireEvent.click(screen.getByRole('button', { name: 'Export table' }));
|
|
296
|
+
|
|
297
|
+
expect(exportComparisonTable).toHaveBeenCalledTimes(1);
|
|
298
|
+
const [exportedTools] = exportComparisonTable.mock.calls[0];
|
|
299
|
+
expect(exportedTools[0].comparisonOptions).toEqual(
|
|
300
|
+
expect.objectContaining({
|
|
301
|
+
cca_type_of_outputs: ['Maps and graphs'],
|
|
302
|
+
cca_adaptation_support_cycle_step: [
|
|
303
|
+
'Step 2: Assessing Climate Change Risks and Vulnerabilities',
|
|
304
|
+
],
|
|
305
|
+
}),
|
|
306
|
+
);
|
|
307
|
+
});
|
|
249
308
|
});
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Footer component.
|
|
3
|
+
* @module components/theme/Footer/Footer
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { useIntl } from 'react-intl';
|
|
8
|
+
import { useSelector, shallowEqual } from 'react-redux';
|
|
9
|
+
import { flattenToAppURL } from '@plone/volto/helpers/Url/Url';
|
|
10
|
+
import EEAFooter from '@eeacms/volto-eea-design-system/ui/Footer/Footer';
|
|
11
|
+
import config from '@plone/volto/registry';
|
|
12
|
+
import isArray from 'lodash/isArray';
|
|
13
|
+
import messages from '@eeacms/volto-cca-policy/messages';
|
|
14
|
+
|
|
15
|
+
const footerMessages = [
|
|
16
|
+
messages.sitemap,
|
|
17
|
+
messages.managedBy,
|
|
18
|
+
messages.exploreEnvironmentalInformationSystems,
|
|
19
|
+
messages.about,
|
|
20
|
+
messages.aboutUs,
|
|
21
|
+
messages.contact,
|
|
22
|
+
messages.contactUs,
|
|
23
|
+
messages.help,
|
|
24
|
+
messages.privacy,
|
|
25
|
+
messages.privacyStatement,
|
|
26
|
+
messages.accessibility,
|
|
27
|
+
messages.legalNotice,
|
|
28
|
+
messages.dashboard,
|
|
29
|
+
messages.login,
|
|
30
|
+
messages.cmsLogin,
|
|
31
|
+
].reduce((result, message) => ({ ...result, [message.id]: message }), {});
|
|
32
|
+
|
|
33
|
+
const Footer = () => {
|
|
34
|
+
const intl = useIntl();
|
|
35
|
+
const { eea } = config.settings;
|
|
36
|
+
const {
|
|
37
|
+
footerActions,
|
|
38
|
+
copyrightActions,
|
|
39
|
+
socialActions,
|
|
40
|
+
contactActions,
|
|
41
|
+
contactExtraActions,
|
|
42
|
+
} = useSelector(
|
|
43
|
+
(state) => ({
|
|
44
|
+
footerActions: state.actions?.actions?.footer_actions,
|
|
45
|
+
copyrightActions: state.actions?.actions?.copyright_actions,
|
|
46
|
+
socialActions: state.actions?.actions?.social_actions,
|
|
47
|
+
contactActions: state.actions?.actions?.contact_actions,
|
|
48
|
+
contactExtraActions: state.actions?.actions?.contact_extra_actions,
|
|
49
|
+
}),
|
|
50
|
+
shallowEqual,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const translate = (text) =>
|
|
54
|
+
footerMessages[text] ? intl.formatMessage(footerMessages[text]) : text;
|
|
55
|
+
|
|
56
|
+
// ZMI > portal_actions > footer_actions
|
|
57
|
+
const actions = isArray(footerActions)
|
|
58
|
+
? footerActions.map((action) => ({
|
|
59
|
+
title: translate(action.title),
|
|
60
|
+
url: flattenToAppURL(action.url),
|
|
61
|
+
}))
|
|
62
|
+
: eea.footerOpts.actions?.map((action) => ({
|
|
63
|
+
...action,
|
|
64
|
+
title: translate(action.title),
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
// ZMI > portal_actions > copyright_actions
|
|
68
|
+
const copyright = isArray(copyrightActions)
|
|
69
|
+
? copyrightActions.map((action) => ({
|
|
70
|
+
title: translate(action.title),
|
|
71
|
+
site: translate(action.title),
|
|
72
|
+
url: flattenToAppURL(action.url),
|
|
73
|
+
}))
|
|
74
|
+
: eea.footerOpts.copyright?.map((action) => ({
|
|
75
|
+
...action,
|
|
76
|
+
title: translate(action.title),
|
|
77
|
+
site: translate(action.site),
|
|
78
|
+
}));
|
|
79
|
+
|
|
80
|
+
// ZMI > portal_actions > social_actions
|
|
81
|
+
const social = isArray(socialActions)
|
|
82
|
+
? socialActions.map((action) => ({
|
|
83
|
+
name: action.id,
|
|
84
|
+
icon: action.icon,
|
|
85
|
+
url: action.url,
|
|
86
|
+
}))
|
|
87
|
+
: eea.footerOpts.social;
|
|
88
|
+
|
|
89
|
+
// ZMI > portal_actions > contact_actions
|
|
90
|
+
const contacts = isArray(contactActions)
|
|
91
|
+
? contactActions.map((action, idx) => ({
|
|
92
|
+
text: translate(action.title),
|
|
93
|
+
icon: action.icon,
|
|
94
|
+
url: flattenToAppURL(action.url),
|
|
95
|
+
children:
|
|
96
|
+
idx === 0
|
|
97
|
+
? (contactExtraActions || []).map((child) => ({
|
|
98
|
+
text: translate(child.title),
|
|
99
|
+
icon: child.icon,
|
|
100
|
+
url: flattenToAppURL(child.url),
|
|
101
|
+
}))
|
|
102
|
+
: [],
|
|
103
|
+
}))
|
|
104
|
+
: eea.footerOpts.contacts?.map((contact) => ({
|
|
105
|
+
...contact,
|
|
106
|
+
text: translate(contact.text),
|
|
107
|
+
children: contact.children?.map((child) => ({
|
|
108
|
+
...child,
|
|
109
|
+
text: translate(child.text),
|
|
110
|
+
})),
|
|
111
|
+
}));
|
|
112
|
+
|
|
113
|
+
// Update options with actions from backend
|
|
114
|
+
const options = {
|
|
115
|
+
...eea.footerOpts,
|
|
116
|
+
social,
|
|
117
|
+
contacts,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<EEAFooter>
|
|
122
|
+
<EEAFooter.Header>
|
|
123
|
+
{translate(eea.footerOpts.logosHeader)}
|
|
124
|
+
</EEAFooter.Header>
|
|
125
|
+
<EEAFooter.SubFooter {...options} />
|
|
126
|
+
<EEAFooter.Header>{translate(eea.footerOpts.header)}</EEAFooter.Header>
|
|
127
|
+
<EEAFooter.SitesButton
|
|
128
|
+
buttonName={translate(eea.footerOpts.buttonName)}
|
|
129
|
+
hrefButton={eea.footerOpts.hrefButton}
|
|
130
|
+
/>
|
|
131
|
+
<EEAFooter.Social {...options} />
|
|
132
|
+
<EEAFooter.Actions actions={actions} copyright={copyright} />
|
|
133
|
+
</EEAFooter>
|
|
134
|
+
);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
export default Footer;
|
|
@@ -25,7 +25,7 @@ import { injectIntl } from 'react-intl';
|
|
|
25
25
|
import Error from '@plone/volto/error';
|
|
26
26
|
|
|
27
27
|
import Breadcrumbs from '@plone/volto/components/theme/Breadcrumbs/Breadcrumbs';
|
|
28
|
-
import Footer from '@
|
|
28
|
+
import Footer from '@eeacms/volto-cca-policy/components/theme/Footer/Footer';
|
|
29
29
|
import Header from '@plone/volto/components/theme/Header/Header';
|
|
30
30
|
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
31
31
|
import OutdatedBrowser from '@plone/volto/components/theme/OutdatedBrowser/OutdatedBrowser';
|