From 8be49fc343ffcdb6d319eca27bf502ffc8c7e259 Mon Sep 17 00:00:00 2001 From: Matteo Velludini Date: Thu, 28 Jun 2018 12:31:41 +0200 Subject: [PATCH 1/2] fix #89 GFI and annotations fixes --- .../actions/__tests__/annotations-test.js | 6 + web/client/actions/annotations.js | 8 ++ web/client/components/map/openlayers/Map.jsx | 33 +++++- .../map/openlayers/__tests__/Map-test.jsx | 4 +- .../mapcontrols/annotations/Annotations.jsx | 5 +- .../annotations/AnnotationsEditor.jsx | 41 +++++-- .../__tests__/AnnotationsEditor-test.js | 27 ----- .../epics/__tests__/annotations-test.js | 47 ++++++-- web/client/epics/annotations.js | 26 ++++- web/client/epics/catalog.js | 10 +- web/client/epics/maplayout.js | 8 +- web/client/plugins/Annotations.jsx | 15 +-- .../reducers/__tests__/annotations-test.js | 103 +++++++----------- web/client/reducers/annotations.js | 9 +- .../selectors/__tests__/annotations-test.js | 4 +- .../selectors/__tests__/mapinfo-test.js | 14 ++- web/client/selectors/annotations.js | 2 + web/client/selectors/mapinfo.js | 2 + .../themes/default/less/annotations.less | 19 ++++ web/client/themes/default/variables.less | 2 + web/client/translations/data.de-DE | 2 +- web/client/translations/data.en-US | 2 +- web/client/translations/data.es-ES | 2 +- web/client/translations/data.fr-FR | 2 +- web/client/translations/data.hr-HR | 2 +- web/client/translations/data.it-IT | 2 +- web/client/translations/data.nl-NL | 2 +- web/client/translations/data.zh-ZH | 2 +- 28 files changed, 252 insertions(+), 149 deletions(-) diff --git a/web/client/actions/__tests__/annotations-test.js b/web/client/actions/__tests__/annotations-test.js index ed78a66dce..6bc2a4c7af 100644 --- a/web/client/actions/__tests__/annotations-test.js +++ b/web/client/actions/__tests__/annotations-test.js @@ -71,6 +71,7 @@ const { changeRadius, CHANGE_RADIUS, changeText, CHANGE_TEXT, CONFIRM_DELETE_FEATURE, confirmDeleteFeature, + OPEN_EDITOR, openEditor, TOGGLE_DELETE_FT_MODAL, toggleDeleteFtModal, ADD_NEW_FEATURE, addNewFeature, LOAD_ANNOTATIONS, loadAnnotations @@ -110,6 +111,11 @@ describe('Test correctness of the annotations actions', () => { expect(result.type).toEqual(REMOVE_ANNOTATION); expect(result.id).toEqual('1'); }); + it('openEditor annotation', () => { + const result = openEditor('1'); + expect(result.type).toEqual(OPEN_EDITOR); + expect(result.id).toEqual('1'); + }); it('addNewFeature', () => { const result = addNewFeature(); expect(result.type).toEqual(ADD_NEW_FEATURE); diff --git a/web/client/actions/annotations.js b/web/client/actions/annotations.js index dd7130e584..2dce607d99 100644 --- a/web/client/actions/annotations.js +++ b/web/client/actions/annotations.js @@ -7,6 +7,7 @@ */ const EDIT_ANNOTATION = 'ANNOTATIONS:EDIT'; +const OPEN_EDITOR = 'ANNOTATIONS:OPEN_EDITOR'; const SHOW_ANNOTATION = 'ANNOTATIONS:SHOW'; const NEW_ANNOTATION = 'ANNOTATIONS:NEW'; const REMOVE_ANNOTATION = 'ANNOTATIONS:REMOVE'; @@ -62,6 +63,12 @@ function confirmDeleteFeature() { type: CONFIRM_DELETE_FEATURE }; } +function openEditor(id) { + return { + type: OPEN_EDITOR, + id + }; +} function changeFormat(format) { return { type: CHANGE_FORMAT, @@ -372,6 +379,7 @@ module.exports = { confirmCloseAnnotations, cancelCloseAnnotations, DOWNLOAD, download, + OPEN_EDITOR, openEditor, CONFIRM_DELETE_FEATURE, confirmDeleteFeature, TOGGLE_DELETE_FT_MODAL, toggleDeleteFtModal, HIGHLIGHT_POINT, highlightPoint, diff --git a/web/client/components/map/openlayers/Map.jsx b/web/client/components/map/openlayers/Map.jsx index 187453fdfd..f4111a8bd9 100644 --- a/web/client/components/map/openlayers/Map.jsx +++ b/web/client/components/map/openlayers/Map.jsx @@ -114,21 +114,44 @@ class OpenlayersMap extends React.Component { // TODO support disableEventListener map.on('moveend', this.updateMapInfoState); map.on('singleclick', (event) => { + const checkPoint = (geometry = {}) => { + if (geometry.getType() === "Point") { + this.markerPresent = true; + const getCoord = geometry.getFirstCoordinate(); + return ol.proj.toLonLat(getCoord, this.props.projection); + } + return null; + }; if (this.props.onClick && !this.map.disabledListeners.singleclick) { let pos = event.coordinate.slice(); let coords = ol.proj.toLonLat(pos, this.props.projection); let tLng = CoordinatesUtils.normalizeLng(coords[0]); let layerInfo; + this.markerPresent = false; map.forEachFeatureAtPixel(event.pixel, (feature, layer) => { if (layer && layer.get('handleClickOnLayer')) { - layerInfo = layer.get('msId'); + const geom = feature.getGeometry(); - // TODO getFirstCoordinate makes sense only for points, maybe centroid is more appropriate - const getCoord = geom.getType() === "GeometryCollection" ? geom.getGeometries()[0].getFirstCoordinate() : geom.getFirstCoordinate(); - coords = ol.proj.toLonLat(getCoord, this.props.projection); + const type = geom.getType(); + coords = checkPoint(geom) || coords; + if (!this.markerPresent) { + // if no marker is present then take the clicked point + + if (type === "GeometryCollection"/*TODO add support for "FeatureCollection"*/) { + geom.getGeometries().forEach(f => { + coords = checkPoint(f.getGeometry()); + }); + } else { + coords = ol.proj.toLonLat(pos, this.props.projection); + } + } else { + layerInfo = layer.get('msId'); + + } + tLng = CoordinatesUtils.normalizeLng(coords[0]); } - tLng = CoordinatesUtils.normalizeLng(coords[0]); }); + const getElevation = this.map.get('elevationLayer') && this.map.get('elevationLayer').get('getElevation'); this.props.onClick({ pixel: { diff --git a/web/client/components/map/openlayers/__tests__/Map-test.jsx b/web/client/components/map/openlayers/__tests__/Map-test.jsx index e8ac109df3..7cd0729e3a 100644 --- a/web/client/components/map/openlayers/__tests__/Map-test.jsx +++ b/web/client/components/map/openlayers/__tests__/Map-test.jsx @@ -354,8 +354,8 @@ describe('OpenlayersMap', () => { originalEvent: {} }); expect(spy.calls.length).toEqual(1); - expect(spy.calls[0].arguments[0].latlng.lat).toBe(43.9); - expect(spy.calls[0].arguments[0].latlng.lng).toBe(10.3); + expect(spy.calls[0].arguments[0].latlng.lat).toBe(0.5); + expect(spy.calls[0].arguments[0].latlng.lng).toBe(0.5); done(); }, 500); }); diff --git a/web/client/components/mapcontrols/annotations/Annotations.jsx b/web/client/components/mapcontrols/annotations/Annotations.jsx index 35d995c968..19a213a619 100644 --- a/web/client/components/mapcontrols/annotations/Annotations.jsx +++ b/web/client/components/mapcontrols/annotations/Annotations.jsx @@ -323,9 +323,10 @@ class Annotations extends React.Component { closeGlyph="1-close" confirmButtonContent={} closeText={}> - + {this.props.mode === 'editing' ? : + } ); - }else if (this.state.selectFile) { + } else if (this.state.selectFile) { body = ( } diff --git a/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx b/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx index 9056af0a98..dfe92e4895 100644 --- a/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx +++ b/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx @@ -55,6 +55,7 @@ const bbox = require('@turf/bbox'); * @prop {function} onCancelStyle triggered when the user cancels style selection * @prop {function} onCancel triggered when the user cancels the addition/changes made to the annotation * @prop {function} onCleanHighlight triggered when the user exits 'details' mode + * @prop {function} onHighlight triggered when the user hover the infoviewer card * @prop {function} onConfirmDeleteFeature triggered when the user confirms deletion of a feature * @prop {function} onAddText triggered when the user adds new Text geometry to the feature * @prop {function} onToggleUnsavedChangesModal toggles the view of the UnsavedChangesModal @@ -74,7 +75,6 @@ const bbox = require('@turf/bbox'); * @prop {object} drawingText it contains info of the text annotation, 'drawing' if being added or 'show' used to show the modal to add the relative value * @prop {boolean} unsavedChanges flag used to trigger changes of showUnsavedChangesModal * @prop {boolean} unsavedStyle flag used to trigger changes of showUnsavedChangesModal - * @prop {object} removing object to remove, it is also a flag that means we are currently asking for removing an annotation / geometry. Toggles visibility of the confirm dialog * @prop {boolean} closing user asked for closing panel when editing * @prop {string} stylerType selected styler to be shown as body * @prop {boolean} showUnsavedStyleModal flag used to show the UnsavedChangesModal @@ -116,6 +116,7 @@ class AnnotationsEditor extends React.Component { onCancelEdit: PropTypes.func, onCancelStyle: PropTypes.func, onCleanHighlight: PropTypes.func, + onHighlight: PropTypes.func, onAddText: PropTypes.func, onCancel: PropTypes.func, onConfirmDeleteFeature: PropTypes.func, @@ -155,9 +156,9 @@ class AnnotationsEditor extends React.Component { unsavedChanges: PropTypes.bool, unsavedGeometry: PropTypes.bool, unsavedStyle: PropTypes.bool, + mouseHoverEvents: PropTypes.bool, coordinateEditorEnabled: PropTypes.bool, styling: PropTypes.bool, - removing: PropTypes.object, closing: PropTypes.bool, errors: PropTypes.object, stylerType: PropTypes.string, @@ -190,9 +191,12 @@ class AnnotationsEditor extends React.Component { maxZoom: 18, stylerType: "marker" }; - + /** + @prop {object} removing object to remove, it is also a flag that means we are currently asking for removing an annotation / geometry. Toggles visibility of the confirm dialog + */ state = { editedFields: {}, + removing: null, textValue: "" }; @@ -253,7 +257,10 @@ class AnnotationsEditor extends React.Component { glyph: 'trash', tooltipId: "annotations.remove", visible: true, - onClick: () => { this.props.onRemove(this.props.id); } + onClick: () => { + this.setState({removing: this.props.id}); + // this.props.onRemove(this.props.id); + } }, { glyph: 'download', tooltip: , @@ -627,17 +634,24 @@ class AnnotationsEditor extends React.Component { closeText={}> ); - } else if (this.props.removing) { + } else if (this.state.removing) { return ( this.props.onConfirmRemove(this.props.removing)} + onClose={() => { + this.setState({removing: null}); + this.props.onCancelRemove(); + }} + onConfirm={() => { + this.setState({removing: null}); + this.props.onConfirmRemove(this.state.removing); + }} confirmButtonBSStyle="default" closeGlyph="1-close" confirmButtonContent={} closeText={}> - + {this.props.mode === 'editing' ? : + } ); } } @@ -647,8 +661,17 @@ class AnnotationsEditor extends React.Component { return this.renderStyler(); } const editing = this.props.editing && (this.props.editing.properties.id === this.props.id); + let mouseHoverEvents = this.props.mouseHoverEvents ? { + onMouseEnter: () => { + this.props.onHighlight(this.props.id); + }, + onMouseLeave: () => { + this.props.onCleanHighlight(); + } + } : {}; return ( -
+
{this.renderButtons(editing, this.props.coordinateEditorEnabled)} {this.renderError(editing)} {this.renderModals()} diff --git a/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js b/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js index 53d9c9dc14..ad1aeff926 100644 --- a/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js +++ b/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js @@ -121,33 +121,6 @@ describe("test the AnnotationsEditor Panel", () => { expect(spyEdit.calls.length).toEqual(1); expect(spyRemove.calls.length).toEqual(0); }); - it('test click remove annotation', () => { - const feature = { - id: "1", - title: 'mytitle', - description: 'desc' - }; - - const testHandlers = { - onEditHandler: (id) => { return id; }, - onRemoveHandler: (id) => { return id; } - }; - - const spyEdit = expect.spyOn(testHandlers, 'onEditHandler'); - const spyRemove = expect.spyOn(testHandlers, 'onRemoveHandler'); - - const viewer = ReactDOM.render(, document.getElementById("container")); - expect(viewer).toExist(); - - let removeButton = ReactDOM.findDOMNode(TestUtils.scryRenderedDOMComponentsWithTag(viewer, "button")[2]); - - expect(removeButton).toExist(); - TestUtils.Simulate.click(removeButton); - - expect(spyEdit.calls.length).toEqual(0); - expect(spyRemove.calls.length).toEqual(1); - }); it('test click remove geometry', () => { const feature = { diff --git a/web/client/epics/__tests__/annotations-test.js b/web/client/epics/__tests__/annotations-test.js index 2e11d1da48..28e9db53b0 100644 --- a/web/client/epics/__tests__/annotations-test.js +++ b/web/client/epics/__tests__/annotations-test.js @@ -13,25 +13,26 @@ const { createEpicMiddleware, combineEpics } = require('redux-observable'); const {ADD_LAYER, UPDATE_NODE, CHANGE_LAYER_PROPERTIES} = require('../../actions/layers'); const {CHANGE_DRAWING_STATUS, drawingFeatures, DRAWING_FEATURE, selectFeatures} = require('../../actions/draw'); const {set} = require('../../utils/ImmutableUtils'); -const {HIDE_MAPINFO_MARKER, PURGE_MAPINFO_RESULTS} = require('../../actions/mapInfo'); +const {HIDE_MAPINFO_MARKER, PURGE_MAPINFO_RESULTS, purgeMapInfoResults} = require('../../actions/mapInfo'); const {configureMap} = require('../../actions/config'); +const {CLOSE_IDENTIFY} = require('../../actions/mapInfo'); // const {TOGGLE_CONTROL} = require('../../actions/controls'); const {editAnnotation, confirmRemoveAnnotation, saveAnnotation, cancelEditAnnotation, setStyle, highlight, cleanHighlight, download, loadAnnotations, SET_STYLE, toggleStyle, - resetCoordEditor, changeRadius, changeText, changeSelected, confirmDeleteFeature + resetCoordEditor, changeRadius, changeText, changeSelected, confirmDeleteFeature, openEditor, SHOW_ANNOTATION } = require('../../actions/annotations'); -const {TOGGLE_CONTROL, toggleControl} = require('../../actions/controls'); +const {TOGGLE_CONTROL, toggleControl, SET_CONTROL_PROPERTY} = require('../../actions/controls'); const {addAnnotationsLayerEpic, editAnnotationEpic, removeAnnotationEpic, saveAnnotationEpic, newAnnotationEpic, addAnnotationEpic, disableInteractionsEpic, cancelEditAnnotationEpic, startDrawingMultiGeomEpic, endDrawGeomEpic, endDrawTextEpic, cancelTextAnnotationsEpic, setStyleEpic, restoreStyleEpic, highlighAnnotationEpic, cleanHighlightAnnotationEpic, closeAnnotationsEpic, confirmCloseAnnotationsEpic, downloadAnnotations, onLoadAnnotations, onChangedSelectedFeatureEpic, onBackToEditingFeatureEpic, redrawOnChangeRadiusEpic, redrawOnChangeTextEpic, - editSelectedFeatureEpic, editCircleFeatureEpic, closeMeasureToolEpic + editSelectedFeatureEpic, editCircleFeatureEpic, purgeMapInfoEpic, closeMeasureToolEpic, openEditorEpic } = require('../annotations')({}); const rootEpic = combineEpics(addAnnotationsLayerEpic, editAnnotationEpic, removeAnnotationEpic, saveAnnotationEpic, newAnnotationEpic, addAnnotationEpic, disableInteractionsEpic, cancelEditAnnotationEpic, startDrawingMultiGeomEpic, endDrawGeomEpic, endDrawTextEpic, cancelTextAnnotationsEpic, setStyleEpic, restoreStyleEpic, highlighAnnotationEpic, cleanHighlightAnnotationEpic, closeAnnotationsEpic, confirmCloseAnnotationsEpic, downloadAnnotations, onLoadAnnotations, onChangedSelectedFeatureEpic, onBackToEditingFeatureEpic, redrawOnChangeRadiusEpic, redrawOnChangeTextEpic, - editSelectedFeatureEpic, editCircleFeatureEpic, closeMeasureToolEpic + editSelectedFeatureEpic, editCircleFeatureEpic, purgeMapInfoEpic, closeMeasureToolEpic, openEditorEpic ); const epicMiddleware = createEpicMiddleware(rootEpic); const mockStore = configureMockStore([epicMiddleware]); @@ -153,10 +154,10 @@ describe('annotations Epics', () => { it('remove annotation', (done) => { store.subscribe(() => { const actions = store.getActions(); - if (actions.length >= 8) { - expect(actions[5].type).toBe(UPDATE_NODE); - expect(actions[6].type).toBe(HIDE_MAPINFO_MARKER); - expect(actions[7].type).toBe(PURGE_MAPINFO_RESULTS); + if (actions.length >= 6) { + expect(actions[3].type).toBe(UPDATE_NODE); + expect(actions[4].type).toBe(HIDE_MAPINFO_MARKER); + expect(actions[5].type).toBe(PURGE_MAPINFO_RESULTS); done(); } }); @@ -571,4 +572,32 @@ describe('annotations Epics', () => { store.dispatch(action); }); + it('purgeMapInfoEpic', (done) => { + let action = purgeMapInfoResults(); + + store.subscribe(() => { + const actions = store.getActions(); + if (actions.length >= 2) { + expect(actions[1].type).toBe(CHANGE_DRAWING_STATUS); + done(); + } + }); + + store.dispatch(action); + }); + it('openEditorEpic', (done) => { + let action = openEditor("1"); + + store.subscribe(() => { + const actions = store.getActions(); + if (actions.length >= 4) { + expect(actions[1].type).toBe(CLOSE_IDENTIFY); + expect(actions[2].type).toBe(SET_CONTROL_PROPERTY); + expect(actions[3].type).toBe(SHOW_ANNOTATION); + done(); + } + }); + + store.dispatch(action); + }); }); diff --git a/web/client/epics/annotations.js b/web/client/epics/annotations.js index 1877a3b7b5..1d31ef6af4 100644 --- a/web/client/epics/annotations.js +++ b/web/client/epics/annotations.js @@ -9,7 +9,7 @@ const Rx = require('rxjs'); const {saveAs} = require('file-saver'); const {MAP_CONFIG_LOADED} = require('../actions/config'); -const {TOGGLE_CONTROL, toggleControl} = require('../actions/controls'); +const {TOGGLE_CONTROL, toggleControl, setControlProperty} = require('../actions/controls'); const {addLayer, updateNode, changeLayerProperties, removeLayer} = require('../actions/layers'); const {hideMapinfoMarker, purgeMapInfoResults} = require('../actions/mapInfo'); const {set} = require('../utils/ImmutableUtils'); @@ -18,10 +18,13 @@ const {reprojectGeoJson} = require('../utils/CoordinatesUtils'); const {error} = require('../actions/notifications'); const {updateAnnotationGeometry, setStyle, toggleStyle, cleanHighlight, toggleAdd, + showAnnotation, editAnnotation, CONFIRM_REMOVE_ANNOTATION, SAVE_ANNOTATION, EDIT_ANNOTATION, CANCEL_EDIT_ANNOTATION, SET_STYLE, RESTORE_STYLE, HIGHLIGHT, CLEAN_HIGHLIGHT, CONFIRM_CLOSE_ANNOTATIONS, START_DRAWING, CANCEL_CLOSE_TEXT, SAVE_TEXT, DOWNLOAD, LOAD_ANNOTATIONS, CHANGED_SELECTED, RESET_COORD_EDITOR, CHANGE_RADIUS, - ADD_NEW_FEATURE, CHANGE_TEXT, NEW_ANNOTATION, TOGGLE_STYLE, CONFIRM_DELETE_FEATURE} = require('../actions/annotations'); + ADD_NEW_FEATURE, CHANGE_TEXT, NEW_ANNOTATION, TOGGLE_STYLE, CONFIRM_DELETE_FEATURE, OPEN_EDITOR +} = require('../actions/annotations'); +const {closeIdentify} = require('../actions/mapInfo'); const {FEATURES_SELECTED, GEOMETRY_CHANGED, DRAWING_FEATURE} = require('../actions/draw'); const {PURGE_MAPINFO_RESULTS} = require('../actions/mapInfo'); @@ -181,7 +184,7 @@ module.exports = (viewer) => ({ return Rx.Observable.from([ changeDrawingStatus("replace", store.getState().annotations.featureType, "annotations", [store.getState().annotations.editing], {}), toggleDrawOrEdit(store.getState()) - ]); + ]); } const newFeatures = annotationsLayerSelector(store.getState()).features.filter(f => f.properties.id !== action.id); return Rx.Observable.from([ @@ -192,6 +195,15 @@ module.exports = (viewer) => ({ purgeMapInfoResults() ].concat(newFeatures.length === 0 ? [removeLayer('annotations')] : [])); }), + openEditorEpic: action$ => action$.ofType(OPEN_EDITOR) + .switchMap((action) => { + return Rx.Observable.from([ + closeIdentify(), + setControlProperty("annotations", "enabled", true), + showAnnotation(action.id), + editAnnotation(action.id) + ]); + }), saveAnnotationEpic: (action$, store) => action$.ofType(SAVE_ANNOTATION) .switchMap((action) => { const annotationsLayer = head(store.getState().layers.flat.filter(l => l.id === 'annotations')); @@ -219,13 +231,19 @@ module.exports = (viewer) => ({ changeLayerProperties('annotations', {visibility: true}) ])); }), - cancelEditAnnotationEpic: (action$, store) => action$.ofType(CANCEL_EDIT_ANNOTATION, PURGE_MAPINFO_RESULTS) + cancelEditAnnotationEpic: (action$, store) => action$.ofType(CANCEL_EDIT_ANNOTATION) .switchMap(() => { return Rx.Observable.from([ changeDrawingStatus("clean", store.getState().annotations.featureType || '', "annotations", [], {}), changeLayerProperties('annotations', {visibility: true}) ]); }), + purgeMapInfoEpic: (action$, store) => action$.ofType( PURGE_MAPINFO_RESULTS) + .switchMap(() => { + return Rx.Observable.from([ + changeDrawingStatus("clean", store.getState().annotations.featureType || '', "annotations", [], {}) + ]); + }), startDrawingMultiGeomEpic: (action$, store) => action$.ofType(START_DRAWING) .filter(() => store.getState().annotations.editing.features && !!store.getState().annotations.editing.features.length || store.getState().annotations.featureType === "Circle") .switchMap( () => { diff --git a/web/client/epics/catalog.js b/web/client/epics/catalog.js index 9edce1359e..d3849263eb 100644 --- a/web/client/epics/catalog.js +++ b/web/client/epics/catalog.js @@ -12,6 +12,7 @@ const {showLayerMetadata} = require('../actions/layers'); const {error, success} = require('../actions/notifications'); const {SET_CONTROL_PROPERTY} = require('../actions/controls'); const {closeFeatureGrid} = require('../actions/featuregrid'); +const {purgeMapInfoResults, hideMapinfoMarker} = require('../actions/mapInfo'); const {newServiceSelector, selectedServiceSelector, servicesSelector} = require('../selectors/catalog'); const {getSelectedLayer} = require('../selectors/layers'); const axios = require('../libs/ajax'); @@ -116,11 +117,16 @@ module.exports = (API) => ({ let deleteServiceAction = deleteCatalogService(selectedService); return services[selectedService] ? Rx.Observable.of(notification, deleteServiceAction) : Rx.Observable.of(notification); }), - closeFeatureGridEpic: (action$) => + /** + catalog opening must close other panels like: + - GFI + - FeatureGrid + */ + openCatalogEpic: (action$) => action$.ofType(SET_CONTROL_PROPERTY) .filter((action) => action.control === "metadataexplorer" && action.value) .switchMap(() => { - return Rx.Observable.of(closeFeatureGrid()); + return Rx.Observable.of(closeFeatureGrid(), purgeMapInfoResults(), hideMapinfoMarker()); }), getMetadataRecordById: (action$, store) => action$.ofType(GET_METADATA_RECORD_BY_ID) diff --git a/web/client/epics/maplayout.js b/web/client/epics/maplayout.js index d51f4c4df5..f4dd20f5ce 100644 --- a/web/client/epics/maplayout.js +++ b/web/client/epics/maplayout.js @@ -12,7 +12,7 @@ const {MAP_CONFIG_LOADED} = require('../actions/config'); const {SIZE_CHANGE, CLOSE_FEATURE_GRID, OPEN_FEATURE_GRID} = require('../actions/featuregrid'); const {PURGE_MAPINFO_RESULTS, ERROR_FEATURE_INFO} = require('../actions/mapInfo'); const {SHOW_SETTINGS, HIDE_SETTINGS} = require('../actions/layers'); -const {mapInfoRequestsSelector} = require('../selectors/mapinfo'); +const {isMapInfoOpen} = require('../selectors/mapinfo'); /** * Epìcs for feature grid @@ -36,7 +36,7 @@ const updateMapLayoutEpic = (action$, store) => .switchMap(() => { if (get(store.getState(), "browser.mobile")) { - const bottom = mapInfoRequestsSelector(store.getState()).length > 0 ? {bottom: '50%'} : {bottom: undefined}; + const bottom = isMapInfoOpen(store.getState()) ? {bottom: '50%'} : {bottom: undefined}; const boundingMapRect = { ...bottom }; @@ -49,7 +49,7 @@ const updateMapLayoutEpic = (action$, store) => if (get(store.getState(), "mode") === 'embedded') { const height = {height: 'calc(100% - ' + mapLayout.bottom.sm + 'px)'}; - const bottom = mapInfoRequestsSelector(store.getState()).length > 0 ? {bottom: '50%'} : {bottom: undefined}; + const bottom = isMapInfoOpen(store.getState()) ? {bottom: '50%'} : {bottom: undefined}; const boundingMapRect = { ...bottom }; @@ -70,7 +70,7 @@ const updateMapLayoutEpic = (action$, store) => get(store.getState(), "controls.details.enabled") && {right: mapLayout.right.md} || null, get(store.getState(), "controls.annotations.enabled") && {right: mapLayout.right.md} || null, get(store.getState(), "controls.metadataexplorer.enabled") && {right: mapLayout.right.md} || null, - mapInfoRequestsSelector(store.getState()).length > 0 && {right: mapLayout.right.md} || null + isMapInfoOpen(store.getState()) && {right: mapLayout.right.md} || null ].filter(panel => panel)) || {right: 0}; const dockSize = getDockSize(store.getState()) * 100; diff --git a/web/client/plugins/Annotations.jsx b/web/client/plugins/Annotations.jsx index b808599261..36948c9fa3 100644 --- a/web/client/plugins/Annotations.jsx +++ b/web/client/plugins/Annotations.jsx @@ -22,7 +22,7 @@ const {cancelRemoveAnnotation, confirmRemoveAnnotation, editAnnotation, newAnnot cancelCloseAnnotations, confirmCloseAnnotations, startDrawing, changeStyler, setUnsavedChanges, toggleUnsavedChangesModal, changedProperties, setUnsavedStyle, toggleUnsavedStyleModal, addText, download, loadAnnotations, changeSelected, resetCoordEditor, changeRadius, changeText, toggleUnsavedGeometryModal, addNewFeature, setInvalidSelected, - highlightPoint, confirmDeleteFeature, toggleDeleteFtModal, changeFormat + highlightPoint, confirmDeleteFeature, toggleDeleteFtModal, changeFormat, openEditor } = require('../actions/annotations'); const { zoomToExtent } = require('../actions/map'); @@ -37,6 +37,7 @@ const commonEditorActions = { onConfirmDeleteFeature: confirmDeleteFeature, onCleanHighlight: cleanHighlight, onHighlightPoint: highlightPoint, + onHighlight: highlight, onError: validationError, onSave: saveAnnotation, onRemove: removeAnnotation, @@ -62,6 +63,10 @@ const commonEditorActions = { onChangeRadius: changeRadius, onSetInvalidSelected: setInvalidSelected, onChangeText: changeText, + onCancelRemove: cancelRemoveAnnotation, + onCancelClose: cancelCloseAnnotations, + onConfirmClose: confirmCloseAnnotations, + onConfirmRemove: confirmRemoveAnnotation, onDownload: download }; const AnnotationsEditor = connect(annotationsInfoSelector, @@ -72,12 +77,8 @@ const AnnotationsEditor = connect(annotationsInfoSelector, const AnnotationsInfoViewer = connect(annotationsInfoSelector, { - onCancelRemove: cancelRemoveAnnotation, - onCancelEdit: cancelEditAnnotation, - onCancelClose: cancelCloseAnnotations, - onConfirmClose: confirmCloseAnnotations, - onConfirmRemove: confirmRemoveAnnotation, - ...commonEditorActions + ...commonEditorActions, + onEdit: openEditor })(require('../components/mapcontrols/annotations/AnnotationsEditor')); const panelSelector = createSelector([annotationsListSelector], (list) => ({ diff --git a/web/client/reducers/__tests__/annotations-test.js b/web/client/reducers/__tests__/annotations-test.js index e1cf596438..a1b23da64c 100644 --- a/web/client/reducers/__tests__/annotations-test.js +++ b/web/client/reducers/__tests__/annotations-test.js @@ -11,6 +11,21 @@ const annotations = require('../annotations'); const {DEFAULT_ANNOTATIONS_STYLES} = require('../../utils/AnnotationsUtils'); const {isEmpty} = require('lodash'); +const testFeatures = { + point1: { + properties: { id: '1' }, + geometry: { type: "Point", coordinates: [1, 1] } + }, + point1Changed: { + properties: {id: '1'}, + geometry: { type: "Point", coordinates: [10, 1]} + }, + lineString1: { + properties: { id: 'line1' }, + geometry: { type: "LineString", coordinates: [[1, 1], [3, 3]] } + } +}; + const { REMOVE_ANNOTATION, CONFIRM_REMOVE_ANNOTATION, CANCEL_REMOVE_ANNOTATION, EDIT_ANNOTATION, CANCEL_EDIT_ANNOTATION, SAVE_ANNOTATION, TOGGLE_ADD, @@ -764,73 +779,50 @@ describe('Test the annotations reducer', () => { }); it('resetCoordEditor in creation mode of a Point ', () => { - const feature = { - properties: { - id: '1' - }, - geometry: { - type: "Point", - coordinates: [1, 1] - } - }; + const {point1, lineString1} = testFeatures; const featureColl = { type: "FeatureCollection", - features: [], - properties: { - id: '1asdfads' - }, + features: [lineString1], + tempFeatures: [lineString1], + properties: { id: '1asdfads' }, style: {} }; const state = annotations({ editing: featureColl, - selected: feature, + selected: point1, + drawing: true, unsavedGeometry: false }, resetCoordEditor()); expect(state.unsavedGeometry).toBe(false); expect(state.selected).toBe(null); expect(state.drawing).toBe(false); expect(state.showUnsavedGeometryModal).toBe(false); - expect(state.editing.features.length).toBe(0); + expect(state.editing.features.length).toBe(1); + expect(state.editing.features[0].geometry.type).toBe("LineString"); }); it('resetCoordEditor in edit mode of a Point, with no Changes ', () => { - const feature = { - properties: { - id: '1' - }, - geometry: { - type: "Point", - coordinates: [1, 1] - } - }; - const featureChanged = { - properties: { - id: '1' - }, - geometry: { - type: "Point", - coordinates: [10, 1] - } - }; + const {point1, point1Changed} = testFeatures; + const featureColl = { type: "FeatureCollection", - features: [feature], - properties: { - id: '1asdfads' - }, + features: [point1], + tempFeatures: [point1], + properties: { id: '1asdfads' }, style: {} }; const state = annotations({ editing: featureColl, - selected: featureChanged, + selected: point1Changed, + drawing: false, unsavedGeometry: false }, resetCoordEditor()); expect(state.unsavedGeometry).toBe(false); expect(state.selected).toBe(null); expect(state.drawing).toBe(false); expect(state.showUnsavedGeometryModal).toBe(false); - expect(state.editing.features.length).toBe(0); + expect(state.editing.features.length).toBe(1); }); @@ -849,6 +841,7 @@ describe('Test the annotations reducer', () => { const featureColl = { type: "FeatureCollection", features: [], + tempFeatures: [], properties: { id: '1asdfads' }, @@ -869,39 +862,21 @@ describe('Test the annotations reducer', () => { }); it('resetCoordEditor in edit mode of a Point, with Changes ', () => { - const feature = { - properties: { - id: '1' - }, - geometry: { - type: "Point", - coordinates: [1, 1] - } - }; - const featureChanged = { - properties: { - id: '1' - }, - geometry: { - type: "Point", - coordinates: [10, 1] - } - }; + const {point1, point1Changed} = testFeatures; + const featureColl = { type: "FeatureCollection", - features: [featureChanged], - tempFeatures: [feature], - properties: { - id: '1asdfads' - }, + features: [point1Changed], + tempFeatures: [point1], + properties: { id: '1asdfads' }, style: {} }; const state = annotations({ editing: featureColl, - selected: featureChanged, + selected: point1Changed, unsavedGeometry: true }, resetCoordEditor()); - expect(state.unsavedGeometry).toBe(true); + expect(state.unsavedGeometry).toBe(false); expect(state.selected).toBe(null); expect(state.drawing).toBe(false); expect(state.showUnsavedGeometryModal).toBe(false); diff --git a/web/client/reducers/annotations.js b/web/client/reducers/annotations.js index 3034b4627b..0cac72ee29 100644 --- a/web/client/reducers/annotations.js +++ b/web/client/reducers/annotations.js @@ -297,10 +297,12 @@ function annotations(state = { validationErrors: {} }, action) { let newState = set(`editing.features`, state.editing.features.map(f => { return set("properties.canEdit", false, f); }), state); - const oldfeatures = newState.editing.features; + const newfeatures = newState.editing.features; + const tempFeatures = newState.editing.tempFeatures; // only for the circles the feature is not being added - const features = state.unsavedGeometry ? state.editing.tempFeatures : - (newState.featureType !== "Circle" ? slice(oldfeatures, 0, oldfeatures.length - 1) : oldfeatures); + + const features = !state.unsavedGeometry ? state.editing.tempFeatures : + (newState.featureType !== "Circle" ? state.drawing ? slice(newfeatures, 0, newfeatures.length - 1) : tempFeatures : tempFeatures); return assign({}, newState, { editing: { ...newState.editing, @@ -308,6 +310,7 @@ function annotations(state = { validationErrors: {} }, action) { }, drawing: false, coordinateEditorEnabled: false, + unsavedGeometry: false, selected: null, showUnsavedGeometryModal: false }); diff --git a/web/client/selectors/__tests__/annotations-test.js b/web/client/selectors/__tests__/annotations-test.js index 2de3a4c568..a8782528f6 100644 --- a/web/client/selectors/__tests__/annotations-test.js +++ b/web/client/selectors/__tests__/annotations-test.js @@ -524,14 +524,14 @@ describe('Test annotations selectors', () => { }); it('test annotationsInfoSelector', () => { const retVal = annotationsInfoSelector(state); - expect(Object.keys(retVal).length).toBe(22); + expect(Object.keys(retVal).length).toBe(23); const params = ["closing", "config", "drawing", "drawingText", "errors", "editing", "coordinateEditorEnabled", "editedFields", "mode", "removing", "selected", "featureType", "showUnsavedChangesModal", "showUnsavedStyleModal", "showUnsavedGeometryModal", "showDeleteFeatureModal", "stylerType", "styling", "unsavedChanges", "unsavedStyle", - "unsavedGeometry", "format" ]; + "unsavedGeometry", "format", "mouseHoverEvents" ]; Object.keys(retVal).forEach(r => { expect(params.indexOf(r) !== -1).toBe(true); }); diff --git a/web/client/selectors/__tests__/mapinfo-test.js b/web/client/selectors/__tests__/mapinfo-test.js index 64c742b0c3..1faab80105 100644 --- a/web/client/selectors/__tests__/mapinfo-test.js +++ b/web/client/selectors/__tests__/mapinfo-test.js @@ -8,7 +8,7 @@ const expect = require('expect'); -const {mapInfoRequestsSelector, generalInfoFormatSelector, stopGetFeatureInfoSelector} = require('../mapinfo'); +const {mapInfoRequestsSelector, generalInfoFormatSelector, stopGetFeatureInfoSelector, isMapInfoOpen} = require('../mapinfo'); describe('Test mapinfo selectors', () => { it('test generalInfoFormatSelector default value', () => { @@ -37,6 +37,18 @@ describe('Test mapinfo selectors', () => { }); expect(props).toEqual(['request']); }); + it('test isMapInfoOpen no state', () => { + const props = isMapInfoOpen({}); + expect(props).toEqual(false); + }); + it('test isMapInfoOpen', () => { + const props = isMapInfoOpen({ + mapInfo: { + requests: ['request'] + } + }); + expect(props).toEqual(true); + }); it('test stopGetFeatureInfoSelector', () => { const props = stopGetFeatureInfoSelector({ mapInfo: { diff --git a/web/client/selectors/annotations.js b/web/client/selectors/annotations.js index c2ef32613e..a81344a043 100644 --- a/web/client/selectors/annotations.js +++ b/web/client/selectors/annotations.js @@ -8,6 +8,7 @@ const {createSelector} = require('reselect'); const {layersSelector} = require('./layers'); +const {isMapInfoOpen} = require('./mapInfo'); const {head, get} = require('lodash'); const assign = require('object-assign'); @@ -42,6 +43,7 @@ const errorsSelector = (state) => get(state, "annotations.validationErrors", {}) const configSelector = (state) => get(state, "annotations.config", {}); const annotationsInfoSelector = (state) => (assign({}, { + mouseHoverEvents: isMapInfoOpen(state), closing: closingSelector(state), format: formatSelector(state), config: configSelector(state), diff --git a/web/client/selectors/mapinfo.js b/web/client/selectors/mapinfo.js index cfd7d5eec9..49a0f2a286 100644 --- a/web/client/selectors/mapinfo.js +++ b/web/client/selectors/mapinfo.js @@ -27,6 +27,7 @@ const {queryPanelSelector} = require('./controls'); * @return {object} the mapinfo requests */ const mapInfoRequestsSelector = state => get(state, "mapInfo.requests") || []; +const isMapInfoOpen = state => !!mapInfoRequestsSelector(state) && mapInfoRequestsSelector(state).length > 0; /** * selects generalInfoFormat from state @@ -56,6 +57,7 @@ const stopGetFeatureInfoSelector = createSelector(mapInfoDisabledSelector, measu (isMapInfoDisabled, isMeasureActive, isDrawSupportActive, isGridEditing, isAnnotationsEditing, isQueryPanelActive) => isMapInfoDisabled || !!isMeasureActive || isDrawSupportActive || isGridEditing || !!isAnnotationsEditing || !!isQueryPanelActive); module.exports = { + isMapInfoOpen, generalInfoFormatSelector, mapInfoRequestsSelector, stopGetFeatureInfoSelector diff --git a/web/client/themes/default/less/annotations.less b/web/client/themes/default/less/annotations.less index 15dd7104ef..659f909d43 100644 --- a/web/client/themes/default/less/annotations.less +++ b/web/client/themes/default/less/annotations.less @@ -453,3 +453,22 @@ } } + +.mapstore-identify-viewer { + .mapstore-annotations-info-viewer { + .mapstore-annotations-info-viewer-buttons { + -webkit-box-shadow: none; + box-shadow: none; + } + } + .mapstore-annotations-info-viewer.hover-background:hover { + background: @ms2-color-shade-super-lighter; + } + .mapstore-annotations-info-viewer+.mapstore-annotations-info-viewer { + .mapstore-annotations-info-viewer-buttons { + border-top: 1px solid @ms2-color-shade-lighter; + padding-top: 5px; + margin-top: 5px; + } + } +} diff --git a/web/client/themes/default/variables.less b/web/client/themes/default/variables.less index 47dbe0e540..d7ec1e4f43 100644 --- a/web/client/themes/default/variables.less +++ b/web/client/themes/default/variables.less @@ -39,6 +39,8 @@ @ms2-color-shade-dark: #333333; @ms2-color-shade-light: #999999; @ms2-color-shade-lighter: #dddddd; +@ms2-color-shade-super-lighter: lighten(@ms2-color-shade-lighter, 10%); + @icon-margin-ratio: 2; @icon-resize-ratio: 1.6; diff --git a/web/client/translations/data.de-DE b/web/client/translations/data.de-DE index 0e0dc2e872..cd6a1829c7 100644 --- a/web/client/translations/data.de-DE +++ b/web/client/translations/data.de-DE @@ -755,7 +755,7 @@ "addMarker": "Fügen Sie eine Geometrie hinzu", "styleGeometry": "Stil ändern", "deleteGeometry": "Entfernen Sie alle Anmerkungsgeometrien", - "removeannotation": "Möchten Sie die Annotation entfernen?", + "removeannotation": "Möchten Sie die Anmerkung mit Titel entfernen: {title}?", "removegeometry": "Möchten Sie alle Annotationspunkte entfernen?", "confirm": "Bestätigen", "title": "Anmerkungen", diff --git a/web/client/translations/data.en-US b/web/client/translations/data.en-US index 0b7621916c..9048ec0845 100644 --- a/web/client/translations/data.en-US +++ b/web/client/translations/data.en-US @@ -756,7 +756,7 @@ "addMarker": "Add a new geometry", "styleGeometry": "Change style", "deleteGeometry": "Remove all annotation geometries", - "removeannotation": "Do you want to remove the annotation?", + "removeannotation": "Do you want to remove the annotation with title: {title}?", "removegeometry": "Do you want to remove all annotation features?", "confirm": "Confirm", "mandatory": "Mandatory field", diff --git a/web/client/translations/data.es-ES b/web/client/translations/data.es-ES index 8b298df02b..5fb1d5b4ad 100644 --- a/web/client/translations/data.es-ES +++ b/web/client/translations/data.es-ES @@ -755,7 +755,7 @@ "addMarker": "Agrega una geometría", "styleGeometry": "Cambia estilo", "deleteGeometry": "Eliminar todas las geometrías de anotación", - "removeannotation": "Desea eliminar la anotación?", + "removeannotation": "Desea eliminar la anotación con título: {title}?", "removegeometry": "Desea eliminar todos los puntos de anotación?", "confirm": "Confirmar", "title": "Anotaciones", diff --git a/web/client/translations/data.fr-FR b/web/client/translations/data.fr-FR index 9c5482766e..efc09342c6 100644 --- a/web/client/translations/data.fr-FR +++ b/web/client/translations/data.fr-FR @@ -756,7 +756,7 @@ "addMarker": "Ajouter une géométrie", "styleGeometry": "Changer le style", "deleteGeometry": "Supprimer toutes les géométries d'annotations", - "removeannotation": "Voulez-vous supprimer l'annotation?", + "removeannotation": "Voulez-vous supprimer l'annotation avec titre: {title}?", "removegeometry": "Voulez-vous supprimer tous les points d'annotation?", "confirm": "Confirmer", "title": "Annotations", diff --git a/web/client/translations/data.hr-HR b/web/client/translations/data.hr-HR index 3a5bfc4b2c..2dddf5d7b1 100644 --- a/web/client/translations/data.hr-HR +++ b/web/client/translations/data.hr-HR @@ -740,7 +740,7 @@ "addMarker": "Dodaj novu točku na karti", "styleGeometry": "Odaberi različiti stil za točke", "deleteGeometry": "Ukloni geometrije napomena", - "removeannotation": "Želite li ukloniti pribilješku?", + "removeannotation": "Do you want to remove the annotation with title: {title}?", "removegeometry": "Želite li ukloniti sve pribilješke?", "confirm": "Potvrdi", "undoGeom": "Are you sure to exit without saving? (You will lose any changes)", diff --git a/web/client/translations/data.it-IT b/web/client/translations/data.it-IT index f0290f0fe5..ffac349455 100644 --- a/web/client/translations/data.it-IT +++ b/web/client/translations/data.it-IT @@ -755,7 +755,7 @@ "addMarker": "Aggiungi una geometria", "styleGeometry": "Cambia stile", "deleteGeometry": "Rimuovi tutte le feature", - "removeannotation": "Vuoi rimuovere l'annotazione?", + "removeannotation": "Vuoi rimuovere l'annotazione con titolo: {title}?", "removegeometry": "Vuoi rimuovere tutti i punti dell'annotazione?", "confirm": "Conferma", "mandatory": "Campo obbligatorio", diff --git a/web/client/translations/data.nl-NL b/web/client/translations/data.nl-NL index 2811fb9e2a..31c538bf69 100644 --- a/web/client/translations/data.nl-NL +++ b/web/client/translations/data.nl-NL @@ -606,7 +606,7 @@ "addMarker": "Add a new geometry", "styleGeometry": "Change style", "deleteGeometry": "Remove all annotation geometries", - "removeannotation": "Do you want to remove the annotation?", + "removeannotation": "Do you want to remove the annotation with title: {title}?", "removegeometry": "Do you want to remove all annotation features?", "confirm": "Confirm", "mandatory": "Mandatory field", diff --git a/web/client/translations/data.zh-ZH b/web/client/translations/data.zh-ZH index 8ec1e16fe5..33145dd982 100644 --- a/web/client/translations/data.zh-ZH +++ b/web/client/translations/data.zh-ZH @@ -619,7 +619,7 @@ "addMarker": "在地图上添加一个新点", "styleGeometry": "为点选择不同的风格", "deleteGeometry": "Remove all annotation geometries", - "removeannotation": "你想删除标注?", + "removeannotation": "Do you want to remove the annotation with title: {title}?", "removegeometry": "你想删除所有标注点吗??", "confirm": "确认", "mandatory": "必填项", From 9c8266ca8984a8d5c6247bf831d7c9ae6d17bd6a Mon Sep 17 00:00:00 2001 From: Matteo Velludini Date: Thu, 28 Jun 2018 14:48:24 +0200 Subject: [PATCH 2/2] fix tests and improve login reset coord editor --- .../annotations/AnnotationsEditor.jsx | 1 - .../__tests__/AnnotationsEditor-test.js | 29 +++++++++++++++++++ .../reducers/__tests__/annotations-test.js | 3 +- web/client/reducers/annotations.js | 7 +++-- web/client/selectors/annotations.js | 2 +- 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx b/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx index dfe92e4895..38cdf9075f 100644 --- a/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx +++ b/web/client/components/mapcontrols/annotations/AnnotationsEditor.jsx @@ -259,7 +259,6 @@ class AnnotationsEditor extends React.Component { visible: true, onClick: () => { this.setState({removing: this.props.id}); - // this.props.onRemove(this.props.id); } }, { glyph: 'download', diff --git a/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js b/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js index ad1aeff926..8a7a273d35 100644 --- a/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js +++ b/web/client/components/mapcontrols/annotations/__tests__/AnnotationsEditor-test.js @@ -121,7 +121,36 @@ describe("test the AnnotationsEditor Panel", () => { expect(spyEdit.calls.length).toEqual(1); expect(spyRemove.calls.length).toEqual(0); }); + it('test click remove annotation', () => { + const feature = { + id: "1", + title: 'mytitle', + description: 'desc' + }; + + const testHandlers = { + onEditHandler: (id) => { return id; }, + onRemoveHandler: (id) => { return id; } + }; + + const spyEdit = expect.spyOn(testHandlers, 'onEditHandler'); + const viewer = ReactDOM.render(, document.getElementById("container")); + expect(viewer).toExist(); + + let removeButton = ReactDOM.findDOMNode(TestUtils.scryRenderedDOMComponentsWithTag(viewer, "button")[2]); + + expect(removeButton).toExist(); + TestUtils.Simulate.click(removeButton); + + const dialog = document.getElementById("confirm-dialog"); + let buttons = document.getElementsByTagName("button"); + + expect(spyEdit.calls.length).toEqual(0); + expect(dialog).toExist(); + expect(buttons.length).toBe(7); + }); it('test click remove geometry', () => { const feature = { id: "1", diff --git a/web/client/reducers/__tests__/annotations-test.js b/web/client/reducers/__tests__/annotations-test.js index a1b23da64c..73e2709851 100644 --- a/web/client/reducers/__tests__/annotations-test.js +++ b/web/client/reducers/__tests__/annotations-test.js @@ -782,12 +782,13 @@ describe('Test the annotations reducer', () => { const {point1, lineString1} = testFeatures; const featureColl = { type: "FeatureCollection", - features: [lineString1], + features: [lineString1, point1], tempFeatures: [lineString1], properties: { id: '1asdfads' }, style: {} }; const state = annotations({ + featureType: "Point", editing: featureColl, selected: point1, drawing: true, diff --git a/web/client/reducers/annotations.js b/web/client/reducers/annotations.js index 0cac72ee29..a75498a310 100644 --- a/web/client/reducers/annotations.js +++ b/web/client/reducers/annotations.js @@ -298,11 +298,12 @@ function annotations(state = { validationErrors: {} }, action) { return set("properties.canEdit", false, f); }), state); const newfeatures = newState.editing.features; - const tempFeatures = newState.editing.tempFeatures; // only for the circles the feature is not being added - const features = !state.unsavedGeometry ? state.editing.tempFeatures : - (newState.featureType !== "Circle" ? state.drawing ? slice(newfeatures, 0, newfeatures.length - 1) : tempFeatures : tempFeatures); + let features = newState.editing.tempFeatures; + if (state.featureType !== "Circle" && state.drawing) { + features = slice(newfeatures, 0, newfeatures.length - 1); + } return assign({}, newState, { editing: { ...newState.editing, diff --git a/web/client/selectors/annotations.js b/web/client/selectors/annotations.js index a81344a043..a509a8b3df 100644 --- a/web/client/selectors/annotations.js +++ b/web/client/selectors/annotations.js @@ -8,7 +8,7 @@ const {createSelector} = require('reselect'); const {layersSelector} = require('./layers'); -const {isMapInfoOpen} = require('./mapInfo'); +const {isMapInfoOpen} = require('./mapinfo'); const {head, get} = require('lodash'); const assign = require('object-assign');