Skip to content

Commit

Permalink
First Implementation of the 3d switcher.
Browse files Browse the repository at this point in the history
The GlobeSwitcher plugin allow to switch to Globe view. In this pull request I also syncronize the maptype with it's reducer to keep in sync the maptype forever in the state.
This is a first step to manage maptype's dependent tools (e.g. navigation tools) using react-redux system.
  • Loading branch information
offtherailz committed Apr 20, 2017
1 parent 55aa830 commit 563a90e
Show file tree
Hide file tree
Showing 23 changed files with 571 additions and 47 deletions.
8 changes: 8 additions & 0 deletions docma-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"framework" : [
"web/client/components/index.jsdoc",
"web/client/components/buttons/FullScreenButton.jsx",
"web/client/components/buttons/GlobeViewSwitcherButton.jsx",
"web/client/components/buttons/GoFullButton.jsx",
"web/client/components/mapcontrols/search/SearchBar.jsx",
"web/client/components/buttons/ToggleButton.jsx",
Expand All @@ -116,16 +117,22 @@
"web/client/actions/index.jsdoc",
"web/client/actions/controls.js",
"web/client/actions/fullscreen.js",
"web/client/actions/globeswitcher.js",
"web/client/actions/maps.js",
"web/client/actions/maptype.js",
"web/client/actions/search.js",

"web/client/reducers/index.jsdoc",
"web/client/reducers/controls.js",
"web/client/reducers/globeswitcher.js",
"web/client/reducers/maps.js",
"web/client/reducers/maptype.js",
"web/client/reducers/search.js",

"web/client/epics/index.jsdoc",
"web/client/epics/fullscreen.js",
"web/client/epics/globeswitcher.js",
"web/client/epics/maptype.js",
"web/client/epics/search.js",

"web/client/utils/index.jsdoc",
Expand All @@ -136,6 +143,7 @@
"web/client/plugins/index.jsdoc",
"web/client/plugins/BackgroundSwitcher.jsx",
"web/client/plugins/DrawerMenu.jsx",
"web/client/plugins/GlobeViewSwitcher.jsx",
"web/client/plugins/GoFull.jsx",
"web/client/plugins/Map.jsx",
"web/client/plugins/FullScreen.jsx",
Expand Down
31 changes: 31 additions & 0 deletions web/client/actions/__tests__/globeswitcher-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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.
*/

const expect = require('expect');
const {
toggle3d,
updateLast2dMapType,
TOGGLE_3D,
UPDATE_LAST_2D_MAPTYPE
} = require('../globeswitcher');

describe('Test correctness of the maptype actions', () => {

it('toggle3d', () => {
const retVal = toggle3d(true);
expect(retVal).toExist();
expect(retVal.type).toBe(TOGGLE_3D);
expect(retVal.enable).toBe(true);
});
it('updateLast2dMapType', () => {
const retVal = updateLast2dMapType("leaflet");
expect(retVal).toExist();
expect(retVal.type).toBe(UPDATE_LAST_2D_MAPTYPE);
expect(retVal.mapType).toBe('leaflet');
});
});
23 changes: 23 additions & 0 deletions web/client/actions/__tests__/maptype-test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.
*/

const expect = require('expect');
const {
MAP_TYPE_CHANGED,
changeMapType
} = require('../maptype');

describe('Test correctness of the maptype actions', () => {

it('changeMapType', () => {
const retVal = changeMapType('maptype');
expect(retVal).toExist();
expect(retVal.type).toBe(MAP_TYPE_CHANGED);
expect(retVal.mapType).toBe('maptype');
});
});
58 changes: 58 additions & 0 deletions web/client/actions/globeswitcher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.
*/


const TOGGLE_3D = "TOGGLE_3D";
const UPDATE_LAST_2D_MAPTYPE = "UPDATE_LAST_2D_MAPTYPE";
/**
* when 3d mode have to be toggled
* @memberof actions.globeswitcher
* @param {boolean} enable true for enable, false for disable
* @return {action} the action of type `TOGGLE_FULLSCREEN` with enable flag and element selector.
* ```
* {
* type: TOGGLE_3D,
* enable
* }
* ```
*/
function toggle3d(enable, originalMapType) {
return {
type: TOGGLE_3D,
enable,
originalMapType
};
}
/**
* saves the last 2d map
* @memberof actions.globeswitcher
* @param {string} mapType last maptype
* @return {object} action
* ```
* {
* type: MAPTYPE_2D_SELECTED,
* mapType
* }
* ```
*/
function updateLast2dMapType(mapType) {
return {
type: UPDATE_LAST_2D_MAPTYPE,
mapType
};
}
/**
* Actions for Globe Switcher Plugin.
* @name actions.globeswitcher
*/
module.exports = {
toggle3d,
updateLast2dMapType,
UPDATE_LAST_2D_MAPTYPE,
TOGGLE_3D
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2016, GeoSolutions Sas.
/*
* Copyright 2017, GeoSolutions Sas.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
Expand All @@ -8,11 +8,20 @@

const MAP_TYPE_CHANGED = 'MAP_TYPE_CHANGED';

/**
* changes the map type
* @memberof actions.maptype
* @param {string} mapType the mapType.
* @return {action} the action of type `MAP_TYPE_CHANGED` with mapType
*/
function changeMapType(mapType) {
return {
type: MAP_TYPE_CHANGED,
mapType
};
}

/**
* Actions for map type management.Allow to manage the default map type.
* @name actions.maptype
*/
module.exports = {MAP_TYPE_CHANGED, changeMapType};
89 changes: 89 additions & 0 deletions web/client/components/buttons/GlobeViewSwitcherButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
* 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.
*/

const React = require('react');

const ToggleButton = require('./ToggleButton');
const {Tooltip} = require('react-bootstrap');
const Message = require('../I18N/Message');
/**
* Toggle button for 3d. Wraps {@link #components.buttons.ToggleButton} with some defaults
* @memberof components.buttons
* @class
* @prop {string} [id] an id for the html component
* @prop {object} [btnConfig] the configuration to pass to the bootstrap button
* @prop {object} [options] the options to send when toggle is clicked
* @prop {string|element} [text] the text to disaplay
* @prop {string|element} [help] the help text
* @prop {string} glyphicon the icon name
* @prop {bool} active the status of the button
* @prop {function} onClick. The method to call when clicked. the method will return as parameter the toggled `pressed` prop and the `options` object
* @prop {node} [activeTooltip] the tooltip to use on mouse hover
* @prop {node} [notActiveTooltip] the tooltip to use on mouse hover when the button is active
* @prop {string} [tooltipPlace] positon of the tooltip, one of: 'top', 'right', 'bottom', 'left'
* @prop {object} css style object for the component
* @prop {btnType} [btnType] one of 'normal', 'image'
* @prop {string} image if type is 'image', the src of the image
* @prop {string} pressedStyle the bootstrap style for pressedStyle
* @prop {string} defaultStyle the bootstrap style when not pressed
*
*/
const GlobeViewSwitcherButton = React.createClass({
propTypes: {
id: React.PropTypes.string,
btnConfig: React.PropTypes.object,
options: React.PropTypes.object,
text: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]),
help: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]),
glyphicon: React.PropTypes.string,
active: React.PropTypes.bool,
onClick: React.PropTypes.func,
activeTooltip: React.PropTypes.string,
notActiveTooltip: React.PropTypes.string,
tooltipPlace: React.PropTypes.string,
style: React.PropTypes.object,
btnType: React.PropTypes.oneOf(['normal', 'image']),
image: React.PropTypes.string,
pressedStyle: React.PropTypes.string,
defaultStyle: React.PropTypes.string
},
getDefaultProps() {
return {
id: 'globeviewswitcher-btn',
activeTooltip: 'globeswitcher.tooltipDeactivate',
notActiveTooltip: 'globeswitcher.tooltipActivate',
tooltipPlace: 'left',
defaultStyle: 'primary',
pressedStyle: 'success',
glyphicon: 'globe',
btnConfig: {
className: "square-button"
}
};
},
getButtonProperties() {
return ['id',
'btnConfig',
'options',
'text',
'glyphicon',
'onClick',
'tooltipPlace',
'style',
'btnType',
'image',
'pressedStyle',
'defaultStyle'
].reduce((result, key) => { result[key] = this.props[key]; return result; }, {});
},
render() {
return <ToggleButton {...this.getButtonProperties()} pressed={this.props.active} tooltip={<Tooltip><Message msgId={this.props.active ? this.props.activeTooltip : this.props.notActiveTooltip}/></Tooltip>} />;
}
});

module.exports = GlobeViewSwitcherButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* 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');

var React = require('react');
var ReactDOM = require('react-dom');
var GlobeViewSwitcherButton = require('../GlobeViewSwitcherButton');

describe("test the GlobeViewSwitcherButton", () => {
beforeEach((done) => {
document.body.innerHTML = '<div id="container"></div>';
setTimeout(done);
});

afterEach((done) => {
ReactDOM.unmountComponentAtNode(document.getElementById("container"));
document.body.innerHTML = '';
setTimeout(done);
});

it('test default properties', () => {
const tb = ReactDOM.render(<GlobeViewSwitcherButton/>, document.getElementById("container"));
expect(tb).toExist();

const tbNode = ReactDOM.findDOMNode(tb);
expect(tbNode).toExist();
expect(tbNode.id).toBe('globeviewswitcher-btn');
expect(tbNode).toExist();
expect(tbNode.className.indexOf('primary') >= 0).toBe(true);
});
});
52 changes: 52 additions & 0 deletions web/client/epics/__tests__/globeswitcher-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* 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 {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);
}
};
describe('globeswitcher Epics', () => {
it('produces the search epic', (done) => {
epicTest(updateRouteOn3dSwitch, 2, assign({hash: "/viewer/leaflet/2"}, toggle3d(true, "leaflet")), actions => {
expect(actions.length).toBe(2);
actions.map((action) => {
switch (action.type) {
case "@@router/TRANSITION":
expect(action.payload.method).toBe('push');
expect(action.payload.args.length).toBe(1);
break;
case UPDATE_LAST_2D_MAPTYPE:
expect(action.mapType).toBe("leaflet");
break;
default:
expect(true).toBe(false);

}
});
done();
});

});
});
Loading

0 comments on commit 563a90e

Please sign in to comment.