Skip to content

Commit

Permalink
Config, button, reux, filter for restricted area
Browse files Browse the repository at this point in the history
  • Loading branch information
Gaetanbrl committed Aug 21, 2024
1 parent 7b1e9b4 commit 7882325
Show file tree
Hide file tree
Showing 8 changed files with 137 additions and 12 deletions.
6 changes: 6 additions & 0 deletions web/client/actions/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*/

export const SET_UP = 'FEATUREGRID:SET_UP';
export const SET_RESTRICTED_AREA = "FEATUREGRID:SET_RESTRICTED_AREA";
export const SELECT_FEATURES = 'FEATUREGRID:SELECT_FEATURES';
export const DESELECT_FEATURES = 'FEATUREGRID:DESELECT_FEATURES';
export const CLEAR_SELECTION = 'FEATUREGRID:CLEAR_SELECTION';
Expand Down Expand Up @@ -404,3 +405,8 @@ export const setViewportFilter = (viewportFilter) => ({
type: SET_VIEWPORT_FILTER,
value: viewportFilter
});

export const setRestrictedArea = (area) => ({
type: SET_RESTRICTED_AREA,
area: area
});
6 changes: 6 additions & 0 deletions web/client/components/data/featuregrid/FeatureGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class FeatureGrid extends React.PureComponent {
static propTypes = {
autocompleteEnabled: PropTypes.bool,
editingAllowedRoles: PropTypes.array,
restrictedArea: PropTypes.object,
restrictedAreaUrl: PropTypes.string,
restrictedAreaOperator: PropTypes.string,
gridOpts: PropTypes.object,
changes: PropTypes.object,
selectBy: PropTypes.object,
Expand All @@ -56,6 +59,9 @@ class FeatureGrid extends React.PureComponent {
};
static defaultProps = {
editingAllowedRoles: ["ADMIN"],
restrictedArea: {},
restrictedAreaUrl: "",
restrictedAreaOperator: "CONTAINS",
autocompleteEnabled: false,
gridComponent: AdaptiveGrid,
changes: {},
Expand Down
23 changes: 20 additions & 3 deletions web/client/components/data/featuregrid/toolbars/Toolbar.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import './toolbar.css';
import { sortBy } from 'lodash';
import {ButtonGroup, Checkbox, Glyphicon, FormControl, FormGroup, Col} from 'react-bootstrap';
import { sortBy, isEmpty } from 'lodash';
import {ButtonGroup, Checkbox, Glyphicon, FormControl, FormGroup, Col, Button} from 'react-bootstrap';

import Message from '../../../I18N/Message';
import withHint from '../enhancers/withHint';
Expand Down Expand Up @@ -35,7 +35,23 @@ const standardButtons = {
disabled={disabled}
visible={mode === "VIEW" && isEditingAllowed && areLayerFeaturesEditable(layer)}
onClick={events.switchEditMode}
glyph="pencil"/>),
glyph="pencil" />),
isRestrictedByArea: ({ restrictedArea }) => {
return <Button
id="fg-isRestrictedByArea-button"
keyProp="fg-restrictedarea-button"
className="square-button-md"
bsStyle="warning"
tooltipId="featuregrid.toolbar.restrictedByArea"
disabled
style={isEmpty(restrictedArea) ? {
width: 0,
padding: 0,
borderWidth: 0
} : {}}>
<Glyphicon glyph="1-point-dashed" />
</Button>
},
filter: ({isFilterActive = false, viewportFilter, disabled, isSearchAllowed, mode, showAdvancedFilterButton = true, events = {}}) => (<TButton
id="search"
keyProp="search"
Expand Down Expand Up @@ -273,6 +289,7 @@ const standardButtons = {

// standard buttons with position set to index in this array. shape {name, Component, position} is aligned with attributes expected from tools injected.
const buttons = [
{name: "isRestrictedByArea", Component: standardButtons.isRestrictedByArea}, // GRID - features load is restricted by area
{name: "editMode", Component: standardButtons.editMode}, // EDITOR
{name: "backToViewMode", Component: standardButtons.backToViewMode}, // EDITOR
{name: "addFeature", Component: standardButtons.addFeature}, // EDITOR
Expand Down
58 changes: 54 additions & 4 deletions web/client/epics/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {get, head, isEmpty, find, castArray, includes, reduce} from 'lodash';
import { LOCATION_CHANGE } from 'connected-react-router';
import axios from '../libs/ajax';
import bbox from '@turf/bbox';
import booleanIntersects from "@turf/boolean-intersects";
import { fidFilter } from '../utils/ogc/Filter/filter';
import { getDefaultFeatureProjection, getPagesToLoad, gridUpdateToQueryUpdate, updatePages } from '../utils/FeatureGridUtils';

Expand All @@ -25,6 +26,7 @@ import {
import requestBuilder from '../utils/ogc/WFST/RequestBuilder';
import { findGeometryProperty } from '../utils/ogc/WFS/base';
import { FEATURE_INFO_CLICK, HIDE_MAPINFO_MARKER, closeIdentify, hideMapinfoMarker } from '../actions/mapInfo';
import { LOGIN_SUCCESS, LOGOUT } from "../actions/security"

import {
query,
Expand Down Expand Up @@ -110,7 +112,8 @@ import {
setPagination,
launchUpdateFilterFunc,
LAUNCH_UPDATE_FILTER_FUNC, SET_LAYER,
SET_VIEWPORT_FILTER, setViewportFilter
SET_VIEWPORT_FILTER, setViewportFilter,
setRestrictedArea,
} from '../actions/featuregrid';

import {
Expand Down Expand Up @@ -144,7 +147,10 @@ import {
getAttributeFilters,
selectedLayerSelector,
multiSelect,
paginationSelector, isViewportFilterActive, viewportFilter
paginationSelector, isViewportFilterActive, viewportFilter,
restrictedAreaSrcSelector,
restrictedAreaSelector,
additionnalGridFilters
} from '../selectors/featuregrid';

import { error, warning } from '../actions/notifications';
Expand All @@ -169,6 +175,7 @@ import {dockPanelsSelector} from "../selectors/maplayout";
import {shutdownToolOnAnotherToolDrawing} from "../utils/ControlUtils";
import {mapTypeSelector} from "../selectors/maptype";
import { MapLibraries } from '../utils/MapTypeUtils';
import { isAdminUserSelector, isLoggedIn } from '../selectors/security';

const setupDrawSupport = (state, original) => {
const defaultFeatureProj = getDefaultFeatureProjection();
Expand Down Expand Up @@ -205,7 +212,16 @@ const setupDrawSupport = (state, original) => {
});

// Remove features with geometry null or id "empty_row"
const cleanFeatures = features.filter(ft => ft.geometry !== null || ft.id !== 'empty_row');
const cleanFeatures = features.filter(ft => {
console.log("clean features");
const restrictedArea = restrictedAreaSelector(state);
let isValidFeature = ft.geometry !== null || ft.id !== 'empty_row';
if (isValidFeature && !isEmpty(restrictedArea)) {
// allow only feature inside restricted area
isValidFeature = booleanIntersects(restrictedArea, ft.geometry);
}
return isValidFeature
});

if (cleanFeatures.length > 0) {
return Rx.Observable.from([
Expand Down Expand Up @@ -262,7 +278,7 @@ const createLoadPageFlow = (store) => ({page, size, reason} = {}) => {
wfsURL(state),
addPagination({
...(wfsFilter(state)),
...viewportFilter(state)
...additionnalGridFilters(state)
},
getPagination(state, {page, size})
),
Expand Down Expand Up @@ -487,6 +503,7 @@ export const enableGeometryFilterOnEditMode = (action$, store) =>
action$.ofType(TOGGLE_MODE)
.filter(() => modeSelector(store.getState()) === MODES.EDIT)
.switchMap(() => {
console.log("enableGeometryFilterOnEditMode")
const currentFilter = find(getAttributeFilters(store.getState()), f => f.type === 'geometry') || {};
return currentFilter.value ? Rx.Observable.empty() : Rx.Observable.of(updateFilter({
attribute: findGeometryProperty(describeSelector(store.getState())).name,
Expand Down Expand Up @@ -1283,3 +1300,36 @@ export const resetViewportFilter = (action$, store) =>
return viewportFilter(store.getState()) !== null ? Rx.Observable.of(setViewportFilter(null))
: Rx.Observable.empty();
});

export const requestRestrictedArea = (action$, store) =>
action$.ofType(OPEN_FEATURE_GRID, LOGIN_SUCCESS)
.filter(() =>
{
return !isAdminUserSelector(store.getState())
&& isLoggedIn(store.getState())
&& !isEmpty(restrictedAreaSrcSelector(store.getState()))}
)
.switchMap((action) => {
const src = restrictedAreaSrcSelector(store.getState());
if (src.url) {
return Rx.Observable.defer(() => fetch(src?.url).then(r => r?.json?.()))
.switchMap(result => {
return Rx.Observable.of(
setRestrictedArea(result),
changePage(0)
)
})
} else {
return Rx.Observable.of(
setRestrictedArea(src?.raw || {}),
changePage(0)
)
}
})

export const resetRestrictedArea = (action$, store) =>
action$.ofType(LOGOUT, CLOSE_FEATURE_GRID)
.filter((a) => !isEmpty(restrictedAreaSrcSelector(store.getState())))
.switchMap(() => Rx.Observable.of(
setRestrictedArea({})
))
4 changes: 3 additions & 1 deletion web/client/plugins/FeatureEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,9 @@ const EditorPlugin = connect(
virtualScroll: this.props.virtualScroll ?? true,
editingAllowedRoles: this.props.editingAllowedRoles,
editingAllowedGroups: this.props.editingAllowedGroups,
maxStoredPages: this.props.maxStoredPages
maxStoredPages: this.props.maxStoredPages,
restrictedAreaUrl: this.props.restrictedAreaUrl,
restrictedArea: this.props.restrictedArea
});
},
componentDidUpdate(prevProps) {
Expand Down
4 changes: 3 additions & 1 deletion web/client/plugins/featuregrid/panels/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ import {
timeSyncActive,
isViewportFilterActive,
isFilterByViewportSupported,
selectedLayerSelector
selectedLayerSelector,
restrictedAreaSelector
} from '../../../selectors/featuregrid';
import { mapLayoutValuesSelector } from '../../../selectors/maplayout';
import {isCesium, mapTypeSelector} from '../../../selectors/maptype';
Expand Down Expand Up @@ -95,6 +96,7 @@ const Toolbar = connect(
disableZoomAll: (state) => state && state.featuregrid.virtualScroll || featureCollectionResultSelector(state).features.length === 0,
isSearchAllowed: (state) => !isCesium(state),
isEditingAllowed: isEditingAllowedSelector,
restrictedArea: restrictedAreaSelector,
hasSupportedGeometry,
isFilterActive,
showTimeSyncButton: showTimeSync,
Expand Down
10 changes: 8 additions & 2 deletions web/client/reducers/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ import {
SET_TIME_SYNC,
UPDATE_EDITORS_OPTIONS,
SET_PAGINATION,
SET_VIEWPORT_FILTER
SET_VIEWPORT_FILTER,
SET_RESTRICTED_AREA,
} from '../actions/featuregrid';
import { MAP_CONFIG_LOADED } from '../actions/config';

Expand Down Expand Up @@ -156,7 +157,9 @@ function featuregrid(state = emptyResultsState, action) {
editingAllowedRoles: action.options.editingAllowedRoles || state.editingAllowedRoles || ["ADMIN"],
editingAllowedGroups: action.options.editingAllowedGroups || state.editingAllowedGroups || [],
virtualScroll: !!action.options.virtualScroll,
maxStoredPages: action.options.maxStoredPages || 5
maxStoredPages: action.options.maxStoredPages || 5,
restrictedAreaUrl: action.options.restrictedAreaUrl || "",
restrictedArea: action.options.restrictedArea || {}
});
}
case LOAD_MORE_FEATURES:
Expand Down Expand Up @@ -440,6 +443,9 @@ function featuregrid(state = emptyResultsState, action) {
}
case MAP_CONFIG_LOADED: {
return {...state, ...get(action, 'config.featureGrid', {})};
}
case SET_RESTRICTED_AREA: {
return { ...state, restrictedArea: { ...state.restrictedArea, geometry: action.area } };
}
default:
return state;
Expand Down
38 changes: 37 additions & 1 deletion web/client/selectors/featuregrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/

import { head, get, isObject } from 'lodash';
import { head, get, isObject, isEmpty } from 'lodash';

import { getLayerFromId } from './layers';
import { findGeometryProperty } from '../utils/ogc/WFS/base';
Expand Down Expand Up @@ -202,6 +202,11 @@ export const isEditingAllowedSelector = (state) => {
})(state);
return (canEdit || isAllowed) && !isCesium(state);
};

export const restrictedAreaSrcSelector = state => get(state, "featuregrid.restrictedArea");
export const restrictedAreaOperatorSelector = state => get(state, "featuregrid.restrictedArea.operator");
export const restrictedAreaSelector = state => get(state, "featuregrid.restrictedArea.geometry");

export const paginationSelector = state => get(state, "featuregrid.pagination");
export const useLayerFilterSelector = state => get(state, "featuregrid.useLayerFilter", true);

Expand Down Expand Up @@ -235,3 +240,34 @@ export const viewportFilter = createShallowSelectorCreator(isEqual)(
} : {};
}
);

export const restrictedAreaFilter = createShallowSelectorCreator(isEqual)(
restrictedAreaSelector,
projectionSelector,
describeSelector,
state => restrictedAreaOperatorSelector(state),
(restrictedArea, projection, describeLayer, operator) => {
const attribute = findGeometryProperty(describeLayer)?.name;
console.log(restrictedArea);
return !isEmpty(restrictedArea) ? {
spatialField: [
{
geometry: {
...restrictedArea,
projection: "EPSG:4326"
},
attribute: attribute,
method: "Polygon",
operation: operator || "CONTAINS",
restrictedArea: true
}
]
} : {};
}
)

export const additionnalGridFilters = (state) => {
const restrictedArea = restrictedAreaFilter(state)?.spatialField || [];
const viewport = viewportFilter(state)?.spatialField || [];
return {spatialField: [...restrictedArea, ...viewport]}
}

0 comments on commit 7882325

Please sign in to comment.