@eeacms/volto-cca-policy 1.0.29 → 1.0.31

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,14 @@ 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.0.31](https://github.com/eea/volto-cca-policy/compare/1.0.30...1.0.31) - 29 September 2026
8
+
9
+ ### [1.0.30](https://github.com/eea/volto-cca-policy/compare/1.0.29...1.0.30) - 25 September 2026
10
+
11
+ #### :nail_care: Enhancements
12
+
13
+ - change(navigator): reorder facets [kreafox - [`97f3aff`](https://github.com/eea/volto-cca-policy/commit/97f3afffc6b41b7655e586367257ac6c87663ec7)]
14
+
7
15
  ### [1.0.29](https://github.com/eea/volto-cca-policy/compare/1.0.28...1.0.29) - 25 September 2026
8
16
 
9
17
  #### :rocket: New Features
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eeacms/volto-cca-policy",
3
- "version": "1.0.29",
3
+ "version": "1.0.31",
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",
@@ -223,6 +223,14 @@ const NavigatorGeographicCoverageFacet = ({
223
223
  />
224
224
  ))}
225
225
  </div>
226
+ <ExpandableFacetGroup
227
+ field={COUNTRIES_FIELD}
228
+ id="navigator-geographic-countries"
229
+ label={intl.formatMessage(messages.countries)}
230
+ emptyMessage={intl.formatMessage(messages.noOptionsAvailable)}
231
+ options={countryOptions}
232
+ onChange={(option) => updateChildFilter(COUNTRIES_FIELD, option)}
233
+ />
226
234
  <ExpandableFacetGroup
227
235
  field={TRANSNATIONAL_REGION_FIELD}
228
236
  id="navigator-geographic-transnational-regions"
@@ -233,14 +241,6 @@ const NavigatorGeographicCoverageFacet = ({
233
241
  updateChildFilter(TRANSNATIONAL_REGION_FIELD, option)
234
242
  }
235
243
  />
236
- <ExpandableFacetGroup
237
- field={COUNTRIES_FIELD}
238
- id="navigator-geographic-countries"
239
- label={intl.formatMessage(messages.countries)}
240
- emptyMessage={intl.formatMessage(messages.noOptionsAvailable)}
241
- options={countryOptions}
242
- onChange={(option) => updateChildFilter(COUNTRIES_FIELD, option)}
243
- />
244
244
  <NavigatorActiveFilters
245
245
  filters={filters}
246
246
  onRemove={(field, value, type) => removeFilter(field, value, type)}
@@ -24,7 +24,8 @@ export function cleanDocumentTitle(title) {
24
24
  if (!title || typeof title !== 'string') return '';
25
25
  const pipeIndex = title.indexOf('|');
26
26
  const firstPart = pipeIndex === -1 ? title : title.slice(0, pipeIndex);
27
- return firstPart.trim() || title.trim();
27
+ const normalizedTitle = title.replace(/\s+/g, ' ').trim();
28
+ return firstPart.replace(/\s+/g, ' ').trim() || normalizedTitle;
28
29
  }
29
30
 
30
31
  /**
@@ -33,8 +34,8 @@ export function cleanDocumentTitle(title) {
33
34
  */
34
35
  export function matchesDocumentTitle(docTitle, searchTitle) {
35
36
  if (!docTitle || !searchTitle) return false;
36
- const d1 = docTitle.trim().toLowerCase();
37
- const s1 = searchTitle.trim().toLowerCase();
37
+ const d1 = docTitle.replace(/\s+/g, ' ').trim().toLowerCase();
38
+ const s1 = searchTitle.replace(/\s+/g, ' ').trim().toLowerCase();
38
39
  if (d1 === s1) return true;
39
40
 
40
41
  const dClean = cleanDocumentTitle(docTitle).toLowerCase();
@@ -78,6 +78,15 @@ describe('matchesDocumentTitle', () => {
78
78
  ).toBe(true);
79
79
  });
80
80
 
81
+ it('matches a single-line marker title to a newline-bearing catalogue title', () => {
82
+ expect(
83
+ matchesDocumentTitle(
84
+ 'EFFIS \n- European Forest Fire Information System – Fire Hazard and Wildfire risk views. | Tool catalogue',
85
+ 'EFFIS - European Forest Fire Information System – Fire Hazard and Wildfire risk views.',
86
+ ),
87
+ ).toBe(true);
88
+ });
89
+
81
90
  it('returns false for non-matching or empty titles', () => {
82
91
  expect(matchesDocumentTitle('Alpha', 'Beta')).toBe(false);
83
92
  expect(matchesDocumentTitle(null, 'Beta')).toBe(false);
@@ -4,7 +4,17 @@
4
4
  */
5
5
 
6
6
  export const DOC_MARKER_RE =
7
- /!?\[\[?\s*(?:doc|document|tool|tools)\s*[:-]\s*([^\]\r\n]+)\]?\]/gi;
7
+ /!?\[\[?\s*(?:doc|document|tool|tools)\s*[:-]\s*([^\]]+)\]?\]/gi;
8
+
9
+ export function normalizeDocMarkerWhitespace(markdown) {
10
+ if (typeof markdown !== 'string') return markdown;
11
+ DOC_MARKER_RE.lastIndex = 0;
12
+ const normalized = markdown.replace(DOC_MARKER_RE, (marker) =>
13
+ marker.replace(/\s+/g, ' '),
14
+ );
15
+ DOC_MARKER_RE.lastIndex = 0;
16
+ return normalized;
17
+ }
8
18
 
9
19
  export const NEXT_STEPS_HEADING_RE =
10
20
  /^(suggested\s+next\s+steps|next\s+steps|recommended\s+next\s+steps|recommended\s+workflow|suggested\s+workflow|action\s+plan|how\s+to\s+use(\s+(them|these|this|the\s+tools))?|how\s+to\s+apply(\s+(them|these|this|the\s+tools))?|how\s+to\s+get\s+started|step-by-step\s+guidance)\b/i;
@@ -22,6 +22,7 @@ import {
22
22
  cleanStrayLeadingAsterisks,
23
23
  deduplicateAdjacentHeadings,
24
24
  normalizeCitationParagraphsToLists,
25
+ normalizeDocMarkerWhitespace,
25
26
  parseMarkdownLines,
26
27
  shouldUnwrapCodeNode,
27
28
  unwrapCardLists,
@@ -75,11 +76,19 @@ export const remarkCcaDocCards = function () {
75
76
  const parseFn =
76
77
  typeof this?.parse === 'function' ? (str) => this.parse(str) : null;
77
78
 
78
- return (tree) => {
79
+ return (tree, file) => {
79
80
  if (!tree || !Array.isArray(tree.children)) {
80
81
  return tree;
81
82
  }
82
83
 
84
+ const markdown = file?.value;
85
+ if (typeof markdown === 'string' && typeof parseFn === 'function') {
86
+ const normalizedMarkdown = normalizeDocMarkerWhitespace(markdown);
87
+ if (normalizedMarkdown !== markdown) {
88
+ tree = parseFn(normalizedMarkdown);
89
+ }
90
+ }
91
+
83
92
  // 1. Pre-pass: unwrap code blocks that contain markdown sections or doc markers
84
93
  for (let i = 0; i < tree.children.length; i += 1) {
85
94
  const node = tree.children[i];
@@ -45,6 +45,27 @@ describe('remarkCcaDocCards', () => {
45
45
  expect(cards(result)).toEqual(['Climate Action Plan']);
46
46
  });
47
47
 
48
+ it('normalizes line breaks in a catalogue title before parsing markdown', () => {
49
+ const markdown =
50
+ '![[doc: EFFIS \n- European Forest Fire Information System – Fire Hazard and Wildfire risk views.]]';
51
+ const parse = jest.fn((source) => ({
52
+ type: 'root',
53
+ children: [{ type: 'text', value: source }],
54
+ }));
55
+ const transform = remarkCcaDocCards.call({ parse });
56
+ const result = transform(
57
+ { type: 'root', children: [] },
58
+ { value: markdown },
59
+ );
60
+
61
+ expect(parse).toHaveBeenCalledWith(
62
+ '![[doc: EFFIS - European Forest Fire Information System – Fire Hazard and Wildfire risk views.]]',
63
+ );
64
+ expect(cards(result)).toEqual([
65
+ 'EFFIS - European Forest Fire Information System – Fire Hazard and Wildfire risk views.',
66
+ ]);
67
+ });
68
+
48
69
  it('keeps text before and after a mid-sentence marker', () => {
49
70
  const tree = {
50
71
  type: 'root',