Skip to content

Commit

Permalink
First Implementation of the 3d switcher. (#1754)
Browse files Browse the repository at this point in the history
* First Implementation of the 3d switcher.

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.

* Fixed duplicated export and docs
  • Loading branch information
offtherailz authored May 3, 2017
1 parent 049f697 commit 5359643
Show file tree
Hide file tree
Showing 24 changed files with 568 additions and 48 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 @@ -137,6 +144,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";
/**
* Emitted when 3d map 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 5359643

Please sign in to comment.