Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Showing spatial filter selection area when FeatureGrid is open #2906

Merged
merged 6 commits into from
May 17, 2018
9 changes: 9 additions & 0 deletions web/client/actions/__tests__/featuregrid-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ const {
sizeChange, SIZE_CHANGE,
START_SYNC_WMS, startSyncWMS,
storeAdvancedSearchFilter, STORE_ADVANCED_SEARCH_FILTER,
setShowCurrentFilter, SET_SHOW_CURRENT_FILTER,
fatureGridQueryResult, GRID_QUERY_RESULT,
moreFeatures, LOAD_MORE_FEATURES,
hideSyncPopover, HIDE_SYNC_POPOVER,
Expand Down Expand Up @@ -294,4 +295,12 @@ describe('Test correctness of featurgrid actions', () => {
expect(retval.type).toBe(LOAD_MORE_FEATURES);
expect(retval.pages).toBe(pages);
});

it('Test setShowCurrentFilter', () => {
const showFilteredObject = true;
const retval = setShowCurrentFilter(showFilteredObject);
expect(retval).toExist();
expect(retval.type).toBe(SET_SHOW_CURRENT_FILTER);
expect(retval.showFilteredObject).toBe(showFilteredObject);
});
});
8 changes: 8 additions & 0 deletions web/client/actions/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/

const SET_SHOW_CURRENT_FILTER = 'SET_SHOW_CURRENT_FILTER';
const SELECT_FEATURES = 'FEATUREGRID:SELECT_FEATURES';
const DESELECT_FEATURES = 'FEATUREGRID:DESELECT_FEATURES';
const CLEAR_SELECTION = 'FEATUREGRID:CLEAR_SELECTION';
Expand Down Expand Up @@ -106,6 +107,12 @@ function selectFeatures(features, append) {
append
};
}
function setShowCurrentFilter(showFilteredObject) {
return {
type: SET_SHOW_CURRENT_FILTER,
showFilteredObject
};
}
function geometryChanged(features) {
return {
type: GEOMETRY_CHANGED,
Expand Down Expand Up @@ -364,6 +371,7 @@ module.exports = {
OPEN_FEATURE_GRID, openFeatureGrid,
CLOSE_FEATURE_GRID_CONFIRM, closeFeatureGridConfirm,
FEATURE_GRID_CLOSE_CONFIRMED, closeFeatureGridConfirmed,
SET_SHOW_CURRENT_FILTER, setShowCurrentFilter,
DISABLE_TOOLBAR, disableToolbar,
OPEN_ADVANCED_SEARCH, openAdvancedSearch,
ZOOM_ALL, zoomAll,
Expand Down
13 changes: 11 additions & 2 deletions web/client/plugins/FeatureEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@ const {createSelector, createStructuredSelector} = require('reselect');
const {bindActionCreators} = require('redux');
const {get} = require('lodash');

const Grid = require('../components/data/featuregrid/FeatureGrid');
const {lifecycle} = require('recompose');
const Grid = lifecycle({
componentDidMount() {
this.props.onMount(this.props.showFilteredObject);
}
})(require('../components/data/featuregrid/FeatureGrid'));
const {paginationInfo, describeSelector, wfsURLSelector, typeNameSelector} = require('../selectors/query');
const {modeSelector, changesSelector, newFeaturesSelector, hasChangesSelector, selectedFeaturesSelector, getDockSize} = require('../selectors/featuregrid');
const { toChangesMap} = require('../utils/FeatureGridUtils');
Expand All @@ -20,7 +25,7 @@ const BorderLayout = require('../components/layout/BorderLayout');
const EMPTY_ARR = [];
const EMPTY_OBJ = {};
const {gridTools, gridEvents, pageEvents, toolbarEvents} = require('./featuregrid/index');
const {initPlugin, sizeChange} = require('../actions/featuregrid');
const {initPlugin, sizeChange, setShowCurrentFilter} = require('../actions/featuregrid');
const ContainerDimensions = require('react-container-dimensions').default;
const {mapLayoutValuesSelector} = require('../selectors/maplayout');
const Dock = connect(createSelector(
Expand All @@ -42,6 +47,7 @@ const Dock = connect(createSelector(
* @prop {number} cfg.maxStoredPages default 5. In virtual Scroll mode determines the size of the loaded pages cache
* @prop {number} cfg.vsOverScan default 20. Number of rows to load above/below the visible slice of the grid
* @prop {number} cfg.scrollDebounce default 50. milliseconds of debounce interval between two scroll event
* @prop {boolean} cfg.showFilteredObject default false. Displays spatial filter selection area when true
* @classdesc
* FeatureEditor Plugin Provides functionalities to browse/edit data via WFS. The grid can be configured to use paging or
* <br/>virtual scroll mechanisms. By defualt virtual scroll is enabled. When on virtual scroll mode, the maxStoredPages param
Expand Down Expand Up @@ -139,6 +145,8 @@ const FeatureDock = (props = {
footer={getFooter(props)}>
{getDialogs(props.tools)}
<Grid
onMount={props.onMount}
showFilteredObject={props.showFilteredObject}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document this prop in jsdoc

editingAllowedRoles={props.editingAllowedRoles}
initPlugin={props.initPlugin}
customEditorsOptions={props.customEditorsOptions}
Expand Down Expand Up @@ -217,6 +225,7 @@ const selector = createSelector(
);
const EditorPlugin = connect(selector,
(dispatch) => ({
onMount: bindActionCreators(setShowCurrentFilter, dispatch),
gridEvents: bindActionCreators(gridEvents, dispatch),
pageEvents: bindActionCreators(pageEvents, dispatch),
initPlugin: bindActionCreators((options) => initPlugin(options), dispatch),
Expand Down
5 changes: 3 additions & 2 deletions web/client/plugins/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ class MapPlugin extends React.Component {
key={feature.id}
crs={projection}
type={feature.type}
style={feature.style || null }
geometry={feature.geometry}/>);
})}
</plugins.Layer>);
Expand Down Expand Up @@ -316,7 +317,7 @@ class MapPlugin extends React.Component {
const {mapSelector, projectionDefsSelector} = require('../selectors/map');
const { mapTypeSelector } = require('../selectors/maptype');
const {layerSelectorWithMarkers} = require('../selectors/layers');
const {selectedFeatures} = require('../selectors/highlight');
const {highlighedFeatures} = require('../selectors/highlight');
const {securityTokenSelector} = require('../selectors/security');

const selector = createSelector(
Expand All @@ -325,7 +326,7 @@ const selector = createSelector(
mapSelector,
mapTypeSelector,
layerSelectorWithMarkers,
selectedFeatures,
highlighedFeatures,
(state) => state.mapInitialConfig && state.mapInitialConfig.loadingError && state.mapInitialConfig.loadingError.data,
securityTokenSelector,
(state) => state.mousePosition && state.mousePosition.enabled
Expand Down
6 changes: 5 additions & 1 deletion web/client/reducers/__tests__/featuregrid-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const featuregrid = require('../featuregrid');
const {setFeatures, dockSizeFeatures, setLayer, toggleTool, customizeAttribute, selectFeatures, deselectFeatures, createNewFeatures, updateFilter,
featureSaving, toggleSelection, clearSelection, MODES, toggleEditMode, toggleViewMode, saveSuccess, clearChanges, saveError, startDrawingFeature,
deleteGeometryFeature, geometryChanged, setSelectionOptions, changePage, featureModified, setPermission, disableToolbar, openFeatureGrid, closeFeatureGrid,
toggleShowAgain, hideSyncPopover, initPlugin, sizeChange, storeAdvancedSearchFilter} = require('../../actions/featuregrid');
toggleShowAgain, hideSyncPopover, initPlugin, sizeChange, storeAdvancedSearchFilter, setShowCurrentFilter} = require('../../actions/featuregrid');
const {featureTypeLoaded, createQuery} = require('../../actions/wfsquery');

const {changeDrawingStatus} = require('../../actions/draw');
Expand Down Expand Up @@ -324,4 +324,8 @@ describe('Test the featuregrid reducer', () => {
let state = featuregrid({selectedLayer: "test_layer"}, storeAdvancedSearchFilter(filterObj));
expect(state.advancedFilters.test_layer).toBe(filterObj);
});
it('SET_SHOW_CURRENT_FILTER', () => {
let state = featuregrid({}, setShowCurrentFilter(true));
expect(state.showFilteredObject).toBe(true);
});
});
7 changes: 6 additions & 1 deletion web/client/reducers/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ const {
SIZE_CHANGE,
STORE_ADVANCED_SEARCH_FILTER,
GRID_QUERY_RESULT,
LOAD_MORE_FEATURES
LOAD_MORE_FEATURES,
SET_SHOW_CURRENT_FILTER
} = require('../actions/featuregrid');
const{
FEATURE_TYPE_LOADED,
Expand All @@ -57,6 +58,7 @@ const emptyResultsState = {
filters: {},
editingAllowedRoles: ["ADMIN"],
enableColumnFilters: true,
showFilteredObject: true,
open: false,
canEdit: false,
focusOnEdit: true,
Expand Down Expand Up @@ -179,6 +181,9 @@ function featuregrid(state = emptyResultsState, action) {
case SET_SELECTION_OPTIONS: {
return assign({}, state, {multiselect: action.multiselect});
}
case SET_SHOW_CURRENT_FILTER: {
return assign({}, state, { showFilteredObject: action.showFilteredObject});
}
case CLEAR_SELECTION:
return assign({}, state, {select: [], changes: []});
case SET_FEATURES:
Expand Down
83 changes: 80 additions & 3 deletions web/client/selectors/__tests__/highlight-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@

const expect = require('expect');
const {
selectedFeatures
} = require('../highlight');
selectedFeatures, filteredspatialObject, filteredspatialObjectCoord,
filteredGeometry, filteredSpatialObjectId, filteredSpatialObjectCrs,
filteredspatialObjectType, filteredFeatures, highlighedFeatures} = require('../highlight');

const idFt1 = "idFt1";
const idFt2 = "idFt2";
Expand All @@ -36,14 +37,42 @@ let feature2 = {
someProp: "someValue"
}
};

let feature3 = [{
type: "Feature",
geometry: {
type: 'Polygon',
coordinates: [ [ 0.000008983152841195214, 0.000017966305681987637 ] ]
},
style: {
fillColor: 'rgba(255, 255, 255, 0.2)',
color: '#ffcc33'
},
id: 'spatial_object'
}];
const initialState = {
featuregrid: {
mode: modeEdit,
select: [feature1, feature2],
changes: [feature2]
changes: [feature2],
showFilteredObject: true,
open: true
},
highlight: {
featuresPath: "featuregrid.select"
},
query: {
filterObj: {
spatialField: {
geometry: {
type: 'Polygon',
coordinates: [[ 1, 2]],
projection: 'EPSG:3857',
id: 'spatial_object'

}
}
}
}
};

Expand All @@ -60,4 +89,52 @@ describe('Test highlight selectors', () => {
expect(features).toExist();
expect(features.length).toBe(0);
});
it('test filteredspatialObject', () => {
const spatialObject = initialState.query.filterObj.spatialField;
const features = filteredspatialObject(initialState);
expect(features).toExist();
expect(features).toBe(spatialObject);
});
it('test filteredGeometry', () => {
const geometry = initialState.query.filterObj.spatialField.geometry;
const features = filteredGeometry(initialState);
expect(features).toExist();
expect(features).toBe(geometry);
});
it('test filteredspatialObjectCoord', () => {
const coordinates = initialState.query.filterObj.spatialField.geometry.coordinates;
const features = filteredspatialObjectCoord(initialState);
expect(features).toExist();
expect(features).toBe(coordinates);
});
it('test filteredSpatialObjectId', () => {
const geometryId = initialState.query.filterObj.spatialField.geometry.id;
const features = filteredSpatialObjectId(initialState);
expect(features).toExist();
expect(features).toBe(geometryId);
});
it('test filteredSpatialObjectCrs', () => {
const geometryCrs = initialState.query.filterObj.spatialField.geometry.projection;
const features = filteredSpatialObjectCrs(initialState);
expect(features).toExist();
expect(features).toBe(geometryCrs);
});
it('test filteredspatialObjectType', () => {
const geometryType = initialState.query.filterObj.spatialField.geometry.type;
const features = filteredspatialObjectType(initialState);
expect(features).toExist();
expect(features).toBe(geometryType);
});
it('test filteredFeatures', () => {
const features = filteredFeatures(initialState);
expect(features).toExist();
expect(features).toEqual(feature3);
});
it('test highlighedFeatures', () => {
const features = highlighedFeatures(initialState);
const featuresSelected = initialState.featuregrid.select;
const combinedFeatures = [...featuresSelected, ...feature3];
expect(features).toExist();
expect(features).toEqual(combinedFeatures);
});
});
50 changes: 48 additions & 2 deletions web/client/selectors/highlight.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,53 @@
const {get} = require('lodash');
const {createSelector} = require('reselect');
const {reprojectGeoJson} = require('../utils/CoordinatesUtils');

const selectedFeatures = (state) => get(state, state && state.highlight && state.highlight.featuresPath || "highlight.emptyFeatures");
const filteredspatialObject = (state) => get(state, state && state.featuregrid.open && state.featuregrid.showFilteredObject && "query.filterObj.spatialField" || "emptyObject");
const filteredGeometry = (state) => filteredspatialObject(state) && filteredspatialObject(state).geometry;
const filteredspatialObjectType = (state) => filteredGeometry(state) && filteredGeometry(state).type || "Polygon";
const filteredspatialObjectCoord = (state) => filteredGeometry(state) && filteredGeometry(state).coordinates || [];
const filteredSpatialObjectCrs = (state) => filteredGeometry(state) && filteredGeometry(state).projection || "EPSG:3857";
const filteredSpatialObjectId = (state) => filteredGeometry(state) && filteredGeometry(state).id || "spatial_object";
const filteredFeatures = createSelector(
[
filteredspatialObjectCoord,
filteredspatialObjectType,
filteredSpatialObjectId,
filteredSpatialObjectCrs
],
( geometryCoordinates, geometryType, geometryId, geometryCrs) => {
let geometry = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: geometryType,
coordinates: geometryCoordinates
},
style: {
fillColor: 'rgba(255, 255, 255, 0.2)',
color: '#ffcc33'
},
id: geometryId
}
]
};
return geometryCoordinates.length > 0 && geometryType ? reprojectGeoJson(geometry, geometryCrs, 'EPSG:4326').features : [];
}

module.exports = {
selectedFeatures: (state) => get(state, state && state.highlight && state.highlight.featuresPath || "highlight.emptyFeatures")
);

const highlighedFeatures = createSelector(
[
filteredFeatures,
selectedFeatures
],
(featuresFiltered, featuresSelected) => [ ...featuresSelected, ...featuresFiltered]
);

module.exports = {
selectedFeatures, filteredFeatures, filteredSpatialObjectId, filteredSpatialObjectCrs, filteredspatialObjectCoord,
filteredspatialObjectType, filteredGeometry, filteredspatialObject, highlighedFeatures
};