From 19a065630912ce297c11b452d56849b68ff94446 Mon Sep 17 00:00:00 2001 From: mbarto Date: Wed, 22 Mar 2017 16:17:54 +0100 Subject: [PATCH] =?UTF-8?q?Fixes=20#1619,=20Fixes=20#1549,=20Fixes=20#1103?= =?UTF-8?q?:=20notification=20system=20and=20docume=E2=80=A6=20(#1620)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixes #1619, Fixes #1549, Fixes #1103: notification system and documentation of the js api * Fixes #1624: configuration from url for the api example * Fixed docs --- docma-config.json | 9 +- docs/developer-guide/plugins-documentation.md | 8 +- package.json | 1 + web/client/components/app/StandardRouter.jsx | 6 +- web/client/containers/Page.jsx | 2 +- web/client/examples/api/init.js | 18 +- web/client/jsapi/MapStore2.js | 156 ++++- web/client/localConfig.json | 556 +++++++++--------- web/client/plugins/QueryPanel.jsx | 2 +- web/client/plugins/Search.jsx | 2 +- web/client/plugins/TOC.jsx | 2 +- web/client/product/pages/Home.jsx | 100 ---- web/client/stores/StandardStore.js | 13 +- 13 files changed, 458 insertions(+), 417 deletions(-) delete mode 100644 web/client/product/pages/Home.jsx diff --git a/docma-config.json b/docma-config.json index 79556fb8bb..650ced12ac 100644 --- a/docma-config.json +++ b/docma-config.json @@ -64,6 +64,8 @@ "items": [ { "label": "Framework", "href": "api/framework"}, + { "separator": true }, + { "label": "JavaScript API", "href": "api/jsapi" }, { "separator": true }, { "label": "Plugins", "href": "api/plugins" } @@ -120,6 +122,7 @@ "web/client/utils/index.jsdoc", "web/client/utils/PluginsUtils.js" ], + "jsapi": "web/client/jsapi/MapStore2.js", "plugins": [ "web/client/plugins/index.jsdoc", "web/client/plugins/Search.jsx", @@ -131,12 +134,8 @@ "./docs/**/*md", { "readme": "./README.md", - "site": "./docs/index.md", "developer-guide": "./docs/developer-guide/index.md", - "plugins-architecture": "./docs/developer-guide/plugins-architecture.md", - "building-and-developing": "./docs/developer-guide/plugins-architecture.md", - "plugins-documentation": "./docs/developer-guide/plugins-documentation.md", - "project-creation-script": "./docs/developer-guide/project-creation-script.md" + "site": "./docs/index.md" } ] } diff --git a/docs/developer-guide/plugins-documentation.md b/docs/developer-guide/plugins-documentation.md index 14c3ee46f8..29a09b7fe1 100644 --- a/docs/developer-guide/plugins-documentation.md +++ b/docs/developer-guide/plugins-documentation.md @@ -17,7 +17,7 @@ Inside the **plugins** section, several modes can be configured (e.g. desktop or } ``` -Each plugin can be simply listed (and the default configuration is used): +Each plugin can be simply listed (and the default configuration is used): ```js "plugins": { @@ -33,7 +33,6 @@ or fully configured: ... "desktop": [{ "name": "Map", - "cfg": { ... } }, @@ -41,7 +40,4 @@ or fully configured: ] } ``` -Look at each plugin documentation page for a list of available configuration properties. - -# Plugins List: - * [Map](map-plugin) +Look at the [plugin reference page](./api/plugins) for a list of available configuration properties. diff --git a/package.json b/package.json index 2c7a2bb269..c88620b3fa 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ }, "//": "replace react-sortable-items with official on npm when 0.0.10 with remove_deprecated PR in included", "dependencies": { + "@carnesen/redux-add-action-listener-enhancer": "0.0.1", "ag-grid": "3.3.3", "ag-grid-react": "3.3.1", "axios": "0.11.1", diff --git a/web/client/components/app/StandardRouter.jsx b/web/client/components/app/StandardRouter.jsx index 96be2b8d48..63d0be7ecf 100644 --- a/web/client/components/app/StandardRouter.jsx +++ b/web/client/components/app/StandardRouter.jsx @@ -14,9 +14,13 @@ const {Router, Route, hashHistory} = require('react-router'); const Localized = require('../I18N/Localized'); +const assign = require('object-assign'); + const Theme = connect((state) => ({ theme: state.theme && state.theme.selectedTheme && state.theme.selectedTheme.id -}))(require('../theme/Theme')); +}), {}, (stateProps, dispatchProps, ownProps) => { + return assign({}, stateProps, dispatchProps, ownProps); +})(require('../theme/Theme')); const StandardRouter = React.createClass({ propTypes: { diff --git a/web/client/containers/Page.jsx b/web/client/containers/Page.jsx index f6b270d7ea..39f265940a 100644 --- a/web/client/containers/Page.jsx +++ b/web/client/containers/Page.jsx @@ -50,7 +50,7 @@ const Page = React.createClass({ desktop: [...this.props.pagePluginsConfig.desktop, ...this.props.pluginsConfig.desktop], mobile: [...this.props.pagePluginsConfig.mobile, ...this.props.pluginsConfig.mobile] }; - return ( { + if (!options.initialState) { + if (options.configUrl) { + return [loadMapConfig.bind(null, options.configUrl || defaultConfig)]; + } + return [configureMap.bind(null, options.config || defaultConfig)]; + } + return []; +}; + + +/** + * MapStore2 JavaScript API. Allows embedding MapStore2 functionalities into + * a standard HTML page. + * @class + */ const MapStore2 = { + /** + * Instantiates an embedded MapStore2 application in the given container. + * @memberof MapStore2 + * @static + * @param {string} container id of the DOM element that should contain the embedded MapStore2 + * @param {object} options set of options of the embedded app + * + * The options object can contain the following properties, to configure the app UI and state: + * * **plugins**: list of plugins (and the related configuration) to be included in the app + * look at [Plugins documentation](./plugins-documentation) for further details + * * **config**: map configuration object for the application (look at [Map Configuration](./maps-configuration) for details) + * * **configUrl**: map configuration url for the application (look at [Map Configuration](./maps-configuration) for details) + * * **initialState**: allows setting the initial application state (look at [State Configuration](./app-state-configuration) for details) + * + * 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 + * * **theme**: theme configuration options: + * * path: path/url of the themes folder related to the current page + * * theme: theme name to be used + * + * ```javascript + * { + * plugins: ['Map', 'ZoomIn', 'ZoomOut'], + * config: { + * map: { + * ... + * } + * }, + * configUrl: '...', + * initialState: { + * defaultState: { + * ... + * } + * }, + * style: '', + * theme: { + * theme: 'mytheme', + * path: 'dist/themes' + * } + * } + * ``` + * @example + * MapStore2.create('container', { + * plugins: ['Map'] + * }); + */ create(container, options) { const embedded = require('../containers/Embedded'); @@ -218,9 +285,9 @@ const MapStore2 = { }))(require('../components/app/StandardRouter')); const appStore = require('../stores/StandardStore').bind(null, initialState || {}, {}); - const initialActions = options.initialState ? [] : [configureMap.bind(null, options.config || defaultConfig)]; + const initialActions = getInitialActions(options); const appConfig = { - storeOpts, + storeOpts: assign({}, storeOpts, {notify: true}), appStore, pluginsDef, initialActions, @@ -242,11 +309,84 @@ const MapStore2 = { }; const themeCfg = options.theme && assign({}, defaultThemeCfg, options.theme) || defaultThemeCfg; - ReactDOM.render(, document.getElementById(container)); + app = ReactDOM.render(, document.getElementById(container)); + app.store.addActionListener((action) => { + (actionListeners[action.type] || []).concat(actionListeners['*'] || []).forEach((listener) => { + listener.call(null, action); + }); + }); + app.store.subscribe(() => { + stateChangeListeners.forEach(({listener, selector}) => { + listener.call(null, selector(app.store.getState())); + }); + }); }, buildPluginsCfg, - getMapNameFromRequest, - loadConfigFromStorage + getParamFromRequest, + loadConfigFromStorage, + /** + * Adds a listener that will be notified of all the MapStore2 events (**actions**), or only some of them. + * + * @memberof MapStore2 + * @static + * @param {string} type type of actions to be captured (* for all) + * @param {function} listener function to be called for each launched action; it will receive + * the action as the only argument + * @example + * MapStore2.onAction('CHANGE_MAP_VIEW', function(action) { + * console.log(action.zoom); + * }); + */ + onAction: (type, listener) => { + const listeners = actionListeners[type] || []; + listeners.push(listener); + actionListeners[type] = listeners; + }, + /** + * Removes an action listener. + * + * @memberof MapStore2 + * @static + * @param {string} type type of actions that is captured by the listener (* for all) + * @param {function} listener listener to be removed + * @example + * MapStore2.offAction('CHANGE_MAP_VIEW', listener); + */ + offAction: (type, listener) => { + const listeners = (actionListeners[type] || []).filter((l) => l !== listener); + actionListeners[type] = listeners; + }, + /** + * Adds a listener that will be notified of each state update. + * + * @memberof MapStore2 + * @static + * @param {function} listener function to be called for each state udpate; it will receive + * the new state as the only argument + * @param {function} [selector] optional function that will produce a partial/derived state + * from the global state before calling the listeners + * @example + * MapStore2.onStateChange(function(map) { + * console.log(map.zoom); + * }, function(state) { + * return (state.map && state.map.present) || state.map || {}; + * }); + */ + onStateChange: (listener, selector = (state) => state) => { + stateChangeListeners.push({listener, selector}); + }, + /** + * Removes a state listener. + * + * @memberof MapStore2 + * @static + * @param {function} listener listener to be removed + * @example + * MapStore2.offStateChange(listener); + */ + offStateChange: (listener) => { + stateChangeListeners = stateChangeListeners.filter((l) => l !== listener); + } }; if (!global.Intl ) { diff --git a/web/client/localConfig.json b/web/client/localConfig.json index a793b97950..2132105f90 100644 --- a/web/client/localConfig.json +++ b/web/client/localConfig.json @@ -1,290 +1,270 @@ { - "proxyUrl": { - "url": "/mapstore/proxy/?url=", - "useCORS": ["https://demo.geo-solutions.it/geoserver"] - }, - "geoStoreUrl": "/mapstore/rest/geostore/", - "printUrl": "https://demo.geo-solutions.it/geoserver/pdf/info.json", - "bingApiKey": "AhuXBu7ipR1gNbBfXhtUAyCZ6rkC5PkWpxs2MnMRZ1ZupxQfivjLCch22ozKSCAn", - "mapquestApiKey": "__API_KEY_MAPQUEST__", - "initialMapFilter": "", - "ignoreMobileCss" : true, - "useAuthenticationRules": true, - "authenticationRules": [ - { - "urlPattern": ".*geostore.*", - "method": "basic" - } - ], - "plugins": { - "mobile": [ - { - "name": "Map", - "cfg": { - "tools": ["locate"] - } - }, "DrawerMenu", - { - "name": "Identify", - "showIn": ["Settings"], - "cfg": { - "style": { - "position": "absolute", - "width": "100%", - "bottom": "0px", - "zIndex": 1023, - "maxHeight": "70%", - "marginBottom": 0 - }, - "draggable": false, - "collapsible": true, - "viewerOptions": { - "container": "{context.ReactSwipe}", - "header": "{context.SwipeHeader}", - "collapsible": false - }, - "bodyClass": "mobile-feature-info" - } - }, - { - "name": "Locate", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, "Home", "TOC", { - "name": "Tutorial", - "cfg": { - "preset": "mapMobile" - } - }, "BackgroundSwitcher", { - "name": "Settings", - "cfg": { - "wrap": true - } - }, "About", - { - "name": "MousePosition", - "cfg": { - "id": "mapstore-mouseposition-mobile" - } - }, - { - "name": "Search", - "cfg": { - "withToggle": ["max-width: 768px", "min-width: 768px"] - } - }, { - "name": "Toolbar", - "id": "NavigationBar", - "cfg": { - "id": "navigationBar" - } - }, { - "name": "Toolbar", - "id": "IdentifyBar", - "stateSelector": "identify", - "cfg": { - "id": "identifyBar" - }, - "isDefault": false - }, "ZoomAll", - { - "name": "MapLoading", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, "Login", - "OmniBar", "BurgerMenu", "Expander" - ], - "desktop": ["Map", "Help", "Share", "DrawerMenu", - { - "name": "Identify", - "showIn": ["IdentifyBar", "Settings"], - "cfg": { - "viewerOptions": { - "container": "{context.ReactSwipe}", - "header": "{context.SwipeHeader}", - "headerOptions": { - "useButtons": true - } - } - } - }, - "MadeWithLove", - { - "name": "Locate", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, "Home", "FeatureGrid", { - "name": "TOC", - "cfg": { - "activateQueryTool": true - } - }, "Tutorial", "BackgroundSwitcher", { - "name": "Measure", - "cfg": { - "showResults": false - } - }, "MeasureResults", "Print", "ShapeFile", { - "name": "Settings", - "cfg": { - "wrap": true - } - }, { - "name": "MetadataExplorer", - "cfg": { - "wrap": true, - "initialCatalogURL": { - "csw": "http://demo.geo-solutions.it/geoserver/csw", - "wms": "http://demo.geo-solutions.it/geoserver/wms", - "wmts": "http://demo.geo-solutions.it/geoserver/gwc/service/wmts" - } - } - }, "About", "MousePosition", { - "name": "Search", - "cfg": { - "withToggle": ["max-width: 768px", "min-width: 768px"] - } - }, { - "name": "Toolbar", - "id": "NavigationBar", - "cfg": { - "id": "navigationBar" - } - }, { - "name": "Toolbar", - "id": "IdentifyBar", - "stateSelector": "identify", - "cfg": { - "id": "identifyBar" - }, - "isDefault": false - }, - "ScaleBox", "ZoomAll", - { - "name": "MapLoading", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, - { - "name": "Snapshot", - "cfg": { - "wrap": true - } - }, - { - "name":"ZoomIn", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, - { - "name":"ZoomOut", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, - "OmniBar", "Login", "Save", "SaveAs", "BurgerMenu", "Expander", "Undo", "Redo" - ], - "embedded": [ - { - "name": "Map", - "cfg": { - "tools": ["locate"] - } - }, "Help", "DrawerMenu", - { - "name": "Identify", - "showIn": ["Settings"], - "cfg": { - "style": { - "position": "absolute", - "width": "100%", - "bottom": "0px", - "zIndex": 1010, - "maxHeight": "70%", - "marginBottom": 0 - }, - "draggable": false, - "collapsible": true, - "viewerOptions": { - "container": "{context.ReactSwipe}", - "header": "{context.SwipeHeader}", - "collapsible": false - }, - "bodyClass": "mobile-feature-info" - } - }, - { - "name": "Locate", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, "TOC", "BackgroundSwitcher", { - "name": "Settings", - "cfg": { - "wrap": true - } - }, "About", - { - "name": "MousePosition", - "cfg": { - "id": "mapstore-mouseposition-mobile" - } - }, - { - "name": "Search", - "cfg": { - "withToggle": ["max-width: 768px", "min-width: 768px"] - } - }, { - "name": "Toolbar", - "id": "NavigationBar", - "cfg": { - "id": "navigationBar" - } - }, { - "name": "Toolbar", - "id": "IdentifyBar", - "stateSelector": "identify", - "cfg": { - "id": "identifyBar" - }, - "isDefault": false - }, - { - "name": "MapLoading", - "override": { - "Toolbar": { - "alwaysVisible": true - } - } - }, - "OmniBar", "BurgerMenu" - ], - "common": [{ - "name": "OmniBar", - "cfg": { - "className": "navbar shadow navbar-home" - } - }, "ManagerMenu", "Login", "Language", "Attribution"], - "maps": ["Header", "Fork", "MapSearch", "HomeDescription", "MapType", "ThemeSwitcher", "CreateNewMap", "Maps", "Examples", "Footer"], - "manager": ["Header", "Redirect", "Manager", "Home", "UserManager", "GroupManager", "Footer"] - } + "proxyUrl": { + "url": "/mapstore/proxy/?url=", + "useCORS": ["https://demo.geo-solutions.it/geoserver"] + }, + "geoStoreUrl": "/mapstore/rest/geostore/", + "printUrl": "https://demo.geo-solutions.it/geoserver/pdf/info.json", + "bingApiKey": "AhuXBu7ipR1gNbBfXhtUAyCZ6rkC5PkWpxs2MnMRZ1ZupxQfivjLCch22ozKSCAn", + "mapquestApiKey": "__API_KEY_MAPQUEST__", + "initialMapFilter": "", + "ignoreMobileCss": true, + "useAuthenticationRules": true, + "authenticationRules": [{ + "urlPattern": ".*geostore.*", + "method": "basic" + }], + "plugins": { + "mobile": [{ + "name": "Map", + "cfg": { + "tools": ["locate"] + } + }, "DrawerMenu", { + "name": "Identify", + "showIn": ["Settings"], + "cfg": { + "style": { + "position": "absolute", + "width": "100%", + "bottom": "0px", + "zIndex": 1023, + "maxHeight": "70%", + "marginBottom": 0 + }, + "draggable": false, + "collapsible": true, + "viewerOptions": { + "container": "{context.ReactSwipe}", + "header": "{context.SwipeHeader}", + "collapsible": false + }, + "bodyClass": "mobile-feature-info" + } + }, { + "name": "Locate", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, "Home", "TOC", { + "name": "Tutorial", + "cfg": { + "preset": "mapMobile" + } + }, "BackgroundSwitcher", { + "name": "Settings", + "cfg": { + "wrap": true + } + }, "About", { + "name": "MousePosition", + "cfg": { + "id": "mapstore-mouseposition-mobile" + } + }, { + "name": "Search", + "cfg": { + "withToggle": ["max-width: 768px", "min-width: 768px"] + } + }, { + "name": "Toolbar", + "id": "NavigationBar", + "cfg": { + "id": "navigationBar" + } + }, { + "name": "Toolbar", + "id": "IdentifyBar", + "stateSelector": "identify", + "cfg": { + "id": "identifyBar" + }, + "isDefault": false + }, "ZoomAll", { + "name": "MapLoading", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, "Login", + "OmniBar", "BurgerMenu", "Expander" + ], + "desktop": ["Map", "Help", "Share", "DrawerMenu", { + "name": "Identify", + "showIn": ["IdentifyBar", "Settings"], + "cfg": { + "viewerOptions": { + "container": "{context.ReactSwipe}", + "header": "{context.SwipeHeader}", + "headerOptions": { + "useButtons": true + } + } + } + }, + "MadeWithLove", { + "name": "Locate", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, "Home", "FeatureGrid", { + "name": "TOC", + "cfg": { + "activateQueryTool": true + } + }, "Tutorial", "BackgroundSwitcher", { + "name": "Measure", + "cfg": { + "showResults": false + } + }, "MeasureResults", "Print", "ShapeFile", { + "name": "Settings", + "cfg": { + "wrap": true + } + }, { + "name": "MetadataExplorer", + "cfg": { + "wrap": true, + "initialCatalogURL": { + "csw": "http://demo.geo-solutions.it/geoserver/csw", + "wms": "http://demo.geo-solutions.it/geoserver/wms", + "wmts": "http://demo.geo-solutions.it/geoserver/gwc/service/wmts" + } + } + }, "About", "MousePosition", { + "name": "Search", + "cfg": { + "withToggle": ["max-width: 768px", "min-width: 768px"] + } + }, { + "name": "Toolbar", + "id": "NavigationBar", + "cfg": { + "id": "navigationBar" + } + }, { + "name": "Toolbar", + "id": "IdentifyBar", + "stateSelector": "identify", + "cfg": { + "id": "identifyBar" + }, + "isDefault": false + }, + "ScaleBox", "ZoomAll", { + "name": "MapLoading", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, { + "name": "Snapshot", + "cfg": { + "wrap": true + } + }, { + "name": "ZoomIn", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, { + "name": "ZoomOut", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, + "OmniBar", "Login", "Save", "SaveAs", "BurgerMenu", "Expander", "Undo", "Redo" + ], + "embedded": [{ + "name": "Map", + "cfg": { + "tools": ["locate"] + } + }, "Help", "DrawerMenu", { + "name": "Identify", + "showIn": ["Settings"], + "cfg": { + "style": { + "position": "absolute", + "width": "100%", + "bottom": "0px", + "zIndex": 1010, + "maxHeight": "70%", + "marginBottom": 0 + }, + "draggable": false, + "collapsible": true, + "viewerOptions": { + "container": "{context.ReactSwipe}", + "header": "{context.SwipeHeader}", + "collapsible": false + }, + "bodyClass": "mobile-feature-info" + } + }, { + "name": "Locate", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, "TOC", "BackgroundSwitcher", { + "name": "Settings", + "cfg": { + "wrap": true + } + }, "About", { + "name": "MousePosition", + "cfg": { + "id": "mapstore-mouseposition-mobile" + } + }, { + "name": "Search", + "cfg": { + "withToggle": ["max-width: 768px", "min-width: 768px"] + } + }, { + "name": "Toolbar", + "id": "NavigationBar", + "cfg": { + "id": "navigationBar" + } + }, { + "name": "Toolbar", + "id": "IdentifyBar", + "stateSelector": "identify", + "cfg": { + "id": "identifyBar" + }, + "isDefault": false + }, { + "name": "MapLoading", + "override": { + "Toolbar": { + "alwaysVisible": true + } + } + }, + "OmniBar", "BurgerMenu" + ], + "common": [{ + "name": "OmniBar", + "cfg": { + "className": "navbar shadow navbar-home" + } + }, "ManagerMenu", "Login", "Language", "Attribution"], + "maps": ["Header", "Fork", "MapSearch", "HomeDescription", "MapType", "ThemeSwitcher", "CreateNewMap", "Maps", "Examples", "Footer"], + "manager": ["Header", "Redirect", "Manager", "Home", "UserManager", "GroupManager", "Footer"] + } } diff --git a/web/client/plugins/QueryPanel.jsx b/web/client/plugins/QueryPanel.jsx index 36958b4f3f..492665f7b6 100644 --- a/web/client/plugins/QueryPanel.jsx +++ b/web/client/plugins/QueryPanel.jsx @@ -115,7 +115,7 @@ const tocSelector = createSelector( [ (state) => state.controls && state.controls.toolbar && state.controls.toolbar.active === 'toc', groupsSelector, - (state) => state.layers.settings || {expanded: false, options: {opacity: 1}}, + (state) => state.layers && state.layers.settings || {expanded: false, options: {opacity: 1}}, (state) => state.controls && state.controls.queryPanel && state.controls.queryPanel.enabled || false ], (enabled, groups, settings, querypanelEnabled) => ({ enabled, diff --git a/web/client/plugins/Search.jsx b/web/client/plugins/Search.jsx index 145a92cd59..59e940f4f9 100644 --- a/web/client/plugins/Search.jsx +++ b/web/client/plugins/Search.jsx @@ -74,7 +74,7 @@ const ToggleButton = require('./searchbar/ToggleButton'); * @memberof plugins * @prop {object} cfg.searchOptions initial search options * @prop {searchService[]} cfg.searchOptions.services a list of services to perform search. - * a **nominaim** search service look like this: + * a **nominatim** search service look like this: * ``` * { * "type": "nominatim", diff --git a/web/client/plugins/TOC.jsx b/web/client/plugins/TOC.jsx index d342f76453..1efad67275 100644 --- a/web/client/plugins/TOC.jsx +++ b/web/client/plugins/TOC.jsx @@ -126,7 +126,7 @@ const tocSelector = createSelector( [ (state) => state.controls && state.controls.toolbar && state.controls.toolbar.active === 'toc', groupsSelector, - (state) => state.layers.settings || {expanded: false, options: {opacity: 1}}, + (state) => state.layers && state.layers.settings || {expanded: false, options: {opacity: 1}}, (state) => state.controls && state.controls.queryPanel && state.controls.queryPanel.enabled || false ], (enabled, groups, settings, querypanelEnabled) => ({ enabled, diff --git a/web/client/product/pages/Home.jsx b/web/client/product/pages/Home.jsx deleted file mode 100644 index 9f4482eabe..0000000000 --- a/web/client/product/pages/Home.jsx +++ /dev/null @@ -1,100 +0,0 @@ -/** - * 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 React = require('react'); - -const {Grid, Row, Col} = require('react-bootstrap'); - -const {loadLocale} = require('../../actions/locale'); -const {changeMapType} = require('../actions/home'); - -const {connect} = require('react-redux'); -const {compose} = require('redux'); - -const Language = require('../components/home/Language'); -const Brand = require('../components/home/Brand'); -const Fork = require('../components/home/Fork'); -const Logo = require('../components/home/Logo'); -const Description = require('../components/home/Description'); -const Examples = require('../components/home/Examples'); -const Footer = require('../components/home/Footer'); -const MapsList = require('../components/home/MapsList'); - -require('../assets/css/home.css'); - -const Home = React.createClass({ - propTypes: { - locale: React.PropTypes.object, - loadLocale: React.PropTypes.func, - maps: React.PropTypes.object, - mapType: React.PropTypes.string, - changeMapType: React.PropTypes.func, - loadMapConfig: React.PropTypes.func - }, - contextTypes: { - router: React.PropTypes.object - }, - render() { - return ( -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - event.target.value)} - mapType={this.props.mapType} title={this.props.locale.messages.manager.maps_title} - onGoToMap={this.goToMap} - /> - {(this.props.maps) ? null :
} - -
-
- ); - }, - goToMap(map) { - this.context.router.push("/viewer/" + this.props.mapType + "/" + map.id); - } -}); - -module.exports = connect((state) => { - return { - maps: state.maps, - locale: state.locale, - mapType: state.home.mapType - }; -}, { - loadLocale, - changeMapType -})(Home); diff --git a/web/client/stores/StandardStore.js b/web/client/stores/StandardStore.js index e87a1e6c78..892bb3f09e 100644 --- a/web/client/stores/StandardStore.js +++ b/web/client/stores/StandardStore.js @@ -15,6 +15,7 @@ const layers = require('../reducers/layers'); const mapConfig = require('../reducers/config'); const DebugUtils = require('../utils/DebugUtils'); +const {compose} = require('redux'); const {combineReducers, combineEpics} = require('../utils/PluginsUtils'); const LayersUtils = require('../utils/LayersUtils'); @@ -23,6 +24,7 @@ const {persistStore, autoRehydrate} = require('redux-persist'); const {createEpicMiddleware} = require('redux-observable'); const SecurityUtils = require('../utils/SecurityUtils'); +const ListenerEnhancer = require('@carnesen/redux-add-action-listener-enhancer').default; module.exports = (initialState = {defaultState: {}, mobile: {}}, appReducers = {}, plugins, storeOpts) => { const allReducers = combineReducers(plugins, { @@ -58,11 +60,16 @@ module.exports = (initialState = {defaultState: {}, mobile: {}}, appReducers = { return newState; }; let store; + let enhancer; + if (storeOpts && storeOpts.persist) { + enhancer = autoRehydrate(); + } + if (storeOpts && storeOpts.notify) { + enhancer = enhancer ? compose(enhancer, ListenerEnhancer) : ListenerEnhancer; + } + store = DebugUtils.createDebugStore(rootReducer, defaultState, [epicMiddleware], enhancer); if (storeOpts && storeOpts.persist) { - store = DebugUtils.createDebugStore(rootReducer, defaultState, [epicMiddleware], autoRehydrate()); persistStore(store, storeOpts.persist, storeOpts.onPersist); - } else { - store = DebugUtils.createDebugStore(rootReducer, defaultState, [epicMiddleware]); } SecurityUtils.setStore(store); return store;