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

GFI and annotations fixes #3035

Merged
merged 2 commits into from
Jun 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions web/client/actions/__tests__/annotations-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 8 additions & 0 deletions web/client/actions/annotations.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
33 changes: 28 additions & 5 deletions web/client/components/map/openlayers/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
4 changes: 2 additions & 2 deletions web/client/components/map/openlayers/__tests__/Map-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down
5 changes: 3 additions & 2 deletions web/client/components/mapcontrols/annotations/Annotations.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,10 @@ class Annotations extends React.Component {
closeGlyph="1-close"
confirmButtonContent={<Message msgId="annotations.confirm" />}
closeText={<Message msgId="annotations.cancel" />}>
<Message msgId={this.props.mode === 'editing' ? "annotations.removegeometry" : "annotations.removeannotation"}/>
{this.props.mode === 'editing' ? <Message msgId="annotations.removegeometry"/> :
<Message msgId="annotations.removeannotation" msgParams={{title: this.props.editing && this.props.editing.properties && this.props.editing.properties.title}}/>}
</ConfirmDialog>);
}else if (this.state.selectFile) {
} else if (this.state.selectFile) {
body = (
<SelecAnnotationsFile
text={<Message msgId="annotations.selectfiletext"/>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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: ""
};

Expand Down Expand Up @@ -253,7 +257,9 @@ 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});
}
}, {
glyph: 'download',
tooltip: <Message msgId="annotations.downloadcurrenttooltip" />,
Expand Down Expand Up @@ -627,17 +633,24 @@ class AnnotationsEditor extends React.Component {
closeText={<Message msgId="annotations.cancel" />}>
<Message msgId="annotations.undoDeleteFeature" />
</ConfirmDialog></Portal>);
} else if (this.props.removing) {
} else if (this.state.removing) {
return (<Portal><ConfirmDialog
show
modal
onClose={this.props.onCancelRemove}
onConfirm={() => 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={<Message msgId="annotations.confirm" />}
closeText={<Message msgId="annotations.cancel" />}>
<Message msgId={this.props.mode === 'editing' ? "annotations.removegeometry" : "annotations.removeannotation"} />
{this.props.mode === 'editing' ? <Message msgId="annotations.removegeometry"/> :
<Message msgId="annotations.removeannotation" msgParams={{title: this.props.feature && this.props.feature.properties && this.props.feature.properties.title}}/>}
</ConfirmDialog></Portal>);
}
}
Expand All @@ -647,8 +660,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 (
<div className="mapstore-annotations-info-viewer">
<div className={"mapstore-annotations-info-viewer" + (this.props.mouseHoverEvents ? " hover-background" : "")} {...mouseHoverEvents}
>
{this.renderButtons(editing, this.props.coordinateEditorEnabled)}
{this.renderError(editing)}
{this.renderModals()}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ describe("test the AnnotationsEditor Panel", () => {
};

const spyEdit = expect.spyOn(testHandlers, 'onEditHandler');
const spyRemove = expect.spyOn(testHandlers, 'onRemoveHandler');

const viewer = ReactDOM.render(<AnnotationsEditor {...feature} onEdit={testHandlers.onEditHandler}
onRemove={testHandlers.onRemoveHandler}/>, document.getElementById("container"));
Expand All @@ -145,10 +144,13 @@ describe("test the AnnotationsEditor Panel", () => {
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(spyRemove.calls.length).toEqual(1);
expect(dialog).toExist();
expect(buttons.length).toBe(7);
});

it('test click remove geometry', () => {
const feature = {
id: "1",
Expand Down
47 changes: 38 additions & 9 deletions web/client/epics/__tests__/annotations-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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();
}
});
Expand Down Expand Up @@ -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);
});
});
Loading