@eeacms/volto-cca-policy 0.3.46 → 0.3.48
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 +28 -0
- package/jest-addon.config.js +421 -6
- package/package.json +2 -2
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.jsx +7 -5
- package/src/components/manage/Blocks/CaseStudyExplorer/CaseStudyMap.test.jsx +17 -0
- package/src/components/manage/Blocks/CaseStudyExplorer/FeatureInteraction.jsx +8 -7
- package/src/components/manage/Blocks/CaseStudyExplorer/useInteractiveStyles.jsx +37 -31
- package/src/components/manage/Blocks/CaseStudyExplorer/utils.js +1 -3
- package/src/components/manage/Blocks/CountryMapObservatory/CountryMapObservatoryOLView.jsx +5 -4
- package/src/components/manage/Blocks/CountryMapObservatory/mapstyle.js +3 -5
- package/src/components/manage/Blocks/index.js +7 -6
- package/src/components/theme/MissionSignatoryProfile/MissionSignatoryProfileView.jsx +14 -3
- package/src/components/theme/MissionSignatoryProfile/MissionSignatoryProfileView.test.jsx +16 -5
- package/src/index.js +2 -2
- package/theme/globals/mission.less +13 -0
- package/src/components/manage/Blocks/MKHMap/Edit.jsx +0 -29
- package/src/components/manage/Blocks/MKHMap/FeatureDisplay.jsx +0 -87
- package/src/components/manage/Blocks/MKHMap/FeatureInteraction.jsx +0 -56
- package/src/components/manage/Blocks/MKHMap/InfoOverlay.jsx +0 -80
- package/src/components/manage/Blocks/MKHMap/View.jsx +0 -118
- package/src/components/manage/Blocks/MKHMap/index.js +0 -25
- package/src/components/manage/Blocks/MKHMap/layers.js +0 -107
- package/src/components/manage/Blocks/MKHMap/map.svg +0 -3
- package/src/components/manage/Blocks/MKHMap/schema.js +0 -15
- package/src/components/manage/Blocks/MKHMap/styles.less +0 -41
- package/src/components/manage/Blocks/MKHMap/useWhyDidYouUpdate.js +0 -33
- package/src/components/theme/MissionSignatoryProfile/TabSections/IntroductionTab.jsx +0 -37
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
3
2
|
const _cached = {};
|
|
4
3
|
|
|
5
|
-
function getStyle(size, haveAdaptecca) {
|
|
4
|
+
function getStyle(size, haveAdaptecca, ol) {
|
|
6
5
|
let style = _cached[size + '_' + haveAdaptecca];
|
|
7
6
|
|
|
8
7
|
if (!style) {
|
|
@@ -41,26 +40,29 @@ function getStyle(size, haveAdaptecca) {
|
|
|
41
40
|
return style;
|
|
42
41
|
}
|
|
43
42
|
|
|
44
|
-
export function useStyles() {
|
|
45
|
-
const selectStyle = React.useCallback(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
export function useStyles(ol) {
|
|
44
|
+
const selectStyle = React.useCallback(
|
|
45
|
+
(feature) => {
|
|
46
|
+
const selected = new ol.style.Style({
|
|
47
|
+
image: new ol.style.Circle({
|
|
48
|
+
radius: 12,
|
|
49
|
+
fill: new ol.style.Fill({
|
|
50
|
+
color: '#005c96',
|
|
51
|
+
}),
|
|
52
|
+
stroke: new ol.style.Stroke({
|
|
53
|
+
color: 'rgba(0, 92, 150, 0.9)',
|
|
54
|
+
width: 2,
|
|
55
|
+
}),
|
|
55
56
|
}),
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
57
|
+
});
|
|
58
|
+
// const color = feature.get('COLOR') || '#eeeeee';
|
|
59
|
+
// selected.getFill().setColor(color);
|
|
60
|
+
const color = feature.values_.features[0].values_['color'] || '#ccc';
|
|
61
|
+
selected.image_.getFill().setColor(color);
|
|
62
|
+
return selected;
|
|
63
|
+
},
|
|
64
|
+
[ol],
|
|
65
|
+
);
|
|
64
66
|
|
|
65
67
|
const convexHullStroke = React.useMemo(
|
|
66
68
|
() =>
|
|
@@ -68,7 +70,7 @@ export function useStyles() {
|
|
|
68
70
|
color: 'rgba(204, 85, 0, 1)',
|
|
69
71
|
width: 1.5,
|
|
70
72
|
}),
|
|
71
|
-
[],
|
|
73
|
+
[ol],
|
|
72
74
|
);
|
|
73
75
|
|
|
74
76
|
const clusterMemberStyle = React.useMemo(() => {
|
|
@@ -85,7 +87,7 @@ export function useStyles() {
|
|
|
85
87
|
});
|
|
86
88
|
};
|
|
87
89
|
return _clusterMemberStyle;
|
|
88
|
-
}, []);
|
|
90
|
+
}, [ol]);
|
|
89
91
|
|
|
90
92
|
const clusterCircleStyle = React.useCallback(
|
|
91
93
|
(cluster, resolution) => {
|
|
@@ -135,7 +137,7 @@ export function useStyles() {
|
|
|
135
137
|
return styles;
|
|
136
138
|
}, []);
|
|
137
139
|
},
|
|
138
|
-
[convexHullStroke, clusterMemberStyle],
|
|
140
|
+
[convexHullStroke, clusterMemberStyle, ol],
|
|
139
141
|
);
|
|
140
142
|
|
|
141
143
|
return { clusterCircleStyle, selectStyle };
|
|
@@ -169,16 +171,20 @@ export function generatePointsCircle(count, clusterCenter, resolution) {
|
|
|
169
171
|
|
|
170
172
|
return res;
|
|
171
173
|
}
|
|
172
|
-
export function clusterStyle(feature) {
|
|
173
|
-
const size = feature.get('features').length;
|
|
174
|
-
const cases = feature
|
|
175
|
-
.get('features')
|
|
176
|
-
.filter((_case) => _case['values_']['origin_adaptecca'] < 20);
|
|
177
174
|
|
|
178
|
-
|
|
175
|
+
export function clusterStyle(ol) {
|
|
176
|
+
function _closure(feature) {
|
|
177
|
+
const size = feature.get('features').length;
|
|
178
|
+
const cases = feature
|
|
179
|
+
.get('features')
|
|
180
|
+
.filter((_case) => _case['values_']['origin_adaptecca'] < 20);
|
|
181
|
+
|
|
182
|
+
return getStyle(size, cases.length > 0 ? 1 : 0, ol);
|
|
183
|
+
}
|
|
184
|
+
return _closure;
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
export function getExtentOfFeatures(features) {
|
|
187
|
+
export function getExtentOfFeatures(features, ol) {
|
|
182
188
|
const points = features.map((f) => f.getGeometry().flatCoordinates);
|
|
183
189
|
const point = new ol.geom.MultiPoint(points);
|
|
184
190
|
return point.getExtent();
|
|
@@ -4,8 +4,8 @@ import { compose } from 'redux';
|
|
|
4
4
|
import { clientOnly } from '@eeacms/volto-cca-policy/helpers';
|
|
5
5
|
import { useHistory } from 'react-router-dom';
|
|
6
6
|
|
|
7
|
+
import { withOpenLayers } from '@eeacms/volto-openlayers-map';
|
|
7
8
|
import { Map, Layer, Layers, Controls } from '@eeacms/volto-openlayers-map/api';
|
|
8
|
-
import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
9
9
|
import {
|
|
10
10
|
euCountryNames,
|
|
11
11
|
tooltipStyle,
|
|
@@ -24,10 +24,10 @@ import './styles.less';
|
|
|
24
24
|
// 'https://raw.githubusercontent.com/eurostat/Nuts2json/master/pub/v2/2021/4326/20M/cntrg.json';
|
|
25
25
|
|
|
26
26
|
const CountryMapObservatoryView = (props) => {
|
|
27
|
-
const { geofeatures, projection } = props;
|
|
27
|
+
const { geofeatures, projection, ol } = props;
|
|
28
28
|
|
|
29
29
|
const history = useHistory();
|
|
30
|
-
const styles = React.useMemo(makeStyles, []);
|
|
30
|
+
const styles = React.useMemo(() => makeStyles(ol), [ol]);
|
|
31
31
|
const tooltipRef = React.useRef();
|
|
32
32
|
const [tileWMSSources, setTileWMSSources] = React.useState();
|
|
33
33
|
const [overlaySource, setOverlaySource] = React.useState();
|
|
@@ -75,7 +75,7 @@ const CountryMapObservatoryView = (props) => {
|
|
|
75
75
|
transition: 0,
|
|
76
76
|
}),
|
|
77
77
|
]);
|
|
78
|
-
}, [geofeatures]);
|
|
78
|
+
}, [geofeatures, ol]);
|
|
79
79
|
|
|
80
80
|
const baseUrl = getBaseUrl(props);
|
|
81
81
|
|
|
@@ -131,4 +131,5 @@ export default compose(
|
|
|
131
131
|
withGeoJsonData,
|
|
132
132
|
withResponsiveContainer('countryMapObservatory'),
|
|
133
133
|
withVisibilitySensor(),
|
|
134
|
+
withOpenLayers,
|
|
134
135
|
)(CountryMapObservatoryView);
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
const flagRenderer = ({ stroke, fill }) => (pixelCoordinates, state) => {
|
|
1
|
+
const flagRenderer = ({ stroke, fill, ol }) => (pixelCoordinates, state) => {
|
|
4
2
|
const context = state.context;
|
|
5
3
|
const geometry = state.geometry.clone();
|
|
6
4
|
geometry.setCoordinates(pixelCoordinates);
|
|
@@ -29,7 +27,7 @@ const flagRenderer = ({ stroke, fill }) => (pixelCoordinates, state) => {
|
|
|
29
27
|
context.restore();
|
|
30
28
|
};
|
|
31
29
|
|
|
32
|
-
export const makeStyles = () => {
|
|
30
|
+
export const makeStyles = (ol) => {
|
|
33
31
|
const fill = new ol.style.Fill();
|
|
34
32
|
const stroke = new ol.style.Stroke({
|
|
35
33
|
// color: 'rgba(255,255,255,0.8)',
|
|
@@ -45,7 +43,7 @@ export const makeStyles = () => {
|
|
|
45
43
|
fill: new ol.style.Fill({
|
|
46
44
|
color: 'rgb(1, 112, 183, 0.8)',
|
|
47
45
|
}),
|
|
48
|
-
renderer: flagRenderer({ fill, stroke }),
|
|
46
|
+
renderer: flagRenderer({ fill, stroke, ol }),
|
|
49
47
|
});
|
|
50
48
|
|
|
51
49
|
const eucountriesStyle = new ol.style.Style({
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { compose } from 'redux';
|
|
2
2
|
|
|
3
|
-
// import installMKHMap from './MKHMap';
|
|
4
3
|
import installECDEIndicatorsBlock from './ECDEIndicators';
|
|
5
4
|
import installCaseStudyExplorerBlock from './CaseStudyExplorer';
|
|
6
5
|
import installSearchAceContent from './SearchAceContent';
|
|
@@ -8,8 +7,6 @@ import installRelevantAceContent from './RelevantAceContent';
|
|
|
8
7
|
import installFilterAceContent from './FilterAceContent';
|
|
9
8
|
import installTransRegionSelect from './TransRegionSelect';
|
|
10
9
|
import installCountryMapObservatory from './CountryMapObservatory';
|
|
11
|
-
import installCountryMapHeatIndex from './CountryMapHeatIndex';
|
|
12
|
-
import installCountryMapProfile from './CountryMapProfile';
|
|
13
10
|
import installCountryProfileDetail from './CountryProfileDetail';
|
|
14
11
|
import installListing from './Listing';
|
|
15
12
|
import installRAST from './RASTBlock';
|
|
@@ -23,6 +20,10 @@ import installRedirectBlock from './RedirectBlock';
|
|
|
23
20
|
import installContentLinks from './ContentLinks';
|
|
24
21
|
import installASTNavigation from './ASTNavigation';
|
|
25
22
|
|
|
23
|
+
// import installMKHMap from './MKHMap';
|
|
24
|
+
// import installCountryMapHeatIndex from './CountryMapHeatIndex';
|
|
25
|
+
// import installCountryMapProfile from './CountryMapProfile';
|
|
26
|
+
|
|
26
27
|
export default function installBlocks(config) {
|
|
27
28
|
config.blocks.blocksConfig.title.restricted = false;
|
|
28
29
|
config.blocks.blocksConfig.layoutSettings.restricted = false;
|
|
@@ -36,12 +37,9 @@ export default function installBlocks(config) {
|
|
|
36
37
|
installC3SIndicatorsOverviewBlock,
|
|
37
38
|
installC3SIndicatorsListingBlock,
|
|
38
39
|
installC3SIndicatorsGlossaryBlock,
|
|
39
|
-
// installMKHMap,
|
|
40
40
|
installECDEIndicatorsBlock,
|
|
41
41
|
installCaseStudyExplorerBlock,
|
|
42
42
|
installCountryMapObservatory,
|
|
43
|
-
installCountryMapHeatIndex,
|
|
44
|
-
installCountryMapProfile,
|
|
45
43
|
installCountryProfileDetail,
|
|
46
44
|
installSearchAceContent,
|
|
47
45
|
installRelevantAceContent,
|
|
@@ -53,5 +51,8 @@ export default function installBlocks(config) {
|
|
|
53
51
|
installRedirectBlock,
|
|
54
52
|
installContentLinks,
|
|
55
53
|
installASTNavigation,
|
|
54
|
+
// installMKHMap,
|
|
55
|
+
// installCountryMapHeatIndex,
|
|
56
|
+
// installCountryMapProfile,
|
|
56
57
|
)(config);
|
|
57
58
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { Link } from 'react-router-dom';
|
|
3
|
+
import { Tab, Container, Divider, Button, Icon } from 'semantic-ui-react';
|
|
3
4
|
import { formatTextToHTML } from '@eeacms/volto-cca-policy/utils';
|
|
4
5
|
import { BannerTitle, HTMLField } from '@eeacms/volto-cca-policy/helpers';
|
|
6
|
+
import { flattenToAppURL } from '@plone/volto/helpers';
|
|
5
7
|
|
|
6
8
|
import GovernanceTab from './TabSections/GovernanceTab';
|
|
7
9
|
import AssessmentTab from './TabSections/AssessmentTab';
|
|
@@ -29,6 +31,9 @@ const MissionSignatoryProfileView = ({ content }) => {
|
|
|
29
31
|
general_text = [{}],
|
|
30
32
|
} = signatoryData;
|
|
31
33
|
|
|
34
|
+
const { Back_To_Map_Link, Country_Or_Area } = general_text?.[0] || {};
|
|
35
|
+
const backToMapPath = flattenToAppURL(content?.parent?.['@id'] || '/');
|
|
36
|
+
|
|
32
37
|
const [activeIndex, setActiveIndex] = React.useState(0);
|
|
33
38
|
|
|
34
39
|
const tabData = {
|
|
@@ -60,12 +65,18 @@ const MissionSignatoryProfileView = ({ content }) => {
|
|
|
60
65
|
hidePublishingDate: true,
|
|
61
66
|
hideDownloadButton: false,
|
|
62
67
|
hideShareButton: false,
|
|
63
|
-
subtitle:
|
|
68
|
+
subtitle: Country_Or_Area,
|
|
64
69
|
}}
|
|
65
70
|
/>
|
|
66
71
|
|
|
67
72
|
<div className="signatory-profile">
|
|
68
|
-
<
|
|
73
|
+
<Link to={backToMapPath}>
|
|
74
|
+
<Button icon inverted primary className="left labeled back-to-map">
|
|
75
|
+
<Icon className="chevron left icon" />
|
|
76
|
+
{Back_To_Map_Link || 'Back to Signatories map'}
|
|
77
|
+
</Button>
|
|
78
|
+
</Link>
|
|
79
|
+
|
|
69
80
|
<Tab
|
|
70
81
|
menu={{
|
|
71
82
|
fluid: true,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { render, fireEvent, screen } from '@testing-library/react';
|
|
2
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
2
3
|
import '@testing-library/jest-dom';
|
|
3
4
|
import MissionSignatoryProfileView from './MissionSignatoryProfileView';
|
|
4
5
|
|
|
@@ -38,15 +39,25 @@ describe('MissionSignatoryProfileView', () => {
|
|
|
38
39
|
{ key: 'Action_Label', value: 'Action' },
|
|
39
40
|
{ key: 'Language', value: 'en' },
|
|
40
41
|
],
|
|
42
|
+
general_text: [
|
|
43
|
+
{
|
|
44
|
+
Back_To_Map_Link: 'Back to map',
|
|
45
|
+
Country_Or_Area: 'Testland',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
41
48
|
},
|
|
42
49
|
},
|
|
43
50
|
},
|
|
51
|
+
parent: {
|
|
52
|
+
'@id': '/signatories-map',
|
|
53
|
+
},
|
|
44
54
|
};
|
|
45
55
|
|
|
56
|
+
const renderWithRouter = (ui) => render(<MemoryRouter>{ui}</MemoryRouter>);
|
|
57
|
+
|
|
46
58
|
it('renders tab labels and default content', () => {
|
|
47
|
-
|
|
59
|
+
renderWithRouter(<MissionSignatoryProfileView content={content} />);
|
|
48
60
|
|
|
49
|
-
// Tab labels
|
|
50
61
|
expect(screen.getByText('Governance')).toBeInTheDocument();
|
|
51
62
|
expect(screen.getByText('Assessment')).toBeInTheDocument();
|
|
52
63
|
expect(screen.getByText('Planning & Target')).toBeInTheDocument();
|
|
@@ -54,7 +65,7 @@ describe('MissionSignatoryProfileView', () => {
|
|
|
54
65
|
});
|
|
55
66
|
|
|
56
67
|
it('switches tabs and renders corresponding content', () => {
|
|
57
|
-
|
|
68
|
+
renderWithRouter(<MissionSignatoryProfileView content={content} />);
|
|
58
69
|
|
|
59
70
|
fireEvent.click(screen.getByText('Governance'));
|
|
60
71
|
expect(screen.getByText('Mocked Governance')).toBeInTheDocument();
|
|
@@ -70,10 +81,10 @@ describe('MissionSignatoryProfileView', () => {
|
|
|
70
81
|
});
|
|
71
82
|
|
|
72
83
|
it('renders footer disclaimer text if present', () => {
|
|
73
|
-
|
|
84
|
+
renderWithRouter(<MissionSignatoryProfileView content={content} />);
|
|
74
85
|
expect(screen.getByText('Disclaimer Title')).toBeInTheDocument();
|
|
75
86
|
expect(
|
|
76
|
-
screen.getByText((
|
|
87
|
+
screen.getByText((text) => text.includes('This is a disclaimer.')),
|
|
77
88
|
).toBeInTheDocument();
|
|
78
89
|
});
|
|
79
90
|
});
|
package/src/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import C3SIndicatorView from './components/theme/Views/C3SIndicatorView';
|
|
|
22
22
|
import DatabaseItemView from './components/theme/Views/DatabaseItemView';
|
|
23
23
|
|
|
24
24
|
import GeocharsWidget from './components/theme/Widgets/GeocharsWidget';
|
|
25
|
-
import GeolocationWidget from './components/theme/Widgets/GeolocationWidget';
|
|
25
|
+
// import GeolocationWidget from './components/theme/Widgets/GeolocationWidget';
|
|
26
26
|
import PromotionalImageWidget from './components/theme/Widgets/PromotionalImageWidget';
|
|
27
27
|
import MigrationButtons from './components/MigrationButtons';
|
|
28
28
|
import HealthHorizontalCardItem from './components/Result/HealthHorizontalCardItem';
|
|
@@ -429,7 +429,7 @@ const applyConfig = (config) => {
|
|
|
429
429
|
};
|
|
430
430
|
// Custom widgets
|
|
431
431
|
config.widgets.id.geochars = GeocharsWidget;
|
|
432
|
-
config.widgets.id.geolocation = GeolocationWidget;
|
|
432
|
+
// config.widgets.id.geolocation = GeolocationWidget;
|
|
433
433
|
config.widgets.id.promotional_image = PromotionalImageWidget;
|
|
434
434
|
|
|
435
435
|
if (config.widgets.views?.widget) {
|
|
@@ -123,6 +123,19 @@ body.subsite-mkh {
|
|
|
123
123
|
margin: 2em 0 !important;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
+
.ui.inverted.button.back-to-map {
|
|
127
|
+
margin-bottom: 2em;
|
|
128
|
+
box-shadow: 0px 0px 0px 2px @pineGreen inset !important;
|
|
129
|
+
color: @pineGreen;
|
|
130
|
+
|
|
131
|
+
&:hover,
|
|
132
|
+
&:active,
|
|
133
|
+
&:focus,
|
|
134
|
+
&:focus-visible {
|
|
135
|
+
background-color: @pineGreen;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
126
139
|
.column > .ui.segment {
|
|
127
140
|
background-color: #fff !important;
|
|
128
141
|
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { SidebarPortal } from '@plone/volto/components';
|
|
3
|
-
import InlineForm from '@plone/volto/components/manage/Form/InlineForm';
|
|
4
|
-
import schema from './schema';
|
|
5
|
-
import View from './View';
|
|
6
|
-
|
|
7
|
-
const Edit = (props) => {
|
|
8
|
-
return (
|
|
9
|
-
<>
|
|
10
|
-
<View {...props} mode="edit" />
|
|
11
|
-
|
|
12
|
-
<SidebarPortal selected={props.selected}>
|
|
13
|
-
<InlineForm
|
|
14
|
-
schema={schema}
|
|
15
|
-
title={schema.title}
|
|
16
|
-
onChangeField={(id, value) => {
|
|
17
|
-
props.onChangeBlock(props.block, {
|
|
18
|
-
...props.data,
|
|
19
|
-
[id]: value,
|
|
20
|
-
});
|
|
21
|
-
}}
|
|
22
|
-
formData={props.data}
|
|
23
|
-
/>
|
|
24
|
-
</SidebarPortal>
|
|
25
|
-
</>
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default Edit;
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { UniversalLink } from '@plone/volto/components';
|
|
3
|
-
|
|
4
|
-
// {
|
|
5
|
-
// "feature": {
|
|
6
|
-
// "OBJECTID": 39,
|
|
7
|
-
// "CNTR_CODE": "PL",
|
|
8
|
-
// "CNTR_NAME": "Poland",
|
|
9
|
-
// "NUTS_ID": "PL9",
|
|
10
|
-
// "NUTS_Name_Excel": "Mazovia (Mazowieckie)",
|
|
11
|
-
// "NAME_LATN": "Makroregion województwo mazowieckie",
|
|
12
|
-
// "NUTS_NAME": "Makroregion województwo mazowieckie",
|
|
13
|
-
// "LEVEL_CODE": "NUTS 1",
|
|
14
|
-
// "Comments": null,
|
|
15
|
-
// "CNTR_FLAG": "https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/4.1.4/flags/4x3/pl.svg",
|
|
16
|
-
// "BIOGEO_REG_CODE": "Continental",
|
|
17
|
-
// "BIOGEO_REG_NAME": "Continental Bio-geographical Region",
|
|
18
|
-
// "_maxOverlap": 35559453062.672485,
|
|
19
|
-
// "BIOGEO_NUTS_AREA": "100",
|
|
20
|
-
// "SHAPE_Length": 1473687.3485873593,
|
|
21
|
-
// "SHAPE_Area": 35559453062.672424
|
|
22
|
-
// }
|
|
23
|
-
// }
|
|
24
|
-
|
|
25
|
-
const NutsRegion = ({ feature }) => {
|
|
26
|
-
const fields = [
|
|
27
|
-
['Name', 'NUTS_NAME'],
|
|
28
|
-
['Country', 'CNTR_NAME'],
|
|
29
|
-
['NUTS level', 'LEVEL_CODE'],
|
|
30
|
-
['NUTS ID', 'NUTS_ID'],
|
|
31
|
-
['Bioregion', 'BIOGEO_REG_NAME'],
|
|
32
|
-
['Area', 'SHAPE_Area'],
|
|
33
|
-
];
|
|
34
|
-
return <FieldsDisplay feature={feature} fields={fields} />;
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const FieldsDisplay = ({ feature, fields }) => (
|
|
38
|
-
<dl className="feature-info">
|
|
39
|
-
{fields.map(([label, name]) => (
|
|
40
|
-
<div key={name}>
|
|
41
|
-
<dt>{label}</dt>
|
|
42
|
-
<dd>{feature[name]}</dd>
|
|
43
|
-
</div>
|
|
44
|
-
))}
|
|
45
|
-
</dl>
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
// {
|
|
49
|
-
// "feature": {
|
|
50
|
-
// "OBJECTID": 61,
|
|
51
|
-
// "CNTR_NAME": "Lithuania",
|
|
52
|
-
// "CNTR_CODE": "LT",
|
|
53
|
-
// "LEVEL_CODE": "LAU",
|
|
54
|
-
// "GISCO_ID": "LT_27",
|
|
55
|
-
// "LAU_ID": "27",
|
|
56
|
-
// "LAU_NAME": "Panevėžio miesto savivaldybė",
|
|
57
|
-
// "LAU_Name_Excel": "Panevėžys",
|
|
58
|
-
// "Aggregated": "*",
|
|
59
|
-
// "Value0": null,
|
|
60
|
-
// "CNTR_FLAG": "https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/4.1.4/flags/4x3/lt.svg"
|
|
61
|
-
// }
|
|
62
|
-
// }
|
|
63
|
-
|
|
64
|
-
const City = ({ feature }) => {
|
|
65
|
-
const fields = [
|
|
66
|
-
['Name', 'LAU_NAME'],
|
|
67
|
-
['Country', 'CNTR_NAME'],
|
|
68
|
-
['Level', 'LEVEL_CODE'],
|
|
69
|
-
['GISCO ID', 'GISCO_ID'],
|
|
70
|
-
];
|
|
71
|
-
return <FieldsDisplay feature={feature} fields={fields} />;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export default function FeatureDisplay({ feature }) {
|
|
75
|
-
return feature ? (
|
|
76
|
-
<div>
|
|
77
|
-
{feature.NUTS_ID ? (
|
|
78
|
-
<NutsRegion feature={feature} />
|
|
79
|
-
) : (
|
|
80
|
-
<City feature={feature} />
|
|
81
|
-
)}
|
|
82
|
-
<UniversalLink href={`/en/mkh/${feature.NUTS_ID || feature.GISCO_ID}`}>
|
|
83
|
-
Visit
|
|
84
|
-
</UniversalLink>
|
|
85
|
-
</div>
|
|
86
|
-
) : null;
|
|
87
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { openlayers as ol } from '@eeacms/volto-openlayers-map';
|
|
3
|
-
import { useMapContext } from '@eeacms/volto-openlayers-map/api';
|
|
4
|
-
|
|
5
|
-
export default function FeatureInteraction({ onFeatureSelect }) {
|
|
6
|
-
const { map } = useMapContext();
|
|
7
|
-
|
|
8
|
-
const selected = React.useMemo(
|
|
9
|
-
() =>
|
|
10
|
-
new ol.style.Style({
|
|
11
|
-
fill: new ol.style.Fill({
|
|
12
|
-
color: '#cccccc',
|
|
13
|
-
}),
|
|
14
|
-
stroke: new ol.style.Stroke({
|
|
15
|
-
color: 'rgba(255, 0, 0, 0.7)',
|
|
16
|
-
width: 2,
|
|
17
|
-
}),
|
|
18
|
-
}),
|
|
19
|
-
[],
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
const selectStyle = React.useCallback(
|
|
23
|
-
(feature) => {
|
|
24
|
-
const color = feature.get('COLOR') || '#eeeeee';
|
|
25
|
-
selected.getFill().setColor(color);
|
|
26
|
-
return selected;
|
|
27
|
-
},
|
|
28
|
-
[selected],
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
React.useEffect(() => {
|
|
32
|
-
if (!map) return;
|
|
33
|
-
const select = new ol.interaction.Select({
|
|
34
|
-
condition: ol.condition.click,
|
|
35
|
-
style: selectStyle,
|
|
36
|
-
});
|
|
37
|
-
map.addInteraction(select);
|
|
38
|
-
select.on('select', function (e) {
|
|
39
|
-
const features = e.target.getFeatures().getArray();
|
|
40
|
-
features.forEach((feature) => {
|
|
41
|
-
onFeatureSelect(feature.values_);
|
|
42
|
-
});
|
|
43
|
-
// if (!features.length) onFeatureSelect(null);
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
map.on('pointermove', (e) => {
|
|
47
|
-
const pixel = map.getEventPixel(e.originalEvent);
|
|
48
|
-
const hit = map.hasFeatureAtPixel(pixel);
|
|
49
|
-
map.getViewport().style.cursor = hit ? 'pointer' : '';
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
return () => map.removeInteraction(select);
|
|
53
|
-
}, [map, selectStyle, onFeatureSelect]);
|
|
54
|
-
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
@@ -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
|
-
}
|