@eeacms/volto-cca-policy 1.0.3 → 1.0.5

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 (72) hide show
  1. package/CHANGELOG.md +117 -1
  2. package/locales/bg/LC_MESSAGES/volto.po +596 -5
  3. package/locales/cs/LC_MESSAGES/volto.po +596 -5
  4. package/locales/da/LC_MESSAGES/volto.po +596 -5
  5. package/locales/de/LC_MESSAGES/volto.po +596 -5
  6. package/locales/el/LC_MESSAGES/volto.po +596 -5
  7. package/locales/en/LC_MESSAGES/volto.po +596 -5
  8. package/locales/es/LC_MESSAGES/volto.po +596 -5
  9. package/locales/et/LC_MESSAGES/volto.po +596 -5
  10. package/locales/fi/LC_MESSAGES/volto.po +596 -5
  11. package/locales/fr/LC_MESSAGES/volto.po +596 -5
  12. package/locales/ga/LC_MESSAGES/volto.po +596 -5
  13. package/locales/hr/LC_MESSAGES/volto.po +596 -5
  14. package/locales/hu/LC_MESSAGES/volto.po +596 -5
  15. package/locales/is/LC_MESSAGES/volto.po +596 -5
  16. package/locales/it/LC_MESSAGES/volto.po +596 -5
  17. package/locales/lt/LC_MESSAGES/volto.po +596 -5
  18. package/locales/lv/LC_MESSAGES/volto.po +596 -5
  19. package/locales/mt/LC_MESSAGES/volto.po +596 -5
  20. package/locales/nl/LC_MESSAGES/volto.po +596 -5
  21. package/locales/nn/LC_MESSAGES/volto.po +596 -5
  22. package/locales/pl/LC_MESSAGES/volto.po +596 -5
  23. package/locales/pt/LC_MESSAGES/volto.po +596 -5
  24. package/locales/ro/LC_MESSAGES/volto.po +596 -5
  25. package/locales/sk/LC_MESSAGES/volto.po +596 -5
  26. package/locales/sl/LC_MESSAGES/volto.po +596 -5
  27. package/locales/sv/LC_MESSAGES/volto.po +596 -5
  28. package/locales/tr/LC_MESSAGES/volto.po +596 -5
  29. package/locales/volto.pot +597 -6
  30. package/package.json +1 -1
  31. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.jsx +17 -27
  32. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueCardItem.test.jsx +6 -0
  33. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueContentView.jsx +1 -1
  34. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.jsx +272 -7
  35. package/src/components/Search/NavigatorCatalogue/NavigatorCatalogueMapView.test.jsx +160 -0
  36. package/src/components/Search/NavigatorCatalogue/utils.js +67 -9
  37. package/src/components/Search/NavigatorCatalogue/utils.test.js +5 -0
  38. package/src/components/manage/Blocks/CountryMapHeatIndex/Interactions.jsx +1 -1
  39. package/src/components/manage/Blocks/CountryMapHeatIndex/View.jsx +5 -6
  40. package/src/components/manage/Blocks/CountryMapObservatory/CountryMapObservatoryOLView.jsx +6 -7
  41. package/src/components/manage/Blocks/CountryMapObservatory/Interactions.jsx +1 -1
  42. package/src/components/manage/Blocks/CountryMapProfile/Interactions.jsx +1 -1
  43. package/src/components/manage/Blocks/CountryMapProfile/OLView.jsx +3 -3
  44. package/src/components/theme/CompareTools/CompareToolsView.jsx +15 -8
  45. package/src/components/theme/CompareTools/CompareToolsView.test.jsx +110 -0
  46. package/src/components/theme/Views/ExtendedToolView.jsx +16 -15
  47. package/src/components/theme/Views/ExtendedToolView.test.jsx +20 -14
  48. package/src/constants.js +0 -48
  49. package/src/helpers/Utils.jsx +20 -11
  50. package/src/helpers/index.js +2 -0
  51. package/src/hocs/index.js +1 -0
  52. package/src/index.js +2 -2
  53. package/theme/globals/navigator.less +180 -66
  54. package/artifacts/BLOCKS.md +0 -167
  55. package/artifacts/link-integrity-workflow/README.md +0 -76
  56. package/artifacts/link-integrity-workflow/index.md +0 -33
  57. package/artifacts/link-integrity-workflow/link-integrity-block-fields-report.md +0 -132
  58. package/artifacts/link-integrity-workflow/link-integrity-blocks-report.md +0 -52
  59. package/artifacts/link-integrity-workflow/understanding-link-integrity.md +0 -143
  60. package/artifacts/link-integrity-workflow/volto-block-link-analysis.md +0 -63
  61. package/artifacts/link-integrity-workflow/volto-block-link-discovery.md +0 -60
  62. package/artifacts/test-fixes/test-fixes-specification.md +0 -267
  63. package/src/components/manage/Blocks/CountryMapHeatIndex/euro-countries-simplified.js +0 -46197
  64. package/src/components/manage/Blocks/CountryMapHeatIndex/flags.js +0 -57
  65. package/src/components/manage/Blocks/CountryMapProfile/euro-countries-simplified.js +0 -46197
  66. package/src/components/manage/Blocks/CountryMapProfile/flags.js +0 -57
  67. package/src/helpers/country_map/flags.js +0 -57
  68. /package/src/components/{Result → Search/Result}/ClusterHorizontalCardItem.jsx +0 -0
  69. /package/src/components/{Result → Search/Result}/HealthHorizontalCardItem.jsx +0 -0
  70. /package/src/{helpers/country_map → data}/euro-countries-simplified.js +0 -0
  71. /package/src/helpers/{country_map/countryMap.js → countryMap.js} +0 -0
  72. /package/src/{helpers/country_map/hocs.jsx → hocs/withGeoJsonData.jsx} +0 -0
@@ -8,6 +8,39 @@
8
8
  @navigatorIconBackgroundColor: #f5f9fb;
9
9
  @navigatorIconColor: #7890a2;
10
10
 
11
+ .navigator-small-clear-button() {
12
+ display: inline-flex;
13
+ width: 28px;
14
+ height: 28px;
15
+ min-height: 28px;
16
+ align-items: center;
17
+ justify-content: center;
18
+ padding: 0 !important;
19
+ border: 0;
20
+ border-radius: 50%;
21
+ margin: 0 !important;
22
+ background: transparent;
23
+ box-shadow: none;
24
+ color: #607482;
25
+ line-height: 1;
26
+
27
+ i.icon {
28
+ display: block;
29
+ width: auto;
30
+ height: auto;
31
+ margin: 0 !important;
32
+ font-size: 1rem;
33
+ line-height: 1;
34
+ }
35
+
36
+ &:hover,
37
+ &:focus {
38
+ background: #e8f0f5;
39
+ box-shadow: none;
40
+ color: #30495b;
41
+ }
42
+ }
43
+
11
44
  .navigator-tool-icon {
12
45
  display: inline-flex;
13
46
  flex: 0 0 auto;
@@ -16,7 +49,7 @@
16
49
  box-sizing: border-box;
17
50
  border: 1px solid @navigatorIconBorderColor;
18
51
  border-radius: 4px;
19
- background-color: #fff;
52
+ background-color: #f7f8fa;
20
53
  color: @navigatorIconColor;
21
54
 
22
55
  i.icon {
@@ -77,6 +110,10 @@
77
110
  margin: 0 !important;
78
111
  }
79
112
 
113
+ .navigator-tool-icon {
114
+ background-color: #fff;
115
+ }
116
+
80
117
  .compare-panel-content {
81
118
  padding: 1rem;
82
119
  }
@@ -154,37 +191,8 @@
154
191
  }
155
192
 
156
193
  .ui.button.compare-panel-tool-clear {
157
- display: inline-flex;
158
- width: 28px;
159
- height: 28px;
160
- min-height: 28px;
194
+ .navigator-small-clear-button();
161
195
  flex: 0 0 auto;
162
- align-items: center;
163
- justify-content: center;
164
- padding: 0 !important;
165
- border: 0;
166
- border-radius: 50%;
167
- margin: 0 !important;
168
- background: transparent;
169
- box-shadow: none;
170
- color: #607482;
171
- line-height: 1;
172
-
173
- i.icon {
174
- display: block;
175
- width: auto;
176
- height: auto;
177
- margin: 0 !important;
178
- font-size: 1rem;
179
- line-height: 1;
180
- }
181
-
182
- &:hover,
183
- &:focus {
184
- background: #e8f0f5;
185
- box-shadow: none;
186
- color: #30495b;
187
- }
188
196
  }
189
197
 
190
198
  .compare-panel-actions {
@@ -206,15 +214,12 @@
206
214
  }
207
215
  }
208
216
 
209
- .ui.button.compare-panel-submit {
210
- margin: 0;
211
- }
212
-
213
- .compare-panel-clear-all {
217
+ .ui.button.compare-panel-clear-all {
214
218
  padding: 0;
215
219
  margin: 0;
216
- background: transparent;
217
- color: @linkColor;
220
+ border: none;
221
+ background: none !important;
222
+ color: @primaryColor;
218
223
 
219
224
  &:hover,
220
225
  &:focus {
@@ -320,7 +325,8 @@
320
325
  table-layout: fixed;
321
326
 
322
327
  thead th,
323
- tbody td {
328
+ tbody td,
329
+ tbody th {
324
330
  border-color: @navigatorBorderColor;
325
331
  }
326
332
 
@@ -335,15 +341,18 @@
335
341
  vertical-align: bottom;
336
342
  }
337
343
 
338
- tbody td {
344
+ tbody td,
345
+ tbody th {
339
346
  min-height: 84px;
340
347
  padding: 1.35rem 1.25rem;
341
348
  line-height: 1.45;
342
349
  vertical-align: top;
343
350
  background: #fff;
351
+ font-weight: inherit;
352
+ text-align: left;
344
353
  }
345
354
 
346
- tbody td:first-child {
355
+ tbody th:first-child {
347
356
  background: @navigatorCriteriaBackgroundColor;
348
357
  }
349
358
  }
@@ -430,40 +439,136 @@
430
439
  }
431
440
  }
432
441
 
433
- body.searchlib-page .searchapp-navigatorCatalogueSearch {
434
- .back-link {
435
- display: none;
442
+ .navigator-catalogue-map {
443
+ display: grid;
444
+ width: 100%;
445
+ height: 600px;
446
+ min-height: 600px;
447
+ align-items: stretch;
448
+ gap: 1.5rem;
449
+ grid-template-columns: minmax(0, 4fr) minmax(12rem, 1fr);
450
+
451
+ .ol-map-wrapper,
452
+ .ol-map {
453
+ height: 600px;
436
454
  }
437
455
 
438
- .search-input,
439
- .sui-search-box {
440
- margin-bottom: 2rem;
456
+ .navigator-catalogue-map-canvas {
457
+ position: relative;
458
+ min-width: 0;
459
+ height: 100%;
460
+ }
461
+
462
+ .ol-map {
463
+ width: 100%;
464
+ height: 100%;
441
465
  }
442
466
 
443
- .navigator-catalogue-map-placeholder {
467
+ .ol-layer {
468
+ transition: opacity 0.3s ease;
469
+ }
470
+ }
471
+
472
+ .navigator-catalogue-map-loading {
473
+ text-align: center;
474
+ display: flex;
475
+ flex-direction: column;
476
+ gap: 1em;
477
+ }
478
+ .navigator-catalogue-map-tooltip {
479
+ position: absolute;
480
+ z-index: 1000;
481
+ min-width: 200px;
482
+ max-width: 280px;
483
+ padding: 1em;
484
+ margin-top: -10px;
485
+ margin-left: 15px;
486
+ background: #fff;
487
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
488
+ pointer-events: auto;
489
+
490
+ .tooltip-header {
491
+ font-size: 16px;
492
+ }
493
+
494
+ .tooltip-body {
495
+ margin: 1em 0;
496
+ font-size: 0.875rem;
497
+ }
498
+
499
+ .tooltip-actions {
500
+ .ui.button {
501
+ width: 100%;
502
+ margin: 0;
503
+ }
504
+ }
505
+
506
+ .ui.button.tooltip-close {
507
+ .navigator-small-clear-button();
508
+ position: absolute;
509
+ top: 0.5rem;
510
+ right: 0.5rem;
511
+ }
512
+ }
513
+
514
+ .navigator-catalogue-map-legend {
515
+ font-size: 16px;
516
+
517
+ .legend-title {
518
+ margin-top: 0;
519
+ }
520
+
521
+ .legend-item {
444
522
  display: flex;
445
- min-height: 320px;
446
523
  align-items: center;
447
- justify-content: center;
448
- border: 1px dashed @navigatorBorderColor;
449
- color: @navigatorMetaTextColor;
450
- gap: 1rem;
524
+ padding: 0.2rem 0;
525
+ gap: 0.5rem;
451
526
 
452
- i.icon {
453
- color: @secondaryColor;
454
- font-size: 2.5rem;
527
+ .legend-color {
528
+ display: inline-block;
529
+ width: 16px;
530
+ height: 16px;
531
+ flex-shrink: 0;
455
532
  }
533
+ }
534
+ }
456
535
 
457
- h3 {
458
- margin-bottom: 0.25rem;
459
- color: @primaryColor;
460
- }
536
+ @media only screen and (max-width: 768px) {
537
+ .navigator-catalogue-map {
538
+ height: auto;
539
+ min-height: 0;
540
+ grid-template-columns: minmax(0, 1fr);
461
541
 
462
- p {
463
- margin: 0;
542
+ .navigator-catalogue-map-canvas {
543
+ height: 400px;
544
+ min-height: 350px;
464
545
  }
465
546
  }
466
547
 
548
+ .navigator-catalogue-map-tooltip {
549
+ top: auto !important;
550
+ bottom: 1rem;
551
+ left: 50% !important;
552
+ margin-left: 0;
553
+ transform: translateX(-50%);
554
+ }
555
+
556
+ .navigator-catalogue-map-legend {
557
+ width: 100%;
558
+ box-sizing: border-box;
559
+ }
560
+ }
561
+
562
+ body.searchlib-page .searchapp-navigatorCatalogueSearch {
563
+ .back-link {
564
+ display: none;
565
+ }
566
+
567
+ .search-input,
568
+ .sui-search-box {
569
+ margin-bottom: 2rem;
570
+ }
571
+
467
572
  .ui.right.sidebar {
468
573
  background-color: #fff;
469
574
  box-shadow: -4px 0 4px rgba(0, 0, 0, 0.25);
@@ -588,7 +693,7 @@ body.searchlib-page .searchapp-navigatorCatalogueSearch {
588
693
  }
589
694
 
590
695
  .license-type {
591
- gap: 0.5em;
696
+ gap: 0.7em;
592
697
  }
593
698
 
594
699
  .navigator-catalogue-cycle-elements {
@@ -663,7 +768,6 @@ body.searchlib-page .searchapp-navigatorCatalogueSearch {
663
768
  min-height: 24px;
664
769
  align-items: center;
665
770
  padding: 0 0.45rem;
666
- border-radius: 2px;
667
771
  font-weight: 500;
668
772
  font-size: 12px;
669
773
 
@@ -687,12 +791,22 @@ body.searchlib-page .searchapp-navigatorCatalogueSearch {
687
791
  background: #ddd8f5;
688
792
  color: #51458a;
689
793
  }
794
+
795
+ &.more {
796
+ border: 0;
797
+ cursor: pointer;
798
+ font-family: inherit;
799
+ }
690
800
  }
691
801
 
692
802
  .navigator-guide-search {
693
803
  .navigator-guide-header {
694
804
  margin-bottom: 2rem;
695
805
  text-align: center;
806
+
807
+ h2 {
808
+ margin-top: 0.5em;
809
+ }
696
810
  }
697
811
 
698
812
  .navigator-guide-preview-header {
@@ -705,10 +819,11 @@ body.searchlib-page .searchapp-navigatorCatalogueSearch {
705
819
 
706
820
  .navigator-guide-eyebrow,
707
821
  .navigator-guide-preview-label {
708
- font-size: 0.75rem;
822
+ font-size: 13px;
709
823
  font-weight: 700;
710
824
  letter-spacing: 0.08em;
711
825
  text-transform: uppercase;
826
+ color: @navigatorAccentColor;
712
827
  }
713
828
 
714
829
  .navigator-guide-layout {
@@ -902,7 +1017,6 @@ body.searchlib-page .searchapp-navigatorCatalogueSearch {
902
1017
  &.selected {
903
1018
  border-color: @primaryColor;
904
1019
  background: fade(@primaryColor, 5%);
905
- font-weight: 500;
906
1020
  }
907
1021
 
908
1022
  > span {
@@ -1,167 +0,0 @@
1
- # Custom Blocks in `volto-cca-policy`
2
-
3
- This addon registers **20 custom blocks** and extends **2 existing blocks** (Listing, Tabs Block) with new variations.
4
- All blocks are installed via `src/components/manage/Blocks/index.js`.
5
-
6
- ---
7
-
8
- ## Custom Blocks
9
-
10
- ### AST Navigation
11
- - **Block ID:** `astNavigation`
12
- - **Group:** `site`
13
- - **Restricted to:** Mission pages (via `blockAvailableInMission`)
14
- - **What it does:** Renders a visual navigation map (logo map) for the *Adaptation Support Tool (AST)*. Supports two image types (`ast` and `uast`). Editors configure 6 linked items that map to clickable regions on the logo image. Clicking a region navigates to the corresponding content page.
15
-
16
- ### C3S Indicators Glossary
17
- - **Block ID:** `c3SIndicatorsGlossaryBlock`
18
- - **Group:** `site`
19
- - **Restricted to:** Mission pages
20
- - **What it does:** Displays a glossary table of C3S (Copernicus Climate Change Service) indicator terms. The content is provided by a server-side `@components` view (`c3s_indicators_glossary_table`) and rendered as raw HTML.
21
-
22
- ### C3S Indicators Listing
23
- - **Block ID:** `c3SIndicatorListingBlock`
24
- - **Group:** `site`
25
- - **Restricted to:** Mission pages
26
- - **What it does:** Renders a description and a linked list of C3S indicators. Content (description text + item list with URLs) is provided by the server-side `@components` view `c3s_indicators_listing`.
27
-
28
- ### C3S Indicators Overview
29
- - **Block ID:** `c3SIndicatorsOverviewBlock`
30
- - **Group:** `site`
31
- - **Restricted to:** Mission pages
32
- - **What it does:** Displays an HTML description/overview of C3S indicators, fetched from the server-side `@components` view `c3s_indicators_overview`.
33
-
34
- ### Case Study Explorer
35
- - **Block ID:** `caseStudyExplorer`
36
- - **Group:** `site`
37
- - **Restricted to:** Mission pages
38
- - **What it does:** An interactive map-based explorer for climate adaptation case studies. Loads case study data from an ArcGIS JSON endpoint (`@@case-studies-map.arcgis.json`). Provides filter controls (sectors, impacts, etc.) and an interactive map with clickable features. Supports URL-based filter parameters.
39
-
40
- ### Collection Statistics
41
- - **Block ID:** `collectionStats`
42
- - **Group:** `site`
43
- - **What it does:** Displays aggregated statistics for a content collection. Shows two groups of stats with icons and counts:
44
- - **Health impacts:** Climate-sensitive diseases, Heat, Wildfires, Droughts and floods, Air pollution and aero-allergens
45
- - **Content types:** Adaptation options, Case studies, Guidance, Indicators, Information portals, Organisations, Publications, Research projects, Tools, Videos
46
- - Stats are computed from query stats via `getQueryStats` and can link to filtered search results.
47
-
48
- ### Content Links
49
- - **Block ID:** `contentLinks`
50
- - **Group:** `site`
51
- - **Variations:**
52
- - `default` — Simple list of linked content items
53
- - `navigationList` — Navigation-style list with active-state highlighting based on current URL
54
- - `dropdown` — Dropdown selector for linking to content items (with configurable placeholder text)
55
- - **What it does:** Displays a set of manually selected content items as links. Useful for sidebars, navigation menus, or quick-access link groups.
56
-
57
- ### Country Map Heat Index
58
- - **Block ID:** `countryMapHeatIndex`
59
- - **Group:** `site`
60
- - **Restricted to:** Mission pages
61
- - **What it does:** An interactive OpenLayers map of European countries colored by heat index data. Fetches metadata from `@@countries-heat-index-json`. Countries are highlighted with tooltips and are clickable, navigating to the respective country page. Includes a filter control and supports lazy loading via visibility sensor.
62
-
63
- ### Country Map Observatory
64
- - **Block ID:** `countryMapObservatory`
65
- - **Group:** `site`
66
- - **Restricted to:** Mission pages
67
- - **What it does:** An interactive OpenLayers map for the Health Observatory section. Renders EU countries with metadata from `@@countries-metadata-extract-2025`. Supports thematic map modes (e.g., "National adaptation policy"), tooltips, and click-to-navigate interactions. Uses WMS tile sources and lazy loading.
68
-
69
- ### Country Map Profile
70
- - **Block ID:** `countryMapProfile`
71
- - **Group:** `site`
72
- - **Restricted to:** Mission pages
73
- - **What it does:** An interactive OpenLayers map for country profiles. Renders EU countries with metadata from `@@countries-metadata-extract-2025` (including flag images). Supports thematic map modes, tooltips, click-to-navigate, and a filter control. Uses WMS tile sources and lazy loading.
74
-
75
- ### Country Profile Detail
76
- - **Block ID:** `countryProfileDetail`
77
- - **Group:** `site`
78
- - **What it does:** Renders the detailed country profile content provided by a server-side `@components` view (`countryprofile.html`). Displays tabbed sections with accordions, including a language disclaimer for non-English content and optional top messages/accordions.
79
-
80
- ### Data Connected Embed Block
81
- - **Block ID:** `data_connected_embed` (extends `@eeacms/volto-datablocks`)
82
- - **What it does:** Customizes the data-connected embed block from `volto-datablocks` to inject the current page language (`lang`) as an additional query parameter. This ensures embedded data visualizations respect the page's language context. Wraps the base `ViewEmbedBlock` with Redux connectivity and `injectIntl`.
83
-
84
- ### ECDE Indicators
85
- - **Block ID:** `ecdeIndicators`
86
- - **Group:** `site`
87
- - **Restricted to:** Mission pages
88
- - **What it does:** Embeds European Climate Data Explorer (ECDE) indicator visualizations from the Copernicus Climate Data Store (CDS). Loads region data from an EEA ArcGIS service and renders interactive CDS toolbox apps (e.g., growing degree days, mean temperature) for selected European NUTS regions.
89
-
90
- ### Filter AceContent
91
- - **Block ID:** `filterAceContent`
92
- - **Group:** `site`
93
- - **Restricted to:** Mission pages
94
- - **Variations:**
95
- - `simpleListing` — Listing view (default)
96
- - `simpleCards` — Card grid view
97
- - **What it does:** Provides a faceted search/filter interface for ACE (Adaptation Content Exchange) content. Supports filtering by bio-regions, countries, climate impacts, sectors, element types, funding programmes, macro-regions, key types, and free-text search. Uses a custom select widget with styled dropdowns.
98
-
99
- ### Flourish Visualization
100
- - **Block ID:** `FlourishEmbedBlock`
101
- - **Group:** `site`
102
- - **What it does:** Embeds interactive data visualizations from [Flourish.studio](https://flourish.studio). Editors paste a Flourish embed code, and the block extracts the visualization URL, wraps it in an iframe with privacy protection (lazy loading via consent gate), and displays it at a fixed height of 980px.
103
-
104
- ### RAST (Related And Sub-Tree) Block
105
- - **Block ID:** `rastBlock`
106
- - **Group:** `site`
107
- - **Restricted to:** Mission pages
108
- - **What it does:** Renders a contextual navigation block showing related content and sub-items from a configurable root path. Supports skipping specific items and optionally showing subfolders. Uses `ContextNavigation` and `RASTAccordion` components to display a hierarchical accordion-style navigation tree.
109
-
110
- ### Read More
111
- - **Block ID:** `readMoreBlock`
112
- - **Group:** `site`
113
- - **What it does:** Creates a collapsible "read more" section. Wraps all preceding sibling blocks in a height-constrained container with an expand/collapse button. Configurable properties include open/closed labels, button position, and initial height.
114
-
115
- ### Redirection Block
116
- - **Block ID:** `redirectBlock`
117
- - **Group:** `site`
118
- - **What it does:** Automatically redirects anonymous users to a configured target URL. Logged-in users (editors) see a discreet notice showing the redirect target instead of being redirected, so they can still edit the page.
119
-
120
- ### Relevant AceContent
121
- - **Block ID:** `relevantAceContent`
122
- - **Group:** `site`
123
- - **Restricted to:** Mission pages
124
- - **What it does:** Displays a list of relevant ACE (Adaptation Content Exchange) items. Supports two modes: manually selected items and dynamically searched results (by element type, sector, search type, special tags, or search text). Can combine both modes. Renders as a simple linked list.
125
-
126
- ### Search AceContent
127
- - **Block ID:** `searchAceContent`
128
- - **Group:** `site`
129
- - **Restricted to:** Mission pages
130
- - **What it does:** Displays search results from the ACE content search API. Shows results as a linked list with translated labels and counts. Includes a "Share your information" button linking to the share page.
131
-
132
- ### Tabs Block — Spotlight Variation
133
- - **Block ID:** `tabs_block` (extends `@eeacms/volto-tabs-block`)
134
- - **Variation added:** `spotlight`
135
- - **What it does:** Adds a "Spotlight" variation to the standard tabs block. Renders tab content with a spotlight-style layout featuring configurable icons or images (with position and size options), simple markdown support, and scroll-to-target behavior.
136
-
137
- ### Trans Region Select
138
- - **Block ID:** `transRegionSelect`
139
- - **Group:** `site`
140
- - **Restricted to:** Mission pages
141
- - **What it does:** Renders a dropdown selector for transnational regions. Fetches region data from the content's `@components` view (`transnationalregion`) and provides a dropdown with links to each region's page, plus a default "Other regions" option.
142
-
143
- ---
144
-
145
- ## Extended Standard Blocks
146
-
147
- ### Listing (standard Volto block — extended)
148
- The standard Volto `listing` block is extended with **6 new variations**:
149
-
150
- | Variation | Description |
151
- |-----------|-------------|
152
- | `dropdown` | Renders listed items as a dropdown selector with a configurable placeholder text |
153
- | `organisationCards` | Displays items as a 4-column card grid with logo/image and description (for organisations) |
154
- | `indicatorCards` | Displays C3S/Lancet Countdown indicators as styled cards with title and description |
155
- | `eventCards` | Displays events as cards with date info, contact details, event URL, and EEA branding |
156
- | `eventAccordion` | Displays events in an accordion layout with formatted date ranges and "read more" expand |
157
- | `simpleListing` | Plain text list of linked items (minimal styling) |
158
- | `simpleCards` | Generic 4-column card grid with image/logo and title |
159
-
160
- Additionally, the listing block's `noResultsComponent` is overridden to render nothing (instead of showing "No results" text).
161
-
162
- ---
163
-
164
- ## Shared Utilities
165
-
166
- - **`withResponsiveContainer.js`** — HOC that wraps map blocks in a responsive container (used by Country Map blocks)
167
- - **`withVisibilitySensor.jsx`** — HOC that defers map initialization until the block is visible in the viewport (lazy loading)
@@ -1,76 +0,0 @@
1
- # Link Integrity Workflow warning Specification
2
-
3
- ## Overview
4
-
5
- To prevent breaking the browsing experience of public (anonymous) website visitors, Climate-ADAPT intercepts workflow transitions that limit content visibility (such as changing a state to **Private**, **Reject**, or **Retract**).
6
-
7
- Before finalizing these transitions, the system performs an asynchronous backend check using the Plone link integrity relation catalog (`@linkintegrity`) to discover if any other published pages link to the target item. If referencing items are found, the user is presented with a warning modal detailing the pages that link to the item, allowing them to either cancel or proceed anyway.
8
-
9
- ---
10
-
11
- ## Architectural Workflow
12
-
13
- ```mermaid
14
- sequenceDiagram
15
- autonumber
16
- actor Editor
17
- participant WorkflowDropdown as Workflow Dropdown (Workflow.jsx)
18
- participant API as Plone REST API (/@linkintegrity)
19
- participant WarningModal as Warning Modal (WorkflowLinkIntegrityModal.jsx)
20
-
21
- Editor->>WorkflowDropdown: Select "Make Private" / "Reject" / "Retract"
22
- WorkflowDropdown->>API: Dispatch linkIntegrityCheck([UID])
23
- WorkflowDropdown->>WarningModal: Open Warning Modal (with Loader active)
24
- Note over WarningModal: Action buttons are disabled during check
25
-
26
- alt No breaches exist
27
- API-->>WorkflowDropdown: Return 0 breaches
28
- WorkflowDropdown->>WorkflowDropdown: Auto-execute workflow transition
29
- WorkflowDropdown->>WarningModal: Close Modal automatically
30
- WorkflowDropdown-->>Editor: Show success toast
31
- else Breaches exist
32
- API-->>WorkflowDropdown: Return breach details
33
- WorkflowDropdown->>WarningModal: Deactivate Loader & enable confirm
34
- WarningModal-->>Editor: Render list of linking pages & warning copy
35
-
36
- alt Editor clicks "Cancel"
37
- Editor->>WarningModal: Click "Cancel"
38
- WarningModal->>WorkflowDropdown: Reset pending transition & close modal
39
- else Editor clicks "Change state anyway"
40
- Editor->>WarningModal: Click "Change state anyway"
41
- WarningModal->>WorkflowDropdown: Trigger onOk() -> executeTransition()
42
- WorkflowDropdown->>WorkflowDropdown: Execute workflow transition
43
- WorkflowDropdown->>WarningModal: Close Modal
44
- WorkflowDropdown-->>Editor: Show success toast
45
- end
46
- end
47
- ```
48
-
49
- ---
50
-
51
- ## Implementation Details
52
-
53
- ### 1. Workflow Interception (Customization)
54
- * **Path**: [Workflow.jsx](file:///home/tibi/work/eea.docker.plone-climateadapt/cca/frontend/src/addons/volto-cca-policy/src/customizations/volto/components/manage/Workflow/Workflow.jsx)
55
- * **Role**: Shadows Volto core's workflow select component. Intercepts transitions containing state keys (`private`, `reject`, `retract`) or URL suffixes (`/reject`, `/retract`). Dispatches `linkIntegrityCheck` and manages `pendingOption` state. Executes transition automatically if 0 breaches are found.
56
-
57
- ### 2. Warning Modal Component
58
- * **Path**: [WorkflowLinkIntegrityModal.jsx](file:///home/tibi/work/eea.docker.plone-climateadapt/cca/frontend/src/addons/volto-cca-policy/src/components/manage/Workflow/WorkflowLinkIntegrityModal.jsx)
59
- * **Role**: A plain HTML overlay dialog rendered via `ReactDOM.createPortal` into a `<div>` appended to `document.body`. Zero `semantic-ui-react` dependencies — no `Confirm`, `Modal`, or `Portal`.
60
- * **Why not `semantic-ui-react`?** The `Confirm` and `Modal` components use internal Portals, auto-controlled state, and shorthand factory systems that made click handlers unreliable in the toolbar dropdown context. The Toolbar's global `document mousedown` handler (`handleClickOutside`) would intercept clicks, close the menu, and unmount the modal before `onConfirm` could fire.
61
- * **Key implementation details**:
62
- * **Portal rendering** — renders at `document.body` level with `z-index: 10000`, placing it outside the toolbar dropdown's DOM subtree and CSS stacking context so it appears as a proper full-page overlay.
63
- * **Capture-phase `mousedown` guard** — a `capture=true` listener on the portal root calls `e.stopPropagation()`, preventing the Toolbar's `handleClickOutside` from firing while the modal is open.
64
- * **Synchronous breach derivation** — `computeBreaches()` computes `brokenReferences` and `breaches` during render (no `useEffect` + `useState`), so the data is always in sync with `loading` in the same render cycle. This prevents a race condition where `loading` becomes `false` but `brokenReferences` is still `0`, causing premature modal closure.
65
- * **Inline styles** — all CSS is embedded via a `<style>` tag, no external stylesheet dependency.
66
- * **Key UX Features**:
67
- * Maintains button state `disabled: loading` during ongoing checks to prevent premature actions.
68
- * Renders a CSS spinner and loading text during the check.
69
- * Displays the exact list of referencing (source) items and target sub-items.
70
- * Displays the warning copy:
71
- > *"By changing the state, we're not breaking references, but may break user experience for final Anonymous users. There are {brokenReferences} {variation} to this item:"*
72
- * Closes on backdrop click, button click, or `Escape` key.
73
-
74
- ### 3. Unit Verification Suite
75
- * **Path**: [WorkflowLinkIntegrityModal.test.jsx](file:///home/tibi/work/eea.docker.plone-climateadapt/cca/frontend/src/addons/volto-cca-policy/src/components/manage/Workflow/WorkflowLinkIntegrityModal.test.jsx)
76
- * **Role**: Houses Jest/React Testing Library assertions verifying loading indicator visibility, auto-proceed behavior with 0 breaches, warnings list aggregation for multiple breaches, and confirm button presence.
@@ -1,33 +0,0 @@
1
- # Link Integrity & Workflow Documentation Index
2
-
3
- This directory houses the research, analysis, and specifications for Plone/Volto Link Integrity tracking and the "Warn Before Private" workflow state transition verification feature.
4
-
5
- Below is an overview of the role and purpose of each document in this directory:
6
-
7
- ---
8
-
9
- ## 📖 Document Catalog
10
-
11
- ### 1. [README.md](./README.md)
12
- * **Role**: **Feature Specification & Technical Implementation Guide**
13
- * **Description**: High-level specification outlining the "Warn before private" workflow transition warning system. It explains how workflow transitions to private or retracted states are intercepted to check for breaches, contains a Mermaid sequence diagram of the operational flow, and details pointers to the exact implementation files (`Workflow.jsx`, `WorkflowLinkIntegrityModal.jsx`, and the unit test suite).
14
-
15
- ### 2. [understanding-link-integrity.md](./understanding-link-integrity.md)
16
- * **Role**: **Initial Research & Mechanics Overview**
17
- * **Description**: Explains the underlying mechanics of Plone's `plone.app.linkintegrity` package, the `@linkintegrity` and `@relations` REST API endpoints, how internal references are stored in the `zc.relation` catalog using `isReferencing`, and proposes the initial architectural solution for shadowing the Volto toolbar component.
18
-
19
- ### 3. [volto-block-link-discovery.md](./volto-block-link-discovery.md)
20
- * **Role**: **Block Parser Link Extraction Specs**
21
- * **Description**: Detailed specifications on how the Plone backend's block-to-HTML parser (via `plone.volto`) parses internal links and retrieves referencing UIDs from complex Volto blocks (e.g. Columns, Teasers, Maps) to keep the relation catalog accurately indexed.
22
-
23
- ### 4. [volto-block-link-analysis.md](./volto-block-link-analysis.md)
24
- * **Role**: **Technical Analysis of Internal Linking**
25
- * **Description**: Analyzes how internal links are serialized, stored, and resolved within customized layouts. Explains matching strategies for Dexterity schemas and Choice relation fields.
26
-
27
- ### 5. [link-integrity-blocks-report.md](./link-integrity-blocks-report.md)
28
- * **Role**: **Volto Blocks Reference Index**
29
- * **Description**: A quick-reference status report listing the Volto blocks whose internal link fields are covered by link integrity tracking and validation rules.
30
-
31
- ### 6. [link-integrity-block-fields-report.md](./link-integrity-block-fields-report.md)
32
- * **Role**: **Field Mapping Specification**
33
- * **Description**: A comprehensive deep-dive report mapping exactly which fields and properties within the custom blocks schemas are indexed and tracked by the link integrity processor.