@eeacms/volto-cca-policy 0.2.69 → 0.2.71
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 +33 -0
- package/package.json +2 -2
- package/src/components/Result/ClusterHorizontalCardItem.jsx +136 -0
- package/src/components/manage/Blocks/C3SIndicatorsGlossaryBlock/C3SIndicatorsGlossaryBlockView.test.jsx +34 -0
- package/src/components/manage/Blocks/C3SIndicatorsListingBlock/C3SIndicatorsListingBlockView.test.jsx +43 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyExplorerEdit.test.jsx +89 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyExplorerView.test.jsx +93 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.jsx +13 -79
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.test.jsx +131 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureDisplay.jsx +5 -1
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureDisplay.test.jsx +59 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureInteraction.jsx +132 -53
- package/src/components/manage/Blocks/CaseStudyExplorer/styles.less +4 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/useInteractiveStyles.jsx +189 -0
- package/src/components/manage/Blocks/MKHMap/InfoOverlay.jsx +20 -8
- package/src/components/manage/Blocks/MKHMap/View.jsx +1 -1
- package/src/components/theme/ImageGallery/styles.less +1 -1
- package/src/index.js +4 -1
- package/src/search/config.js +79 -26
- package/src/search/facets.js +12 -1
- package/src/search/views.js +15 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/InfoOverlay.jsx +0 -80
|
@@ -4,13 +4,25 @@ import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
|
4
4
|
import FeatureDisplay from './FeatureDisplay';
|
|
5
5
|
import { usePrevious } from '@plone/volto/helpers/Utils/usePrevious';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const isCluster = (features) => {
|
|
8
|
+
return features.length > 1 ? true : features[0].values_?.features?.length > 1;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default function InfoOverlay({
|
|
12
|
+
selectedFeature,
|
|
13
|
+
onFeatureSelect,
|
|
14
|
+
layerId,
|
|
15
|
+
hasCusters = false,
|
|
16
|
+
}) {
|
|
8
17
|
const { map } = useMapContext();
|
|
9
18
|
const [tooltip, setTooltipRef] = React.useState();
|
|
10
19
|
const [showTooltip, setShowTooltip] = React.useState();
|
|
11
20
|
|
|
12
21
|
const prevLayerId = usePrevious(layerId);
|
|
13
22
|
|
|
23
|
+
const [isClient, setIsClient] = React.useState(false);
|
|
24
|
+
React.useEffect(() => setIsClient(true), []);
|
|
25
|
+
|
|
14
26
|
React.useEffect(() => {
|
|
15
27
|
if (prevLayerId && layerId !== prevLayerId) {
|
|
16
28
|
setShowTooltip(false);
|
|
@@ -23,7 +35,7 @@ export default function InfoOverlay({ selectedFeature, layerId }) {
|
|
|
23
35
|
const overlay = new ol.Overlay({
|
|
24
36
|
element: document.getElementById('popup-overlay'),
|
|
25
37
|
positioning: 'bottom-center',
|
|
26
|
-
offset: [
|
|
38
|
+
offset: [10, -10],
|
|
27
39
|
stopEvent: false,
|
|
28
40
|
});
|
|
29
41
|
map.addOverlay(overlay);
|
|
@@ -33,11 +45,14 @@ export default function InfoOverlay({ selectedFeature, layerId }) {
|
|
|
33
45
|
const { pixel, target } = evt;
|
|
34
46
|
const features = target.getFeaturesAtPixel(pixel);
|
|
35
47
|
|
|
36
|
-
if (features.length) {
|
|
48
|
+
if (features.length && (hasCusters ? !isCluster(features) : true)) {
|
|
37
49
|
overlay.setPosition(coordinate);
|
|
38
50
|
setShowTooltip(true);
|
|
39
51
|
} else {
|
|
52
|
+
// handle a click in an overlay popup
|
|
53
|
+
if (evt.originalEvent.target.tagName === 'A') return;
|
|
40
54
|
setShowTooltip(false);
|
|
55
|
+
onFeatureSelect(null);
|
|
41
56
|
}
|
|
42
57
|
}
|
|
43
58
|
|
|
@@ -47,10 +62,7 @@ export default function InfoOverlay({ selectedFeature, layerId }) {
|
|
|
47
62
|
map.un('click', handler);
|
|
48
63
|
map.removeOverlay(overlay);
|
|
49
64
|
};
|
|
50
|
-
}, [map, tooltip]);
|
|
51
|
-
|
|
52
|
-
const [isClient, setIsClient] = React.useState(false);
|
|
53
|
-
React.useEffect(() => setIsClient(true), []);
|
|
65
|
+
}, [map, tooltip, onFeatureSelect, hasCusters]);
|
|
54
66
|
|
|
55
67
|
return isClient ? (
|
|
56
68
|
<div
|
|
@@ -62,7 +74,7 @@ export default function InfoOverlay({ selectedFeature, layerId }) {
|
|
|
62
74
|
}}
|
|
63
75
|
ref={setTooltipRef}
|
|
64
76
|
>
|
|
65
|
-
<FeatureDisplay feature={selectedFeature} />
|
|
77
|
+
{selectedFeature ? <FeatureDisplay feature={selectedFeature} /> : null}
|
|
66
78
|
</div>
|
|
67
79
|
) : null;
|
|
68
80
|
}
|
|
@@ -11,7 +11,7 @@ import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
|
11
11
|
|
|
12
12
|
import * as layers from './layers';
|
|
13
13
|
import FeatureInteraction from './FeatureInteraction';
|
|
14
|
-
import InfoOverlay from '
|
|
14
|
+
import InfoOverlay from './InfoOverlay';
|
|
15
15
|
|
|
16
16
|
import './styles.less';
|
|
17
17
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
bottom: 0em;
|
|
10
10
|
left: 0em;
|
|
11
11
|
padding: 10px;
|
|
12
|
-
background: rgba(0, 0, 0, 0.5); /* optional: semi-transparent background */
|
|
12
|
+
// background: rgba(0, 0, 0, 0.5); /* optional: semi-transparent background */
|
|
13
13
|
color: white; /* text color */
|
|
14
14
|
font-size: 14px; /* adjust font size as needed */
|
|
15
15
|
text-align: left; /* optional: center the text */
|
package/src/index.js
CHANGED
|
@@ -22,6 +22,7 @@ import GeocharsWidget from './components/theme/Widgets/GeocharsWidget';
|
|
|
22
22
|
import GeolocationWidget from './components/theme/Widgets/GeolocationWidget';
|
|
23
23
|
import MigrationButtons from './components/MigrationButtons';
|
|
24
24
|
import HealthHorizontalCardItem from './components/Result/HealthHorizontalCardItem';
|
|
25
|
+
import ClusterHorizontalCardItem from './components/Result/ClusterHorizontalCardItem';
|
|
25
26
|
|
|
26
27
|
import { langRedirection } from './store/middleware';
|
|
27
28
|
|
|
@@ -339,7 +340,9 @@ const applyConfig = (config) => {
|
|
|
339
340
|
config.settings.searchlib.resolve.HealthHorizontalCardItem = {
|
|
340
341
|
component: HealthHorizontalCardItem,
|
|
341
342
|
};
|
|
342
|
-
|
|
343
|
+
config.settings.searchlib.resolve.ClusterHorizontalCardItem = {
|
|
344
|
+
component: ClusterHorizontalCardItem,
|
|
345
|
+
};
|
|
343
346
|
// Custom widgets
|
|
344
347
|
config.widgets.id.geochars = GeocharsWidget;
|
|
345
348
|
config.widgets.id.geolocation = GeolocationWidget;
|
package/src/search/config.js
CHANGED
|
@@ -1,27 +1,65 @@
|
|
|
1
1
|
import { mergeConfig } from '@eeacms/search';
|
|
2
|
-
import { build_runtime_mappings } from '@eeacms/volto-globalsearch/utils';
|
|
3
2
|
import { getClientProxyAddress } from './utils';
|
|
4
3
|
import vocabs from './vocabulary';
|
|
5
4
|
|
|
6
5
|
import facets from './facets';
|
|
6
|
+
import views from './views';
|
|
7
7
|
|
|
8
8
|
const ccaConfig = {
|
|
9
9
|
title: 'ClimateAdapt Main',
|
|
10
|
+
...views,
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
export const clusters = {
|
|
13
14
|
name: 'op_cluster',
|
|
14
|
-
field: 'objectProvides',
|
|
15
|
+
// field: 'objectProvides',
|
|
15
16
|
clusters: [
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
{
|
|
18
|
+
name: 'Climate-ADAPT',
|
|
19
|
+
icon: { name: 'file text' },
|
|
20
|
+
values: ['climate'],
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
name: 'Health Observatory',
|
|
24
|
+
icon: { name: 'compass' },
|
|
25
|
+
values: ['observatory'],
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'Mission Portal',
|
|
29
|
+
icon: { name: 'compass' },
|
|
30
|
+
values: ['mission'],
|
|
31
|
+
},
|
|
32
|
+
].map((cluster) => ({
|
|
33
|
+
...cluster,
|
|
34
|
+
defaultResultView: 'ClusterHorizontalCardItem',
|
|
35
|
+
})),
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// console.log('clusters default', clusters, build_runtime_mappings(clusters));
|
|
39
|
+
// console.log(
|
|
40
|
+
// 'clusters mission',
|
|
41
|
+
// clusters_mission,
|
|
42
|
+
// build_runtime_mappings(clusters_mission),
|
|
43
|
+
// );
|
|
44
|
+
|
|
45
|
+
const cca_build_runtime_mappings = {};
|
|
46
|
+
cca_build_runtime_mappings['op_cluster'] = {
|
|
47
|
+
type: 'keyword',
|
|
48
|
+
script: {
|
|
49
|
+
source:
|
|
50
|
+
// "emit('_all_'); if (doc['cca_include_in_search_observatory'][0]) {emit('Health Observatory')} if (doc['cca_include_in_mission.keyword'][0].toString() == 'true') {emit('Mission Portal')} else {emit('Climate-ADAPT')}",
|
|
51
|
+
// "emit('_all_'); if (doc['cca_include_in_search_observatory'][0]) {emit('Health Observatory')} if (doc['cca_include_in_mission.keyword'][0].toString() == 'true' or (doc['id.keyword'].length==1 and doc['id.keyword'][0].toString().indexOf('https://climate-adapt.eea.europa.eu/en/mission')==0)) {emit('Mission Portal')} else {emit('Climate adapt')}",
|
|
52
|
+
// "def objectProvides = ['Adaptation option','Case study','Guidance','Video','Indicator','Information portal','Organisation','Publication reference','Research and knowledge project','Video','Tool'];def vals = doc['objectProvides'];for (defVal in objectProvides) {for (objVal in vals) {if (objVal.contains(defVal)) {emit('Climate-ADAPT')}}}emit('_all_');if (doc['cca_include_in_search_observatory'][0]) {emit('Health Observatory')} if (doc['cca_include_in_mission.keyword'][0].toString() == 'true') {emit('Mission Portal')} else {if (doc['id.keyword'].length==1) { if(doc['id.keyword'][0].toString().contains('climate-adapt.eea.europa.eu/en/mission')) {emit('Mission Portal')}}}",
|
|
53
|
+
"def objectProvides = ['Adaptation option','Case study','Guidance','Video','Indicator','Information portal','Organisation','Publication reference','Research and knowledge project','Video','Tool'];def vals = doc['objectProvides'];for (defVal in objectProvides) {for (objVal in vals) {if (objVal.contains(defVal)) {emit('Climate-ADAPT')}}}emit('_all_');if (doc['cca_include_in_search_observatory'][0]) {for (defVal in objectProvides) {for (objVal in vals) {if (objVal.contains(defVal)){emit('Health Observatory')}}}} if (doc['cca_include_in_mission.keyword'][0].toString() == 'true') {emit('Mission Portal')} else {if (doc['id.keyword'].length==1) { if(doc['id.keyword'][0].toString().contains('climate-adapt.eea.europa.eu/en/mission')) {emit('Mission Portal')}}}",
|
|
54
|
+
},
|
|
23
55
|
};
|
|
24
56
|
|
|
57
|
+
// const mapping = {};
|
|
58
|
+
// mapping[settings.name] = {
|
|
59
|
+
// type: 'keyword',
|
|
60
|
+
// script: { source: source },
|
|
61
|
+
// };
|
|
62
|
+
|
|
25
63
|
export default function installMainSearch(config) {
|
|
26
64
|
const envConfig = ccaConfig;
|
|
27
65
|
|
|
@@ -30,41 +68,56 @@ export default function installMainSearch(config) {
|
|
|
30
68
|
envConfig.app_name = pjson.name;
|
|
31
69
|
envConfig.app_version = pjson.version;
|
|
32
70
|
|
|
71
|
+
// console.log('config.searchui.ccaSearch clusers', clusters);
|
|
72
|
+
// debugger;
|
|
33
73
|
config.searchui.ccaSearch = {
|
|
34
74
|
...mergeConfig(envConfig, config.searchui.globalsearchbase),
|
|
35
75
|
elastic_index: '_es/globalsearch',
|
|
36
76
|
index_name: 'data_searchui',
|
|
37
77
|
host: process.env.RAZZLE_ES_PROXY_ADDR || 'http://localhost:3000',
|
|
38
|
-
runtime_mappings:
|
|
78
|
+
runtime_mappings: cca_build_runtime_mappings,
|
|
39
79
|
...vocabs,
|
|
40
80
|
};
|
|
41
81
|
|
|
42
82
|
const { ccaSearch } = config.searchui;
|
|
43
83
|
|
|
84
|
+
ccaSearch.contentSectionsParams = {
|
|
85
|
+
enable: true,
|
|
86
|
+
sectionFacetsField: 'op_cluster',
|
|
87
|
+
sections: clusters.clusters,
|
|
88
|
+
clusterMapping: Object.assign(
|
|
89
|
+
{},
|
|
90
|
+
...clusters.clusters.map(({ name, values }) =>
|
|
91
|
+
Object.assign({}, ...values.map((v) => ({ [v]: name }))),
|
|
92
|
+
),
|
|
93
|
+
),
|
|
94
|
+
};
|
|
95
|
+
|
|
44
96
|
ccaSearch.permanentFilters.push({
|
|
45
97
|
term: {
|
|
46
98
|
cluster_name: 'cca',
|
|
47
99
|
},
|
|
48
100
|
});
|
|
49
101
|
|
|
50
|
-
ccaSearch.permanentFilters.push({
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
});
|
|
102
|
+
// ccaSearch.permanentFilters.push({
|
|
103
|
+
// terms: {
|
|
104
|
+
// objectProvides: [
|
|
105
|
+
// 'Adaptation option',
|
|
106
|
+
// 'Case study',
|
|
107
|
+
// 'Guidance',
|
|
108
|
+
// 'Video',
|
|
109
|
+
// 'Indicator',
|
|
110
|
+
// 'Information portal',
|
|
111
|
+
// 'Organisation',
|
|
112
|
+
// 'Publication reference',
|
|
113
|
+
// 'Research and knowledge project',
|
|
114
|
+
// 'Tool',
|
|
115
|
+
// ],
|
|
116
|
+
// },
|
|
117
|
+
// });
|
|
66
118
|
|
|
67
119
|
ccaSearch.facets = facets;
|
|
120
|
+
// console.log('ccaSearch.facets', ccaSearch.facets);
|
|
68
121
|
|
|
69
122
|
ccaSearch.initialView.tilesLandingPageParams.sections = [
|
|
70
123
|
{
|
package/src/search/facets.js
CHANGED
|
@@ -18,7 +18,17 @@ const adaptation_sectors = {
|
|
|
18
18
|
showAllOptions: true,
|
|
19
19
|
alwaysVisible: true,
|
|
20
20
|
};
|
|
21
|
-
|
|
21
|
+
const op_cluster = {
|
|
22
|
+
field: 'op_cluster',
|
|
23
|
+
factory: 'MultiTermFacet',
|
|
24
|
+
isFilterable: true,
|
|
25
|
+
isMulti: true,
|
|
26
|
+
label: 'Section',
|
|
27
|
+
show: 10000,
|
|
28
|
+
showInFacetsList: false,
|
|
29
|
+
ignoreNLPWhenActive: true,
|
|
30
|
+
blacklist: ['Others', 'Publications'],
|
|
31
|
+
};
|
|
22
32
|
// const clusters = {
|
|
23
33
|
// field: 'op_cluster',
|
|
24
34
|
// factory: 'MultiTermFacet',
|
|
@@ -113,6 +123,7 @@ const origin_websites = {
|
|
|
113
123
|
const facets = [
|
|
114
124
|
adaptation_sectors,
|
|
115
125
|
// clusters,
|
|
126
|
+
op_cluster,
|
|
116
127
|
objectProvides,
|
|
117
128
|
issued_date,
|
|
118
129
|
climate_impacts,
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
resultViews: [
|
|
3
|
+
{
|
|
4
|
+
id: 'ClusterHorizontalCardItem',
|
|
5
|
+
title: 'Cluster Climate catalogue items',
|
|
6
|
+
icon: 'bars',
|
|
7
|
+
render: null,
|
|
8
|
+
isDefault: true,
|
|
9
|
+
factories: {
|
|
10
|
+
view: 'HorizontalCard.Group',
|
|
11
|
+
item: 'ClusterHorizontalCardItem',
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
],
|
|
15
|
+
};
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { useMapContext } from '@eeacms/volto-openlayers-map/api';
|
|
3
|
-
import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
4
|
-
import FeatureDisplay from './FeatureDisplay';
|
|
5
|
-
import { usePrevious } from '@plone/volto/helpers/Utils/usePrevious';
|
|
6
|
-
|
|
7
|
-
const isCluster = (features) => {
|
|
8
|
-
return features.length > 1 ? true : features[0].values_?.features?.length > 1;
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
export default function InfoOverlay({
|
|
12
|
-
selectedFeature,
|
|
13
|
-
onFeatureSelect,
|
|
14
|
-
layerId,
|
|
15
|
-
hasCusters = false,
|
|
16
|
-
}) {
|
|
17
|
-
const { map } = useMapContext();
|
|
18
|
-
const [tooltip, setTooltipRef] = React.useState();
|
|
19
|
-
const [showTooltip, setShowTooltip] = React.useState();
|
|
20
|
-
|
|
21
|
-
const prevLayerId = usePrevious(layerId);
|
|
22
|
-
|
|
23
|
-
const [isClient, setIsClient] = React.useState(false);
|
|
24
|
-
React.useEffect(() => setIsClient(true), []);
|
|
25
|
-
|
|
26
|
-
React.useEffect(() => {
|
|
27
|
-
if (prevLayerId && layerId !== prevLayerId) {
|
|
28
|
-
setShowTooltip(false);
|
|
29
|
-
}
|
|
30
|
-
}, [layerId, prevLayerId]);
|
|
31
|
-
|
|
32
|
-
React.useEffect(() => {
|
|
33
|
-
if (!(map && tooltip)) return;
|
|
34
|
-
|
|
35
|
-
const overlay = new ol.Overlay({
|
|
36
|
-
element: document.getElementById('popup-overlay'),
|
|
37
|
-
positioning: 'bottom-center',
|
|
38
|
-
offset: [10, -10],
|
|
39
|
-
stopEvent: false,
|
|
40
|
-
});
|
|
41
|
-
map.addOverlay(overlay);
|
|
42
|
-
|
|
43
|
-
function handler(evt) {
|
|
44
|
-
const coordinate = evt.coordinate;
|
|
45
|
-
const { pixel, target } = evt;
|
|
46
|
-
const features = target.getFeaturesAtPixel(pixel);
|
|
47
|
-
|
|
48
|
-
if (features.length && (hasCusters ? !isCluster(features) : true)) {
|
|
49
|
-
overlay.setPosition(coordinate);
|
|
50
|
-
setShowTooltip(true);
|
|
51
|
-
} else {
|
|
52
|
-
// handle a click in an overlay popup
|
|
53
|
-
if (evt.originalEvent.target.tagName === 'A') return;
|
|
54
|
-
setShowTooltip(false);
|
|
55
|
-
onFeatureSelect(null);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
map.on('click', handler);
|
|
60
|
-
|
|
61
|
-
return () => {
|
|
62
|
-
map.un('click', handler);
|
|
63
|
-
map.removeOverlay(overlay);
|
|
64
|
-
};
|
|
65
|
-
}, [map, tooltip, onFeatureSelect, hasCusters]);
|
|
66
|
-
|
|
67
|
-
return isClient ? (
|
|
68
|
-
<div
|
|
69
|
-
id="popup-overlay"
|
|
70
|
-
style={{
|
|
71
|
-
position: 'absolute',
|
|
72
|
-
zIndex: 1,
|
|
73
|
-
visibility: showTooltip ? 'visible' : 'hidden',
|
|
74
|
-
}}
|
|
75
|
-
ref={setTooltipRef}
|
|
76
|
-
>
|
|
77
|
-
{selectedFeature ? <FeatureDisplay feature={selectedFeature} /> : null}
|
|
78
|
-
</div>
|
|
79
|
-
) : null;
|
|
80
|
-
}
|