diff --git a/web/client/components/mapcontrols/measure/__tests__/MeasureDialog-test.jsx b/web/client/components/mapcontrols/measure/__tests__/MeasureDialog-test.jsx
index 659d70899e..27c870b48d 100644
--- a/web/client/components/mapcontrols/measure/__tests__/MeasureDialog-test.jsx
+++ b/web/client/components/mapcontrols/measure/__tests__/MeasureDialog-test.jsx
@@ -48,7 +48,7 @@ describe("test the MeasureDialog", () => {
let measurement = {};
const mc = ReactDOM.render(
, document.getElementById("container"));
expect(mc).toExist();
- const dialog = document.getElementById('measure');
+ const dialog = document.getElementById('measure-dialog');
expect(dialog).toExist();
});
@@ -79,7 +79,7 @@ describe("test the MeasureDialog", () => {
const btnGroups = dom.getElementsByClassName('btn-group');
expect(btnGroups.length).toBe(2);
- const dialog = document.getElementById('measure');
+ const dialog = document.getElementById('measure-dialog');
expect(dialog).toNotExist();
expect(spyMount.calls.length).toBe(1);
expect(spyMount).toHaveBeenCalledWith(showCoordinateEditor);
@@ -119,7 +119,7 @@ describe("test the MeasureDialog", () => {
const btnGroups = dom.getElementsByClassName('btn-group');
expect(btnGroups.length).toBe(2);
- const dialog = document.getElementById('measure');
+ const dialog = document.getElementById('measure-dialog');
expect(dialog).toNotExist();
expect(spyMount.calls.length).toBe(1);
expect(spyToggleMeasure.calls.length).toBe(1);
diff --git a/web/client/components/misc/Dialog.jsx b/web/client/components/misc/Dialog.jsx
index 7ef917539d..1ccad14564 100644
--- a/web/client/components/misc/Dialog.jsx
+++ b/web/client/components/misc/Dialog.jsx
@@ -27,7 +27,8 @@ class Dialog extends React.Component {
onClickOut: PropTypes.func,
modal: PropTypes.bool,
start: PropTypes.object,
- draggable: PropTypes.bool
+ draggable: PropTypes.bool,
+ bounds: PropTypes.object
};
static defaultProps = {
@@ -35,7 +36,7 @@ class Dialog extends React.Component {
backgroundStyle: {
background: "rgba(0,0,0,.5)"
},
- start: {x: 0, y: 0},
+ start: {x: 0, y: 150},
className: "modal-dialog modal-content",
maskLoading: false,
containerClassName: "",
@@ -43,7 +44,8 @@ class Dialog extends React.Component {
bodyClassName: "modal-body",
footerClassName: "modal-footer",
modal: false,
- draggable: true
+ draggable: true,
+ bounds: 'parent'
};
renderLoading = () => {
@@ -72,7 +74,7 @@ class Dialog extends React.Component {
};
render() {
- const body = (
+ const body = (
{this.renderRole('header')}
@@ -84,7 +86,7 @@ class Dialog extends React.Component {
{this.renderRole('footer')}
:
}
);
- const dialog = this.props.draggable ? (
+ const dialog = this.props.draggable ? (
{body}
) : body;
let containerStyle = assign({}, this.props.style.display ? {display: this.props.style.display} : {}, this.props.backgroundStyle);
@@ -105,4 +107,5 @@ class Dialog extends React.Component {
};
}
+
module.exports = Dialog;
diff --git a/web/client/epics/__tests__/annotations-test.js b/web/client/epics/__tests__/annotations-test.js
index 38927ae692..602d5a29a7 100644
--- a/web/client/epics/__tests__/annotations-test.js
+++ b/web/client/epics/__tests__/annotations-test.js
@@ -16,7 +16,7 @@ const {set} = require('../../utils/ImmutableUtils');
const {HIDE_MAPINFO_MARKER, PURGE_MAPINFO_RESULTS, purgeMapInfoResults} = require('../../actions/mapInfo');
const {configureMap} = require('../../actions/config');
const {CLOSE_IDENTIFY} = require('../../actions/mapInfo');
-const {editAnnotation, confirmRemoveAnnotation, saveAnnotation, cancelEditAnnotation,
+const {editAnnotation, confirmRemoveAnnotation, saveAnnotation, startDrawing, cancelEditAnnotation,
setStyle, highlight, cleanHighlight, download, loadAnnotations, SET_STYLE, toggleStyle,
resetCoordEditor, changeRadius, changeText, changeSelected, confirmDeleteFeature, openEditor, SHOW_ANNOTATION
} = require('../../actions/annotations');
@@ -856,4 +856,24 @@ describe('annotations Epics', () => {
store.dispatch(action);
});
+ it('should safely start drawing annotation when no annotation config provided', (done) => {
+ store = mockStore({
+ annotations: {
+ editing: {
+ features: [{}]
+ }
+ }
+ });
+
+ store.subscribe(() => {
+ const actions = store.getActions();
+ if (actions.length >= 2) {
+ expect(actions[1].type).toBe(CHANGE_DRAWING_STATUS);
+ done();
+ }
+ });
+ const action = startDrawing();
+ store.dispatch(action);
+ });
+
});
diff --git a/web/client/epics/__tests__/catalog-test.js b/web/client/epics/__tests__/catalog-test.js
index b973ed09ed..5ae0bcd8b6 100644
--- a/web/client/epics/__tests__/catalog-test.js
+++ b/web/client/epics/__tests__/catalog-test.js
@@ -6,15 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
-const expect = require('expect');
-
+import expect from 'expect';
+import csw from '../../api/CSW';
const API = {
- csw: require('../../api/CSW')
+ csw
};
-const {getMetadataRecordById} = require('../catalog')(API);
-const {SHOW_NOTIFICATION} = require('../../actions/notifications');
-const {testEpic} = require('./epicTestUtils');
-const {getMetadataRecordById: initAction} = require('../../actions/catalog');
+import catalog from '../catalog';
+const {getMetadataRecordById} = catalog(API);
+import {SHOW_NOTIFICATION} from '../../actions/notifications';
+import {testEpic} from './epicTestUtils';
+import {getMetadataRecordById as initAction} from '../../actions/catalog';
describe('catalog Epics', () => {
it('getMetadataRecordById', (done) => {
@@ -35,4 +36,5 @@ describe('catalog Epics', () => {
});
});
+
});
diff --git a/web/client/epics/annotations.js b/web/client/epics/annotations.js
index ab3d3dd48b..a48cef202e 100644
--- a/web/client/epics/annotations.js
+++ b/web/client/epics/annotations.js
@@ -8,6 +8,7 @@
const Rx = require('rxjs');
const {saveAs} = require('file-saver');
+const {get} = require('lodash');
const {MAP_CONFIG_LOADED} = require('../actions/config');
const {TOGGLE_CONTROL, toggleControl, setControlProperty} = require('../actions/controls');
const {addLayer, updateNode, changeLayerProperties, removeLayer} = require('../actions/layers');
@@ -320,7 +321,7 @@ module.exports = (viewer) => ({
const feature = state.annotations.editing;
const type = state.annotations.featureType;
const defaultTextAnnotation = state.annotations.defaultTextAnnotation;
- const multiGeom = state.annotations.config.multiGeometry;
+ const multiGeom = get(state, 'annotations.config.multiGeometry');
const drawOptions = {
featureProjection: "EPSG:4326",
stopAfterDrawing: !multiGeom,
diff --git a/web/client/epics/catalog.js b/web/client/epics/catalog.js
index d3849263eb..e35523dec5 100644
--- a/web/client/epics/catalog.js
+++ b/web/client/epics/catalog.js
@@ -7,13 +7,23 @@
*/
const Rx = require('rxjs');
-const {ADD_SERVICE, GET_METADATA_RECORD_BY_ID, DELETE_SERVICE, deleteCatalogService, addCatalogService, savingService} = require('../actions/catalog');
+const {
+ ADD_SERVICE, GET_METADATA_RECORD_BY_ID, DELETE_SERVICE, deleteCatalogService, addCatalogService, savingService,
+ CHANGE_TEXT, textSearch
+} = require('../actions/catalog');
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 {
+ delayAutoSearchSelector,
+ newServiceSelector,
+ pageSizeSelector,
+ selectedServiceSelector,
+ servicesSelector,
+ selectedCatalogSelector
+} = require('../selectors/catalog');
const {getSelectedLayer} = require('../selectors/layers');
const axios = require('../libs/ajax');
@@ -162,5 +172,18 @@ module.exports = (API) => ({
position: "tc"
}), showLayerMetadata({}, false));
});
+ }),
+ autoSearchEpic: (action$, {getState = () => {}} = {}) =>
+ action$.ofType(CHANGE_TEXT)
+ .debounce(() => {
+ const state = getState();
+ const delay = delayAutoSearchSelector(state);
+ return Rx.Observable.timer(delay);
+ })
+ .switchMap(({text}) => {
+ const state = getState();
+ const pageSize = pageSizeSelector(state);
+ const {type, url} = selectedCatalogSelector(state);
+ return Rx.Observable.of(textSearch(type, url, 1, pageSize, text));
})
});
diff --git a/web/client/examples/api/index.html b/web/client/examples/api/index.html
index 5c0d58aa77..80ca465dd0 100644
--- a/web/client/examples/api/index.html
+++ b/web/client/examples/api/index.html
@@ -83,6 +83,9 @@ Embed MapStore2 in your website
Toggle Weather Layer (if present)
+