diff --git a/src/components/manage/Blocks/ArticlesSparql/style.css b/src/components/manage/Blocks/ArticlesSparql/style.css index a992662..db03b71 100644 --- a/src/components/manage/Blocks/ArticlesSparql/style.css +++ b/src/components/manage/Blocks/ArticlesSparql/style.css @@ -6,6 +6,7 @@ align-items: center; height: 250px; justify-content: center; + z-index: 1; } .articles .article { @@ -16,19 +17,30 @@ } .articles .articles-row.can-be-half:last-child { + position: relative; + overflow: hidden; + transform: translateY(-20%); + z-index: 0; -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0))); } + .articles .articles-row.can-be-half:last-child .article { - height: 50%; + position: relative; + transform: translateY(20%); overflow: hidden; -webkit-mask-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0,0,0,1)), to(rgba(0,0,0,0))); } +.articles .article.hero { + align-items: center; +} + .articles .article.hero img { border-radius: 2em; max-height: 200px; + max-width: -webkit-fill-available; width: auto; height: auto; } @@ -73,7 +85,7 @@ } .articles-redirect { - position: absolute; + position: absolute !important; bottom: 7em; left: 50%; transform: translateX(-50%); @@ -83,4 +95,10 @@ .sm-height-fit-content { height: fit-content !important; } +} + +@media (max-width: 768px) { + .articles .articles-row.can-be-half:last-child { + transform: translateY(-10%); + } } \ No newline at end of file diff --git a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx index 357631c..e24eb3e 100644 --- a/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx +++ b/src/components/manage/Blocks/DiscodataOpenlayersMapBlock/View.jsx @@ -24,42 +24,6 @@ import navigationSVG from '@plone/volto/icons/navigation.svg'; import 'ol/ol.css'; import './style.css'; -const pinSVG = (fill = '#000') => { - return ``; -}; - -const factorySVG = () => { - return ``; -}; - -const refinerieSVG = () => { - return ``; -}; - -const nop = () => { - return null; -}; - -const SVG_COLLECTION = { - Chemicals: nop, - 'Electricity and heat production': nop, - 'Extractive industry': nop, - 'Ferrous metal': nop, - 'Food and drink': nop, - 'Fuel processing': nop, - 'Incineration with energy recovery': nop, - Landfill: nop, - Livestock: nop, - 'Non-ferrous metal': nop, - 'Non-metallic minerals': nop, - 'Other manufacturing': nop, - 'Other waste management': nop, - 'Pulp, paper and wood': nop, - Refineries: refinerieSVG, - 'Waste management': nop, - 'Wastewater treatment': nop, -}; - const splitBy = (arr, delimiter) => { if (Array.isArray(arr)) { return ( @@ -78,13 +42,11 @@ let Map, EsriJSON, VectorSource, VectorSourceEvent, - bboxStrategy, XYZ, fromLonLat, toLonLat, toStringHDMS, createXYZ, - Icon, CircleStyle, Fill, Stroke, @@ -132,6 +94,7 @@ const OpenlayersMapView = (props) => { const [loader, setLoader] = useState(false); const [mapRendered, setMapRendered] = useState(false); const [firstFilteringUpdate, setFirstFilteringUpdate] = useState(false); + const selectedSiteCoordinates = useRef(null); const regionsSourceWhere = useRef(''); const firstFilteringDone = useRef(false); const ToggleSidebarControl = useRef(null); @@ -177,13 +140,11 @@ const OpenlayersMapView = (props) => { EsriJSON = require('ol/format/EsriJSON').default; VectorSource = require('ol/source/Vector').default; VectorSourceEvent = require('ol/source/Vector').VectorSourceEvent; - bboxStrategy = require('ol/loadingstrategy').bbox; XYZ = require('ol/source/XYZ').default; fromLonLat = require('ol/proj').fromLonLat; toLonLat = require('ol/proj').toLonLat; toStringHDMS = require('ol/coordinate').toStringHDMS; createXYZ = require('ol/tilegrid').createXYZ; - Icon = require('ol/style/Icon.js').default; CircleStyle = require('ol/style/Circle.js').default; Fill = require('ol/style/Fill.js').default; Stroke = require('ol/style/Stroke.js').default; @@ -259,7 +220,7 @@ const OpenlayersMapView = (props) => { radius: 3, fill: new Fill({ color: '#00FF00' }), stroke: new Stroke({ color: '#6A6A6A', width: 1 }), - zIndex: 0, + zIndex: 1, }), }), ); @@ -274,24 +235,7 @@ const OpenlayersMapView = (props) => { useEffect(() => { if (mapRendered) { updateFilters(); - const baseSql = `(CNTR_CODE LIKE '%:options%')`; - const countries = - props.discodata_query.search.siteCountry?.filter( - (country) => country, - ) || []; - const newRegionsSourceWhere = - countries.length > 0 - ? `(${countries - .map((country) => baseSql.replace(':options', country)) - .join(' OR ')})` - : ''; - if ( - hasRegionsFeatures && - newRegionsSourceWhere !== regionsSourceWhere.current - ) { - regionsSourceWhere.current = newRegionsSourceWhere; - state.map.regionsSourceLayer.getSource().refresh(); - } + updateRegionsFilters(); } /* eslint-disable-next-line */ }, [ @@ -307,26 +251,56 @@ const OpenlayersMapView = (props) => { if (mapRendered) { if (['byLocationTerm', 'bySiteTerm'].includes(state.updateMapPosition)) { onSourceChange(); - } else if ( - state.map.sitesSourceQuery.where !== state.map.oldSitesSourceQuery.where - ) { + } else if (['byAdvancedFilters'].includes(state.updateMapPosition)) { + onSourceChange(); + if (!state.map.sitesSourceLayer.getVisible()) { + state.map.sitesSourceLayer.setVisible(true); + } + if (hasRegionsFeatures && !state.map.regionsSourceLayer.getVisible()) { + state.map.regionsSourceLayer.setVisible(false); + } state.map.sitesSourceLayer && state.map.sitesSourceLayer.getSource().refresh(); } if (!firstFilteringDone.current) { firstFilteringDone.current = true; } + if (!state.updateMapPosition && !state.map.sitesSourceQuery.where) { + applyZoom(); + } } /* eslint-disable-next-line */ }, [state.map.sitesSourceQuery?.where, state.updateMapPosition]) if (mapRendered && !firstFilteringUpdate) { updateFilters(); + updateRegionsFilters(); setFirstFilteringUpdate(true); } + function updateRegionsFilters() { + const baseSql = `(CNTR_CODE LIKE '%:options%')`; + const countries = + props.discodata_query.search.siteCountry?.filter((country) => country) || + []; + const newRegionsSourceWhere = + countries.length > 0 + ? `(${countries + .map((country) => baseSql.replace(':options', country)) + .join(' OR ')})` + : ''; + if ( + hasRegionsFeatures && + newRegionsSourceWhere !== regionsSourceWhere.current + ) { + regionsSourceWhere.current = newRegionsSourceWhere; + state.map.regionsSourceLayer.getSource().refresh(); + } + } + function updateFilters() { const sitesSourceQuery = { ...state.map.sitesSourceQuery }; + let updateMapPosition = null; if (hasSidebar && filterSource === 'eprtr_filters') { sitesSourceQuery.whereStatements = { ...sitesSourceQuery.whereStatements, @@ -417,50 +391,34 @@ const OpenlayersMapView = (props) => { sitesSourceQuery.where = Object.entries(sitesSourceQuery.whereStatements) .map(([id, where]) => where.sql) .join(' AND '); - if ( - sitesSourceQuery.where !== state.map.sitesSourceQuery.where || - locationTerm?.text || - siteTerm - ) { - let updateMapPosition = null; - if ( - filterSource !== 'query_params' && - sitesSourceQuery.where === state.map.sitesSourceQuery.where && - !props.discodata_query.search.advancedFiltering - ) { - if (siteTerm) { + + if (filterSource !== 'query_params') { + if (props.discodata_query.search.advancedFiltering) { + updateMapPosition = 'byAdvancedFilters'; + } else { + if (!siteTerm && !locationTerm?.text) { + updateMapPosition = 'byAdvancedFilters'; + } else if (siteTerm) { updateMapPosition = 'bySiteTerm'; } else if (locationTerm?.text) { updateMapPosition = 'byLocationTerm'; } - } else if ( - filterSource !== 'query_params' && - sitesSourceQuery.where !== state.map.sitesSourceQuery.where && - props.discodata_query.search.advancedFiltering - ) { - updateMapPosition = 'byAdvancedFilters'; - } else if (filterSource === 'query_params') { - if (siteTerm) { - updateMapPosition = 'bySiteTerm'; - } } - if ( - sitesSourceQuery.where !== state.map.sitesSourceQuery.where || - updateMapPosition !== stateRef.current.updateMapPosition - ) { - setState({ - ...state, - map: { - ...state.map, - sitesSourceQuery, - }, - updateMapPosition, - locationTerm, - siteTerm, - }); - } - } else if (!firstFilteringDone.current) { - firstFilteringDone.current = true; + } else if (siteTerm) { + updateMapPosition = 'bySiteTerm'; + } + + if (updateMapPosition) { + setState({ + ...state, + map: { + ...state.map, + sitesSourceQuery, + }, + updateMapPosition, + locationTerm, + siteTerm, + }); } } @@ -513,6 +471,34 @@ const OpenlayersMapView = (props) => { return false; } + function applyZoom() { + if (stateRef.current.map && stateRef.current.map.element) { + const newZoom = stateRef.current.map.element.getView().getZoom(); + if ( + newZoom > zoomSwitch || + stateRef.current.map.sitesSourceQuery?.where + ) { + // if (!stateRef.current.map.sitesSourceLayer.getVisible()) { + // stateRef.current.map.sitesSourceLayer.getSource().refresh(); + // } + stateRef.current.map.sitesSourceLayer.setVisible(true); + hasRegionsFeatures && + stateRef.current.map.regionsSourceLayer.setVisible(false); + } else if (newZoom > 2) { + stateRef.current.map.sitesSourceLayer.setVisible(false); + // if (!stateRef.current.map.regionsSourceLayer.getVisible()) { + // stateRef.current.map.regionsSourceLayer.getSource().refresh(); + // } + hasRegionsFeatures && + stateRef.current.map.regionsSourceLayer.setVisible(true); + } else { + stateRef.current.map.sitesSourceLayer.setVisible(false); + hasRegionsFeatures && + stateRef.current.map.regionsSourceLayer.setVisible(false); + } + } + } + function getLocation(options) { if ( stateRef.current.locationTerm?.text && @@ -564,17 +550,11 @@ const OpenlayersMapView = (props) => { .then((response) => { const data = JSON.parse(response.request.response); const item = data.results?.[0]; - if (item) { - setTimeout(() => { - setSelectedSite( - stateRef.current.map.sitesSourceLayer - .getSource() - .getClosestFeatureToCoordinate([item.x, item.y]), - ); - }, 3000); - + selectedSiteCoordinates.current = [item.x, item.y]; + if (item && item.x && item.y) { + stateRef.current.map.sitesSourceLayer.getSource().refresh(); stateRef.current.map.element.getView().animate({ - center: [item.x, item.y], + center: selectedSiteCoordinates.current, duration: filterSource !== 'query_params' ? 1000 : 0, zoom: 15, }); @@ -584,30 +564,58 @@ const OpenlayersMapView = (props) => { } } + function getLocationByAdvancedFilters(options) { + axios + .get( + encodeURI( + `${settings.providerUrl}?query=SELECT + MIN(shape_wm.STX) AS MIN_X, + MIN(shape_wm.STY) AS MIN_Y, + MAX(shape_wm.STX) AS MAX_X, + MAX(shape_wm.STY) AS MAX_Y + FROM [IED].[latest].[SiteMap] + ${ + stateRef.current.map.sitesSourceQuery.where + ? 'WHERE ' + stateRef.current.map.sitesSourceQuery.where + : '' + }`, + ), + ) + .then((response) => { + const data = JSON.parse(response.request.response); + const extent = data.results?.[0]; + if (stateRef.current.map.sitesSourceQuery?.where) { + stateRef.current.map.element + .getView() + .fit([extent.MIN_X, extent.MIN_Y, extent.MAX_X, extent.MAX_Y], { + maxZoom: 15, + }); + } + }) + .catch((error) => {}); + } + function onSourceChange() { const options = { duration: 2000, maxZoom: 15, }; if (stateRef.current.updateMapPosition === 'bySiteTerm') { + stateRef.current.map.element.getView().cancelAnimations(); getSiteTermLocation(options); } if (stateRef.current.updateMapPosition === 'byLocationTerm') { + stateRef.current.map.element.getView().cancelAnimations(); setSelectedSite(null); getLocation(options); } if (stateRef.current.updateMapPosition === 'byAdvancedFilters') { + stateRef.current.map.element.getView().cancelAnimations(); setSelectedSite(null); - stateRef.current.map.element - .getView() - .fit(stateRef.current.map.sitesSourceLayer.getSource().getExtent()); + getLocationByAdvancedFilters(options); } // UPDATE OLD FILTERS - if ( - stateRef.current.map.sitesSourceQuery.where !== - stateRef.current.map.oldSitesSourceQuery.where || - stateRef.current.updateMapPosition !== null - ) { + if (stateRef.current.updateMapPosition !== null) { setState({ ...stateRef.current, map: { @@ -795,9 +803,8 @@ const OpenlayersMapView = (props) => { if (features.length > 0) { sitesSource.addFeatures(features); } - sitesSource.dispatchEvent( - new VectorSourceEvent('updateFilters'), + new VectorSourceEvent('updateClosestFeature'), ); } }, @@ -929,7 +936,11 @@ const OpenlayersMapView = (props) => { }), ); // Center by user location - if (navigator.geolocation && filterSource !== 'query_params') { + if ( + navigator.geolocation && + filterSource !== 'query_params' && + !stateRef.current.updateMapPosition + ) { navigator.geolocation.getCurrentPosition( (position) => { return centerPosition(map, position, 12); @@ -940,9 +951,16 @@ const OpenlayersMapView = (props) => { ); } // Events - sitesSource.on('updateFilters', function (e) { + sitesSource.on('updateClosestFeature', function (e) { if (!reqs && e.target.getState() === 'ready') { - onSourceChange(); + if (selectedSiteCoordinates.current) { + const closestFeature = sitesSource.getClosestFeatureToCoordinate( + selectedSiteCoordinates.current, + ); + closestFeature.setStyle(); + setSelectedSite(closestFeature); + selectedSiteCoordinates.current = null; + } } }); if (hasPopups) { @@ -985,19 +1003,7 @@ const OpenlayersMapView = (props) => { } let newZoom = map.getView().getZoom(); if (currentZoom !== newZoom) { - if (newZoom > zoomSwitch) { - if (!sitesSourceLayer.getVisible()) { - sitesSourceLayer.getSource().refresh(); - } - sitesSourceLayer.setVisible(true); - hasRegionsFeatures && regionsSourceLayer.setVisible(false); - } else if (newZoom > 2) { - sitesSourceLayer.setVisible(false); - hasRegionsFeatures && regionsSourceLayer.setVisible(true); - } else { - sitesSourceLayer.setVisible(false); - hasRegionsFeatures && regionsSourceLayer.setVisible(false); - } + applyZoom(); currentZoom = newZoom; } props.setQueryParam({