Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
698d031
Add legend count
arxitpln May 16, 2025
8e18c13
ArcGISLegend able to manage dynamicLegend
arxitpln May 16, 2025
6e93840
Unused paramter deletion
arxitpln May 16, 2025
f325d89
Trasmit
arxitpln May 16, 2025
0537fbb
Add dynamic legend check
arxitpln May 16, 2025
4446e1c
Remove unused parameters
arxitpln May 16, 2025
f662957
Add Configs
arxitpln May 20, 2025
c2cd086
Add dynamic legend to plugin
arxitpln May 20, 2025
4d299a2
Add enableDynamicLegend in TOC
arxitpln May 20, 2025
c563d76
Add dynamic legend capabilities
arxitpln May 20, 2025
2eab47c
Add fontAntiAliasing
arxitpln May 20, 2025
ad6aca6
Add plugin code
arxitpln May 20, 2025
fc2336f
Merge branch 'arxit-dynamic-legend-count' into arxit-legend-merge
arxitpln May 20, 2025
c4470a7
Merge branch 'arxit-arcgis-dynamic-legend' into arxit-legend-merge
arxitpln May 20, 2025
7379eb1
Merge Correction
arxitpln May 20, 2025
014dbae
Add Translations
arxitpln May 20, 2025
8977b5b
Add configs
arxitpln May 20, 2025
dc8f867
Add Select to plugins
arxitpln May 20, 2025
21d1a3b
Correction on getCQLGeometryElement
arxitpln May 20, 2025
be98cad
Add treeHeadr to TOC and LayerTree
arxitpln May 20, 2025
ca0a494
tooltip → description
arxitpln May 20, 2025
cb7625b
Salect → SelectPlugin
arxitpln May 20, 2025
1ea363c
Add select Code
arxitpln May 20, 2025
60f145b
Correction call on OnUpdate
arxitpln May 20, 2025
c4b1197
Trasnmit onUpdate
arxitpln May 20, 2025
d3f3ff8
Merge branch 'arxit-floating-dynamic-legend' into arxit-legend-merge
arxitpln May 20, 2025
7ded0c4
Correction on Transmit
arxitpln May 20, 2025
ece88e3
Merge branch 'arxit-floating-dynamic-legend' into arxit-legend-merge
arxitpln May 20, 2025
2a40ff6
Add translations
arxitpln May 20, 2025
d04fb17
Merge branch 'arxit-floating-dynamic-legend' into arxit-legend-merge
arxitpln May 20, 2025
fa83e81
Merge branch 'arxit-select' into arxit-merge
arxitpln May 20, 2025
5d60a51
Use of disableResolutionLimits for min- and maxResolution
arxitpln May 28, 2025
68bf5a7
Merge branch 'arxit-floating-dynamic-legend' into arxit-legend-merge
arxitpln May 28, 2025
9cbed7e
Merge branch 'arxit-legend-merge' into arxit-merge
arxitpln May 28, 2025
a11b673
review changes
allyoucanmap May 29, 2025
12fb4ab
Revert to original code
arxitpln Jun 6, 2025
9890e7b
Add Dynamic Legend options
arxitpln Jun 6, 2025
6880a60
Add WMSLegendOptions
arxitpln Jun 6, 2025
e23cb1e
Select → LayersSelection in translations
arxitpln Jun 6, 2025
2183893
Select → LayersSelection for configs
arxitpln Jun 6, 2025
6b790cb
Select → LayersSelection for plugins
arxitpln Jun 6, 2025
bb840f7
Select → LayersSelection for the plugin
arxitpln Jun 6, 2025
f56a754
Merge remote-tracking branch 'allyoucanmap/arxit-floating-dynamic-leg…
arxitpln Jun 6, 2025
123c805
@allyoucanmap suggested changes
arxitpln Jun 6, 2025
5d26cde
Remove Duplicate
arxitpln Jul 24, 2025
9892f8c
Test 1st draft
arxitpln Jul 24, 2025
95268df
default layout for this type of plugin is a side panel
arxitpln Jul 25, 2025
c8272e8
 When the legend is completely empty there is no feedback to the user.
arxitpln Jul 25, 2025
887c50a
visualize the legend as a flat list of layers without groups
arxitpln Jul 25, 2025
53211d8
Add isFloating & flatLegend to cfg
arxitpln Jul 25, 2025
a20f887
DynamicLegend JsDoc
arxitpln Jul 25, 2025
17d2612
Split DynamicLegend Component
arxitpln Jul 25, 2025
eeb99b1
Merge branch 'arxit-floating-dynamic-legend' into arxit-legend-merge
arxitpln Jul 25, 2025
cb345ef
Merge branch 'arxit-legend-merge' into arxit-merge
arxitpln Jul 25, 2025
0075d05
Add LayersSelect JsDoc
arxitpln Jul 25, 2025
b719940
Merge branch 'arxit-select' into arxit-merge
arxitpln Jul 25, 2025
0cd59de
Update ArcGISLegend.jsx
arxitpln Sep 26, 2025
9a88a5c
Debug
Oct 28, 2025
6bddebe
Update ArcGISLegend.jsx and start the update of ArcGISLegend-test.jsx
Oct 30, 2025
6731f03
Updates on ArcGIS Legend and associated tests
Nov 5, 2025
c3b9a3a
Add a unit test for Display.jsx regarding updates on ArcGISLegend.
Nov 5, 2025
9917c93
Add a message in case the layers are not included in the map view.
Nov 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions project/standard/templates/configs/pluginsConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,13 +139,35 @@
"children": ["Permalink"],
"autoEnableChildren": ["Permalink"]
},
{
"name": "DynamicLegend",
"glyph": "align-left",
"title": "plugins.DynamicLegend.title",
"description": "plugins.DynamicLegend.description",
"dependencies": ["SidebarMenu"],
"defaultConfig": {
"isFloating": false,
"flatLegend": false
}
},
{
"name": "Permalink",
"glyph": "link",
"title": "plugins.Permalink.title",
"description": "plugins.Permalink.description",
"denyUserSelection": true
},
{
"name": "LayersSelection",
"glyph": "hand-down",
"title": "plugins.LayersSelection.title",
"description": "plugins.LayersSelection.description",
"dependencies": [
"Toolbar",
"BurgerMenu",
"SidebarMenu"
]
},
{
"name": "BackgroundSelector",
"title": "plugins.BackgroundSelector.title",
Expand Down
25 changes: 25 additions & 0 deletions web/client/components/TOC/fragments/settings/Display.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import ThreeDTilesSettings from './ThreeDTilesSettings';
import ModelTransformation from './ModelTransformation';
import StyleBasedWMSJsonLegend from '../../../../plugins/TOC/components/StyleBasedWMSJsonLegend';
import VectorLegend from '../../../../plugins/TOC/components/VectorLegend';
import { isMapServerUrl } from '../../../../utils/ArcGISUtils';

export default class extends React.Component {
static propTypes = {
Expand Down Expand Up @@ -401,6 +402,30 @@ export default class extends React.Component {
</Col>}
</div>
</Row>}
{this.props.element.type === "arcgis" && isMapServerUrl(this.props.element.url) &&
<Row>
<div className={"legend-options"}>
<Col xs={12} className={"legend-label"}>
<label key="legend-options-title" className="control-label"><Message msgId="layerProperties.legendOptions.title" /></label>
</Col>
<Col xs={12} className="first-selectize">
<FormGroup>
{!hideDynamicLegend && <Checkbox
data-qa="display-dynamic-legend-filter"
value="enableDynamicLegend"
key="enableDynamicLegend"
disabled={enableInteractiveLegend}
onChange={(e) => {
this.props.onChange("enableDynamicLegend", e.target.checked);
}}
checked={enableDynamicLegend || enableInteractiveLegend} >
<Message msgId="layerProperties.enableDynamicLegend.label"/>
&nbsp;<InfoPopover text={<Message msgId="layerProperties.enableDynamicLegend.info" />} />
</Checkbox>}
</FormGroup>
</Col>
</div>
</Row>}
</Grid>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -531,4 +531,45 @@ describe('test Layer Properties Display module component', () => {
expect(spy.calls[0].arguments[0]).toEqual("enableDynamicLegend");
expect(spy.calls[0].arguments[1]).toEqual(true);
});

it('tests arcgis Layer Properties Legend component', () => {
const l = {
name: 'arcgisLayer',
title: 'ArcGIS Layer',
visibility: true,
storeIndex: 9,
type: 'arcgis',
url: 'https://sampleserver.arcgisonline.com/arcgis/rest/services'
};
const settings = {
options: {
opacity: 1
}
};
const handlers = {
onChange() {}
};
let spy = expect.spyOn(handlers, "onChange");

const comp = ReactDOM.render(
<Display element={l} settings={settings} onChange={handlers.onChange}/>,
document.getElementById("container")
);

expect(comp).toBeTruthy();

const legendOptions = document.querySelector('.legend-options');
expect(legendOptions).toBeTruthy();

const dynamicLegendCheckbox = document.querySelector(".legend-options input[data-qa='display-dynamic-legend-filter']");
expect(dynamicLegendCheckbox).toBeTruthy();
expect(dynamicLegendCheckbox.checked).toBeFalsy();

dynamicLegendCheckbox.checked = true;
ReactTestUtils.Simulate.change(dynamicLegendCheckbox);

expect(spy).toHaveBeenCalled();
expect(spy.calls[0].arguments[0]).toEqual("enableDynamicLegend");
expect(spy.calls[0].arguments[1]).toEqual(true);
});
});
30 changes: 30 additions & 0 deletions web/client/configs/localConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -413,12 +413,42 @@
],
"desktop": [
"Details",
{
"name": "DynamicLegend",
"cfg": {
"isFloating": false,
"flatLegend": false
}
},
{
"name": "BrandNavbar",
"cfg": {
"containerPosition": "header"
}
},
{
"name": "LayersSelection",
"cfg": {
"highlightOptions": {
"color": "#3388ff",
"dashArray": "",
"fillColor": "#3388ff",
"fillOpacity": 0.2,
"radius": 4,
"weight": 4
},
"queryOptions": {
"maxCount": -1
},
"selectTools": [
"Point",
"Line",
"Circle",
"Rectangle",
"Polygon"
]
}
},
{ "name": "SecurityPopup" },
{
"name": "Map",
Expand Down
22 changes: 22 additions & 0 deletions web/client/configs/pluginsConfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,34 @@
"children": ["Permalink"],
"autoEnableChildren": ["Permalink"]
},
{
"name": "DynamicLegend",
"glyph": "align-left",
"title": "plugins.DynamicLegend.title",
"description": "plugins.DynamicLegend.description",
"dependencies": ["SidebarMenu"],
"defaultConfig": {
"isFloating": false,
"flatLegend": false
}
},
{
"name": "Permalink",
"glyph": "link",
"title": "plugins.Permalink.title",
"description": "plugins.Permalink.description"
},
{
"name": "LayersSelection",
"glyph": "hand-down",
"title": "plugins.LayersSelection.title",
"description": "plugins.LayersSelection.description",
"dependencies": [
"Toolbar",
"BurgerMenu",
"SidebarMenu"
]
},
{
"name": "BackgroundSelector",
"title": "plugins.BackgroundSelector.title",
Expand Down
30 changes: 30 additions & 0 deletions web/client/configs/simple.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@
}
],
"desktop": [
{
"name": "DynamicLegend",
"cfg": {
"isFloating": false,
"flatLegend": false
}
},
{
"name": "Map",
"cfg": {
Expand All @@ -89,6 +96,29 @@
"zoomControl": false
}
},
{
"name": "LayersSelection",
"cfg": {
"highlightOptions": {
"color": "#3388ff",
"dashArray": "",
"fillColor": "#3388ff",
"fillOpacity": 0.2,
"radius": 4,
"weight": 4
},
"queryOptions": {
"maxCount": -1
},
"selectTools": [
"Point",
"Line",
"Circle",
"Rectangle",
"Polygon"
]
}
},
{
"name": "Help"
},
Expand Down
96 changes: 96 additions & 0 deletions web/client/plugins/LayersSelection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import React from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { get } from 'lodash';
import { Glyphicon } from 'react-bootstrap';

import { createPlugin } from '../utils/PluginsUtils';
import { layersSelector } from '../selectors/layers';
import { updateNode, addLayer, changeLayerProperties } from '../actions/layers';
import { zoomToExtent } from '../actions/map';
import controls from '../reducers/controls';
import { toggleControl } from '../actions/controls';
import Message from '../components/I18N/Message';

import SelectComponent from './layersSelection/components/LayersSelection';
import epics from './layersSelection/epics/layersSelection';
import select from './layersSelection/reducers/layersSelection';
import { storeConfiguration, cleanSelection, addOrUpdateSelection } from './layersSelection/actions/layersSelection';
import { getSelectSelections, getSelectQueryMaxFeatureCount } from './layersSelection/selectors/layersSelection';

/**
* Select plugin that enables layer feature selection in the map.
* It connects Redux state and actions to the SelectComponent UI.
* Uses selectors to retrieve visibility, layers, selection results, and feature count.
*
* @function
* @returns {Object} A plugin definition object used by the application to render and control the Select tool.
*/
export default createPlugin('Select', {
component: connect(
createSelector([
(state) => get(state, 'controls.select.enabled'),
layersSelector,
getSelectSelections,
getSelectQueryMaxFeatureCount
], (isVisible, layers, selections, maxFeatureCount) => ({
isVisible,
layers,
selections,
maxFeatureCount
})),
{
onClose: toggleControl.bind(null, 'select', null),
onUpdateNode: updateNode,
storeConfiguration,
cleanSelection,
addOrUpdateSelection,
zoomToExtent,
addLayer,
changeLayerProperties
}
)(SelectComponent),
options: {
disablePluginIf: "{state('router') && (state('router').endsWith('new') || state('router').includes('newgeostory') || state('router').endsWith('dashboard'))}"
},
reducers: {
...controls,
select
},
epics: epics,
containers: {
BurgerMenu: {
name: 'select',
position: 1000,
priority: 2,
doNotHide: true,
text: <Message msgId="layersSelection.title"/>,
tooltip: <Message msgId="layersSelection.tooltip"/>,
icon: <Glyphicon glyph="hand-down"/>,
action: toggleControl.bind(null, 'select', null),
toggle: true
},
SidebarMenu: {
name: 'select',
position: 1000,
priority: 1,
doNotHide: true,
text: <Message msgId="layersSelection.title"/>,
tooltip: <Message msgId="layersSelection.tooltip"/>,
icon: <Glyphicon glyph="hand-down"/>,
action: toggleControl.bind(null, 'select', null),
toggle: true
},
Toolbar: {
name: 'select',
alwaysVisible: true,
position: 2,
priority: 0,
doNotHide: true,
tooltip: <Message msgId="layersSelection.title"/>,
icon: <Glyphicon glyph="hand-down"/>,
action: toggleControl.bind(null, 'select', null),
toggle: true
}
}
});
Loading