Skip to content

Commit

Permalink
Merge branch 'master' into fullscreen
Browse files Browse the repository at this point in the history
  • Loading branch information
offtherailz authored Mar 31, 2017
2 parents f3eedfd + 421a8af commit 7079bf5
Show file tree
Hide file tree
Showing 80 changed files with 692 additions and 379 deletions.
1 change: 0 additions & 1 deletion docma-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@
"label": "Download",
"href": "index.html",
"items": [
{ "label": "<code>mvn clean install</code>" },
{
"label": "MapStore 2 Releases",
"href": "https://github.com/geosolutions-it/MapStore2/releases",
Expand Down
3 changes: 2 additions & 1 deletion docs/developer-guide/configuration-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
MapStore2 (and every application developed with MapStore2) allows customization through configuration.
Several configuration files (at development and / or run time) are available to configure all the different aspects of an application.

* [Maps configuration](maps-configuration)
* [Application Configuration](local-config)
* [Maps configuration](maps-configuration)
69 changes: 69 additions & 0 deletions docs/developer-guide/local-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Application configuration
The application will load by default it will load the `localConfig.js`

You can load a custom configuration by passing the `localConfig` argument in query string:

```
localhost:8081/?localConfig=myConfig#/viewer/openlayers/0
```


The **localConfig** file contains the main information about URLs to load and plugins to load in the various modes.

This is the main structure:
```
{
// URL of geoStore
"geoStoreUrl": "rest/geostore/",
// printURL the url of the print service, if any
"printUrl": "/geoserver-test/pdf/info.json",
// a string or an object for the proxy URL.
"proxyUrl": {
// if it is an object, the url entry holds the url to the proxy
"url": "/MapStore2/proxy/?url=",
// useCORS array contains a list of services that support CORS and so do not need a proxy
"useCORS": ["http://nominatim.openstreetmap.org", "https://nominatim.openstreetmap.org"]
},
// API keys for bing and mapquest services
"bingApiKey",
"mapquestApiKey",
// path to the translation files directory (if different from default)
"translationsPath",
// if true, every ajax and mapping request will be authenticated with the configurations if match a rule
"useAuthenticationRules": true
// the athentication rules to match
"authenticationRules": [
{ // every rule has a `urlPattern` regex to match
"urlPattern": ".*geostore.*",
// and a authentication `method` to use (basic, authkey)
"method": "basic"
}, {
"urlPattern": "\\/geoserver.*",
"method": "authkey"
},
// optional state initializer (it will override the one defined in appConfig.js)
"initialState": {
// default initial state for every mode (will override initialState imposed by plugins reducers)
"defaultState": {
...
},
// mobile override (defined properties will overide default in mobile mode)
"mobile": {
...
}
}
"plugins": {
// plugins to load for the mobile mode
"mobile": [...]
// plugins to load for the desktop mode
"desktop": [...]
// plugins to load for the embedded mode
"embedded": [...]
// plugins to load for the myMode mode
"myMode": [...]
}
],
```
If you are building your own app, you can choose to create your custom modes or force one of them by passing the `mode` parameter in the query string.

For configuring plugins, see the [Configuring Plugins Section](plugins-documentation) and the [plugin reference page](./api/plugins)
2 changes: 1 addition & 1 deletion docs/developer-guide/map-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ module.exports = {
}],
"toolsOptions": {
"test": {
"label": "ciao"
"label": "Hello"
}
...
}
Expand Down
2 changes: 1 addition & 1 deletion prod-webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ webpackConfig.plugins = [
options: {
postcss: {
plugins: [
require('postcss-prefix-selector')({prefix: '.ms2', exclude: ['.ms2']})
require('postcss-prefix-selector')({prefix: '.ms2', exclude: ['.ms2', '[data-ms2-container]']})
]
},
context: __dirname
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"proxyUrl": "/mapstore/proxy/?url=",
"geoStoreUrl": "/mapstore/rest/geostore",
"printUrl": "https://demo.geo-solutions.it/geoserver/pdf/info.json",
"themePrefix": "__PROJECTNAME__",
"translationsPath": "./MapStore2/web/client/translations",
"plugins": {
"desktop": ["Map", "Home"]
Expand Down
2 changes: 1 addition & 1 deletion project/prod-webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ webpackConfig.plugins = [
options: {
postcss: {
plugins: [
require('postcss-prefix-selector')({prefix: '.__PROJECTNAME__', exclude: ['.__PROJECTNAME__', '.ms2']})
require('postcss-prefix-selector')({prefix: '.__PROJECTNAME__', exclude: ['.__PROJECTNAME__', '.ms2', '[data-ms2-container]']})
]
},
context: __dirname
Expand Down
2 changes: 1 addition & 1 deletion project/static/js/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const StandardRouter = connect((state) => ({
pages
}))(require('../MapStore2/web/client/components/app/StandardRouter'));

const appStore = require('../MapStore2/web/client/stores/StandardStore').bind(null, initialState, {});
const appStore = require('../MapStore2/web/client/stores/StandardStore').bind(null, initialState, {}, {}, {});

const appConfig = {
storeOpts,
Expand Down
6 changes: 3 additions & 3 deletions project/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports = {
options: {
postcss: {
plugins: [
require('postcss-prefix-selector')({prefix: '.__PROJECTNAME__', exclude: ['.ms2', '.__PROJECTNAME__']})
require('postcss-prefix-selector')({prefix: '.__PROJECTNAME__', exclude: ['.ms2', '.__PROJECTNAME__', '[data-ms2-container]']})
]
},
context: __dirname
Expand Down Expand Up @@ -104,8 +104,8 @@ module.exports = {
name: "[path][name].[ext]",
limit: 8192
}
}]
},
}]
},
{
test: /\.jsx?$/,
exclude: /(ol\.js)$|(Cesium\.js)$|(cesium\.js)$/,
Expand Down
42 changes: 42 additions & 0 deletions web/client/api/__tests__/searchText-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/**
* 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 {API} = require('../searchText');
const axios = require('axios');

describe('Test correctness of the searchText APIs', () => {

const myFun = (param) => {
// do stuff
return param;
};
function fun() {
return axios.get('base/web/client/test-resources/featureCollectionZone.js');
}

it('setter and getter services', (done) => {
let servName = "myService";
API.Utils.setService(servName, myFun);
try {
expect(API.Services).toExist();
expect(API.Services[servName]).toExist();
expect(API.Utils.getService(servName)).toExist();
done();
} catch(ex) {
done(ex);
}
});

let serviceType = 'myCustomService';
it('setService', (done) => {
API.Utils.setService(serviceType, fun);
expect(API.Utils.getService(serviceType)).toBe(fun);
done();
});
});
49 changes: 28 additions & 21 deletions web/client/api/searchText.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,40 +9,47 @@ const WFS = require('./WFS');
const assign = require('object-assign');
const GeoCodeUtils = require('../utils/GeoCodeUtils');
const {generateTemplateString} = require('../utils/TemplateUtils');
/*
const toNominatim = (fc) =>
fc.features && fc.features.map( (f) => ({
boundingbox: f.properties.bbox,
lat: 1,
lon: 1,
display_name: `${f.properties.STATE_NAME} (${f.properties.STATE_ABBR})`

}));
*/

module.exports = {
let Services = {
nominatim: (searchText, options = {}) =>
require('./Nominatim')
.geocode(searchText, options)
.then( res => GeoCodeUtils.nominatimToGeoJson(res.data)),
wfs: (searchText, {url, typeName, queriableAttributes, outputFormat="application/json", predicate ="ILIKE", staticFilter="", blacklist = [], item, ...params }) => {
wfs: (searchText, {url, typeName, queriableAttributes = [], outputFormat="application/json", predicate ="ILIKE", staticFilter="", blacklist = [], item, ...params }) => {
// split into words and remove blacklisted words
const staticFilterParsed = generateTemplateString(staticFilter || "")(item);
let searchWords = searchText.split(" ").filter(w => w).filter( w => blacklist.indexOf(w.toLowerCase()) < 0 );

// if the searchtext is empty use the full searchText
// if the array searchWords is empty, then use the full searchText
if (searchWords.length === 0 ) {
searchWords = [searchText];
searchWords = !!searchText ? [searchText] : [];
}
let filter;
if (searchWords.length > 0 ) {
filter = "(".concat( searchWords.map( (w) => queriableAttributes.map( attr => `${attr} ${predicate} '%${w.replace("'", "''")}%'`).join(" OR ")).join(') AND (')).concat(")");
}

filter = filter ? filter.concat(staticFilterParsed) : staticFilterParsed || null;

return WFS
.getFeatureSimple(url, assign({
maxFeatures: 10,
startIndex: 0,
typeName,
outputFormat,
// create a filter like : `(ATTR ilike '%word1%') AND (ATTR ilike '%word2%')`
cql_filter: "(".concat( searchWords.map( (w) => queriableAttributes.map( attr => `${attr} ${predicate} '%${w.replace("'", "''")}%'`).join(" OR ")).join(') AND (')).concat(")") .concat(staticFilterParsed)
}, params))
maxFeatures: 10,
typeName,
outputFormat,
// create a filter like : `(ATTR ilike '%word1%') AND (ATTR ilike '%word2%')`
cql_filter: filter
}, params))
.then( response => response.features );
}
};

const Utils = {
setService: (type, fun) => {
Services[type] = fun;
},
getService: (type) => {
return !!Services[type] ? Services[type] : null;
}
};

module.exports = {API: {Services, Utils}};
3 changes: 2 additions & 1 deletion web/client/components/I18N/FlagButton.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
* LICENSE file in the root directory of this source tree.
*/
var React = require('react');
var {Button, Tooltip, OverlayTrigger} = require('react-bootstrap');
var {Button, Tooltip} = require('react-bootstrap');
const OverlayTrigger = require('../misc/OverlayTrigger');
var LocaleUtils = require('../../utils/LocaleUtils');


Expand Down
2 changes: 1 addition & 1 deletion web/client/components/TOC/DefaultLayer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ var DefaultLayer = React.createClass({
{this.renderCollapsible()}
{this.renderTools()}
<InlineSpinner loading={this.props.node.loading}/>
<ConfirmModal ref="removelayer" className="clayer_removal_confirm_button" show= {this.state.showDeleteDialog} onHide={this.closeDeleteDialog} onClose={this.closeDeleteDialog} onConfirm={this.onConfirmDelete} titleText={this.props.confirmDeleteText} confirmText={this.props.confirmDeleteText} cancelText={<Message msgId="cancel" />} body={this.props.confirmDeleteMessage} />
<ConfirmModal ref="removelayer" show= {this.state.showDeleteDialog} onHide={this.closeDeleteDialog} onClose={this.closeDeleteDialog} onConfirm={this.onConfirmDelete} titleText={this.props.confirmDeleteText} confirmText={this.props.confirmDeleteText} cancelText={<Message msgId="cancel" />} body={this.props.confirmDeleteMessage} />
</Node>
);
},
Expand Down
4 changes: 2 additions & 2 deletions web/client/components/TOC/__tests__/DefaultLayer-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ describe('test DefaultLayer module component', () => {
const tool = ReactDOM.findDOMNode(TestUtils.scryRenderedDOMComponentsWithClass(comp, "clayer_removal_button")[0]);
expect(tool).toExist();
tool.click();
const confirmButton = document.getElementsByClassName("clayer_removal_confirm_button")[0];
const confirmButton = document.getElementsByClassName("btn-primary")[0];
expect(confirmButton).toExist();
confirmButton.click();
expect(spy.calls.length).toBe(1);
Expand Down Expand Up @@ -279,7 +279,7 @@ describe('test DefaultLayer module component', () => {
};
// helper function to get current modals
const getModals = function() {
return document.getElementsByTagName("body")[0].getElementsByClassName('modal-dialog');
return document.getElementsByTagName("body")[0].getElementsByClassName('modal-dialog-container');
};
// no modals should be available
const element1 = {layer: {id: 'layer1', name: 'layer1'}, settings: {}};
Expand Down
3 changes: 2 additions & 1 deletion web/client/components/TOC/fragments/LayersTool.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
*/

const React = require('react');
const {Glyphicon, OverlayTrigger, Tooltip} = require('react-bootstrap');
const {Glyphicon, Tooltip} = require('react-bootstrap');
const OverlayTrigger = require('../../misc/OverlayTrigger');
const Message = require('../../I18N/Message');

require("./css/layertool.css");
Expand Down
18 changes: 3 additions & 15 deletions web/client/components/TOC/fragments/SettingsModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

const React = require('react');
const {Modal, Button, Glyphicon, Tabs, Tab} = require('react-bootstrap');
const {Button, Glyphicon, Tabs, Tab} = require('react-bootstrap');

require("./css/settingsModal.css");

Expand All @@ -16,7 +16,7 @@ const ConfirmButton = require('../../buttons/ConfirmButton');
const General = require('./settings/General');
const Display = require('./settings/Display');
const WMSStyle = require('./settings/WMSStyle');
const {Portal} = require('react-overlays');
const Portal = require('../../misc/Portal');
const assign = require('object-assign');
const Message = require('../../I18N/Message');

Expand All @@ -37,7 +37,6 @@ const SettingsModal = React.createClass({
confirmDeleteText: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]),
closeText: React.PropTypes.oneOfType([React.PropTypes.string, React.PropTypes.element]),
options: React.PropTypes.object,
asModal: React.PropTypes.bool,
buttonSize: React.PropTypes.string,
closeGlyph: React.PropTypes.string,
panelStyle: React.PropTypes.object,
Expand All @@ -57,7 +56,6 @@ const SettingsModal = React.createClass({
updateNode: () => {},
removeNode: () => {},
retrieveLayerData: () => {},
asModal: true,
buttonSize: "large",
closeGlyph: "",
panelStyle: {
Expand Down Expand Up @@ -152,17 +150,7 @@ const SettingsModal = React.createClass({
</span>);

if (this.props.settings.expanded) {
return this.props.asModal ? (
<Modal {...this.props.options} container={document.querySelector(".ms2 > #container") } show={this.props.settings.expanded}>
<Modal.Header><Modal.Title>{this.props.titleText}</Modal.Title></Modal.Header>
<Modal.Body>
{tabs}
</Modal.Body>
<Modal.Footer>
{footer}
</Modal.Footer>
</Modal>
) : (<Portal container={document.querySelector(".ms2 > #container") }><Dialog id={this.props.id} style={this.props.panelStyle} className={this.props.panelClassName}>
return (<Portal><Dialog id={this.props.id} style={this.props.panelStyle} className={this.props.panelClassName}>
<span role="header">
<span className="layer-settings-panel-title">{this.props.titleText}</span>
<button onClick={this.onClose} className="layer-settings-panel-close close">{this.props.closeGlyph ? <Glyphicon glyph={this.props.closeGlyph}/> : <span>×</span>}</button>
Expand Down
Loading

0 comments on commit 7079bf5

Please sign in to comment.