Skip to content

Commit 73cece8

Browse files
Mloweedgarofftherailz
authored andcommitted
Showing spatial filter selection area when FeatureGrid is open (#2906)
1 parent bb3c1c5 commit 73cece8

8 files changed

Lines changed: 170 additions & 11 deletions

File tree

web/client/actions/__tests__/featuregrid-test.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const {
4040
sizeChange, SIZE_CHANGE,
4141
START_SYNC_WMS, startSyncWMS,
4242
storeAdvancedSearchFilter, STORE_ADVANCED_SEARCH_FILTER,
43+
setShowCurrentFilter, SET_SHOW_CURRENT_FILTER,
4344
fatureGridQueryResult, GRID_QUERY_RESULT,
4445
moreFeatures, LOAD_MORE_FEATURES,
4546
hideSyncPopover, HIDE_SYNC_POPOVER,
@@ -294,4 +295,12 @@ describe('Test correctness of featurgrid actions', () => {
294295
expect(retval.type).toBe(LOAD_MORE_FEATURES);
295296
expect(retval.pages).toBe(pages);
296297
});
298+
299+
it('Test setShowCurrentFilter', () => {
300+
const showFilteredObject = true;
301+
const retval = setShowCurrentFilter(showFilteredObject);
302+
expect(retval).toExist();
303+
expect(retval.type).toBe(SET_SHOW_CURRENT_FILTER);
304+
expect(retval.showFilteredObject).toBe(showFilteredObject);
305+
});
297306
});

web/client/actions/featuregrid.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9+
const SET_SHOW_CURRENT_FILTER = 'SET_SHOW_CURRENT_FILTER';
910
const SELECT_FEATURES = 'FEATUREGRID:SELECT_FEATURES';
1011
const DESELECT_FEATURES = 'FEATUREGRID:DESELECT_FEATURES';
1112
const CLEAR_SELECTION = 'FEATUREGRID:CLEAR_SELECTION';
@@ -106,6 +107,12 @@ function selectFeatures(features, append) {
106107
append
107108
};
108109
}
110+
function setShowCurrentFilter(showFilteredObject) {
111+
return {
112+
type: SET_SHOW_CURRENT_FILTER,
113+
showFilteredObject
114+
};
115+
}
109116
function geometryChanged(features) {
110117
return {
111118
type: GEOMETRY_CHANGED,
@@ -364,6 +371,7 @@ module.exports = {
364371
OPEN_FEATURE_GRID, openFeatureGrid,
365372
CLOSE_FEATURE_GRID_CONFIRM, closeFeatureGridConfirm,
366373
FEATURE_GRID_CLOSE_CONFIRMED, closeFeatureGridConfirmed,
374+
SET_SHOW_CURRENT_FILTER, setShowCurrentFilter,
367375
DISABLE_TOOLBAR, disableToolbar,
368376
OPEN_ADVANCED_SEARCH, openAdvancedSearch,
369377
ZOOM_ALL, zoomAll,

web/client/plugins/FeatureEditor.jsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ const {createSelector, createStructuredSelector} = require('reselect');
1111
const {bindActionCreators} = require('redux');
1212
const {get} = require('lodash');
1313

14-
const Grid = require('../components/data/featuregrid/FeatureGrid');
14+
const {lifecycle} = require('recompose');
15+
const Grid = lifecycle({
16+
componentDidMount() {
17+
this.props.onMount(this.props.showFilteredObject);
18+
}
19+
})(require('../components/data/featuregrid/FeatureGrid'));
1520
const {paginationInfo, describeSelector, wfsURLSelector, typeNameSelector} = require('../selectors/query');
1621
const {modeSelector, changesSelector, newFeaturesSelector, hasChangesSelector, selectedFeaturesSelector, getDockSize} = require('../selectors/featuregrid');
1722
const { toChangesMap} = require('../utils/FeatureGridUtils');
@@ -20,7 +25,7 @@ const BorderLayout = require('../components/layout/BorderLayout');
2025
const EMPTY_ARR = [];
2126
const EMPTY_OBJ = {};
2227
const {gridTools, gridEvents, pageEvents, toolbarEvents} = require('./featuregrid/index');
23-
const {initPlugin, sizeChange} = require('../actions/featuregrid');
28+
const {initPlugin, sizeChange, setShowCurrentFilter} = require('../actions/featuregrid');
2429
const ContainerDimensions = require('react-container-dimensions').default;
2530
const {mapLayoutValuesSelector} = require('../selectors/maplayout');
2631
const Dock = connect(createSelector(
@@ -42,6 +47,7 @@ const Dock = connect(createSelector(
4247
* @prop {number} cfg.maxStoredPages default 5. In virtual Scroll mode determines the size of the loaded pages cache
4348
* @prop {number} cfg.vsOverScan default 20. Number of rows to load above/below the visible slice of the grid
4449
* @prop {number} cfg.scrollDebounce default 50. milliseconds of debounce interval between two scroll event
50+
* @prop {boolean} cfg.showFilteredObject default false. Displays spatial filter selection area when true
4551
* @classdesc
4652
* FeatureEditor Plugin Provides functionalities to browse/edit data via WFS. The grid can be configured to use paging or
4753
* <br/>virtual scroll mechanisms. By defualt virtual scroll is enabled. When on virtual scroll mode, the maxStoredPages param
@@ -139,6 +145,8 @@ const FeatureDock = (props = {
139145
footer={getFooter(props)}>
140146
{getDialogs(props.tools)}
141147
<Grid
148+
onMount={props.onMount}
149+
showFilteredObject={props.showFilteredObject}
142150
editingAllowedRoles={props.editingAllowedRoles}
143151
initPlugin={props.initPlugin}
144152
customEditorsOptions={props.customEditorsOptions}
@@ -217,6 +225,7 @@ const selector = createSelector(
217225
);
218226
const EditorPlugin = connect(selector,
219227
(dispatch) => ({
228+
onMount: bindActionCreators(setShowCurrentFilter, dispatch),
220229
gridEvents: bindActionCreators(gridEvents, dispatch),
221230
pageEvents: bindActionCreators(pageEvents, dispatch),
222231
initPlugin: bindActionCreators((options) => initPlugin(options), dispatch),

web/client/plugins/Map.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ class MapPlugin extends React.Component {
207207
key={feature.id}
208208
crs={projection}
209209
type={feature.type}
210+
style={feature.style || null }
210211
geometry={feature.geometry}/>);
211212
})}
212213
</plugins.Layer>);
@@ -318,7 +319,7 @@ class MapPlugin extends React.Component {
318319
const {mapSelector, projectionDefsSelector} = require('../selectors/map');
319320
const { mapTypeSelector } = require('../selectors/maptype');
320321
const {layerSelectorWithMarkers} = require('../selectors/layers');
321-
const {selectedFeatures} = require('../selectors/highlight');
322+
const {highlighedFeatures} = require('../selectors/highlight');
322323
const {securityTokenSelector} = require('../selectors/security');
323324

324325
const selector = createSelector(
@@ -327,7 +328,7 @@ const selector = createSelector(
327328
mapSelector,
328329
mapTypeSelector,
329330
layerSelectorWithMarkers,
330-
selectedFeatures,
331+
highlighedFeatures,
331332
(state) => state.mapInitialConfig && state.mapInitialConfig.loadingError && state.mapInitialConfig.loadingError.data,
332333
securityTokenSelector,
333334
(state) => state.mousePosition && state.mousePosition.enabled

web/client/reducers/__tests__/featuregrid-test.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const featuregrid = require('../featuregrid');
4747
const {setFeatures, dockSizeFeatures, setLayer, toggleTool, customizeAttribute, selectFeatures, deselectFeatures, createNewFeatures, updateFilter,
4848
featureSaving, toggleSelection, clearSelection, MODES, toggleEditMode, toggleViewMode, saveSuccess, clearChanges, saveError, startDrawingFeature,
4949
deleteGeometryFeature, geometryChanged, setSelectionOptions, changePage, featureModified, setPermission, disableToolbar, openFeatureGrid, closeFeatureGrid,
50-
toggleShowAgain, hideSyncPopover, initPlugin, sizeChange, storeAdvancedSearchFilter} = require('../../actions/featuregrid');
50+
toggleShowAgain, hideSyncPopover, initPlugin, sizeChange, storeAdvancedSearchFilter, setShowCurrentFilter} = require('../../actions/featuregrid');
5151
const {featureTypeLoaded, createQuery} = require('../../actions/wfsquery');
5252

5353
const {changeDrawingStatus} = require('../../actions/draw');
@@ -324,4 +324,8 @@ describe('Test the featuregrid reducer', () => {
324324
let state = featuregrid({selectedLayer: "test_layer"}, storeAdvancedSearchFilter(filterObj));
325325
expect(state.advancedFilters.test_layer).toBe(filterObj);
326326
});
327+
it('SET_SHOW_CURRENT_FILTER', () => {
328+
let state = featuregrid({}, setShowCurrentFilter(true));
329+
expect(state.showFilteredObject).toBe(true);
330+
});
327331
});

web/client/reducers/featuregrid.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ const {
4040
SIZE_CHANGE,
4141
STORE_ADVANCED_SEARCH_FILTER,
4242
GRID_QUERY_RESULT,
43-
LOAD_MORE_FEATURES
43+
LOAD_MORE_FEATURES,
44+
SET_SHOW_CURRENT_FILTER
4445
} = require('../actions/featuregrid');
4546
const{
4647
FEATURE_TYPE_LOADED,
@@ -57,6 +58,7 @@ const emptyResultsState = {
5758
filters: {},
5859
editingAllowedRoles: ["ADMIN"],
5960
enableColumnFilters: true,
61+
showFilteredObject: true,
6062
open: false,
6163
canEdit: false,
6264
focusOnEdit: true,
@@ -179,6 +181,9 @@ function featuregrid(state = emptyResultsState, action) {
179181
case SET_SELECTION_OPTIONS: {
180182
return assign({}, state, {multiselect: action.multiselect});
181183
}
184+
case SET_SHOW_CURRENT_FILTER: {
185+
return assign({}, state, { showFilteredObject: action.showFilteredObject});
186+
}
182187
case CLEAR_SELECTION:
183188
return assign({}, state, {select: [], changes: []});
184189
case SET_FEATURES:

web/client/selectors/__tests__/highlight-test.js

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88

99
const expect = require('expect');
1010
const {
11-
selectedFeatures
12-
} = require('../highlight');
11+
selectedFeatures, filteredspatialObject, filteredspatialObjectCoord,
12+
filteredGeometry, filteredSpatialObjectId, filteredSpatialObjectCrs,
13+
filteredspatialObjectType, filteredFeatures, highlighedFeatures} = require('../highlight');
1314

1415
const idFt1 = "idFt1";
1516
const idFt2 = "idFt2";
@@ -36,14 +37,42 @@ let feature2 = {
3637
someProp: "someValue"
3738
}
3839
};
40+
41+
let feature3 = [{
42+
type: "Feature",
43+
geometry: {
44+
type: 'Polygon',
45+
coordinates: [ [ 0.000008983152841195214, 0.000017966305681987637 ] ]
46+
},
47+
style: {
48+
fillColor: 'rgba(255, 255, 255, 0.2)',
49+
color: '#ffcc33'
50+
},
51+
id: 'spatial_object'
52+
}];
3953
const initialState = {
4054
featuregrid: {
4155
mode: modeEdit,
4256
select: [feature1, feature2],
43-
changes: [feature2]
57+
changes: [feature2],
58+
showFilteredObject: true,
59+
open: true
4460
},
4561
highlight: {
4662
featuresPath: "featuregrid.select"
63+
},
64+
query: {
65+
filterObj: {
66+
spatialField: {
67+
geometry: {
68+
type: 'Polygon',
69+
coordinates: [[ 1, 2]],
70+
projection: 'EPSG:3857',
71+
id: 'spatial_object'
72+
73+
}
74+
}
75+
}
4776
}
4877
};
4978

@@ -60,4 +89,52 @@ describe('Test highlight selectors', () => {
6089
expect(features).toExist();
6190
expect(features.length).toBe(0);
6291
});
92+
it('test filteredspatialObject', () => {
93+
const spatialObject = initialState.query.filterObj.spatialField;
94+
const features = filteredspatialObject(initialState);
95+
expect(features).toExist();
96+
expect(features).toBe(spatialObject);
97+
});
98+
it('test filteredGeometry', () => {
99+
const geometry = initialState.query.filterObj.spatialField.geometry;
100+
const features = filteredGeometry(initialState);
101+
expect(features).toExist();
102+
expect(features).toBe(geometry);
103+
});
104+
it('test filteredspatialObjectCoord', () => {
105+
const coordinates = initialState.query.filterObj.spatialField.geometry.coordinates;
106+
const features = filteredspatialObjectCoord(initialState);
107+
expect(features).toExist();
108+
expect(features).toBe(coordinates);
109+
});
110+
it('test filteredSpatialObjectId', () => {
111+
const geometryId = initialState.query.filterObj.spatialField.geometry.id;
112+
const features = filteredSpatialObjectId(initialState);
113+
expect(features).toExist();
114+
expect(features).toBe(geometryId);
115+
});
116+
it('test filteredSpatialObjectCrs', () => {
117+
const geometryCrs = initialState.query.filterObj.spatialField.geometry.projection;
118+
const features = filteredSpatialObjectCrs(initialState);
119+
expect(features).toExist();
120+
expect(features).toBe(geometryCrs);
121+
});
122+
it('test filteredspatialObjectType', () => {
123+
const geometryType = initialState.query.filterObj.spatialField.geometry.type;
124+
const features = filteredspatialObjectType(initialState);
125+
expect(features).toExist();
126+
expect(features).toBe(geometryType);
127+
});
128+
it('test filteredFeatures', () => {
129+
const features = filteredFeatures(initialState);
130+
expect(features).toExist();
131+
expect(features).toEqual(feature3);
132+
});
133+
it('test highlighedFeatures', () => {
134+
const features = highlighedFeatures(initialState);
135+
const featuresSelected = initialState.featuregrid.select;
136+
const combinedFeatures = [...featuresSelected, ...feature3];
137+
expect(features).toExist();
138+
expect(features).toEqual(combinedFeatures);
139+
});
63140
});

web/client/selectors/highlight.js

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,53 @@
11
const {get} = require('lodash');
2+
const {createSelector} = require('reselect');
3+
const {reprojectGeoJson} = require('../utils/CoordinatesUtils');
24

5+
const selectedFeatures = (state) => get(state, state && state.highlight && state.highlight.featuresPath || "highlight.emptyFeatures");
6+
const filteredspatialObject = (state) => get(state, state && state.featuregrid.open && state.featuregrid.showFilteredObject && "query.filterObj.spatialField" || "emptyObject");
7+
const filteredGeometry = (state) => filteredspatialObject(state) && filteredspatialObject(state).geometry;
8+
const filteredspatialObjectType = (state) => filteredGeometry(state) && filteredGeometry(state).type || "Polygon";
9+
const filteredspatialObjectCoord = (state) => filteredGeometry(state) && filteredGeometry(state).coordinates || [];
10+
const filteredSpatialObjectCrs = (state) => filteredGeometry(state) && filteredGeometry(state).projection || "EPSG:3857";
11+
const filteredSpatialObjectId = (state) => filteredGeometry(state) && filteredGeometry(state).id || "spatial_object";
12+
const filteredFeatures = createSelector(
13+
[
14+
filteredspatialObjectCoord,
15+
filteredspatialObjectType,
16+
filteredSpatialObjectId,
17+
filteredSpatialObjectCrs
18+
],
19+
( geometryCoordinates, geometryType, geometryId, geometryCrs) => {
20+
let geometry = {
21+
type: "FeatureCollection",
22+
features: [
23+
{
24+
type: "Feature",
25+
geometry: {
26+
type: geometryType,
27+
coordinates: geometryCoordinates
28+
},
29+
style: {
30+
fillColor: 'rgba(255, 255, 255, 0.2)',
31+
color: '#ffcc33'
32+
},
33+
id: geometryId
34+
}
35+
]
36+
};
37+
return geometryCoordinates.length > 0 && geometryType ? reprojectGeoJson(geometry, geometryCrs, 'EPSG:4326').features : [];
38+
}
339

4-
module.exports = {
5-
selectedFeatures: (state) => get(state, state && state.highlight && state.highlight.featuresPath || "highlight.emptyFeatures")
40+
);
41+
42+
const highlighedFeatures = createSelector(
43+
[
44+
filteredFeatures,
45+
selectedFeatures
46+
],
47+
(featuresFiltered, featuresSelected) => [ ...featuresSelected, ...featuresFiltered]
48+
);
649

50+
module.exports = {
51+
selectedFeatures, filteredFeatures, filteredSpatialObjectId, filteredSpatialObjectCrs, filteredspatialObjectCoord,
52+
filteredspatialObjectType, filteredGeometry, filteredspatialObject, highlighedFeatures
753
};

0 commit comments

Comments
 (0)