Skip to content

Commit

Permalink
Plugins disable functionalities (#1807)
Browse files Browse the repository at this point in the history
* add expression to disable plugins

* add unit tests
  • Loading branch information
offtherailz authored and mbarto committed May 11, 2017
1 parent 1774aa0 commit c84fd7b
Show file tree
Hide file tree
Showing 13 changed files with 58 additions and 21 deletions.
2 changes: 1 addition & 1 deletion web/client/components/plugins/PluginsContainer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const PluginsContainer = React.createClass({
},
renderPlugins(plugins) {
return plugins
.filter((Plugin) => !PluginsUtils.handleExpression(this.props.pluginsState, this.props.plugins && this.props.plugins.requires, Plugin.hide))
.filter((Plugin) => !PluginsUtils.handleExpression(this.getState, this.props.plugins && this.props.plugins.requires, Plugin.hide))
.map(this.getPluginDescriptor)
.filter((Plugin) => Plugin && !Plugin.impl.loadPlugin)
.filter(this.filterPlugins)
Expand Down
2 changes: 1 addition & 1 deletion web/client/containers/Embedded.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const ConfigUtils = require('../utils/ConfigUtils');
const PluginsContainer = connect((state) => ({
mode: (urlQuery.mode || (state.browser && state.browser.mobile ? 'mobile' : 'desktop')),
pluginsState: state && state.controls || {},
monitoredState: PluginsUtils.filterState(state, ConfigUtils.getConfigProp('monitorState') || [])
monitoredState: PluginsUtils.getMonitoredState(state, ConfigUtils.getConfigProp('monitorState'))
}))(require('../components/plugins/PluginsContainer'));

const Embedded = React.createClass({
Expand Down
2 changes: 1 addition & 1 deletion web/client/containers/MapViewer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const PluginsContainer = connect((state) => ({
pluginsConfig: state.plugins || ConfigUtils.getConfigProp('plugins') || null,
mode: (urlQuery.mode || state.mode || (state.browser && state.browser.mobile ? 'mobile' : 'desktop')),
pluginsState: state && state.controls || {},
monitoredState: PluginsUtils.filterState(state, ConfigUtils.getConfigProp('monitorState') || [])
monitoredState: PluginsUtils.getMonitoredState(state, ConfigUtils.getConfigProp('monitorState'))
}))(require('../components/plugins/PluginsContainer'));

const MapViewer = React.createClass({
Expand Down
2 changes: 1 addition & 1 deletion web/client/containers/Page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const ConfigUtils = require('../utils/ConfigUtils');

const PluginsContainer = connect((state) => ({
mode: urlQuery.mode || ((urlQuery.mobile || (state.browser && state.browser.mobile)) ? 'mobile' : 'desktop'),
monitoredState: PluginsUtils.filterState(state, ConfigUtils.getConfigProp('monitorState') || [])
monitoredState: PluginsUtils.getMonitoredState(state, ConfigUtils.getConfigProp('monitorState'))
}))(require('../components/plugins/PluginsContainer'));

const Page = React.createClass({
Expand Down
1 change: 1 addition & 0 deletions web/client/plugins/Locate.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ require('./locate/locate.css');

module.exports = {
LocatePlugin: assign(LocatePlugin, {
disablePluginIf: "{state('mapType') === 'cesium'}",
Toolbar: {
name: 'locate',
position: 2,
Expand Down
1 change: 1 addition & 0 deletions web/client/plugins/Measure.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ const Measure = connect(

module.exports = {
MeasurePlugin: assign(Measure, {
disablePluginIf: "{state('mapType') === 'cesium'}",
BurgerMenu: {
name: 'measurement',
position: 9,
Expand Down
1 change: 1 addition & 0 deletions web/client/plugins/Print.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ const PrintPlugin = connect(selector, {

module.exports = {
PrintPlugin: assign(PrintPlugin, {
disablePluginIf: "{state('mapType') === 'cesium'}",
Toolbar: {
name: 'print',
position: 7,
Expand Down
32 changes: 17 additions & 15 deletions web/client/plugins/ScaleBox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Message = require('./locale/Message');
const ScaleBox = require("../components/mapcontrols/scale/ScaleBox");

const mapUtils = require('../utils/MapUtils');

const assign = require('object-assign');

const selector = createSelector([mapSelector], (map) => ({
currentZoomLvl: map && map.zoom,
Expand All @@ -30,6 +30,16 @@ const selector = createSelector([mapSelector], (map) => ({

require('./scalebox/scalebox.css');

const ScaleBoxTool = React.createClass({
render() {
return (<HelpWrapper id="mapstore-scalebox-container"
key="scalebox-help"
helpText={<Message msgId="helptexts.scaleBox"/>}>
<ScaleBox key="scaleBox" {...this.props}/>
</HelpWrapper>);
}
});

/**
* ScaleBox Plugin. Provides a selector for the scale of the map.
* @class ScaleBox
Expand All @@ -42,20 +52,12 @@ require('./scalebox/scalebox.css');
* @prop {Boolean} cfg.useRawInput set true if you want to use an normal html input object
*
*/
const ScaleBoxPlugin = React.createClass({
render() {
return (<HelpWrapper id="mapstore-scalebox-container"
key="scalebox-help"
helpText={<Message msgId="helptexts.scaleBox"/>}>
<ScaleBox key="scaleBox" {...this.props}/>
</HelpWrapper>);
}
});


const ScaleBoxPlugin = connect(selector, {
onChange: changeZoomLevel
})(ScaleBoxTool);
module.exports = {
ScaleBoxPlugin: connect(selector, {
onChange: changeZoomLevel
})(ScaleBoxPlugin),
ScaleBoxPlugin: assign(ScaleBoxPlugin, {
disablePluginIf: "{state('mapType') === 'cesium'}"
}),
reducers: {}
};
1 change: 1 addition & 0 deletions web/client/plugins/ShapeFile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ module.exports = {
resolve(ShapeFilePlugin);
});
}, enabler: (state) => state.shapefile && state.shapefile.enabled || state.toolbar && state.toolbar.active === 'shapefile'}, {
disablePluginIf: "{state('mapType') === 'cesium'}",
Toolbar: {
name: 'shapefile',
position: 9,
Expand Down
2 changes: 2 additions & 0 deletions web/client/plugins/ZoomIn.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const React = require('react');
const {connect} = require('react-redux');
const {createSelector} = require('reselect');
const {mapSelector} = require('../selectors/map');

// TODO: make step and glyphicon configurable
const selector = createSelector([mapSelector], (map) => ({currentZoom: map && map.zoom, id: "zoomin-btn", step: 1, glyphicon: "plus"}));

Expand Down Expand Up @@ -38,6 +39,7 @@ const assign = require('object-assign');

module.exports = {
ZoomInPlugin: assign(ZoomInButton, {
disablePluginIf: "{state('mapType') === 'cesium'}",
Toolbar: {
name: "ZoomIn",
position: 3,
Expand Down
1 change: 1 addition & 0 deletions web/client/plugins/ZoomOut.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const assign = require('object-assign');

module.exports = {
ZoomOutPlugin: assign(ZoomOutButton, {
disablePluginIf: "{state('mapType') === 'cesium'}",
Toolbar: {
name: "ZoomOut",
position: 4,
Expand Down
13 changes: 11 additions & 2 deletions web/client/utils/PluginsUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const {omit, isObject, head, isArray, isString} = require('lodash');
const {combineReducers} = require('redux');
const {connect} = require('react-redux');
const url = require('url');

const defaultMonitoredState = [{name: "mapType", path: 'maptype.mapType'}, {name: "user", path: 'security.user'}];
const {combineEpics} = require('redux-observable');

const {memoize, get} = require('lodash');
Expand Down Expand Up @@ -66,6 +66,13 @@ const handleExpression = (state, context, expression) => {
return expression;
};

const filterDisabledPlugins = (item, state = {}, plugins = {}) => {
const disablePluginIf = item && item.plugin && item.plugin.disablePluginIf || item.cfg.disablePluginIf;
if (disablePluginIf && !(item && item.cfg && item.cfg.skipAutoDisable)) {
return !handleExpression(state, plugins.requires, disablePluginIf);
}
return true;
};
const showIn = (state, requires, cfg, name, id, isDefault) => {
return ((id && cfg.showIn && handleExpression(state, requires, cfg.showIn).indexOf(id) !== -1) ||
(cfg.showIn && handleExpression(state, requires, cfg.showIn).indexOf(name) !== -1) ||
Expand Down Expand Up @@ -130,7 +137,7 @@ const getPluginItems = (state, plugins, pluginsConfig, name, id, isDefault, load
plugin: pluginImpl,
items: getPluginItems(state, plugins, pluginsConfig, pluginName, null, true, loadedPlugins)
});
});
}).filter( (item) => filterDisabledPlugins(item, state, plugins) );
};

const getReducers = (plugins) => Object.keys(plugins).map((name) => plugins[name].reducers)
Expand Down Expand Up @@ -182,6 +189,8 @@ const PluginsUtils = {
},
getReducers,
filterState,
filterDisabledPlugins,
getMonitoredState: (state, monitorState = []) => filterState(state, defaultMonitoredState.concat(monitorState)),
getPlugins: (plugins) => Object.keys(plugins).map((name) => plugins[name])
.reduce((previous, current) => assign({}, previous, omit(current, 'reducers')), {}),
/**
Expand Down
19 changes: 19 additions & 0 deletions web/client/utils/__tests__/PluginUtils-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,25 @@ describe('PluginsUtils', () => {
const domElement = ReactDOM.findDOMNode(app);
expect(domElement.innerText).toBe("plugintest");
});
it('handleExpression', () => {
expect(PluginsUtils.handleExpression({state1: "test1"}, {context1: "test2"}, "{state.state1 + ' ' + context.context1}")).toBe("test1 test2");
});
it('filterState', () => {
expect(PluginsUtils.filterState({state1: "test1"}, [{name: "A", path: "state1"}]).A).toBe("test1");
});
it('filterDisabledPlugins', () => {
expect(PluginsUtils.filterDisabledPlugins(
{plugin: {
disablePluginIf: "{true}"
}},
{},
{}
)).toBe(false);
});
it('getMonitoredState', () => {
expect(PluginsUtils.getMonitoredState({maptype: {mapType: "leaflet"}}).mapType).toBe("leaflet");
});

it('handleExpression', () => {
expect(PluginsUtils.handleExpression({state1: "test1"}, {context1: "test2"}, "{state.state1 + ' ' + context.context1}")).toBe("test1 test2");
});
Expand Down

0 comments on commit c84fd7b

Please sign in to comment.