Skip to content

Commit

Permalink
Fix #1818. Add action triggering via JS-API
Browse files Browse the repository at this point in the history
  • Loading branch information
offtherailz committed May 17, 2017
1 parent 54458a4 commit e6516dd
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 21 deletions.
28 changes: 28 additions & 0 deletions web/client/epics/__tests__/epicTestUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

const Rx = require('rxjs');
const { ActionsObservable } = require('redux-observable');

module.exports = {
/**
* Utility to test an epic
* @param {epic} epic the epic to test
* @param {number} count the number of actions to wait (note, the stream)
* @param {object|object[]} action the action(s) to trigger
* @param {Function} callback The check function, called after `count` actions received
* @param {Object} [state={}] the state
*/
testEpic: (epic, count, action, callback, state = {}) => {
const actions = new Rx.Subject();
const actions$ = new ActionsObservable(actions);
const store = { getState: () => state };
epic(actions$, store)
.take(count)
.toArray()
.subscribe(callback);
if (action.length) {
action.map(act => actions.next(act));
} else {
actions.next(action);
}
}
};
20 changes: 3 additions & 17 deletions web/client/epics/__tests__/globeswitcher-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,12 @@ var expect = require('expect');

const {toggle3d, UPDATE_LAST_2D_MAPTYPE} = require('../../actions/globeswitcher');
const assign = require('object-assign');
const Rx = require('rxjs');
const { ActionsObservable } = require('redux-observable');

const {updateRouteOn3dSwitch} = require('../globeswitcher');
const epicTest = (epic, count, action, callback, state = {}) => {
const actions = new Rx.Subject();
const actions$ = new ActionsObservable(actions);
const store = { getState: () => state };
epic(actions$, store)
.take(count)
.toArray()
.subscribe(callback);
if (action.length) {
action.map(act => actions.next(act));
} else {
actions.next(action);
}
};
const {testEpic} = require('./epicTestUtils');
describe('globeswitcher Epics', () => {
it('produces the search epic', (done) => {
epicTest(updateRouteOn3dSwitch, 2, assign({hash: "/viewer/leaflet/2"}, toggle3d(true, "leaflet")), actions => {
testEpic(updateRouteOn3dSwitch, 2, assign({hash: "/viewer/leaflet/2"}, toggle3d(true, "leaflet")), actions => {
expect(actions.length).toBe(2);
actions.map((action) => {
switch (action.type) {
Expand Down
34 changes: 34 additions & 0 deletions web/client/epics/__tests__/jsapi-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

var expect = require('expect');


const {generateActionTrigger} = require('../jsapi');
const {testEpic} = require('./epicTestUtils');
describe('jsapi epic', () => {
it('check jsapi epic triggering', (done) => {
let {epic, trigger, stop} = generateActionTrigger("B");
trigger({type: "C"});
testEpic(epic, 1, [{type: "A"}, {type: "B"}], actions => {
actions.map((action) => {
switch (action.type) {
case "C":
stop();
done();
break;
default:
expect(true).toBe(false);

}
});
done();
});

});
});
19 changes: 19 additions & 0 deletions web/client/epics/jsapi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const Rx = require('rxjs');

module.exports = {
generateActionTrigger: (startAction) => {
var eventStream = new Rx.Subject();
let init = false;
const buffer = [];
eventStream.publish();
return {
trigger: (action) => init ? eventStream.next(action) : buffer.push(action),
stop: () => eventStream.complete(),
epic: (action$) =>
action$.ofType(startAction).take(1).switchMap(() => {
init = true;
return Rx.Observable.from(buffer).concat(eventStream);
})
};
}
};
2 changes: 2 additions & 0 deletions web/client/examples/api/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ <h1>Embed MapStore2 in your website</h1>
<a href="https://github.com/geosolutions-it/MapStore2/tree/master/web/client/examples/api" target="_blank">full code</a>
of this example.
</p>
<button id="zoomToUSA">Zoom to USA</button>
<input type="checkbox" id="ck" checked disabled/>Toggle Weather Layer (if present)
</div>
<script src="../../dist/api.js"></script>
<script type="text/javascript">
Expand Down
32 changes: 32 additions & 0 deletions web/client/examples/api/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,37 @@ function init() {
}, function(state) {
return (state.map && state.map.present) || state.map || {}
});
MapStore2.onAction("MAP_CONFIG_LOADED", function(action) {
var layers = action && action.config && action.config.map && action.config.map.layers;
var layerIndex = layers.findIndex(function(e) {
return e.name === "nurc:Arc_Sample";
});
if (layerIndex >= 0) {
var layer = layers[layerIndex];
document.querySelector('#ck').disabled = false;
document.querySelector('#ck').addEventListener('change', function(event) {
MapStore2.triggerAction({
type: 'CHANGE_LAYER_PROPERTIES',
newProperties: {
visibility: event.target.checked
},
layer: layer.id
});
});
}

});
document.getElementById("zoomToUSA").addEventListener("click", function() {
MapStore2.triggerAction({
type: 'ZOOM_TO_EXTENT',
extent: {
minx: '-124.731422',
miny: '24.955967',
maxx: '-66.969849',
maxy: '49.371735'
},
crs: 'EPSG:4326'
});
});
/*eslint-enable */
}
29 changes: 25 additions & 4 deletions web/client/jsapi/MapStore2.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const ConfigUtils = require('../utils/ConfigUtils');
const {connect} = require('react-redux');

const {configureMap, loadMapConfig} = require('../actions/config');
const {generateActionTrigger} = require('../epics/jsapi');

const url = require('url');

Expand All @@ -30,7 +31,7 @@ const defaultPlugins = {
"mobile": localConfig.plugins.embedded,
"desktop": localConfig.plugins.embedded
};

let triggerAction;
function mergeDefaultConfig(pluginName, cfg) {
var propertyName;
var i;
Expand Down Expand Up @@ -123,6 +124,7 @@ const MapStore2 = {
* Styling can be configured either using a **theme**, or a complete custom **less stylesheet**, using the
* following options properties:
* * **style**: less style to be applied
* * **startAction**: the actionType to wait before start triggering actions. By default CHANGE_MAP_VIEW
* * **theme**: theme configuration options:
* * path: path/url of the themes folder related to the current page
* * theme: theme name to be used
Expand Down Expand Up @@ -173,8 +175,11 @@ const MapStore2 = {
locale: state.locale || {},
pages
}))(require('../components/app/StandardRouter'));

const appStore = require('../stores/StandardStore').bind(null, initialState || {}, {}, {});
const actionTrigger = generateActionTrigger(options.startAction || "CHANGE_MAP_VIEW");
triggerAction = actionTrigger.trigger;
const appStore = require('../stores/StandardStore').bind(null, initialState || {}, {}, {
jsAPIEpic: actionTrigger.epic
});
const initialActions = getInitialActions(options);
const appConfig = {
storeOpts: assign({}, storeOpts, {notify: true}),
Expand Down Expand Up @@ -301,7 +306,23 @@ const MapStore2 = {
*/
withPlugins: (plugins, options) => {
return assign({}, MapStore2, {create: partialRight(MapStore2.create, partialRight.placeholder, partialRight.placeholder, plugins), defaultOptions: options || {}});
}
},
/**
* Triggers an action
* @param {object} action The action to trigger.
* @example
* triggerAction({
* type: 'ZOOM_TO_EXTENT',
* extent: {
* minx: '-124.731422',
* miny: '24.955967',
* maxx: '-66.969849',
* maxy: '49.371735'
* },
* crs: 'EPSG:4326'
* })
*/
triggerAction: (action) => triggerAction(action)
};

if (!global.Intl ) {
Expand Down

0 comments on commit e6516dd

Please sign in to comment.