Skip to content

Commit

Permalink
Fix #1931. Implemented full screen button (#1638)
Browse files Browse the repository at this point in the history
  • Loading branch information
offtherailz authored Apr 3, 2017
1 parent 109f5bc commit 7ac597b
Show file tree
Hide file tree
Showing 26 changed files with 442 additions and 18 deletions.
13 changes: 9 additions & 4 deletions docma-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,17 +107,21 @@
{
"framework" : [
"web/client/components/index.jsdoc",
"web/client/components/buttons/FullScreenButton.jsx",
"web/client/components/mapcontrols/search/SearchBar.jsx",
"web/client/components/buttons/ToggleButton.jsx",

"web/client/actions/index.jsdoc",
"web/client/actions/search.js",
"web/client/actions/controls.js",
"web/client/actions/fullscreen.js",
"web/client/actions/search.js",

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

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

"web/client/utils/index.jsdoc",
Expand All @@ -126,12 +130,13 @@
"jsapi": "web/client/jsapi/MapStore2.js",
"plugins": [
"web/client/plugins/index.jsdoc",
"web/client/plugins/Search.jsx",
"web/client/plugins/BackgroundSwitcher.jsx",
"web/client/plugins/Map.jsx",
"web/client/plugins/FullScreen.jsx",
"web/client/plugins/Identify.jsx",
"web/client/plugins/Login.jsx",
"web/client/plugins/ScrollTop.jsx"
"web/client/plugins/ScrollTop.jsx",
"web/client/plugins/Search.jsx"
]
},
"./docs/**/*md",
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"redux-undo": "0.5.0",
"reselect": "2.5.1",
"rxjs": "5.1.1",
"screenfull": "3.1.0",
"shpjs": "3.3.2",
"turf-bbox": "3.0.10",
"turf-buffer": "3.0.10",
Expand Down
25 changes: 25 additions & 0 deletions web/client/actions/__tests__/fullscreen-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* 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 {
TOGGLE_FULLSCREEN,
toggleFullscreen
} = require('../fullscreen');

describe('Test correctness of the fullscreen actions', () => {
it('toggleFullscreen', () => {
const testControl = 'test';
var retval = toggleFullscreen(true, testControl);

expect(retval).toExist();
expect(retval.type).toBe(TOGGLE_FULLSCREEN);
expect(retval.enable).toBe(true);
expect(retval.elementSelector).toBe(testControl);
});
});
28 changes: 28 additions & 0 deletions web/client/actions/fullscreen.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2016, 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_FULLSCREEN = "TOGGLE_FULLSCREEN";
/**
* when fullscreen have to be toggled
* @param {boolean} enable true for enable, false for disable
* @param {string} elementSelector querySelector string to use to get the element to fullscreen.
* @return {action} the action of type `TOGGLE_FULLSCREEN` with enable flag and element selector.
*/
function toggleFullscreen(enable, elementSelector) {
return {
type: TOGGLE_FULLSCREEN,
enable,
elementSelector
};
}

module.exports = {
toggleFullscreen,
TOGGLE_FULLSCREEN
};
2 changes: 1 addition & 1 deletion web/client/components/TOC/DefaultLayer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ var DefaultLayer = React.createClass({
className="toc-zoomTool"
ref="target"
style={{"float": "right", cursor: "pointer"}}
glyph="1-full-screen"
glyph="zoom-in"
onClick={(node) => this.props.onZoom(node.bbox.bounds, node.bbox.crs)}/>
);
}
Expand Down
89 changes: 89 additions & 0 deletions web/client/components/buttons/FullScreenButton.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 fullscreen. 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 FullScreenButton = React.createClass({
propTypes: {
id: React.PropTypes.string,
btnConfig: React.PropTypes.object,
options: React.PropTypes.options,
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: 'fullscreen-btn',
activeTooltip: 'fullscreen.tooltipDeactivate',
notActiveTooltip: 'fullscreen.tooltipActivate',
tooltipPlace: 'left',
defaultStyle: 'primary',
pressedStyle: 'success',
glyphicon: '1-full-screen',
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 = FullScreenButton;
28 changes: 25 additions & 3 deletions web/client/components/buttons/ToggleButton.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/**
/*
* Copyright 2015, GeoSolutions Sas.
* All rights reserved.
*
Expand All @@ -12,11 +12,32 @@ var {Button, Glyphicon} = require('react-bootstrap');
const OverlayTrigger = require('../misc/OverlayTrigger');

var ImageButton = require('./ImageButton');

/**
* Toggle button with tooltip and icons or image support.
* @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} pressed 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} [tooltip] the tooltip to use on mouse hover
* @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
*
*/
var ToggleButton = React.createClass({
propTypes: {
id: React.PropTypes.string,
btnConfig: React.PropTypes.object,
options: React.PropTypes.options,
text: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]),
help: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]),
glyphicon: React.PropTypes.string,
Expand All @@ -33,6 +54,7 @@ var ToggleButton = React.createClass({
getDefaultProps() {
return {
onClick: () => {},
options: {},
pressed: false,
tooltipPlace: "top",
style: {width: "100%"},
Expand All @@ -42,7 +64,7 @@ var ToggleButton = React.createClass({
};
},
onClick() {
this.props.onClick(!this.props.pressed);
this.props.onClick(!this.props.pressed, this.props.options);
},
renderNormalButton() {
return (
Expand Down
36 changes: 36 additions & 0 deletions web/client/components/buttons/__tests__/FullScreenButton-test.jsx
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 FullScreenButton = require('../FullScreenButton');

describe("test the FullScreenButton", () => {
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(<FullScreenButton/>, document.getElementById("container"));
expect(tb).toExist();

const tbNode = ReactDOM.findDOMNode(tb);
expect(tbNode).toExist();
expect(tbNode.id).toBe('fullscreen-btn');
expect(tbNode).toExist();
expect(tbNode.className.indexOf('primary') >= 0).toBe(true);
});
});
6 changes: 4 additions & 2 deletions web/client/components/buttons/__tests__/ToggleButton-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,16 @@ describe("test the ToggleButton", () => {
const testHandlers = {
onClick: (pressed) => {return pressed; }
};
const test = {test: "test"};
const spy = expect.spyOn(testHandlers, 'onClick');
const tb = ReactDOM.render(<ToggleButton pressed onClick={testHandlers.onClick} btnType={btnType}/>, document.getElementById("container"));
const tb = ReactDOM.render(<ToggleButton pressed options={test} onClick={testHandlers.onClick} btnType={btnType}/>, document.getElementById("container"));

const tbNode = ReactDOM.findDOMNode(tb);
tbNode.click();

expect(spy.calls.length).toEqual(1);
expect(spy.calls[0].arguments).toEqual([false]);
expect(spy.calls[0].arguments[0]).toEqual(false);
expect(spy.calls[0].arguments[1]).toEqual(test);
};

genericTest('normal');
Expand Down
2 changes: 1 addition & 1 deletion web/client/components/data/featuregrid/FeatureGrid.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ const FeatureGrid = React.createClass({

let tools = [];
if (this.props.toolbar.zoom) {
tools.push(<Button key="zoom" onClick={this.zoomToFeatures}><Glyphicon glyph="search"/></Button>);
tools.push(<Button key="zoom" onClick={this.zoomToFeatures}><Glyphicon glyph="zoom-in"/></Button>);
}

if (this.props.toolbar.exporter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const ZoomToFeatureIcon = React.createClass({
render() {
const geometry = this.props.params && this.props.params.data && this.props.params.data.geometry;
return geometry && geometry.coordinates ? (
<Glyphicon glyph="search" width={16}/>
<Glyphicon glyph="zoom-in" width={16}/>
) : null;
}
});
Expand Down
64 changes: 64 additions & 0 deletions web/client/epics/__tests__/fullscreen-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

/**
* 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 configureMockStore = require('redux-mock-store').default;
const { createEpicMiddleware, combineEpics } = require('redux-observable');
const {toggleFullscreen} = require('../../actions/fullscreen');
const {SET_CONTROL_PROPERTY} = require('../../actions/controls');
const screenfull = require('screenfull');

const {toggleFullscreenEpic } = require('../fullscreen');
const rootEpic = combineEpics(toggleFullscreenEpic);
const epicMiddleware = createEpicMiddleware(rootEpic);
const mockStore = configureMockStore([epicMiddleware]);

describe('search Epics', () => {
let store;
beforeEach(() => {
store = mockStore();
});

afterEach(() => {
epicMiddleware.replaceEpic(rootEpic);
screenfull.exit();
});

it('produces the search epic', (done) => {
let changed = false;
let action = toggleFullscreen(true, "html");
if ( screenfull.enabled ) {
screenfull.onchange( () => {changed = true; });
}
store.dispatch( action );

const actions = store.getActions();
expect(actions.length).toBe(2);
expect(actions[1].type).toBe(SET_CONTROL_PROPERTY);

setTimeout( () => {
// emulate user exit by hitting esc
if ( screenfull.enabled ) {
screenfull.exit();
}
setTimeout( () => {
const newActions = store.getActions();
if ( screenfull.enabled ) {
expect(newActions.length).toBe(3);
expect(actions[2].type).toBe(SET_CONTROL_PROPERTY);
expect(changed).toBe(true);
}
done();
}, 10);

}, 10);

});
});
Loading

0 comments on commit 7ac597b

Please sign in to comment.