@eeacms/volto-bise-policy 1.2.45 → 1.2.47

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 (48) hide show
  1. package/.eslintrc.js +7 -7
  2. package/CHANGELOG.md +38 -1
  3. package/jest-addon.config.js +34 -13
  4. package/package.json +3 -2
  5. package/src/components/Widgets/EUNISObjectListWidget.jsx +8 -7
  6. package/src/components/Widgets/GeolocationWidget.jsx +1 -1
  7. package/src/components/Widgets/NRRWidgets.jsx +1 -1
  8. package/src/components/manage/Blocks/BodyClass/View.jsx +1 -1
  9. package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyExplorerView.jsx +1 -1
  10. package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyExplorerView.test.jsx +1 -1
  11. package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyFilters.jsx +50 -64
  12. package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyFilters.test.jsx +15 -36
  13. package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyListing.test.jsx +13 -37
  14. package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.jsx +1 -1
  15. package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.test.jsx +3 -51
  16. package/src/components/manage/Blocks/CaseStudyExplorer/FeatureDisplay.test.jsx +1 -1
  17. package/src/components/manage/Blocks/CaseStudyExplorer/FeatureInteraction.test.jsx +4 -14
  18. package/src/components/manage/Blocks/CaseStudyExplorer/InfoOverlay.test.jsx +12 -27
  19. package/src/components/manage/Blocks/CaseStudyExplorer/testUtils.js +84 -0
  20. package/src/components/manage/Blocks/CaseStudyExplorer/utils.test.js +1 -1
  21. package/src/components/manage/Blocks/CustomCSS/CustomCSSEdit.jsx +1 -1
  22. package/src/components/manage/Blocks/CustomJS/CustomJSEdit.jsx +1 -1
  23. package/src/components/manage/Blocks/FactsheetsListing/FactsheetsListingEdit.jsx +1 -1
  24. package/src/components/manage/Blocks/FactsheetsListing/FactsheetsListingView.jsx +2 -2
  25. package/src/components/manage/Blocks/KeyFacts/KeyFactsEdit.jsx +1 -1
  26. package/src/components/manage/Blocks/MaesViewer/MaesViewerEdit.jsx +1 -1
  27. package/src/components/manage/Blocks/MaesViewer/MaesViewerView.jsx +3 -4
  28. package/src/components/manage/Blocks/MaesViewer/utils.js +12 -9
  29. package/src/components/manage/Blocks/Navigation/Edit.jsx +1 -1
  30. package/src/components/manage/Blocks/Navigation/View.jsx +2 -2
  31. package/src/components/manage/Blocks/schema.js +1 -1
  32. package/src/customizations/@eeacms/volto-datablocks/components/manage/Blocks/SimpleDataTable/Edit.jsx +1 -1
  33. package/src/customizations/@eeacms/volto-datablocks/components/manage/Blocks/SimpleDataTable/View.jsx +6 -6
  34. package/src/customizations/@eeacms/volto-datablocks/components/manage/Blocks/SimpleDataTable/templates/colored/View.jsx +1 -1
  35. package/src/customizations/@eeacms/volto-datablocks/components/manage/Blocks/SimpleDataTable/templates/smart/View.jsx +5 -4
  36. package/src/customizations/@eeacms/volto-eea-design-system/ui/Header/HeaderMenuPopUp.js +3 -1
  37. package/src/customizations/@eeacms/volto-eea-website-theme/components/theme/SubsiteClass.jsx +2 -1
  38. package/src/customizations/volto/components/theme/Header/Header.jsx +7 -11
  39. package/src/customizations/volto/components/theme/View/View.jsx +10 -14
  40. package/src/customizations/volto/reducers/breadcrumbs/breadcrumbs.js +3 -6
  41. package/src/customizations/volto/reducers/navigation/navigation.js +3 -6
  42. package/src/customizations/volto/reducers/types/types.js +2 -5
  43. package/src/express-middleware.js +1 -1
  44. package/src/helpers.js +1 -1
  45. package/src/index.js +11 -6
  46. package/src/{styles-config.js → styles-config.jsx} +49 -60
  47. package/theme/globals/site.overrides +4 -0
  48. /package/src/components/manage/Blocks/MaesViewer/{schema.js → schema.jsx} +0 -0
package/.eslintrc.js CHANGED
@@ -16,16 +16,16 @@ if (configFile) {
16
16
  voltoPath = `./${jsConfig.baseUrl}/${pathsConfig['@plone/volto'][0]}`;
17
17
  }
18
18
 
19
- const AddonConfigurationRegistry = require(`${voltoPath}/addon-registry.js`);
20
- const reg = new AddonConfigurationRegistry(projectRootPath);
19
+ const { AddonRegistry } = require('@plone/registry/addon-registry');
20
+ const { registry } = AddonRegistry.init(projectRootPath);
21
21
 
22
22
  // Extends ESlint configuration for adding the aliases to `src` directories in Volto addons
23
- const addonAliases = Object.keys(reg.packages).map((o) => [
23
+ const addonAliases = Object.keys(registry.packages).map((o) => [
24
24
  o,
25
- reg.packages[o].modulePath,
25
+ registry.packages[o].modulePath,
26
26
  ]);
27
27
 
28
- const addonExtenders = reg.getEslintExtenders().map((m) => require(m));
28
+ const addonExtenders = registry.getEslintExtenders().map((m) => require(m));
29
29
 
30
30
  const defaultConfig = {
31
31
  extends: `${voltoPath}/.eslintrc`,
@@ -34,7 +34,7 @@ const defaultConfig = {
34
34
  alias: {
35
35
  map: [
36
36
  ['@plone/volto', '@plone/volto/src'],
37
- ['@plone/volto-slate', '@plone/volto/packages/volto-slate/src'],
37
+ ['@plone/volto-slate', '@plone/volto-slate/src'],
38
38
  ...addonAliases,
39
39
  ['@package', `${__dirname}/src`],
40
40
  ['@root', `${__dirname}/src`],
@@ -54,7 +54,7 @@ const defaultConfig = {
54
54
  allowReferrer: true,
55
55
  },
56
56
  ],
57
- }
57
+ },
58
58
  };
59
59
 
60
60
  const config = addonExtenders.reduce(
package/CHANGELOG.md CHANGED
@@ -4,7 +4,44 @@ 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.2.45](https://github.com/eea/volto-bise-policy/compare/1.2.44...1.2.45) - 4 May 2026
7
+ ### [1.2.47](https://github.com/eea/volto-bise-policy/compare/1.3.0-beta.1...1.2.47) - 17 June 2026
8
+
9
+ #### :rocket: Dependency updates
10
+
11
+ - Release @eeacms/volto-openlayers-map@2.0.1 [EEA Jenkins - [`89854c4`](https://github.com/eea/volto-bise-policy/commit/89854c42c4d04ecb53876eac41c52a53ec8547ad)]
12
+
13
+ #### :hammer_and_wrench: Others
14
+
15
+ - update jenkinsfile [nileshgulia1 - [`84315d2`](https://github.com/eea/volto-bise-policy/commit/84315d29e36427a50fcc1a939c9e650b69bd81f2)]
16
+ - fix sonarqube [nileshgulia1 - [`2da4f19`](https://github.com/eea/volto-bise-policy/commit/2da4f1921027093a95d9011ef3ff8d2977fc0dcc)]
17
+ - fix duplicated code [nileshgulia1 - [`91cdb7a`](https://github.com/eea/volto-bise-policy/commit/91cdb7ad2221506a15ed988e28c7e918b07bcbbf)]
18
+ - fix slashmenu styles on content box [nileshgulia1 - [`13765ad`](https://github.com/eea/volto-bise-policy/commit/13765ad26acc9af1f1066b164b4c58393b902c01)]
19
+ ### [1.3.0-beta.1](https://github.com/eea/volto-bise-policy/compare/1.2.46...1.3.0-beta.1) - 27 May 2026
20
+
21
+ #### :bug: Bug Fixes
22
+
23
+ - fix: pathname undefined in Aapp.jsx [nileshgulia1 - [`0d1285c`](https://github.com/eea/volto-bise-policy/commit/0d1285c898d4c7a280b0dc611b76efa9e7d41b3b)]
24
+ - fix(CaseStudyExplorer): reduce code duplication [nileshgulia1 - [`95e3682`](https://github.com/eea/volto-bise-policy/commit/95e3682eeaeb4e37bc5849e927c20e374e6944d7)]
25
+ - fix(CaseStudyExplorer): reduce code duplication [nileshgulia1 - [`a9b307c`](https://github.com/eea/volto-bise-policy/commit/a9b307caaa7ecd93ae18fc5478642c2a74d571ed)]
26
+
27
+ #### :house: Internal changes
28
+
29
+ - style: Automated code fix [eea-jenkins - [`c116337`](https://github.com/eea/volto-bise-policy/commit/c1163379eaf659ae075eb9e552555498c38dfa88)]
30
+ - style: Automated code fix [eea-jenkins - [`120388e`](https://github.com/eea/volto-bise-policy/commit/120388e0eae779dac0af2d416819be787158082c)]
31
+ - style: Automated code fix [eea-jenkins - [`32bdad2`](https://github.com/eea/volto-bise-policy/commit/32bdad20d0e5eeced3d7026c6e2e2b5c7d7ebf22)]
32
+
33
+ #### :hammer_and_wrench: Others
34
+
35
+ - remove App.js customization [nileshgulia1 - [`488d6e1`](https://github.com/eea/volto-bise-policy/commit/488d6e187a376224177dbabb5b662b33fe7877d1)]
36
+ - refactor code as per sonarQube [nileshgulia1 - [`5e96d28`](https://github.com/eea/volto-bise-policy/commit/5e96d288bf13fd6644e61e47c210ce73fbd00607)]
37
+ - bump querystring in package.json [nileshgulia1 - [`299b753`](https://github.com/eea/volto-bise-policy/commit/299b753d62a487cc162581a4252691e7a3c03f62)]
38
+ - fix useEffect [nileshgulia1 - [`40e0f1f`](https://github.com/eea/volto-bise-policy/commit/40e0f1f871945a08115301c4aea7a57197adfc34)]
39
+ - cosmetics [nileshgulia1 - [`202e2b2`](https://github.com/eea/volto-bise-policy/commit/202e2b29b07f1f6764f7732f2eb056bedfa14fff)]
40
+ - eslint . [nileshgulia1 - [`dc50e42`](https://github.com/eea/volto-bise-policy/commit/dc50e426426cf162b9ace7cd727ab9e656c5b88c)]
41
+ - upgrade to Volto 18 refs #302160 [nileshgulia1 - [`ef610e6`](https://github.com/eea/volto-bise-policy/commit/ef610e64f45288043a848bde7a335475fb6f6dd4)]
42
+ ### [1.2.46](https://github.com/eea/volto-bise-policy/compare/1.2.45...1.2.46) - 5 May 2026
43
+
44
+ ### [1.2.45](https://github.com/eea/volto-bise-policy/compare/1.2.44...1.2.45) - 5 May 2026
8
45
 
9
46
  #### :rocket: Dependency updates
10
47
 
@@ -1,4 +1,23 @@
1
- require('dotenv').config({ path: __dirname + '/.env' })
1
+ require('dotenv').config({ path: __dirname + '/.env' });
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ // Volto 18 exposes @plone/volto-slate as a top-level package.
7
+ const voltoSlatePath = fs.existsSync(
8
+ path.join(
9
+ __dirname,
10
+ '..',
11
+ '..',
12
+ '..',
13
+ 'node_modules',
14
+ '@plone',
15
+ 'volto-slate',
16
+ 'src',
17
+ ),
18
+ )
19
+ ? '<rootDir>/node_modules/@plone/volto-slate/src'
20
+ : '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src';
2
21
 
3
22
  module.exports = {
4
23
  testMatch: ['**/src/addons/**/?(*.)+(spec|test).[jt]s?(x)'],
@@ -8,25 +27,27 @@ module.exports = {
8
27
  ],
9
28
  moduleNameMapper: {
10
29
  '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
30
+ '@plone-collective/volto-authomatic/(.*)$':
31
+ '<rootDir>/node_modules/@plone-collective/volto-authomatic/src/$1',
11
32
  '@plone/volto/cypress': '<rootDir>/node_modules/@plone/volto/cypress',
12
33
  '@plone/volto/babel': '<rootDir>/node_modules/@plone/volto/babel',
13
34
  '@plone/volto/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
14
35
  '@package/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
15
36
  '@root/(.*)$': '<rootDir>/node_modules/@plone/volto/src/$1',
16
37
  '@plone/volto-quanta/(.*)$': '<rootDir>/src/addons/volto-quanta/src/$1',
17
- '@eeacms/search/(.*)$': '<rootDir>/src/addons/volto-searchlib/searchlib/$1',
18
- '@eeacms/search': '<rootDir>/src/addons/volto-searchlib/searchlib',
38
+ '@eeacms/search/(.*)$':
39
+ '<rootDir>/node_modules/@eeacms/volto-searchlib/searchlib/$1',
40
+ '@eeacms/search':
41
+ '<rootDir>/node_modules/@eeacms/volto-searchlib/searchlib',
19
42
  '@eeacms/(.*?)/(.*)$': '<rootDir>/node_modules/@eeacms/$1/src/$2',
20
- '@plone/volto-slate$':
21
- '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src',
22
- '@plone/volto-slate/(.*)$':
23
- '<rootDir>/node_modules/@plone/volto/packages/volto-slate/src/$1',
43
+ '@plone/volto-slate$': voltoSlatePath,
44
+ '@plone/volto-slate/(.*)$': `${voltoSlatePath}/$1`,
24
45
  '~/(.*)$': '<rootDir>/src/$1',
25
46
  'load-volto-addons':
26
47
  '<rootDir>/node_modules/@plone/volto/jest-addons-loader.js',
27
48
  },
28
49
  transformIgnorePatterns: [
29
- '/node_modules/(?!(@plone|@root|@package|@eeacms)/).*/',
50
+ '/node_modules/(?!(@plone|@root|@package|@eeacms|@plone-collective)/).*/',
30
51
  ],
31
52
  transform: {
32
53
  '^.+\\.js(x)?$': 'babel-jest',
@@ -37,10 +58,10 @@ module.exports = {
37
58
  },
38
59
  coverageThreshold: {
39
60
  global: {
40
- branches: 5,
41
- functions: 5,
42
- lines: 5,
43
- statements: 5,
61
+ branches: 0,
62
+ functions: 0,
63
+ lines: 0,
64
+ statements: 0,
44
65
  },
45
66
  },
46
67
  ...(process.env.JEST_USE_SETUP === 'ON' && {
@@ -48,4 +69,4 @@ module.exports = {
48
69
  '<rootDir>/node_modules/@eeacms/volto-bise-policy/jest.setup.js',
49
70
  ],
50
71
  }),
51
- }
72
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-bise-policy",
3
- "version": "1.2.45",
3
+ "version": "1.2.47",
4
4
  "description": "@eeacms/volto-bise-policy: Volto add-on",
5
5
  "main": "src/index.js",
6
6
  "author": "European Environment Agency: IDM2 A-Team",
@@ -30,11 +30,12 @@
30
30
  "@eeacms/volto-datablocks": "*",
31
31
  "@eeacms/volto-eea-design-system": "*",
32
32
  "@eeacms/volto-eea-website-theme": "*",
33
- "@eeacms/volto-openlayers-map": "2.0.0",
33
+ "@eeacms/volto-openlayers-map": "2.0.1",
34
34
  "@eeacms/volto-resize-helper": "*",
35
35
  "@plone-collective/volto-authomatic": "2.0.1",
36
36
  "esri-loader": "3.7.0",
37
37
  "plotly.js": "^2.28.0",
38
+ "querystring": "0.2.1",
38
39
  "react-plotly.js": "2.6.0"
39
40
  },
40
41
  "devDependencies": {
@@ -1,8 +1,11 @@
1
1
  import React from 'react';
2
2
  import { defineMessages, useIntl } from 'react-intl';
3
3
  import { Accordion, Button, Segment } from 'semantic-ui-react';
4
- import { DragDropList, FormFieldWrapper, Icon } from '@plone/volto/components';
5
- import { applySchemaDefaults, reorderArray } from '@plone/volto/helpers';
4
+ import DragDropList from '@plone/volto/components/manage/DragDropList/DragDropList';
5
+ import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
6
+ import Icon from '@plone/volto/components/theme/Icon/Icon';
7
+ import { reorderArray } from '@plone/volto/helpers/Utils/Utils';
8
+ import { applySchemaDefaults } from '@plone/volto/helpers/Blocks/Blocks';
6
9
  import ObjectWidget from '@plone/volto/components/manage/Widgets/ObjectWidget';
7
10
 
8
11
  import upSVG from '@plone/volto/icons/up-key.svg';
@@ -420,11 +423,9 @@ export const EUNISCountryCodeView = ({ value }) => {
420
423
 
421
424
  if (!items || items.length === 0) return null;
422
425
 
423
- return items.map((country) => (
424
- <div>
425
- <div key={country['@id']} className="country-item">
426
- {country.countryCode?.join(', ')}
427
- </div>
426
+ return items.map((country, index) => (
427
+ <div key={country['@id'] ?? index}>
428
+ <div className="country-item">{country.countryCode?.join(', ')}</div>
428
429
  <div className="eunis-widget-view">
429
430
  {country.national.map((item) => (
430
431
  <div key={item['@id']} className="eunis-widget-item">
@@ -4,7 +4,7 @@ import { Input, Label, Button } from 'semantic-ui-react';
4
4
  import config from '@plone/volto/registry';
5
5
 
6
6
  import { injectIntl } from 'react-intl';
7
- import { FormFieldWrapper } from '@plone/volto/components';
7
+ import FormFieldWrapper from '@plone/volto/components/manage/Widgets/FormFieldWrapper';
8
8
  import MapContainer from './GeolocationWidgetMapContainer';
9
9
 
10
10
  const defaultValue = {
@@ -1,4 +1,4 @@
1
- import { UniversalLink } from '@plone/volto/components';
1
+ import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
2
2
  import { Popup } from 'semantic-ui-react';
3
3
  export const NRRTypologyOfMeasuresView = ({ value }) => {
4
4
  let parsedValue = value;
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { BodyClass } from '@plone/volto/helpers';
2
+ import BodyClass from '@plone/volto/helpers/BodyClass/BodyClass';
3
3
 
4
4
  const View = (props) => {
5
5
  return (
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Grid } from 'semantic-ui-react'; // Dropdown,
3
- import { addAppURL } from '@plone/volto/helpers';
3
+ import { addAppURL } from '@plone/volto/helpers/Url/Url';
4
4
  // import config from '@plone/volto/registry';
5
5
  import CaseStudyMap from './CaseStudyMap';
6
6
  import { ActiveFilters, CaseStudyFilters, SearchBox } from './CaseStudyFilters';
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { render } from '@testing-library/react';
3
- import '@testing-library/jest-dom/extend-expect';
3
+ import '@testing-library/jest-dom';
4
4
  import { useCases } from './hooks';
5
5
  import CaseStudyExplorerView from './CaseStudyExplorerView';
6
6
 
@@ -72,7 +72,7 @@ export function CaseStudyFilter(props) {
72
72
  <label
73
73
  htmlFor={label + index}
74
74
  className="filter-input"
75
- key={index}
75
+ key={value}
76
76
  >
77
77
  <input
78
78
  value={value}
@@ -221,15 +221,42 @@ function SearchBoxComponent(props) {
221
221
  );
222
222
  }
223
223
 
224
+ function FilterGroup({
225
+ filterName,
226
+ filterLabel,
227
+ activeFilterCodes,
228
+ filters,
229
+ onRemoveFilter,
230
+ }) {
231
+ return activeFilterCodes.length > 0 ? (
232
+ <div className="filter-wrapper">
233
+ <div className="filter-label">{filterLabel}</div>
234
+ {activeFilterCodes.map((filterCode) => {
235
+ const label = filters[filterName][filterCode];
236
+ return (
237
+ <div className="ui basic label filter-value" key={filterCode}>
238
+ <span>{label}</span>
239
+ <i
240
+ tabIndex="0"
241
+ onKeyPress={() => {}}
242
+ onClick={() => {
243
+ onRemoveFilter(filterName, filterCode);
244
+ scrollToElement('search-input');
245
+ }}
246
+ role="button"
247
+ className="close icon"
248
+ ></i>
249
+ </div>
250
+ );
251
+ })}
252
+ </div>
253
+ ) : null;
254
+ }
255
+
224
256
  function ActiveFiltersComponent(props) {
225
257
  const { filters, activeFilters, setActiveFilters } = props;
226
258
  const hasActiveFilters = Object.entries(activeFilters).some(
227
- ([filterName, filterList]) => {
228
- if (filterList.length > 0) {
229
- return true;
230
- }
231
- return false;
232
- },
259
+ ([_, filterList]) => filterList.length > 0,
233
260
  );
234
261
 
235
262
  const clearFilters = () => {
@@ -245,10 +272,7 @@ function ActiveFiltersComponent(props) {
245
272
 
246
273
  const removeFilter = (filterName, filterCode) => {
247
274
  const temp = JSON.parse(JSON.stringify(activeFilters));
248
- temp[filterName] = temp[filterName].filter((value) => {
249
- if (value !== filterCode) return value;
250
- return null;
251
- });
275
+ temp[filterName] = temp[filterName].filter((value) => value !== filterCode);
252
276
 
253
277
  const filterInputs = document.querySelectorAll(
254
278
  '#cse-filter .filter-input input',
@@ -276,62 +300,24 @@ function ActiveFiltersComponent(props) {
276
300
  </div>
277
301
  <div className="filter-list-content">
278
302
  <div className="filter">
279
- {activeFilters.measures_implemented.length > 0 ? (
280
- <div className="filter-wrapper">
281
- <div className="filter-label">Measures implemented:</div>
282
- {activeFilters.measures_implemented.map((filterCode) => {
283
- const filterLabel = filters.measures_implemented[filterCode];
284
- return (
285
- <div className="ui basic label filter-value">
286
- <span>{filterLabel}</span>
287
- <i
288
- tabIndex="0"
289
- onKeyPress={() => {}}
290
- onClick={() => {
291
- removeFilter('measures_implemented', filterCode);
292
- scrollToElement('search-input');
293
- }}
294
- role="button"
295
- className="close icon"
296
- ></i>
297
- </div>
298
- );
299
- })}
300
- </div>
301
- ) : (
302
- ''
303
- )}
304
- {activeFilters.typology_of_measures.length > 0 ? (
305
- <div className="filter-wrapper">
306
- <div className="filter-label">Typology of measures:</div>
307
- {activeFilters.typology_of_measures.map((filterCode) => {
308
- const filterLabel = filters.typology_of_measures[filterCode];
309
- return (
310
- <div className="ui basic label filter-value">
311
- <span>{filterLabel}</span>
312
- <i
313
- tabIndex="0"
314
- onKeyPress={() => {}}
315
- onClick={() => {
316
- removeFilter('typology_of_measures', filterCode);
317
- scrollToElement('search-input');
318
- }}
319
- role="button"
320
- className="close icon"
321
- ></i>
322
- </div>
323
- );
324
- })}
325
- </div>
326
- ) : (
327
- ''
328
- )}
303
+ <FilterGroup
304
+ filterName="measures_implemented"
305
+ filterLabel="Measures implemented:"
306
+ activeFilterCodes={activeFilters.measures_implemented}
307
+ filters={filters}
308
+ onRemoveFilter={removeFilter}
309
+ />
310
+ <FilterGroup
311
+ filterName="typology_of_measures"
312
+ filterLabel="Typology of measures:"
313
+ activeFilterCodes={activeFilters.typology_of_measures}
314
+ filters={filters}
315
+ onRemoveFilter={removeFilter}
316
+ />
329
317
  </div>
330
318
  </div>
331
319
  </div>
332
- ) : (
333
- ''
334
- );
320
+ ) : null;
335
321
  }
336
322
 
337
323
  export const CaseStudyFilters = withOpenLayers(CaseStudyFiltersComponent);
@@ -1,6 +1,6 @@
1
1
  import './mockJsdom';
2
2
  import React from 'react';
3
- import '@testing-library/jest-dom/extend-expect';
3
+ import '@testing-library/jest-dom';
4
4
  import { render } from '@testing-library/react';
5
5
 
6
6
  import {
@@ -9,6 +9,7 @@ import {
9
9
  SearchBox,
10
10
  CaseStudyFilter,
11
11
  } from './CaseStudyFilters';
12
+ import { createMockFilters } from './testUtils';
12
13
 
13
14
  jest.mock('@eeacms/volto-openlayers-map', () => ({
14
15
  openlayers: {
@@ -28,41 +29,32 @@ jest.mock('@eeacms/volto-openlayers-map', () => ({
28
29
  ),
29
30
  }));
30
31
 
31
- describe('CaseStudyFilters', () => {
32
- const mockSetActiveFilters = jest.fn();
33
- window.URL.createObjectURL = function () {};
34
- global.URL.createObjectURL = jest.fn();
32
+ window.URL.createObjectURL = function () {};
33
+ global.URL.createObjectURL = jest.fn();
35
34
 
36
- const mockFilters = {
37
- typology_of_measures: { sector1: 'Sector 1', sector2: 'Sector 2' },
38
- };
35
+ const mockFilters = createMockFilters();
36
+ const mockSetActiveFilters = jest.fn();
39
37
 
38
+ describe('CaseStudyFilters', () => {
40
39
  it('renders without crashing', () => {
41
40
  const { container } = render(
42
41
  <CaseStudyFilters
43
42
  filters={mockFilters}
44
- activeFilters={{ typology_of_measures: [] }}
43
+ activeFilters={{ measures_implemented: [], typology_of_measures: [] }}
45
44
  setActiveFilters={mockSetActiveFilters}
46
45
  />,
47
46
  );
48
47
 
49
- // CaseStudyFilters component returns empty content (commented out filters)
50
- // Just verify it renders without error
51
48
  expect(container).toBeTruthy();
52
49
  });
53
50
  });
54
51
 
55
52
  describe('ActiveFilters', () => {
56
- const mockSetActiveFilters = jest.fn();
57
- const mockFilters = {
58
- typology_of_measures: { sector1: 'Sector 1', sector2: 'Sector 2' },
59
- };
60
-
61
53
  it('renders without crashing', () => {
62
54
  render(
63
55
  <ActiveFilters
64
56
  filters={mockFilters}
65
- activeFilters={{ typology_of_measures: [] }}
57
+ activeFilters={{ measures_implemented: [], typology_of_measures: [] }}
66
58
  setActiveFilters={mockSetActiveFilters}
67
59
  />,
68
60
  );
@@ -70,41 +62,28 @@ describe('ActiveFilters', () => {
70
62
  });
71
63
 
72
64
  describe('SearchBox', () => {
73
- const mockSetActiveFilters = jest.fn();
74
- const mockFilters = {
75
- typology_of_measures: { sector1: 'Sector 1', sector2: 'Sector 2' },
76
- };
77
-
78
- const mockSetSearchInput = jest.fn();
79
- const mockSearchInput = 'bise';
80
-
81
65
  it('renders without crashing', () => {
82
66
  render(
83
67
  <SearchBox
84
68
  filters={mockFilters}
85
- activeFilters={{ typology_of_measures: [] }}
69
+ activeFilters={{ measures_implemented: [], typology_of_measures: [] }}
86
70
  setActiveFilters={mockSetActiveFilters}
87
- searchInput={mockSearchInput}
88
- setSearchInput={mockSetSearchInput}
71
+ searchInput="bise"
72
+ setSearchInput={jest.fn()}
89
73
  />,
90
74
  );
91
75
  });
92
76
  });
93
77
 
94
78
  describe('CaseStudyFilter', () => {
95
- const mockSetActiveFilters = jest.fn();
96
- const mockFilters = {
97
- typology_of_measures: { sector1: 'Sector 1', sector2: 'Sector 2' },
98
- };
99
-
100
79
  it('renders without crashing', () => {
101
80
  render(
102
81
  <CaseStudyFilter
103
- filterTitle={'Case study filter'}
82
+ filterTitle="Case study filter"
104
83
  filters={mockFilters}
105
- activeFilters={{ typology_of_measures: [] }}
84
+ activeFilters={{ measures_implemented: [], typology_of_measures: [] }}
106
85
  setActiveFilters={mockSetActiveFilters}
107
- filterName={'Filter name'}
86
+ filterName="measures_implemented"
108
87
  />,
109
88
  );
110
89
  });
@@ -7,6 +7,7 @@ import {
7
7
  scrollToElement,
8
8
  zoomMapToFeatures,
9
9
  } from './utils';
10
+ import { createMockMap, createMockPointsSource } from './testUtils';
10
11
 
11
12
  jest.mock('@eeacms/volto-openlayers-map', () => ({
12
13
  withOpenLayers: (Component) => Component,
@@ -18,44 +19,19 @@ jest.mock('./utils', () => ({
18
19
  zoomMapToFeatures: jest.fn(),
19
20
  }));
20
21
 
21
- const mockMap = {
22
- getInteractions: () => ({
23
- array_: [
24
- {},
25
- {},
26
- {},
27
- {},
28
- {},
29
- {},
30
- {},
31
- {},
32
- {},
33
- {
34
- getFeatures: () => ({
35
- clear: jest.fn(),
36
- push: jest.fn(),
37
- }),
38
- },
39
- ],
40
- }),
41
- getPixelFromCoordinate: jest.fn(() => [100, 200]),
42
- getFeaturesAtPixel: jest.fn(() => ['mockFeature']),
43
- };
44
-
45
- const mockPointsSource = {
46
- getFeatures: () => [
47
- {
48
- values_: {
49
- title: 'Feature 1',
50
- path: '/feature1',
51
- description: 'Description 1',
52
- typology_of_measures: ['SectorA'],
53
- measures_implemented: [{ title: 'M1', path: '/m1' }],
54
- geometry: { flatCoordinates: [0, 0] },
55
- },
22
+ const mockMap = createMockMap();
23
+ const mockPointsSource = createMockPointsSource([
24
+ {
25
+ values_: {
26
+ title: 'Feature 1',
27
+ path: '/feature1',
28
+ description: 'Description 1',
29
+ typology_of_measures: ['SectorA'],
30
+ measures_implemented: [{ title: 'M1', path: '/m1' }],
31
+ geometry: { flatCoordinates: [0, 0] },
56
32
  },
57
- ],
58
- };
33
+ },
34
+ ]);
59
35
 
60
36
  const selectedCase = {
61
37
  title: 'Selected Title',
@@ -75,7 +75,7 @@ function CaseStudyMap(props) {
75
75
  }, [activeItems, pointsSource, ol]);
76
76
 
77
77
  React.useEffect(() => {
78
- if (!map) return null;
78
+ if (!map) return;
79
79
 
80
80
  const moveendListener = (e) => {
81
81
  // console.log('map.getView()', map.getView());
@@ -3,6 +3,7 @@ import { render, screen, fireEvent } from '@testing-library/react';
3
3
  import '@testing-library/jest-dom';
4
4
  import CaseStudyMap from './CaseStudyMap';
5
5
  import { getFeatures, centerAndResetMapZoom, scrollToElement } from './utils';
6
+ import { createMockMap, createMockOl } from './testUtils';
6
7
 
7
8
  jest.mock('@eeacms/volto-openlayers-map', () => ({
8
9
  withOpenLayers: (Comp) => Comp,
@@ -34,57 +35,8 @@ jest.mock('./utils', () => ({
34
35
  scrollToElement: jest.fn(),
35
36
  }));
36
37
 
37
- const mockOl = {
38
- source: {
39
- TileWMS: jest.fn(() => ({ type: 'TileWMS' })),
40
- Vector: jest.fn(() => ({
41
- clear: jest.fn(),
42
- addFeatures: jest.fn(),
43
- })),
44
- Cluster: jest.fn(() => ({})),
45
- },
46
- style: {
47
- Style: jest.fn(() => ({})),
48
- Circle: jest.fn(() => ({})),
49
- Stroke: jest.fn(() => ({})),
50
- Fill: jest.fn(() => ({})),
51
- Text: jest.fn(() => ({})),
52
- },
53
- proj: {
54
- transform: jest.fn(() => [111, 222]),
55
- fromLonLat: jest.fn(() => [333, 444]),
56
- },
57
- };
58
-
59
- const mockMap = {
60
- on: jest.fn(),
61
- un: jest.fn(),
62
- getView: jest.fn(() => ({
63
- getZoom: () => 4,
64
- getCenter: () => [111, 222],
65
- })),
66
- getInteractions: jest.fn(() => ({
67
- array_: [
68
- {},
69
- {},
70
- {},
71
- {},
72
- {},
73
- {},
74
- {},
75
- {},
76
- {},
77
- {
78
- getFeatures: jest.fn(() => ({
79
- clear: jest.fn(),
80
- push: jest.fn(),
81
- })),
82
- },
83
- ],
84
- })),
85
- getPixelFromCoordinate: jest.fn(() => [10, 20]),
86
- getFeaturesAtPixel: jest.fn(() => ['f']),
87
- };
38
+ const mockOl = createMockOl();
39
+ const mockMap = createMockMap();
88
40
 
89
41
  describe('CaseStudyMap', () => {
90
42
  beforeEach(() => {