From 2bfad332c201dae46ffca7402f508c8f0e03628b Mon Sep 17 00:00:00 2001 From: saidaipparla Date: Mon, 5 Dec 2016 13:23:13 +0100 Subject: [PATCH 1/2] fix #1319 exported contents wiki folder to mapstore2 --- web/client/wiki/Application-Tutorial.md | 212 ++++++++++++++++++ web/client/wiki/Building-and-developing.md | 79 +++++++ web/client/wiki/Developers-Guide.md | 36 +++ web/client/wiki/Developing-with-MapStore-2.md | 63 ++++++ ...ontend-building-tools-and-configuration.md | 48 ++++ web/client/wiki/Home.md | 22 ++ web/client/wiki/How-to-use-a-CDN.md | 4 + ...Infrastructure-and-general-architecture.md | 26 +++ web/client/wiki/Maps-configuration.md | 42 ++++ web/client/wiki/Plugins-architecture.md | 101 +++++++++ web/client/wiki/Project-Creation-Script.md | 19 ++ .../wiki/React-0.14.x-Migration-Guide.md | 50 +++++ .../wiki/ReactJS-and-Redux-introduction.md | 167 ++++++++++++++ 13 files changed, 869 insertions(+) create mode 100644 web/client/wiki/Application-Tutorial.md create mode 100644 web/client/wiki/Building-and-developing.md create mode 100644 web/client/wiki/Developers-Guide.md create mode 100644 web/client/wiki/Developing-with-MapStore-2.md create mode 100644 web/client/wiki/Frontend-building-tools-and-configuration.md create mode 100644 web/client/wiki/Home.md create mode 100644 web/client/wiki/How-to-use-a-CDN.md create mode 100644 web/client/wiki/Infrastructure-and-general-architecture.md create mode 100644 web/client/wiki/Maps-configuration.md create mode 100644 web/client/wiki/Plugins-architecture.md create mode 100644 web/client/wiki/Project-Creation-Script.md create mode 100644 web/client/wiki/React-0.14.x-Migration-Guide.md create mode 100644 web/client/wiki/ReactJS-and-Redux-introduction.md diff --git a/web/client/wiki/Application-Tutorial.md b/web/client/wiki/Application-Tutorial.md new file mode 100644 index 0000000000..e84ac1da63 --- /dev/null +++ b/web/client/wiki/Application-Tutorial.md @@ -0,0 +1,212 @@ +Writing a new MapStore2 based application can be done following these steps: + * create a new folder for the application, inside the MapStore2 directory tree (e.g. web/client/examples/myapp), and the following folder structure: + +``` ++-- myapp + +-- index.html + +-- config.json + +-- webpack.config.js + +-- app.jsx + +-- containers + | +-- myapp.jsx + +-- stores + +-- myappstore.js +``` + * create an **index.html** file inside the application folder + +```html + + + + + + + MyApp + + + + + +
+ + + +``` + * create an **app.jsx** for the main app ReactJS component + +```javascript +var React = require('react'); +var ReactDOM = require('react-dom'); + +var Provider = require('react-redux').Provider; + +// include application component +var MyApp = require('./containers/MyApp'); +var url = require('url'); + +var loadMapConfig = require('../../actions/config').loadMapConfig; +var ConfigUtils = require('../../utils/ConfigUtils'); + +// initializes Redux store +var store = require('./stores/myappstore'); + +// reads parameter(s) from the url +const urlQuery = url.parse(window.location.href, true).query; + +// get configuration file url (defaults to config.json on the app folder) +const { configUrl, legacy } = ConfigUtils.getConfigurationOptions(urlQuery, 'config', 'json'); + +// dispatch an action to load the configuration from the config.json file +store.dispatch(loadMapConfig(configUrl, legacy)); + +// Renders the application, wrapped by the Redux Provider to connect the store to components +ReactDOM.render( + + + , + document.getElementById('container') +); +``` + * create a **myapp.jsx** component inside the **containers** folder, that will contain the all-in-one Smart Component of the application + +```javascript +var React = require('react'); +var connect = require('react-redux').connect; +var LMap = require('../../../components/map/leaflet/Map'); +var LLayer = require('../../../components/map/leaflet/Layer'); + +var MyApp = React.createClass({ + propTypes: { + // redux store slice with map configuration (bound through connect to store at the end of the file) + mapConfig: React.PropTypes.object, + // redux store dispatch func + dispatch: React.PropTypes.func + }, + renderLayers(layers) { + if (layers) { + return layers.map(function(layer) { + return ; + }); + } + return null; + }, + render() { + // wait for loaded configuration before rendering + if (this.props.mapConfig && this.props.mapConfig.map) { + return ( + + {this.renderLayers(this.props.mapConfig.layers)} + + ); + } + return null; + } +}); + +// include support for OSM and WMS layers +require('../../../components/map/leaflet/plugins/OSMLayer'); +require('../../../components/map/leaflet/plugins/WMSLayer'); + +// connect Redux store slice with map configuration +module.exports = connect((state) => { + return { + mapConfig: state.mapConfig + }; +})(MyApp); +``` + + * create a **myappstore.js** store initalizer inside the **stores** folder, that will create the global Redux store for the application, combining the needed reducers and middleware components + +```javascript +var {createStore, combineReducers, applyMiddleware} = require('redux'); + +var thunkMiddleware = require('redux-thunk'); +var mapConfig = require('../../../reducers/config'); + + // reducers +const reducers = combineReducers({ + mapConfig +}); + +// compose middleware(s) to createStore +let finalCreateStore = applyMiddleware(thunkMiddleware)(createStore); + +// export the store with the given reducers (and middleware applied) +module.exports = finalCreateStore(reducers, {}); +``` + + * create a **config.json** file with basic map configuration + +```javascript +{ + "map": { + "projection": "EPSG:900913", + "units": "m", + "center": {"x": 1250000.000000, "y": 5370000.000000, "crs": "EPSG:900913"}, + "zoom":5, + "layers": [ + { + "type": "osm", + "title": "Open Street Map", + "name": "mapnik", + "group": "background", + "visibility": true + }, + { + "type": "wms", + "url":"http://demo.geo-solutions.it/geoserver/wms", + "visibility": true, + "opacity": 0.5, + "title": "Weather data", + "name": "nurc:Arc_Sample", + "group": "Meteo", + "format": "image/png" + } + ] + } +} +``` + +* create a **webpack.config.js** file with build configuration + +```javascript +var path = require("path"); + +module.exports = { + entry: { + myapp: path.join(__dirname, "app") + }, + output: { + path: path.join(__dirname, "dist"), + publicPath: "/dist/", + filename: "myapp.js" + }, + resolve: { + extensions: ["", ".js", ".jsx"] + }, + module: { + loaders: [ + { test: /\.jsx?$/, loader: "babel-loader" } + ] + }, + devtool: 'inline-source-map', + debug: true +}; +``` + +Now the application is ready, to launch it in development mode, you can use the following command (launch it from the MapStore2 main folder): + +``` +./node_modules/.bin/webpack-dev-server --config web/client/examples/myapp/webpack.config.js --progress --colors --port 8081 --content-base web/client/examples/myapp +``` + +Then point your preferred browser to the following url: [http://localhost:8081](http://localhost:8081) \ No newline at end of file diff --git a/web/client/wiki/Building-and-developing.md b/web/client/wiki/Building-and-developing.md new file mode 100644 index 0000000000..e24ba2928b --- /dev/null +++ b/web/client/wiki/Building-and-developing.md @@ -0,0 +1,79 @@ +Due to the dual nature of the project (Java backend and Javascript frontend) building and developing using the MapStore 2 framework requires two distinct set of tools, [Apache Maven](https://maven.apache.org/) for Java and [NPM](https://www.npmjs.com/) for Javascript. + +A basic knowledge of both tools is required. + +# Developing and debugging the MapStore 2 framework +To start developing the MapStore 2 framework you have to: + * download developer tools and frontend dependencies locally: + +`npm install` + +After a while (depending on the network bandwidth) the full set of dependencies and tools will be downloaded to the **node_modules** subfolder. + + * start a development instance of the framework and example applications: + +`npm run examples` + + * or you can start a development instance **without the examples**: + +`npm start` + +Then point your preferred browser to [http://localhost:8081](http://localhost:8081). + +The HomePage contains links to the available demo applications. + +## Frontend debugging +The development instance uses file watching and live reload, so each time a MapStore 2 file is changed, the browser will reload the updated application. + +Use your favourite editor / IDE to develop and debug on the browser as needed. + +We suggest to use one of the following: + * [Atom](https://atom.io/) with the following plugins: + * editorconfig + * linter + * linter-eslint + * react + * lcovinfo + * [Sublime Text Editor](http://www.sublimetext.com/) with the following plugins: + * Babel + * Babel snippets + * Emmet + +## Backend services debugging +TBD + +## Frontend testing +To run the MapStore 2 frontend test suite you can use: + +`npm test` + +You can also have a continuosly running watching test runner, that will execute the complete suite each time a file is changed, launching: + +`npm run continuoustest` + +To run ESLint checks launch: + +`npm run lint` + +To run the same tests Travis will check (before a pull request): +`npm run travis` + +# General building and deploying +Maven is the main tool for building and deploying a complete application. It takes care of: + * building the java libraries and webapp(s) + * calling NPM as needed to take care of the frontend builds + * launching both backend and frontend test suites + * creating the final war for deploy into a J2EE container (e.g. Tomcat) + +To create the final war, you have several options: + * full build, including submodules (e.g. GeoStore) + +`./build.sh` + +or + +`mvn clean install -Pgeostore,proxy, extjs,postgres,h2_disk` + + * fast build (will use the last compiled version of submodules) + +`mvn clean install` diff --git a/web/client/wiki/Developers-Guide.md b/web/client/wiki/Developers-Guide.md new file mode 100644 index 0000000000..ee7f0ea090 --- /dev/null +++ b/web/client/wiki/Developers-Guide.md @@ -0,0 +1,36 @@ +# Quick Start: + +Clone the repository with the --recursive option to automatically clone submodules: + +`git clone --recursive https://github.com/geosolutions-it/MapStore2.git` + +Install NodeJS 0.12 , if needed, from [here](https://nodejs.org/en/download/releases/). + +Start the demo locally: + +`npm cache clean` (this is useful to prevent errors on Windows during install) + +`npm install` + +`npm start` + +Then point your preferred browser to [http://localhost:8081](http://localhost:8081). + +Install latest Maven, if needed, from [here](https://maven.apache.org/download.cgi) (version 3.1.0 is required). + +Build the deployable war: + +`./build.sh` + +Deploy the generated mapstore.war file (in web/target) to your favourite J2EE container (e.g. Tomcat). + +# Developers documentation + * [Infrastructure](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Infrastructure-and-general-architecture) + * [Building and developing](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Building-and-developing) + * [Frontend building tools and configuration](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Frontend-building-tools-and-configuration) + * [Developing with MapStore 2](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Developing-with-MapStore-2) + * [ReactJS and Redux introduction](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/ReactJS-and-Redux-introduction) + * [ReactJS 0.14.x](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/React-0.14.x-Migration-Guide) + * [Maps configuration](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Maps-configuration) + * [Plugins architecture](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Plugins-architecture) + * [How to use a CDN](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/How-to-use-a-CDN) diff --git a/web/client/wiki/Developing-with-MapStore-2.md b/web/client/wiki/Developing-with-MapStore-2.md new file mode 100644 index 0000000000..6b151360c5 --- /dev/null +++ b/web/client/wiki/Developing-with-MapStore-2.md @@ -0,0 +1,63 @@ +# Folders structure + +This is the overall framework folder structure: + +``` ++-- package.json ++-- pom.xml ++-- build.sh ++-- karma.conf.*.js ++-- tests.webpack.js ++-- webpack.config.js ++-- prod-webpack.config.js ++-- .babelrc ++-- .eslintrc ++-- .editorconfig ++-- .travis.yml ++-- ... ++-- geostore (submodule) ++-- web (MapStore2 maven module) + +-- pom.xml + +-- src (maven java webapp src folder) + | +-- main + | | +-- java + | | +-- resources + | | +-- webapp + | +-- test + | +-- java + | +-- resources + +-- client + | +-- index.html (demo application home page) + +-- plugins (ReactJS smart components with required reducers) + +-- components (ReactJS dumb components) + | +-- category + | | +-- .jsx (ReactJS component) + | | +-- ... + | | +-- __tests__ (unit tests folder) + | | +-- -test.jsx + | +-- ... + +-- actions (Redux actions) + +-- reducers (Redux reducers) + +-- stores (Redux stores) + +-- translations (i18n localization files) + | +-- data.en-US + | ... + | product (the MapStore2 main application) + | +... + +-- examples (example applications) + +-- 3dviewer + | +-- index.html + | +-- app.jsx + | +-- containers (app specific smart components) + | +-- components (app specific dumb components) + | +-- stores (app specific stores) + | +-- reducers (app specific reducers) + | +-- ... + +-- ... +``` + +If you want to create an application based on MapStore2 you can use the [Project Creation Script](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Project-Creation-Script). + +If you want to learn how to develop a simple MapStore2 based application you can follow the [tutorial](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Application-Tutorial) + +If you want to learn how to develop a plugins based MapStore2 based application you can follow the [plugins tutorial](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Plugins-architecture#building-an-application-using-plugins) diff --git a/web/client/wiki/Frontend-building-tools-and-configuration.md b/web/client/wiki/Frontend-building-tools-and-configuration.md new file mode 100644 index 0000000000..1a8436ebba --- /dev/null +++ b/web/client/wiki/Frontend-building-tools-and-configuration.md @@ -0,0 +1,48 @@ +Frontend building is delegated to [NPM](https://www.npmjs.com/) and so leverages the NodeJS ecosystem. + +In particular: + * a **[package.json](https://github.com/geosolutions-it/MapStore2/blob/master/package.json)** file is used to configure frontend dependencies, needed tools and building scripts + * **[babel](https://babeljs.io/)** is used for ES6/7 and JSX transpiling integrated with the other tools (e.g. webpack) + * **[webpack-dev-server](http://webpack.github.io/docs/webpack-dev-server.html)** is used to host the development application instance + * **[mocha](http://mochajs.org/)/[expect](https://github.com/mjackson/expect)** is used as a testing framework (with BDD style unit-tests) + * **[webpack](http://webpack.github.io/)**: as the bundling tool, for development (see [webpack.config.js](https://github.com/geosolutions-it/MapStore2/blob/master/webpack.config.js)), deploy (see [prod-webpack.config.js](https://github.com/geosolutions-it/MapStore2/blob/master/prod-webpack.config.js)) and test (see [test.webpack.js](https://github.com/geosolutions-it/MapStore2/blob/master/tests.webpack.js) + * **[karma](http://karma-runner.github.io/)** is used as the test suite runner, with several plugins to allow for custom reporting, browser running and so on; the test suite running is configured through different configuration files, for **[single running](https://github.com/geosolutions-it/MapStore2/blob/master/karma.conf.single-run.js)** or **[continuous testing](https://github.com/geosolutions-it/MapStore2/blob/master/karma.conf.continuous-test.js)** + * **[istanbul](https://gotwarlost.github.io/istanbul/)/[coveralls](https://www.npmjs.com/package/coveralls)** are used for code coverage reporting + * **[eslint](eslint.org)** is used to enforce coding styles guidelines, the tool is configured using a **[.eslintrc](https://github.com/geosolutions-it/MapStore2/blob/master/.eslintrc)** file + +# Available scripts + * download dependencies and init developer environment + +`npm install` + + * start development instance + +`npm start` + +* start development instance with examples + +`npm run examples` + + * run test suite once + +`npm test` + + * run continuous test suite running + +`npm run continuoustest` + + * run single build / bundling + +`npm run compile` + + * run ESLint checks + +`npm run lint` + + * run tests from Maven + +`npm run mvntest` + + * build for travis + +`npm run travis` \ No newline at end of file diff --git a/web/client/wiki/Home.md b/web/client/wiki/Home.md new file mode 100644 index 0000000000..c9632543ab --- /dev/null +++ b/web/client/wiki/Home.md @@ -0,0 +1,22 @@ +![MapStore Logo](https://github.com/geosolutions-it/MapStore2/blob/master/MapStore2.png) + +**[MapStore](http://mapstore2.geo-solutions.it/)** is a framework to build _web mapping_ applications using standard mapping libraries, such as _OpenLayers 3_ and _Leaflet_. + +MapStore has several example applications: + + * **[MapViewer](http://mapstore2.geo-solutions.it/mapstore/)** is a simple viewer of preconfigured maps (optionally stored in a database using GeoStore) + * **[Scalebar Example](http://mapstore2.geo-solutions.it/mapstore/examples/scalebar/)** + * **[Layer Tree Example](http://mapstore2.geo-solutions.it/mapstore/examples/layertree/)** + * **[Mouse Position Game](http://mapstore2.geo-solutions.it/mapstore/examples/mouseposition/)** + * **MapPublisher TODO** has been developed to create, save and share in a simple and intuitive way maps and mashups created selecting contents by server like OpenStreetMap, Google Maps, MapQuest or specific servers provided by your organization or third party. + +MapStore 2 is based on OpenLayers 3, Leaflet and ReactJS, and is licensed under the GPLv3 license. + +# Quick Start + +TBD (put download links here) + +# Documentation + * [Developers Guide](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Developers-Guide) + * [Users Guide] TBD + * [Release Checklist](https://github.com/geosolutions-it/MapStore2/wiki/Release-Checklist) diff --git a/web/client/wiki/How-to-use-a-CDN.md b/web/client/wiki/How-to-use-a-CDN.md new file mode 100644 index 0000000000..cce4fa0f96 --- /dev/null +++ b/web/client/wiki/How-to-use-a-CDN.md @@ -0,0 +1,4 @@ +The LeafletDraw plugin and the MapStore2 theme are linked via rawgit.com but in production it should be used a proper CDN. +Once you have a stable version: +- upload the [LeafletDraw plugin](http://rawgit.com/Leaflet/Leaflet.draw/0.2.3/dist/) and the [MapStore2 theme](https://github.com/geosolutions-it/MapStore2-theme/tree/master/theme/default) on your CDN +- edit the [index.html](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/index.html) file to use your published resources. diff --git a/web/client/wiki/Infrastructure-and-general-architecture.md b/web/client/wiki/Infrastructure-and-general-architecture.md new file mode 100644 index 0000000000..dd855a994b --- /dev/null +++ b/web/client/wiki/Infrastructure-and-general-architecture.md @@ -0,0 +1,26 @@ +MapStore 2 leverages a full separation of concerns between the **backend** and the **frontend**. + +The frontend is a Javascript web application communicating with MapStore 2 own web services using AJAX and external ones through an internal, configurable, _proxy_. + +The backend is a suite of web services, developed in Java and deployed into a J2EE container (e.g. Apache Tomcat). +![General Infrastructure](https://docs.google.com/drawings/d/1X-yA-_GQ6HqhoYQfIbuxzdt8c-9fD0K3tf1WVbXecSE/pub?w=480&h=360) + +# Frontend + +The frontend is based on the [ReactJS](https://facebook.github.io/react/) library and the [Redux](http://rackt.github.io/redux/) architecture, which is a specific implementation of the [Flux](http://facebook.github.io/flux/) architecture. + +![Flux infrastructure](https://facebook.github.io/flux/img/flux-simple-f8-diagram-with-client-action-1300w.png) + +It allows plugging different mapping libraries (with **Leaflet** and **OpenLayers 3** as our first implementation targets) abstracting libraries implementation details using ReactJS _web components_ and _actions based communication_. + +![MapStore 2 - Frontend](https://docs.google.com/drawings/d/1k8Qja6ZFeOpoW3WqbZJvU3f7PvKpL-oTGq0vErQng44/pub?w=480&h=360) + +# Backend + +Backend services include at least (but not only) these ones: + * Generic, configurable, **HTTP-Proxy** to avoid CORS issues when the frontend tries to communicate with external services, based on the GeoSolutions [http-proxy](https://github.com/geosolutions-it/http-proxy) project. + * Internal **storage** for non structured resources (json, XML, etc.) based on the GeoSolutions [GeoStore](https://github.com/geosolutions-it/geostore) project. + * **Configuration** services, to allow full application(s) and services configurability + * **Security** with the ability to configure authentication using an internal or external service, and a flexible authorization policy for services and resources access + +![MapStore 2 - Backend](https://docs.google.com/drawings/d/12SURY5tdrjOXwYx0kH1LHUmHogZpWvmcEoFCGJOgJWY/pub?w=480&h=360) \ No newline at end of file diff --git a/web/client/wiki/Maps-configuration.md b/web/client/wiki/Maps-configuration.md new file mode 100644 index 0000000000..7c75e7a960 --- /dev/null +++ b/web/client/wiki/Maps-configuration.md @@ -0,0 +1,42 @@ +# Map options + + +# Layers option + + +## Layer types + +* WMS +* Bing +* Google +* MapQuest +* OSM +* [[TileProvider|Maps-configuration#tileprovider]] + +### WMS + +### Bing + +### Google + +### MapQuest + +### TileProvider +TileProvider is a shortcut to easily configure many different layer sources. +It's enough to add provider property and 'tileprovider' as type property to the layer configuration object. Property value should be in the form of ProviderName.VariantName. + +List of available layer [here](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/utils/ConfigProvider.js) + +i.e. +> ``{ +"type": "tileprovider", +"title": "Title", +"provider": "Stamen.Toner", +"name": "Name", +"group": "GroupName", +"visibility": false +}`` + +Options passed in configuration object, if already configured by TileProvider, will be overridden. + +Openlayer's TileProvider at the moment doesn't support minZoom configuration property and hi resolution map diff --git a/web/client/wiki/Plugins-architecture.md b/web/client/wiki/Plugins-architecture.md new file mode 100644 index 0000000000..72ac231980 --- /dev/null +++ b/web/client/wiki/Plugins-architecture.md @@ -0,0 +1,101 @@ +MapStore2 fully embraces both ReactJS and Redux concepts, enhancing them with the **plugin** concept. + +A plugin in MapStore2 is a smart ReactJS component that is: + * **connected** to a Redux store, so that some properties are automatically wired to the standard MapStore2 state + * **wired** to standard actions for common events + +In addition a plugin: + * declares one or more **reducers** that need to be added to the Redux store + * is fully **configurable** to be easily customized to a certain level + +## Building an application using plugins +To use plugins you need to: + * declare available (required) plugins, properly requiring them from the root application component + * load / declare plugins configuration + * create a store that dynamically includes plugins required reducers + * use a PluginsContainer component as the container for your plugins enabled application slice (can be the whole application or just a part of it) + +### Declare available plugins +Create a plugins.js file where you declare all the needed plugins: + +plugins.js: +```javascript +module.exports = { + plugins: { + MyPlugin: require('../plugins/My') + }, + requires: {} +}; +``` +### Load / Create plugins configuration object +Create a pluginsConfig.js file where you configure your plugins (see [our plugins.jg](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/product/plugins.js)): + +pluginsConfig.js: +```javascript +module.exports = { + standard: { + PluginName: require('../path/to/plugin') + } +} +``` + +### Declare a plugins compatible Redux Store +Create a store that properly initializes plugins reducers (see [standardStore.js](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/stores/StandardStore.js)) : + +store.js: +```javascript +const {combineReducers} = require('../utils/PluginsUtils'); +const {createDebugStore} = require('../utils/DebugUtils'); + +module.exports = (plugins) => { + const allReducers = combineReducers(plugins, { + ... + }); + return createDebugStore(allReducers, {}); +}; +``` + +### Use a PluginContainer to render all your plugins +In the root application component require plugins declaration and configuration and use them to initialize both the store and a PluginsContainer (see our [PluginContainer.jsx](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/components/plugins/PluginsContainer.jsx)): + +App.jsx: +```javascript +const {pluginsDef} = require('./plugins.js'); +const pluginsCfg = require('./pluginsConfig.json'); + +const store = require('./store')(pluginsDef); + +const plugins = PluginsUtils.getPlugins(pluginsDef); + +ReactDOM.render(, ...container...); +``` + +## Developing a plugin +An example is better than a thousand words: + +My.jsx: +```javascript + +// this is a dumb component +const MyComponent = require('../components/MyComponent'); +const {connect} = require('react-redux'); + +// let's wire it to state and actions +const MyPlugin = connect((state) => ({ + myproperty: state.myreducer.property +}), { + myaction +})(MyComponent); + +// let's export the plugin and a set of required reducers +const myreducer = require('../reducers/myreducer'); +module.exports = { + MyPlugin, + reducers: {myreducer} +}; +``` + +## The Plugins Example Application +The [example](http://qa.mapstore2.geo-solutions.it/mapstore/examples/plugins/) shows the plugins infrastructure power in an interactive way. + +The UI allows to add / remove plugins from the base applications, and to configure them using a JSON object with plugins configuration properties. diff --git a/web/client/wiki/Project-Creation-Script.md b/web/client/wiki/Project-Creation-Script.md new file mode 100644 index 0000000000..88e5e27399 --- /dev/null +++ b/web/client/wiki/Project-Creation-Script.md @@ -0,0 +1,19 @@ +To create a new project you can use the createProject script: + +``` +node ./createProject.js +``` + +All the arguments are mandatory: + * **projectName**: short project name that will be used as the repository name on github, webapp path and name in package.json + * **projectVersion**: project version in package.json + * **projectDescription**: project description, used in sample index page and as description in package.json + * **gitRepositoryUrl**: full url to the github repository where the project will be published + * **outputFolder**: folder where the project will be created (must exist) + +At the end of the script execution, the given outputFolder will be populated by all the configuration files needed to start working on the project and a sample application with two pages (home and main). Moreover, the local git repo will be initialized and the MapStore2 submodule added and downloaded. + +Following steps are: + * npm install to download dependencies + * npm start to test the project + * git add / push to publish the initial project on the git repo \ No newline at end of file diff --git a/web/client/wiki/React-0.14.x-Migration-Guide.md b/web/client/wiki/React-0.14.x-Migration-Guide.md new file mode 100644 index 0000000000..96cbec14c4 --- /dev/null +++ b/web/client/wiki/React-0.14.x-Migration-Guide.md @@ -0,0 +1,50 @@ +# Migration Hints +We are migrating MapStore 2 to use the newest 0.14.x version of ReactJS. + +There are some differences in the new release that require some boring steps to make things working. [Here](https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html) you can find the full release notes document from Facebook. + +Here are some quick tips: + * Wherever you use React.render(...), React.findDOMNode(...) or React.umountComponentAtNode(...) you should: + * import the new react-dom library + * use ReactDOM.render(...), ReactDOM.findDOMNode(...) or ReactDOM.umountComponentAtNode(...) + +```javascript +const ReactDOM = require('react-dom'); +... +ReactDOM.render(..., ...); +``` + + * you should not do these things anymore (they are deprecated): + * component.getDOMNode(...) (use React.findDOMNode(component) instead) + * component.setProps(...), component.replaceProps(...) (you should re-render the component with the new props instead) + * require('react/addons') (require the new react-addon- for each of the needed addons instead) + * component.cloneWithProps(...) (use React.cloneElement instead) + * Context enabled containers (Provider, Localized, etc.) have a simpler syntax: + +```html +// old syntax + + {() => } + + +// new syntax + + + +``` + * new Debug component usage: the Debug component is not a wrapper anymore: + +```html +// old syntax + + + + + + +// new syntax + + + + +``` \ No newline at end of file diff --git a/web/client/wiki/ReactJS-and-Redux-introduction.md b/web/client/wiki/ReactJS-and-Redux-introduction.md new file mode 100644 index 0000000000..398a847137 --- /dev/null +++ b/web/client/wiki/ReactJS-and-Redux-introduction.md @@ -0,0 +1,167 @@ +# ReactJS +[ReactJS](https://facebook.github.io/react/index.html) 0.14.8 is used to develop MapStore2. The main purpose of ReactJS is to allow writing the **View** of the application, through the composition of _small components_, in a _declarative way_. + +Components are written using a "templating" language, called [**JSX**](https://react-bootstrap.github.io/introduction.html), that is a sort of composition of HTML and Javascript code. The difference between JSX and older approaches like _JSP_ is that JSX templates are mixed with Javascript code inside javascript files. + +## ReactJS component example +Component definition: + +```javascript +var MyComponent = React.createClass({ + render: function() { + return

{this.props.title}

; + } +}); +``` + +Component usage: +```javascript +React.render(, document.body); +``` +## Properties, State and Event handlers +Components can define and use **properties**, like the title one used in the example. These are immutable, and cannot be changed by component's code. + +Components can also use **state** that can change. When the state changes, the component is updated (re-rendered) automatically. + +```javascript +var MyComponent = React.createClass({ + getInitialState: function() { + return { + title: 'CHANGE_ME' + }; + }, + changeTitle: function() { + this.setState({ + title: 'CHANGED' + }); + }, + render: function() { + return

{this.state.title}

; + } +}); +``` +In this example, the initial state includes a title property whose value is CHANGE_ME. + +When the h1 element is clicked, the state is changed so that title becomes CHANGED. + +The HTML page is automatically updated by ReactJS, each time the state changes (each time this.setState is called). For this reason we say that JSX allows to declaratively describe the View for each possible application state. + +## Lifecycle hooks +Components can re-define some [lifecycle methods](https://facebook.github.io/react/docs/component-specs.html), to execute actions in certain moments of the component life. + +```javascript +var MyComponent = React.createClass({ + ... + componentWillMount: function() { + console.log('not mounted yet'); + }, + componentDidMount: function() { + var domElement = React.findDOMNode(this); + console.log('DOM mounted'); + }, + ... +}); +``` + +# Redux +[Redux](http://redux.js.org/index.html), and its companion [react-redux](https://github.com/reactjs/react-redux) are used to handle the application state and bind it to ReactJS components. + +Redux promotes a unidirectional dataflow (inspired by the [Flux](https://facebook.github.io/flux/) architecture) and immutable state transformation using reducers, to achieve predictable and reproducable application behaviour. + +A single, global, **Store** is delegated to contain all the application state. + +The state can be changed dispatching **Actions** to the store. + +Each action produces a new state (the state is never changed, a new state is produced and that is the new application state), through the usage of one or more **reducers**. + +**(Smart) Components** can be connected to the store and be notified when the state changes, so that views are automatically updated. + +## Actions +In Redux, actions are actions descriptors, generated by an action creator. Actions descriptors are usually defined by an **action type** and a set of parameters that specify the action payload. + +```javascript +const CHANGE_TITLE= 'CHANGE_TITLE'; + +// action creator +function changeTitle(newTitle) { + return { + type: CHANGE_TITLE, + title: newTitle + }; +} + +``` + +## Reducers +Reducers are functions that receive an action and the current state and: + * produce a new state, for each recognized action + * produce the current state for unrecognized actions + * produce initial state, if the current state is undefined + +```javascript +function reducer(state = {title: "CHANGE_ME"}, action) { + switch (action.type) { + case CHANGE_TITLE: + return {title: action.title}; + default: + return state; + } +} +``` +## Store +The redux store combines different reducers to produce a global state, with a slice for each used reducer. + +```javascript +var rootReducer = combineReducers({ + slice1: reducer1, + slice2: reducer2 +}); +var initialState = {slice1: {}, slice2: {}}; + +var store = createStore(rootReducer, initialState); +``` + +The Redux store receives actions, through a dispatch method, and creates a new application state, using the configured reducers. + +```javascript +store.dispatch(changeTitle('New title')); +``` + +You can subscribe to the store, to be notified whenever the state changes. + +```javascript +store.subscribe(function handleChange() {}); +``` +## Redux and ReactJS integration +The **react-redux** library can be used to connect the Redux application state to ReactJS components. + +This can be done in the following way: + * wrap the ReactJS root component with the react-redux **Provider** component, to bind the Redux store to the ReactJS view + +```javascript +React.render( + + {() => } + , + document.getElementById('container') +); +``` + + * explicitly connect one or more (smart) components to a all or part of the state (you can also transform the state and have computed properties) + +```javascript +connect(function(state) { + return { + title: state.title, + name: state.namespace + '.' + state.name, + }; +})(App); +``` + +The connected component will get automatic access to the configured slice through properties: + +```javascript +function render() { + return

{this.props.title}

{this.props.name}

Date: Mon, 5 Dec 2016 13:46:44 +0100 Subject: [PATCH 2/2] fix --- .../developer-guide}/Application-Tutorial.md | 0 .../Building-and-developing.md | 0 .../developer-guide}/Developers-Guide.md | 18 +++++++++--------- .../Developing-with-MapStore-2.md | 6 +++--- ...rontend-building-tools-and-configuration.md | 0 .../wiki => docs/developer-guide}/Home.md | 2 +- .../developer-guide}/How-to-use-a-CDN.md | 0 .../Infrastructure-and-general-architecture.md | 0 .../developer-guide}/Maps-configuration.md | 0 .../developer-guide}/Plugins-architecture.md | 0 .../Project-Creation-Script.md | 0 .../React-0.14.x-Migration-Guide.md | 0 .../ReactJS-and-Redux-introduction.md | 0 13 files changed, 13 insertions(+), 13 deletions(-) rename {web/client/wiki => docs/developer-guide}/Application-Tutorial.md (100%) rename {web/client/wiki => docs/developer-guide}/Building-and-developing.md (100%) rename {web/client/wiki => docs/developer-guide}/Developers-Guide.md (67%) rename {web/client/wiki => docs/developer-guide}/Developing-with-MapStore-2.md (88%) rename {web/client/wiki => docs/developer-guide}/Frontend-building-tools-and-configuration.md (100%) rename {web/client/wiki => docs/developer-guide}/Home.md (96%) rename {web/client/wiki => docs/developer-guide}/How-to-use-a-CDN.md (100%) rename {web/client/wiki => docs/developer-guide}/Infrastructure-and-general-architecture.md (100%) rename {web/client/wiki => docs/developer-guide}/Maps-configuration.md (100%) rename {web/client/wiki => docs/developer-guide}/Plugins-architecture.md (100%) rename {web/client/wiki => docs/developer-guide}/Project-Creation-Script.md (100%) rename {web/client/wiki => docs/developer-guide}/React-0.14.x-Migration-Guide.md (100%) rename {web/client/wiki => docs/developer-guide}/ReactJS-and-Redux-introduction.md (100%) diff --git a/web/client/wiki/Application-Tutorial.md b/docs/developer-guide/Application-Tutorial.md similarity index 100% rename from web/client/wiki/Application-Tutorial.md rename to docs/developer-guide/Application-Tutorial.md diff --git a/web/client/wiki/Building-and-developing.md b/docs/developer-guide/Building-and-developing.md similarity index 100% rename from web/client/wiki/Building-and-developing.md rename to docs/developer-guide/Building-and-developing.md diff --git a/web/client/wiki/Developers-Guide.md b/docs/developer-guide/Developers-Guide.md similarity index 67% rename from web/client/wiki/Developers-Guide.md rename to docs/developer-guide/Developers-Guide.md index ee7f0ea090..ef5fe3cfdc 100644 --- a/web/client/wiki/Developers-Guide.md +++ b/docs/developer-guide/Developers-Guide.md @@ -25,12 +25,12 @@ Build the deployable war: Deploy the generated mapstore.war file (in web/target) to your favourite J2EE container (e.g. Tomcat). # Developers documentation - * [Infrastructure](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Infrastructure-and-general-architecture) - * [Building and developing](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Building-and-developing) - * [Frontend building tools and configuration](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Frontend-building-tools-and-configuration) - * [Developing with MapStore 2](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Developing-with-MapStore-2) - * [ReactJS and Redux introduction](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/ReactJS-and-Redux-introduction) - * [ReactJS 0.14.x](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/React-0.14.x-Migration-Guide) - * [Maps configuration](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Maps-configuration) - * [Plugins architecture](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Plugins-architecture) - * [How to use a CDN](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/How-to-use-a-CDN) + * [Infrastructure](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Infrastructure-and-general-architecture) + * [Building and developing](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Building-and-developing) + * [Frontend building tools and configuration](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Frontend-building-tools-and-configuration) + * [Developing with MapStore 2](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Developing-with-MapStore-2) + * [ReactJS and Redux introduction](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/ReactJS-and-Redux-introduction) + * [ReactJS 0.14.x](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/React-0.14.x-Migration-Guide) + * [Maps configuration](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Maps-configuration) + * [Plugins architecture](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Plugins-architecture) + * [How to use a CDN](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/How-to-use-a-CDN) diff --git a/web/client/wiki/Developing-with-MapStore-2.md b/docs/developer-guide/Developing-with-MapStore-2.md similarity index 88% rename from web/client/wiki/Developing-with-MapStore-2.md rename to docs/developer-guide/Developing-with-MapStore-2.md index 6b151360c5..330a207d33 100644 --- a/web/client/wiki/Developing-with-MapStore-2.md +++ b/docs/developer-guide/Developing-with-MapStore-2.md @@ -56,8 +56,8 @@ This is the overall framework folder structure: +-- ... ``` -If you want to create an application based on MapStore2 you can use the [Project Creation Script](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Project-Creation-Script). +If you want to create an application based on MapStore2 you can use the [Project Creation Script](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Project-Creation-Script). -If you want to learn how to develop a simple MapStore2 based application you can follow the [tutorial](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Application-Tutorial) +If you want to learn how to develop a simple MapStore2 based application you can follow the [tutorial](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Application-Tutorial) -If you want to learn how to develop a plugins based MapStore2 based application you can follow the [plugins tutorial](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Plugins-architecture#building-an-application-using-plugins) +If you want to learn how to develop a plugins based MapStore2 based application you can follow the [plugins tutorial](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Plugins-architecture#building-an-application-using-plugins) diff --git a/web/client/wiki/Frontend-building-tools-and-configuration.md b/docs/developer-guide/Frontend-building-tools-and-configuration.md similarity index 100% rename from web/client/wiki/Frontend-building-tools-and-configuration.md rename to docs/developer-guide/Frontend-building-tools-and-configuration.md diff --git a/web/client/wiki/Home.md b/docs/developer-guide/Home.md similarity index 96% rename from web/client/wiki/Home.md rename to docs/developer-guide/Home.md index c9632543ab..a4cd09f489 100644 --- a/web/client/wiki/Home.md +++ b/docs/developer-guide/Home.md @@ -17,6 +17,6 @@ MapStore 2 is based on OpenLayers 3, Leaflet and ReactJS, and is licensed under TBD (put download links here) # Documentation - * [Developers Guide](https://github.com/geosolutions-it/MapStore2/blob/master/web/client/wiki/Developers-Guide) + * [Developers Guide](https://github.com/geosolutions-it/MapStore2/blob/master/docs/developer-guide/Developers-Guide) * [Users Guide] TBD * [Release Checklist](https://github.com/geosolutions-it/MapStore2/wiki/Release-Checklist) diff --git a/web/client/wiki/How-to-use-a-CDN.md b/docs/developer-guide/How-to-use-a-CDN.md similarity index 100% rename from web/client/wiki/How-to-use-a-CDN.md rename to docs/developer-guide/How-to-use-a-CDN.md diff --git a/web/client/wiki/Infrastructure-and-general-architecture.md b/docs/developer-guide/Infrastructure-and-general-architecture.md similarity index 100% rename from web/client/wiki/Infrastructure-and-general-architecture.md rename to docs/developer-guide/Infrastructure-and-general-architecture.md diff --git a/web/client/wiki/Maps-configuration.md b/docs/developer-guide/Maps-configuration.md similarity index 100% rename from web/client/wiki/Maps-configuration.md rename to docs/developer-guide/Maps-configuration.md diff --git a/web/client/wiki/Plugins-architecture.md b/docs/developer-guide/Plugins-architecture.md similarity index 100% rename from web/client/wiki/Plugins-architecture.md rename to docs/developer-guide/Plugins-architecture.md diff --git a/web/client/wiki/Project-Creation-Script.md b/docs/developer-guide/Project-Creation-Script.md similarity index 100% rename from web/client/wiki/Project-Creation-Script.md rename to docs/developer-guide/Project-Creation-Script.md diff --git a/web/client/wiki/React-0.14.x-Migration-Guide.md b/docs/developer-guide/React-0.14.x-Migration-Guide.md similarity index 100% rename from web/client/wiki/React-0.14.x-Migration-Guide.md rename to docs/developer-guide/React-0.14.x-Migration-Guide.md diff --git a/web/client/wiki/ReactJS-and-Redux-introduction.md b/docs/developer-guide/ReactJS-and-Redux-introduction.md similarity index 100% rename from web/client/wiki/ReactJS-and-Redux-introduction.md rename to docs/developer-guide/ReactJS-and-Redux-introduction.md