Skip to content

Commit d3a2a2a

Browse files
allyoucanmapTobia Di Pisa
authored andcommitted
Fix #3415 Layer properties are not accessible if its style is invalid (#3719)
* enabled settings on layer with error * add documentation for get status
1 parent e1e1bbe commit d3a2a2a

2 files changed

Lines changed: 70 additions & 7 deletions

File tree

web/client/components/TOC/Toolbar.jsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,16 @@ class Toolbar extends React.Component {
124124
isLoading = () => {
125125
return head(this.props.selectedLayers.filter(l => l.loading));
126126
}
127-
127+
/**
128+
* retrieve current status based on selected layers and groups
129+
* 'DESELECT' no selection
130+
* 'LAYER' single layer selection
131+
* 'LAYERS' multiple layer selection
132+
* 'GROUP' single group selection, it select also children layers
133+
* 'GROUPS' multiple group selection, it select also children layers
134+
* 'LAYER_LOAD_ERROR' single layer selection with error
135+
* 'LAYERS_LOAD_ERROR' multiple layer selection with error, all selected layer have an error
136+
*/
128137
getStatus = () => {
129138
const {selectedLayers, selectedGroups} = this.props;
130139
const isSingleGroup = this.isNestedGroup();
@@ -133,7 +142,7 @@ class Toolbar extends React.Component {
133142
status = isSingleGroup ? 'GROUP' : status;
134143
status = selectedLayers.length > 1 & selectedGroups.length === 0 ? 'LAYERS' : status;
135144
status = selectedGroups.length > 1 && !isSingleGroup ? 'GROUPS' : status;
136-
status = this.props.selectedLayers.length > 0 && this.props.selectedLayers.filter(l => l.loadingError === 'Error').length === this.props.selectedLayers.length ? 'LAYERS_LOAD_ERROR' : status;
145+
status = this.props.selectedLayers.length > 0 && this.props.selectedLayers.filter(l => l.loadingError === 'Error').length === this.props.selectedLayers.length ? `${status}_LOAD_ERROR` : status;
137146
return status;
138147
}
139148

@@ -176,11 +185,11 @@ class Toolbar extends React.Component {
176185
</Button>
177186
</OverlayTrigger>
178187
: null}
179-
{this.props.activateTool.activateSettingsTool && (status === 'LAYER' || status === 'GROUP') && !this.props.layerMetadata.expanded && !this.props.wfsdownload.expanded ?
188+
{this.props.activateTool.activateSettingsTool && (status === 'LAYER' || status === 'GROUP' || status === 'LAYER_LOAD_ERROR') && !this.props.layerMetadata.expanded && !this.props.wfsdownload.expanded ?
180189
<OverlayTrigger
181190
key="settings"
182191
placement="top"
183-
overlay={<Tooltip id="toc-tooltip-settings">{this.props.text.settingsTooltip[status]}</Tooltip>}>
192+
overlay={<Tooltip id="toc-tooltip-settings">{this.props.text.settingsTooltip[status ? 'LAYER_LOAD_ERROR' && 'LAYER' : status]}</Tooltip>}>
184193
<Button active={this.props.settings.expanded} bsStyle={this.props.settings.expanded ? 'success' : 'primary'} className="square-button-md" onClick={() => { this.showSettings(status); }}>
185194
<Glyphicon glyph="wrench"/>
186195
</Button>
@@ -196,7 +205,7 @@ class Toolbar extends React.Component {
196205
</Button>
197206
</OverlayTrigger>
198207
: null}
199-
{this.props.activateTool.activateRemoveLayer && (status === 'LAYER' || status === 'GROUP' || status === 'LAYERS' || status === 'GROUPS' || status === 'LAYERS_LOAD_ERROR') && this.props.selectedLayers.length > 0 && !this.props.settings.expanded && !this.props.layerMetadata.expanded && !this.props.wfsdownload.expanded ?
208+
{this.props.activateTool.activateRemoveLayer && (status === 'LAYER' || status === 'GROUP' || status === 'LAYERS' || status === 'GROUPS' || status === 'LAYER_LOAD_ERROR' || status === 'LAYERS_LOAD_ERROR') && this.props.selectedLayers.length > 0 && !this.props.settings.expanded && !this.props.layerMetadata.expanded && !this.props.wfsdownload.expanded ?
200209
<OverlayTrigger
201210
key="removeNode"
202211
placement="top"
@@ -206,7 +215,7 @@ class Toolbar extends React.Component {
206215
</Button>
207216
</OverlayTrigger>
208217
: null}
209-
{!this.isLoading() && status === 'LAYERS_LOAD_ERROR' ?
218+
{!this.isLoading() && status === 'LAYER_LOAD_ERROR' || status === 'LAYERS_LOAD_ERROR' ?
210219
<OverlayTrigger
211220
key="reload"
212221
placement="top"
@@ -299,7 +308,7 @@ class Toolbar extends React.Component {
299308

300309
showSettings = (status) => {
301310
if (!this.props.settings.expanded) {
302-
if (status === 'LAYER') {
311+
if (status === 'LAYER' || status === 'LAYER_LOAD_ERROR') {
303312
this.props.onToolsActions.onSettings( this.props.selectedLayers[0].id, 'layers', {opacity: parseFloat(this.props.selectedLayers[0].opacity !== undefined ? this.props.selectedLayers[0].opacity : 1)});
304313
} else if (status === 'GROUP') {
305314
this.props.onToolsActions.onSettings(this.props.selectedGroups[this.props.selectedGroups.length - 1].id, 'groups', {});

web/client/components/TOC/__tests__/Toolbar-test.jsx

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ describe('TOC Toolbar', () => {
162162
it('layer single selection (loading error)', () => {
163163
const spyReload = expect.spyOn(onToolsActions, 'onReload');
164164
const spyShow = expect.spyOn(onToolsActions, 'onShow');
165+
const spySettings = expect.spyOn(onToolsActions, 'onSettings');
165166
const selectedLayers = [{
166167
id: 'l001',
167168
title: 'layer001',
@@ -182,6 +183,59 @@ describe('TOC Toolbar', () => {
182183
const modal = document.getElementsByClassName('modal-dialog').item(0);
183184
expect(modal).toNotExist();
184185

186+
const el = ReactDOM.findDOMNode(cmp);
187+
expect(el).toExist();
188+
const btn = el.getElementsByClassName("btn");
189+
expect(btn.length).toBe(3);
190+
TestUtils.Simulate.click(btn[2]);
191+
expect(spyReload).toHaveBeenCalled();
192+
expect(spyShow).toHaveBeenCalledWith('l001', {visibility: true});
193+
194+
TestUtils.Simulate.click(btn[1]);
195+
const removeModal = document.getElementsByClassName('modal-dialog').item(0);
196+
expect(removeModal).toExist();
197+
198+
TestUtils.Simulate.click(btn[0]);
199+
expect(spySettings).toHaveBeenCalled();
200+
expect(btn[0].querySelector('.glyphicon-wrench')).toExist();
201+
});
202+
203+
it('multiple layer selection (loading error)', () => {
204+
const spyReload = expect.spyOn(onToolsActions, 'onReload');
205+
const spyShow = expect.spyOn(onToolsActions, 'onShow');
206+
const selectedLayers = [{
207+
id: 'l001',
208+
title: 'layer001',
209+
name: 'layer001name',
210+
loadingError: 'Error',
211+
bbox: {
212+
bounds: {
213+
maxx: 10,
214+
maxy: 9,
215+
minx: -10,
216+
miny: -9
217+
}, crs: 'EPSG:4326'
218+
}
219+
}, {
220+
id: 'l002',
221+
title: 'layer002',
222+
name: 'layer002name',
223+
loadingError: 'Error',
224+
bbox: {
225+
bounds: {
226+
maxx: 10,
227+
maxy: 9,
228+
minx: -10,
229+
miny: -9
230+
}, crs: 'EPSG:4326'
231+
}
232+
}];
233+
234+
const cmp = ReactDOM.render(<Toolbar selectedLayers={selectedLayers} onToolsActions={onToolsActions}/>, document.getElementById("container"));
235+
236+
const modal = document.getElementsByClassName('modal-dialog').item(0);
237+
expect(modal).toNotExist();
238+
185239
const el = ReactDOM.findDOMNode(cmp);
186240
expect(el).toExist();
187241
const btn = el.getElementsByClassName("btn");

0 commit comments

Comments
 (0)