@eeacms/volto-arcgis-block
Advanced tools
Comparing version 0.1.40 to 0.1.41
@@ -7,4 +7,16 @@ ### Changelog | ||
#### [0.1.41](https://github.com/eea/volto-arcgis-block/compare/0.1.40...0.1.41) | ||
- Ux improvements [`#129`](https://github.com/eea/volto-arcgis-block/pull/129) | ||
- Use cases [`#128`](https://github.com/eea/volto-arcgis-block/pull/128) | ||
- ESLint fix [`f0b6fa1`](https://github.com/eea/volto-arcgis-block/commit/f0b6fa10a5077af8ff22adec5ea1480a0d18a569) | ||
- Measurement and opacity [`49483b1`](https://github.com/eea/volto-arcgis-block/commit/49483b12f777e7b0887abeb57f94a607fe6aeeb2) | ||
- ESLint fix [`779dfd8`](https://github.com/eea/volto-arcgis-block/commit/779dfd89eea1ca7ada41cc9bfc9f9a106d30f6cc) | ||
- Legend and link [`56019f0`](https://github.com/eea/volto-arcgis-block/commit/56019f095f2d2d2420c492e8b93e335261325933) | ||
#### [0.1.40](https://github.com/eea/volto-arcgis-block/compare/0.1.39...0.1.40) | ||
> 29 April 2022 | ||
- Develop [`#127`](https://github.com/eea/volto-arcgis-block/pull/127) | ||
- Timeslider icon [`#126`](https://github.com/eea/volto-arcgis-block/pull/126) | ||
@@ -11,0 +23,0 @@ - Hide opacity icon [`#125`](https://github.com/eea/volto-arcgis-block/pull/125) |
{ | ||
"name": "@eeacms/volto-arcgis-block", | ||
"version": "0.1.40", | ||
"version": "0.1.41", | ||
"description": "volto-arcgis-block: Volto add-on", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
@@ -48,8 +48,3 @@ import React, { createRef } from 'react'; | ||
this.setState({ showMapMenu: false }); | ||
this.container.current | ||
.querySelector('.active') | ||
.classList.remove('active'); | ||
this.container.current | ||
.querySelector('.esri-icon-measure-area') | ||
.classList.add('active'); | ||
this.toggleDropdownContent(); | ||
this.clearMeasurements(); | ||
@@ -71,26 +66,76 @@ this.clearCoordinates(); | ||
this.areaMeasurement(); | ||
document | ||
.querySelector('#measurement_area .ccl-expandable__button') | ||
.nextElementSibling.appendChild( | ||
document.querySelector('.measurement-area'), | ||
); | ||
document | ||
.querySelector('.measurement-dropdown .ccl-expandable__button') | ||
.setAttribute('aria-expanded', 'true'); | ||
} | ||
} | ||
toggleDropdownContent(e) { | ||
if (e) { | ||
if ( | ||
document.querySelector( | ||
'.measurement-dropdown .ccl-expandable__button[aria-expanded="true"]', | ||
) && | ||
document.querySelector( | ||
'.measurement-dropdown .ccl-expandable__button[aria-expanded="true"]', | ||
) !== e.currentTarget | ||
) { | ||
document | ||
.querySelector( | ||
'.measurement-dropdown .ccl-expandable__button[aria-expanded="true"]', | ||
) | ||
.setAttribute('aria-expanded', 'false'); | ||
} | ||
var aria = e.currentTarget.getAttribute('aria-expanded'); | ||
e.currentTarget.setAttribute( | ||
'aria-expanded', | ||
aria === 'true' ? 'false' : 'true', | ||
); | ||
} else { | ||
if ( | ||
document.querySelector( | ||
'.measurement-dropdown .ccl-expandable__button[aria-expanded="true"]', | ||
) | ||
) { | ||
document | ||
.querySelector( | ||
'.measurement-dropdown .ccl-expandable__button[aria-expanded="true"]', | ||
) | ||
.setAttribute('aria-expanded', 'false'); | ||
} | ||
} | ||
} | ||
areaMeasurementHandler(e) { | ||
e.currentTarget.nextElementSibling.appendChild( | ||
document.querySelector('.measurement-area'), | ||
); | ||
this.toggleDropdownContent(e); | ||
this.clearMeasurements(); | ||
this.clearCoordinates(); | ||
this.areaMeasurement(); | ||
this.container.current.querySelector('.active').classList.remove('active'); | ||
e.target.classList.add('active'); | ||
if (e.currentTarget.getAttribute('aria-expanded') === 'true') { | ||
this.areaMeasurement(); | ||
} | ||
} | ||
distanceMeasurementHandler(e) { | ||
e.currentTarget.nextElementSibling.appendChild( | ||
document.querySelector('.measurement-area'), | ||
); | ||
this.toggleDropdownContent(e); | ||
this.clearMeasurements(); | ||
this.clearCoordinates(); | ||
this.distanceMeasurement(); | ||
this.container.current.querySelector('.active').classList.remove('active'); | ||
e.target.classList.add('active'); | ||
if (e.currentTarget.getAttribute('aria-expanded') === 'true') { | ||
this.distanceMeasurement(); | ||
} | ||
} | ||
coordsMeasurementHandler(e) { | ||
this.toggleDropdownContent(e); | ||
this.clearMeasurements(); | ||
this.container.current.querySelector('.active').classList.remove('active'); | ||
e.target.classList.add('active'); | ||
//*** Add event to show mouse coordinates on click and move ***// | ||
@@ -122,3 +167,3 @@ var getCoordinates = this.props.view.on( | ||
this.setState({ | ||
latlong: pt.latitude.toFixed(4) + ' ' + pt.longitude.toFixed(4), | ||
latlong: { x: pt.latitude.toFixed(4), y: pt.longitude.toFixed(4) }, | ||
}); | ||
@@ -179,5 +224,6 @@ } | ||
<div className="measurement-panel"> | ||
<div className="measurement-buttons"> | ||
<div className="measurement-dropdown" id="measurement_area"> | ||
<div | ||
className="esri-icon-measure-area esri-widget--button esri-widget esri-interactive active" | ||
className="ccl-expandable__button" | ||
aria-expanded="false" | ||
onClick={this.areaMeasurementHandler.bind(this)} | ||
@@ -187,5 +233,15 @@ onKeyDown={this.areaMeasurementHandler.bind(this)} | ||
role="button" | ||
></div> | ||
> | ||
<span className="map-menu-icon esri-icon-measure-area"></span> | ||
<span>Area measurement</span> | ||
<span className="dropdown-icon ccl-icon-chevron-thin-down"></span> | ||
</div> | ||
<div className="measurement-dropdown-container"> | ||
<div className="measurement-area"></div> | ||
</div> | ||
</div> | ||
<div className="measurement-dropdown" id="measurement_distance"> | ||
<div | ||
className="esri-icon-measure-line esri-widget--button esri-widget esri-interactive" | ||
className="ccl-expandable__button" | ||
aria-expanded="false" | ||
onClick={this.distanceMeasurementHandler.bind(this)} | ||
@@ -195,5 +251,13 @@ onKeyDown={this.distanceMeasurementHandler.bind(this)} | ||
role="button" | ||
></div> | ||
> | ||
<span className="map-menu-icon esri-icon-measure-line"></span> | ||
<span>Distance measurement</span> | ||
<span className="dropdown-icon ccl-icon-chevron-thin-down"></span> | ||
</div> | ||
<div className="measurement-dropdown-container"></div> | ||
</div> | ||
<div className="measurement-dropdown" id="measurement_distance"> | ||
<div | ||
className="esri-icon-map-pin esri-widget--button esri-widget esri-interactive" | ||
className="ccl-expandable__button" | ||
aria-expanded="false" | ||
onClick={this.coordsMeasurementHandler.bind(this)} | ||
@@ -203,13 +267,28 @@ onKeyDown={this.coordsMeasurementHandler.bind(this)} | ||
role="button" | ||
></div> | ||
> | ||
<span className="map-menu-icon esri-icon-map-pin"></span> | ||
<span>Get coordinates</span> | ||
<span className="dropdown-icon ccl-icon-chevron-thin-down"></span> | ||
</div> | ||
<div className="measurement-dropdown-container"> | ||
<div className="measurement-coords"> | ||
{this.state.latlong ? ( | ||
<> | ||
<div className="measurement-coords-title"> | ||
Latitude | ||
</div> | ||
<b>{this.state.latlong.x}</b> | ||
<div className="measurement-coords-title"> | ||
Longitude | ||
</div> | ||
<b>{this.state.latlong.y}</b> | ||
</> | ||
) : ( | ||
<div className="measurement-coords-text"> | ||
Hover over the map to get the coordinates | ||
</div> | ||
)} | ||
</div> | ||
</div> | ||
</div> | ||
<div className="measurement-area"></div> | ||
<div className="measurement-coords"> | ||
{this.state.latlong ? ( | ||
<b>Lat/long: </b> | ||
) : ( | ||
'Hover over the map to get the coordinates' | ||
)} | ||
{this.state.latlong && this.state.latlong} | ||
</div> | ||
</div> | ||
@@ -216,0 +295,0 @@ </div> |
@@ -169,2 +169,16 @@ import ReactDOM from 'react-dom'; | ||
const showLogin = (e) => { | ||
e.stopPropagation(); | ||
document.querySelector('.login-panel').style.display = 'block'; | ||
let left = e.currentTarget.offsetLeft + 48; | ||
document.querySelector('.login-panel').style.left = left + 'px'; | ||
let top = | ||
document.querySelector('.tabs').offsetHeight + | ||
15 + | ||
e.currentTarget.closest('.ccl-expandable__button').offsetTop + | ||
e.currentTarget.closest('.ccl-expandable__button').offsetHeight / 2 - | ||
document.querySelector('.login-panel').offsetHeight / 2; | ||
document.querySelector('.login-panel').style.top = top + 'px'; | ||
}; | ||
return ( | ||
@@ -292,8 +306,8 @@ <> | ||
<span | ||
className={'map-menu-icon' + (isLoggedIn ? '' : ' locked')} | ||
onClick={() => { | ||
isLoggedIn && showModal(); | ||
className={'map-menu-icon map-menu-icon-login'} | ||
onClick={(e) => { | ||
isLoggedIn ? showModal() : showLogin(e); | ||
}} | ||
onKeyDown={() => { | ||
isLoggedIn && showModal(); | ||
onKeyDown={(e) => { | ||
isLoggedIn ? showModal() : showLogin(e); | ||
}} | ||
@@ -304,5 +318,6 @@ tabIndex="0" | ||
<FontAwesomeIcon | ||
//className={isLoggedIn ? '' : ' locked'} | ||
className={isLoggedIn ? '' : ' locked'} | ||
icon={['fas', 'download']} | ||
/> | ||
{!isLoggedIn && <FontAwesomeIcon icon={['fas', 'lock']} />} | ||
</span> | ||
@@ -562,2 +577,5 @@ } | ||
> | ||
<div className="dropdown-icon"> | ||
<FontAwesomeIcon icon={['fas', 'caret-right']} /> | ||
</div> | ||
{description ? ( | ||
@@ -569,3 +587,3 @@ <Popup | ||
className="custom" | ||
style={{ transform: 'translateX(0.25rem)' }} | ||
style={{ transform: 'translateX(-0.5rem)' }} | ||
/> | ||
@@ -639,2 +657,5 @@ ) : ( | ||
> | ||
<div className="dropdown-icon"> | ||
<FontAwesomeIcon icon={['fas', 'caret-right']} /> | ||
</div> | ||
<div | ||
@@ -669,3 +690,3 @@ className="ccl-form map-product-checkbox" | ||
className="custom" | ||
style={{ transform: 'translateX(-2.5rem)' }} | ||
style={{ transform: 'translateX(-4rem)' }} | ||
/> | ||
@@ -760,3 +781,3 @@ ) : ( | ||
<div | ||
className="ccl-form-group map-menu-dataset" | ||
className="map-menu-dataset-dropdown" | ||
id={'dataset_' + inheritedIndexDataset} | ||
@@ -766,64 +787,84 @@ datasetid={dataset.DatasetId} | ||
> | ||
<div className="map-dataset-checkbox" key={'b' + datIndex}> | ||
<input | ||
type="checkbox" | ||
id={checkIndex} | ||
parentid={checkProduct} | ||
name="" | ||
value="name" | ||
title={dataset.DatasetTitle} | ||
defcheck={layer_default} | ||
className="ccl-checkbox ccl-required ccl-form-check-input" | ||
<fieldset className="ccl-fieldset" key={'b' + datIndex}> | ||
<div | ||
className="ccl-expandable__button" | ||
aria-expanded="false" | ||
key={'c' + datIndex} | ||
onChange={(e) => { | ||
this.toggleDataset(e.target.checked, checkIndex, e.target); | ||
}} | ||
></input> | ||
<label | ||
className="ccl-form-check-label" | ||
htmlFor={checkIndex} | ||
key={'d' + datIndex} | ||
onClick={this.toggleDropdownContent.bind(this)} | ||
onKeyDown={this.toggleDropdownContent.bind(this)} | ||
tabIndex="0" | ||
role="button" | ||
> | ||
{description ? ( | ||
<Popup | ||
trigger={<span>{dataset.DatasetTitle}</span>} | ||
content={description} | ||
basic | ||
className="custom" | ||
style={{ transform: 'translateX(-3.5rem)' }} | ||
/> | ||
) : ( | ||
<span>{dataset.DatasetTitle}</span> | ||
)} | ||
</label> | ||
<div className="map-menu-icons"> | ||
<a href={dataset.DatasetURL} target="_blank" rel="noreferrer"> | ||
<Popup | ||
trigger={ | ||
<span className="map-menu-icon"> | ||
<FontAwesomeIcon icon={['fa', 'info-circle']} /> | ||
</span> | ||
} | ||
content="Info" | ||
{...popupSettings} | ||
/> | ||
</a> | ||
{!this.props.download && dataset.Downloadable && ( | ||
<AddCartItem | ||
cartData={this.compCfg} | ||
props={this.props} | ||
mapViewer={this.props.mapViewer} | ||
download={this.props.download} | ||
areaData={this.props.area} | ||
dataset={dataset} | ||
/> | ||
)} | ||
<div | ||
className="dropdown-icon" | ||
style={dataset.HandlingLevel ? { visibility: 'hidden' } : {}} | ||
> | ||
<FontAwesomeIcon icon={['fas', 'caret-right']} /> | ||
</div> | ||
<div className="ccl-form map-dataset-checkbox" key={'a' + datIndex}> | ||
<div className="ccl-form-group" key={'b' + datIndex}> | ||
<input | ||
type="checkbox" | ||
id={checkIndex} | ||
parentid={checkProduct} | ||
name="" | ||
value="name" | ||
title={dataset.DatasetTitle} | ||
defcheck={layer_default} | ||
className="ccl-checkbox ccl-required ccl-form-check-input" | ||
key={'c' + datIndex} | ||
onChange={(e) => { | ||
this.toggleDataset(e.target.checked, checkIndex, e.target); | ||
}} | ||
></input> | ||
<label | ||
className="ccl-form-check-label" | ||
htmlFor={checkIndex} | ||
key={'d' + datIndex} | ||
> | ||
{description ? ( | ||
<Popup | ||
trigger={<span>{dataset.DatasetTitle}</span>} | ||
content={description} | ||
basic | ||
className="custom" | ||
style={{ transform: 'translateX(-5.5rem)' }} | ||
/> | ||
) : ( | ||
<span>{dataset.DatasetTitle}</span> | ||
)} | ||
</label> | ||
<div className="map-menu-icons"> | ||
<a href={dataset.DatasetURL} target="_blank" rel="noreferrer"> | ||
<Popup | ||
trigger={ | ||
<span className="map-menu-icon"> | ||
<FontAwesomeIcon icon={['fa', 'info-circle']} /> | ||
</span> | ||
} | ||
content="Info" | ||
{...popupSettings} | ||
/> | ||
</a> | ||
{!this.props.download && dataset.Downloadable && ( | ||
<AddCartItem | ||
cartData={this.compCfg} | ||
props={this.props} | ||
mapViewer={this.props.mapViewer} | ||
download={this.props.download} | ||
areaData={this.props.area} | ||
dataset={dataset} | ||
/> | ||
)} | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<div | ||
className="ccl-form map-menu-layers-container" | ||
id={'layer_container_' + dataset.DatasetId} | ||
> | ||
{layers} | ||
</div> | ||
<div | ||
className="ccl-form map-menu-layers-container" | ||
id={'layer_container_' + dataset.DatasetId} | ||
> | ||
{layers} | ||
</div> | ||
</fieldset> | ||
</div> | ||
@@ -1000,2 +1041,3 @@ ); | ||
} else { | ||
this.layers[elem.id].opacity = 1; | ||
this.map.remove(this.layers[elem.id]); | ||
@@ -1098,4 +1140,7 @@ delete this.activeLayersJSON[elem.id]; | ||
toggleDropdownContent(e) { | ||
var aria = e.target.getAttribute('aria-expanded'); | ||
e.target.setAttribute('aria-expanded', aria === 'true' ? 'false' : 'true'); | ||
var aria = e.currentTarget.getAttribute('aria-expanded'); | ||
e.currentTarget.setAttribute( | ||
'aria-expanded', | ||
aria === 'true' ? 'false' : 'true', | ||
); | ||
} | ||
@@ -1144,8 +1189,9 @@ | ||
)} | ||
{/* <span | ||
<span | ||
className="map-menu-icon active-layer-opacity" | ||
// onClick={() => this.setOpacity(elem)} | ||
// onKeyDown={() => this.setOpacity(elem)} | ||
onClick={(e) => this.showOpacity(elem, e)} | ||
onKeyDown={(e) => this.showOpacity(elem, e)} | ||
tabIndex="0" | ||
role="button" | ||
data-opacity="100" | ||
> | ||
@@ -1157,3 +1203,3 @@ <Popup | ||
/> | ||
</span> */} | ||
</span> | ||
<span | ||
@@ -1361,2 +1407,5 @@ className="map-menu-icon active-layer-hide" | ||
}); | ||
if (document.querySelector('.opacity-panel').style.display === 'block') { | ||
this.closeOpacity(); | ||
} | ||
} else { | ||
@@ -1445,2 +1494,56 @@ activeLayers.forEach((layer) => { | ||
/** | ||
* Method to set layer opacity | ||
* @param {*} elem From the input | ||
* @param {*} e From the click event | ||
*/ | ||
showOpacity(elem, e) { | ||
if ( | ||
document.querySelector('.opacity-slider input').dataset.layer !== elem.id | ||
) { | ||
let opacity = e.currentTarget.dataset.opacity; | ||
document.querySelector('.opacity-slider input').value = opacity; | ||
document.querySelector('.opacity-panel').style.display = 'block'; | ||
let left = e.currentTarget.offsetLeft + 48; | ||
document.querySelector('.opacity-panel').style.left = left + 'px'; | ||
let top = | ||
document.querySelector('.tabs').offsetHeight + | ||
15 + | ||
e.currentTarget.closest('.active-layer').offsetTop + | ||
e.currentTarget.closest('.active-layer').offsetHeight / 2 - | ||
document.querySelector('.opacity-panel').offsetHeight / 2; | ||
document.querySelector('.opacity-panel').style.top = top + 'px'; | ||
document.querySelector('.opacity-slider input').dataset.layer = elem.id; | ||
} | ||
} | ||
setOpacity() { | ||
let layer = document.querySelector('.opacity-slider input').dataset.layer; | ||
let value = document.querySelector('.opacity-panel input').value; | ||
let group = this.getGroup(document.getElementById(layer)); | ||
let groupLayers = this.getGroupLayers(group); | ||
if (group && groupLayers.length > 1) { | ||
groupLayers.forEach((item) => { | ||
this.layers[item].opacity = value / 100; | ||
document.querySelector( | ||
'.active-layer[layer-id="' + item + '"] .active-layer-opacity', | ||
).dataset.opacity = value; | ||
}); | ||
} else { | ||
this.layers[layer].opacity = value / 100; | ||
document.querySelector( | ||
'.active-layer[layer-id="' + layer + '"] .active-layer-opacity', | ||
).dataset.opacity = value; | ||
} | ||
} | ||
closeOpacity() { | ||
document.querySelector('.opacity-panel').style.display = ''; | ||
document.querySelector('.opacity-panel input').dataset.layer = ''; | ||
} | ||
closeLogin() { | ||
document.querySelector('.login-panel').style.display = ''; | ||
} | ||
/** | ||
* Method to show/hide layer from "Active Layers" | ||
@@ -1548,2 +1651,9 @@ * @param {*} e From the click event | ||
} | ||
if (document.querySelector('.opacity-panel').style.display === 'block') { | ||
this.closeOpacity(); | ||
} | ||
if (document.querySelector('.login-panel').style.display === 'block') { | ||
document.querySelector('#login_close').click(); | ||
} | ||
} | ||
@@ -1636,3 +1746,2 @@ } | ||
> | ||
{!this.props.download && <CheckLogin />} | ||
{this.metodprocessJSON()} | ||
@@ -1703,2 +1812,35 @@ </div> | ||
</div> | ||
<div className="opacity-panel"> | ||
<div | ||
className="esri-icon-close" | ||
id="opacity_close" | ||
role="button" | ||
onClick={() => this.closeOpacity()} | ||
onKeyDown={() => this.closeOpacity()} | ||
tabIndex="0" | ||
></div> | ||
<div className="opacity-title">Opacity</div> | ||
<div className="opacity-slider"> | ||
<input | ||
type="range" | ||
defaultValue="100" | ||
min="0" | ||
max="100" | ||
onChange={() => this.setOpacity()} | ||
/> | ||
<span className="opacity-label left">0 %</span> | ||
<span className="opacity-label right">100 %</span> | ||
</div> | ||
</div> | ||
<div className="login-panel"> | ||
<div | ||
className="esri-icon-close" | ||
id="login_close" | ||
role="button" | ||
onClick={() => this.closeLogin()} | ||
onKeyDown={() => this.closeLogin()} | ||
tabIndex="0" | ||
></div> | ||
{!this.props.download && <CheckLogin />} | ||
</div> | ||
</> | ||
@@ -1705,0 +1847,0 @@ ); |
import React, { createRef } from 'react'; | ||
import { Loader } from 'semantic-ui-react'; | ||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; | ||
@@ -74,14 +75,20 @@ let layerControl, | ||
{UseCase.Links_to_web_sites && ( | ||
<p> | ||
For further information | ||
<a | ||
href={UseCase.Links_to_web_sites.split(' ')[0]} | ||
target="_blank" | ||
rel="noreferrer" | ||
> | ||
{' '} | ||
here | ||
</a> | ||
. | ||
</p> | ||
<div className="use-case-detail-link"> | ||
<p> | ||
For further information | ||
<a | ||
href={UseCase.Links_to_web_sites.split(' ')[0]} | ||
target="_blank" | ||
rel="noreferrer" | ||
> | ||
{' '} | ||
here | ||
<FontAwesomeIcon | ||
className="map-menu-icon" | ||
icon={['fas', 'external-link-alt']} | ||
/> | ||
</a> | ||
. | ||
</p> | ||
</div> | ||
)} | ||
@@ -136,2 +143,3 @@ </div> | ||
onClick={() => { | ||
view.popup.close(); | ||
layerControl.getGeometry(val.Spatial_coverage, layerHighlight); | ||
@@ -138,0 +146,0 @@ layerControl.showLayer(layerHighlight.id); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
10653207
8475