diff --git a/web/client/actions/__tests__/tutorial-test.js b/web/client/actions/__tests__/tutorial-test.js
index ce2b1b60b2..7d69a3042a 100644
--- a/web/client/actions/__tests__/tutorial-test.js
+++ b/web/client/actions/__tests__/tutorial-test.js
@@ -34,13 +34,15 @@ describe('Test the tutorial actions', () => {
});
it('setupTutorial', () => {
+ const id = 'id';
const steps = 'steps';
const style = 'style';
const checkbox = 'checkbox';
const defaultStep = 'defaultStep';
- const retval = setupTutorial(steps, style, checkbox, defaultStep);
+ const retval = setupTutorial(id, steps, style, checkbox, defaultStep);
expect(retval).toExist();
expect(retval.type).toBe(SETUP_TUTORIAL);
+ expect(retval.id).toBe(id);
expect(retval.steps).toBe(steps);
expect(retval.style).toBe(style);
expect(retval.checkbox).toBe(checkbox);
diff --git a/web/client/actions/tutorial.js b/web/client/actions/tutorial.js
index e52cdcfec4..1217423966 100644
--- a/web/client/actions/tutorial.js
+++ b/web/client/actions/tutorial.js
@@ -20,9 +20,10 @@ function startTutorial() {
};
}
-function setupTutorial(steps, style, checkbox, defaultStep) {
+function setupTutorial(id, steps, style, checkbox, defaultStep) {
return {
type: SETUP_TUTORIAL,
+ id,
steps,
style,
checkbox,
diff --git a/web/client/components/map/cesium/Map.jsx b/web/client/components/map/cesium/Map.jsx
index 586348338a..640b2ad3c8 100644
--- a/web/client/components/map/cesium/Map.jsx
+++ b/web/client/components/map/cesium/Map.jsx
@@ -6,6 +6,7 @@
* LICENSE file in the root directory of this source tree.
*/
var Cesium = require('../../../libs/cesium');
+const Rx = require('rxjs');
var React = require('react');
var ReactDOM = require('react-dom');
var ConfigUtils = require('../../../utils/ConfigUtils');
@@ -69,10 +70,7 @@ let CesiumMap = React.createClass({
map.imageryLayers.removeAll();
map.camera.moveEnd.addEventListener(this.updateMapInfoState);
this.hand = new Cesium.ScreenSpaceEventHandler(map.scene.canvas);
- this.hand.setInputAction((movement) => {
- this.onClick(map, movement);
- }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
-
+ this.subscribeClickEvent(map);
this.hand.setInputAction(throttle(this.onMouseMove.bind(this), 500), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
map.camera.setView({
@@ -90,11 +88,7 @@ let CesiumMap = React.createClass({
if (this.props.mapOptions.navigationTools) {
this.cesiumNavigation = window.CesiumNavigation;
if (this.cesiumNavigation) {
- this.cesiumNavigation.navigationInitialization(this.props.id, map, {
- enableZoomControls: false,
- enableDistanceLegend: false,
- enableCompassOuterRing: false
- });
+ this.cesiumNavigation.navigationInitialization(this.props.id, map);
}
}
},
@@ -108,11 +102,12 @@ let CesiumMap = React.createClass({
return false;
},
componentWillUnmount() {
+ this.clickStream$.complete();
+ this.pauserStream$.complete();
this.hand.destroy();
this.map.destroy();
},
onClick(map, movement) {
-
if (this.props.onClick && movement.position !== null) {
const cartesian = map.camera.pickEllipsoid(movement.position, map.scene.globe.ellipsoid);
let cartographic = ClickUtils.getMouseXYZ(map, movement) || cartesian && Cesium.Cartographic.fromCartesian(cartesian);
@@ -236,6 +231,54 @@ let CesiumMap = React.createClass({
this.map.camera.setView(position);
}
},
+ subscribeClickEvent(map) {
+ const samePosition = (m1, m2) => m1 && m2 && m1.x === m2.x && m1.y === m2.y;
+ const types = {
+ LEFT_UP: Cesium.ScreenSpaceEventType.LEFT_UP,
+ LEFT_DOWN: Cesium.ScreenSpaceEventType.LEFT_DOWN,
+ LEFT_CLICK: Cesium.ScreenSpaceEventType.LEFT_CLICK,
+ PINCH_START: Cesium.ScreenSpaceEventType.PINCH_START,
+ PINCH_END: Cesium.ScreenSpaceEventType.PINCH_END,
+ PINCH_MOVE: Cesium.ScreenSpaceEventType.PINCH_MOVE
+ };
+ const clickStream$ = new Rx.Subject();
+ const pauserStream$ = new Rx.Subject();
+ Object.keys(types).forEach((type) => this.hand.setInputAction((movement) => {
+ pauserStream$.next({type: types[type], movement});
+ clickStream$.next({type: types[type], movement});
+ }, types[type]));
+
+ /*
+ * trigger onClick only when LEFT_CLICK that follow a LEFT_DOWN at the same position.
+ * Every other mouse event before the LEFT_CLICK will not trigger the onClick function (happens with multitouch devices from cesium).
+ * If a pinch event is ended, wait to start listening left clicks. This to skip the LEFT_UP,LEFT_DOWN, LEFT_CLICK sequence that cesium triggers after a pinch end,
+ * that othewise can not be distinguished from a normal click event.
+ */
+ pauserStream$
+ .filter( ev => ev.type === types.PINCH_END )
+ .switchMap( () => Rx.Observable.of(true).concat(Rx.Observable.of(false).delay(500)))
+ .startWith(false)
+ .switchMap(paused => {
+ // pause is realized by mapping the click stream or an infinite stream
+ return paused ? Rx.Observable.never() : clickStream$;
+ })
+ .filter( ev => ev.type === types.LEFT_DOWN )
+ .switchMap(({movement}) =>
+ clickStream$
+ .filter( ev => ev.type === types.LEFT_CLICK )
+ .takeUntil(
+ Rx.Observable.timer(500).merge(
+ clickStream$
+ .filter( ev =>
+ ev.type !== types.LEFT_UP && ev.type !== types.LEFT_CLICK
+ || ev.type === types.LEFT_UP && !samePosition(movement && movement.position, ev.movement && ev.movement.position)
+ )
+ )
+ )
+ ).subscribe(({movement}) => this.onClick(map, movement));
+ this.clickStream$ = clickStream$;
+ this.pauserStream$ = pauserStream$;
+ },
updateMapInfoState() {
const center = this.getCenter();
const zoom = this.getZoomFromHeight(center.height);
diff --git a/web/client/components/maps/modals/MetadataModal.jsx b/web/client/components/maps/modals/MetadataModal.jsx
index d16cb0f1f6..4fbf1d50b1 100644
--- a/web/client/components/maps/modals/MetadataModal.jsx
+++ b/web/client/components/maps/modals/MetadataModal.jsx
@@ -291,9 +291,7 @@ const MetadataModal = React.createClass({
},
isMetadataChanged() {
return this.props.map && (
- this.props.map.description !== undefined &&
this.props.metadata.description !== this.props.map.description ||
- this.props.map.name !== undefined &&
this.props.metadata.name !== this.props.map.name
);
},
diff --git a/web/client/components/tutorial/Tutorial.jsx b/web/client/components/tutorial/Tutorial.jsx
index dd5af46d7c..06f699eb44 100644
--- a/web/client/components/tutorial/Tutorial.jsx
+++ b/web/client/components/tutorial/Tutorial.jsx
@@ -77,7 +77,7 @@ const Tutorial = React.createClass({
return {
toggle: false,
status: 'run',
- preset: 'map',
+ preset: 'default_tutorial',
presetList: {},
introPosition: (window.innerHeight - 348) / 2,
rawSteps: [],
@@ -121,7 +121,7 @@ const Tutorial = React.createClass({
componentWillMount() {
let rawSteps = this.props.rawSteps.length > 0 ? this.props.rawSteps : this.props.presetList[this.props.preset] || [];
let checkbox = this.props.showCheckbox ?
: ;
- this.props.actions.onSetup(rawSteps, this.props.introStyle, checkbox, this.props.defaultStep);
+ this.props.actions.onSetup('default', rawSteps, this.props.introStyle, checkbox, this.props.defaultStep);
},
componentWillUpdate(newProps) {
if (this.props.steps.length > 0) {
diff --git a/web/client/components/tutorial/__tests__/Tutorial-test.jsx b/web/client/components/tutorial/__tests__/Tutorial-test.jsx
index 8a8b9f4982..2e02f94ad7 100644
--- a/web/client/components/tutorial/__tests__/Tutorial-test.jsx
+++ b/web/client/components/tutorial/__tests__/Tutorial-test.jsx
@@ -87,7 +87,7 @@ describe("Test the Tutorial component", () => {
expect(cmp).toExist();
expect(spySetup).toHaveBeenCalled();
- expect(spySetup).toHaveBeenCalledWith([], {}, , {});
+ expect(spySetup).toHaveBeenCalledWith('default', [], {}, , {});
const domNode = ReactDOM.findDOMNode(cmp);
expect(domNode).toExist();
@@ -120,7 +120,7 @@ describe("Test the Tutorial component", () => {
expect(cmp).toExist();
expect(spySetup).toHaveBeenCalled();
- expect(spySetup).toHaveBeenCalledWith(presetList.test, {},
, {});
+ expect(spySetup).toHaveBeenCalledWith('default', presetList.test, {},
, {});
const domNode = ReactDOM.findDOMNode(cmp);
expect(domNode).toExist();
@@ -164,7 +164,7 @@ describe("Test the Tutorial component", () => {
expect(cmp).toExist();
expect(spySetup).toHaveBeenCalled();
- expect(spySetup).toHaveBeenCalledWith(rawSteps, {}, , {});
+ expect(spySetup).toHaveBeenCalledWith('default', rawSteps, {}, , {});
const domNode = ReactDOM.findDOMNode(cmp);
expect(domNode).toExist();
diff --git a/web/client/epics/tutorial.js b/web/client/epics/tutorial.js
index f6579ac075..57033ac614 100644
--- a/web/client/epics/tutorial.js
+++ b/web/client/epics/tutorial.js
@@ -7,8 +7,13 @@
*/
const Rx = require('rxjs');
-const {START_TUTORIAL, closeTutorial} = require('../actions/tutorial');
+const {START_TUTORIAL, closeTutorial, setupTutorial} = require('../actions/tutorial');
+const {CHANGE_MAP_VIEW} = require('../actions/map');
const {TOGGLE_3D} = require('../actions/globeswitcher');
+const preset = require('../plugins/tutorial/preset');
+const defaultRegex = /\/(viewer)\/(\w+)\/(\d+)/;
+const findMapType = path => path.match(defaultRegex) && path.replace(defaultRegex, "$2");
+import { UPDATE_LOCATION } from 'react-router-redux';
/**
* Closes the tutorial if 3D button has been toggled
@@ -22,6 +27,30 @@ const closeTutorialEpic = (action$) =>
.audit(() => action$.ofType(TOGGLE_3D))
.switchMap( () => Rx.Observable.of(closeTutorial()));
+/**
+ * Setup new steps based on the current maptype
+ * @memberof epics.tutorial
+ * @param {external:Observable} action$ manages `UPDATE_LOCATION`
+ * @return {external:Observable}
+ */
+
+const switchTutorialEpic = (action$, store) =>
+ action$.ofType(UPDATE_LOCATION)
+ .audit(() => action$.ofType(CHANGE_MAP_VIEW))
+ .filter(action =>
+ action.payload
+ && action.payload.pathname
+ && action.payload.pathname.match(defaultRegex))
+ .switchMap( (action) => {
+ const path = findMapType(action.payload.pathname);
+ const browser = store.getState().browser;
+ const mobile = browser && browser.mobile ? '_mobile' : '';
+ return Rx.Observable.of(preset[path + mobile + '_tutorial'] ?
+ setupTutorial(path + mobile, preset[path + mobile + '_tutorial']) :
+ setupTutorial('default' + mobile, preset['default' + mobile + '_tutorial'])
+ );
+ });
+
/**
* Epics for Tutorial
* @name epics.tutorial
@@ -29,5 +58,6 @@ const closeTutorialEpic = (action$) =>
*/
module.exports = {
- closeTutorialEpic
+ closeTutorialEpic,
+ switchTutorialEpic
};
diff --git a/web/client/libs/cesium-navigation/cesium-navigation.css b/web/client/libs/cesium-navigation/cesium-navigation.css
index 257b02a88c..6518c8a90d 100644
--- a/web/client/libs/cesium-navigation/cesium-navigation.css
+++ b/web/client/libs/cesium-navigation/cesium-navigation.css
@@ -137,7 +137,8 @@
height: 95px;
fill: #68ADFE;
}
-#distanceLegendDiv > .navigation-controls > div:nth-child(2) {
+/*#distanceLegendDiv > > div:nth-child(2) {*/
+#distanceLegendDiv .navigation-controls {
display: none;
}
diff --git a/web/client/localConfig.json b/web/client/localConfig.json
index 175b7a8f0e..2cb20b927e 100644
--- a/web/client/localConfig.json
+++ b/web/client/localConfig.json
@@ -78,7 +78,7 @@
}, "Home", "TOC", {
"name": "Tutorial",
"cfg": {
- "preset": "mapMobile"
+ "preset": "default_mobile_tutorial"
}
}, {
"name": "Settings",
diff --git a/web/client/plugins/GlobeViewSwitcher.jsx b/web/client/plugins/GlobeViewSwitcher.jsx
index 0df23e0d9c..4ecefc772f 100644
--- a/web/client/plugins/GlobeViewSwitcher.jsx
+++ b/web/client/plugins/GlobeViewSwitcher.jsx
@@ -40,7 +40,7 @@ module.exports = {
GlobeViewSwitcherPlugin: assign(GlobeViewSwitcher, {
Toolbar: {
name: '3d',
- position: 5,
+ position: 10,
alwaysVisible: true,
tool: true,
priority: 1
diff --git a/web/client/plugins/Tutorial.jsx b/web/client/plugins/Tutorial.jsx
index fd7f8fb8a3..d4959ef8f4 100644
--- a/web/client/plugins/Tutorial.jsx
+++ b/web/client/plugins/Tutorial.jsx
@@ -16,7 +16,7 @@ const I18N = require('../components/I18N/I18N');
const {Glyphicon} = require('react-bootstrap');
const {createSelector} = require('reselect');
const {tutorialSelector} = require('../selectors/tutorial');
-const {closeTutorialEpic} = require('../epics/tutorial');
+const {closeTutorialEpic, switchTutorialEpic} = require('../epics/tutorial');
/*
//////////////////////////
@@ -217,6 +217,7 @@ module.exports = {
tutorial: require('../reducers/tutorial')
},
epics: {
- closeTutorialEpic
+ closeTutorialEpic,
+ switchTutorialEpic
}
};
diff --git a/web/client/plugins/tutorial/preset.js b/web/client/plugins/tutorial/preset.js
index f3cec401ff..3258651116 100644
--- a/web/client/plugins/tutorial/preset.js
+++ b/web/client/plugins/tutorial/preset.js
@@ -7,7 +7,9 @@
*/
module.exports = {
- map: require('./preset/map'),
- home: require('./preset/home'),
- mapMobile: require('./preset/mapMobile')
+ default_tutorial: require('./preset/default_tutorial'),
+ default_mobile_tutorial: require('./preset/default_mobile_tutorial'),
+ home_tutorial: require('./preset/home_tutorial'),
+ cesium_tutorial: require('./preset/cesium_tutorial'),
+ cesium_mobile_tutorial: require('./preset/cesium_mobile_tutorial')
};
diff --git a/web/client/plugins/tutorial/preset/mapMobile.js b/web/client/plugins/tutorial/preset/cesium_mobile_tutorial.js
similarity index 84%
rename from web/client/plugins/tutorial/preset/mapMobile.js
rename to web/client/plugins/tutorial/preset/cesium_mobile_tutorial.js
index 1f630407b6..11cd5e0903 100644
--- a/web/client/plugins/tutorial/preset/mapMobile.js
+++ b/web/client/plugins/tutorial/preset/cesium_mobile_tutorial.js
@@ -11,15 +11,23 @@ const I18N = require('../../../components/I18N/I18N');
const CesiumTooltip = require('../../../components/tutorial/steps/CesiumTooltip');
module.exports = [
- // remove comment to enable intro/autostart
- /*{
- translation: 'intro',
+ {
+ translation: 'introCesium',
selector: '#intro-tutorial'
- },*/
+ },
+ {
+ title: ,
+ text: ,
+ selector: '#map .cesium-viewer'
+ },
{
translation: 'drawerMenu',
selector: '#drawer-menu-button'
},
+ {
+ translation: 'home',
+ selector: '#home-button'
+ },
{
translation: 'searchButton',
selector: '#search-help'
@@ -27,15 +35,5 @@ module.exports = [
{
translation: 'burgerMenu',
selector: '#mapstore-burger-menu'
- },
- {
- title: ,
- text: ,
- selector: '#map .cesium-viewer',
- position: 'bottom'
- },
- {
- translation: 'home',
- selector: '#home-button'
}
];
diff --git a/web/client/plugins/tutorial/preset/map.js b/web/client/plugins/tutorial/preset/cesium_tutorial.js
similarity index 75%
rename from web/client/plugins/tutorial/preset/map.js
rename to web/client/plugins/tutorial/preset/cesium_tutorial.js
index a4abfc6a8e..4c883295f6 100644
--- a/web/client/plugins/tutorial/preset/map.js
+++ b/web/client/plugins/tutorial/preset/cesium_tutorial.js
@@ -11,40 +11,35 @@ const I18N = require('../../../components/I18N/I18N');
const CesiumTooltip = require('../../../components/tutorial/steps/CesiumTooltip');
module.exports = [
- // remove comment to enable intro/autostart
- /*{
- translation: 'intro',
- selector: '#intro-tutorial'
- },*/
- {
- translationHTML: 'drawerMenu',
- selector: '#drawer-menu-button'
- },
{
- translation: 'searchBar',
- selector: '#map-search-bar'
+ translation: 'introCesium',
+ selector: '#intro-tutorial'
},
{
- translation: 'burgerMenu',
- selector: '#mapstore-burger-menu'
+ title: ,
+ text: ,
+ selector: '#map .cesium-viewer',
+ position: 'bottom'
},
{
translation: 'cesiumCompass',
selector: '#distanceLegendDiv .compass'
},
{
- translation: 'cesiumNavigation',
- selector: '#distanceLegendDiv .navigation-controls'
+ translationHTML: 'drawerMenu',
+ selector: '#drawer-menu-button'
},
{
- translation: 'zoomInButton',
- selector: '#zoomin-btn',
- position: 'top'
+ translation: 'searchBar',
+ selector: '#map-search-bar'
},
{
- translation: 'zoomOutButton',
- selector: '#zoomout-btn',
- position: 'top'
+ translation: 'home',
+ selector: '#home-button'
+ },
+ {
+ translation: 'burgerMenu',
+ selector: '#mapstore-burger-menu'
},
{
translation: 'fullscreen',
@@ -55,15 +50,5 @@ module.exports = [
translation: 'identifyButton',
selector: '#identifyBar-container',
position: 'top'
- },
- {
- title: ,
- text: ,
- selector: '#map .cesium-viewer',
- position: 'bottom'
- },
- {
- translation: 'home',
- selector: '#home-button'
}
];
diff --git a/web/client/plugins/tutorial/preset/default_mobile_tutorial.js b/web/client/plugins/tutorial/preset/default_mobile_tutorial.js
new file mode 100644
index 0000000000..cb68be2dd8
--- /dev/null
+++ b/web/client/plugins/tutorial/preset/default_mobile_tutorial.js
@@ -0,0 +1,26 @@
+/**
+ * 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.
+ */
+
+module.exports = [
+ {
+ translation: 'drawerMenu',
+ selector: '#drawer-menu-button'
+ },
+ {
+ translation: 'home',
+ selector: '#home-button'
+ },
+ {
+ translation: 'searchButton',
+ selector: '#search-help'
+ },
+ {
+ translation: 'burgerMenu',
+ selector: '#mapstore-burger-menu'
+ }
+];
diff --git a/web/client/plugins/tutorial/preset/default_tutorial.js b/web/client/plugins/tutorial/preset/default_tutorial.js
new file mode 100644
index 0000000000..0baea9b50b
--- /dev/null
+++ b/web/client/plugins/tutorial/preset/default_tutorial.js
@@ -0,0 +1,46 @@
+/**
+ * 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.
+ */
+
+module.exports = [
+ {
+ translationHTML: 'drawerMenu',
+ selector: '#drawer-menu-button'
+ },
+ {
+ translation: 'searchBar',
+ selector: '#map-search-bar'
+ },
+ {
+ translation: 'home',
+ selector: '#home-button'
+ },
+ {
+ translation: 'burgerMenu',
+ selector: '#mapstore-burger-menu'
+ },
+ {
+ translation: 'zoomInButton',
+ selector: '#zoomin-btn',
+ position: 'top'
+ },
+ {
+ translation: 'zoomOutButton',
+ selector: '#zoomout-btn',
+ position: 'top'
+ },
+ {
+ translation: 'fullscreen',
+ selector: '#fullscreen-btn',
+ position: 'top'
+ },
+ {
+ translation: 'identifyButton',
+ selector: '#identifyBar-container',
+ position: 'top'
+ }
+];
diff --git a/web/client/plugins/tutorial/preset/home.js b/web/client/plugins/tutorial/preset/home_tutorial.js
similarity index 72%
rename from web/client/plugins/tutorial/preset/home.js
rename to web/client/plugins/tutorial/preset/home_tutorial.js
index 76a206102e..bf9abc21f5 100644
--- a/web/client/plugins/tutorial/preset/home.js
+++ b/web/client/plugins/tutorial/preset/home_tutorial.js
@@ -7,12 +7,6 @@
*/
module.exports = [
- // add Tutorial plugin to homepage, "maps" in localConfig with cfg: {preset: "home"}
- // remove comment to enable intro/autostart
- /*{
- translation: 'intro',
- selector: '#intro-tutorial'
- },*/
{
translation: 'mapType',
selector: '#mapstore-maptype',
diff --git a/web/client/reducers/tutorial.js b/web/client/reducers/tutorial.js
index a86cb77875..fe2eafd03d 100644
--- a/web/client/reducers/tutorial.js
+++ b/web/client/reducers/tutorial.js
@@ -28,7 +28,8 @@ const initialState = {
disabled: false,
status: 'close',
stepIndex: 0,
- tourAction: 'next'
+ tourAction: 'next',
+ id: ''
};
function tutorial(state = initialState, action) {
@@ -42,6 +43,12 @@ function tutorial(state = initialState, action) {
case SETUP_TUTORIAL:
let setup = {};
setup.steps = [].concat(action.steps);
+ setup.id = action.id;
+ setup.checkbox = action.checkbox ? action.checkbox : assign({}, state.checkbox);
+ setup.style = action.style ? action.style : assign({}, state.style);
+ setup.defaultStep = action.defaultStep ? action.defaultStep : assign({}, state.defaultStep);
+ setup.disabled = false;
+
setup.steps = setup.steps.filter((step) => {
return step.selector && step.selector.substring(0, 1) === '#' || step.selector.substring(0, 1) === '.';
}).map((step, index) => {
@@ -51,11 +58,11 @@ function tutorial(state = initialState, action) {
let text = step.text ? step.text : '';
text = step.translation ? : text;
text = step.translationHTML ? : text;
- text = (step.selector === '#intro-tutorial') ? : text;
- let style = (step.selector === '#intro-tutorial') ? action.style : {};
+ text = (step.selector === '#intro-tutorial') ? : text;
+ let style = (step.selector === '#intro-tutorial') ? setup.style : {};
let isFixed = (step.selector === '#intro-tutorial') ? true : step.isFixed || false;
assign(style, step.style);
- return assign({}, action.defaultStep, step, {
+ return assign({}, setup.defaultStep, step, {
index,
title,
text,
@@ -64,7 +71,7 @@ function tutorial(state = initialState, action) {
});
});
- const isDisabled = localStorage.getItem('mapstore.plugin.tutorial.disabled');
+ const isDisabled = localStorage.getItem('mapstore.plugin.tutorial.' + action.id + '.disabled');
let hasIntro = false;
setup.steps.forEach((step) => {
if (step.selector === '#intro-tutorial') {
@@ -80,7 +87,7 @@ function tutorial(state = initialState, action) {
setup.steps = setup.steps.filter((step) => {
return step.selector !== '#intro-tutorial';
}).map((step, index) => {
- return assign(step, {index});
+ return assign({}, step, {index});
});
setup.run = false;
@@ -106,7 +113,7 @@ function tutorial(state = initialState, action) {
update.steps = update.steps.filter((step) => {
return step.selector !== '#intro-tutorial';
}).map((step, index) => {
- return assign(step, {index});
+ return assign({}, step, {index});
});
} else if (action.tour.type === 'error:target_not_found') {
update.status = 'error';
@@ -118,7 +125,7 @@ function tutorial(state = initialState, action) {
return assign({}, state, update);
case DISABLE_TUTORIAL:
let disabled = !state.disabled;
- localStorage.setItem('mapstore.plugin.tutorial.disabled', disabled);
+ localStorage.setItem('mapstore.plugin.tutorial.' + state.id + '.disabled', disabled);
return assign({}, state, {
disabled
});
diff --git a/web/client/translations/data.de-DE b/web/client/translations/data.de-DE
index b5efc2e420..c7f00a9080 100644
--- a/web/client/translations/data.de-DE
+++ b/web/client/translations/data.de-DE
@@ -900,6 +900,10 @@
"title": "Custom Application",
"text": "You can use components and plugins of MapStore2 to build custom applications"
},
+ "introCesium": {
+ "title": "3D map instructions",
+ "text": "Click on next button to start the tutorial"
+ },
"cesium": {
"title": "Interactions with the Map",
"pan": "Pan view",
diff --git a/web/client/translations/data.en-US b/web/client/translations/data.en-US
index ed0118882e..533215891d 100644
--- a/web/client/translations/data.en-US
+++ b/web/client/translations/data.en-US
@@ -900,6 +900,10 @@
"title": "Custom Application",
"text": "You can use components and plugins of MapStore2 to build custom applications"
},
+ "introCesium": {
+ "title": "3D map instructions",
+ "text": "Click on next button to start the tutorial"
+ },
"cesium": {
"title": "Interactions with the Map",
"pan": "Pan view",
diff --git a/web/client/translations/data.fr-FR b/web/client/translations/data.fr-FR
index 71822066c5..64fe2ddad9 100644
--- a/web/client/translations/data.fr-FR
+++ b/web/client/translations/data.fr-FR
@@ -902,6 +902,10 @@
"title": "Custom Application",
"text": "You can use components and plugins of MapStore2 to build custom applications"
},
+ "introCesium": {
+ "title": "3D map instructions",
+ "text": "Click on next button to start the tutorial"
+ },
"cesium": {
"title": "Interactions with the Map",
"pan": "Pan view",
diff --git a/web/client/translations/data.it-IT b/web/client/translations/data.it-IT
index e58be86a76..04962a21b0 100644
--- a/web/client/translations/data.it-IT
+++ b/web/client/translations/data.it-IT
@@ -900,6 +900,10 @@
"title": "Applicazioni personalizzate",
"text": "Puoi utilizzare componenti e plugins di MapStore2 per costruire applicazioni personalizzate"
},
+ "introCesium": {
+ "title": "Istruzioni della mappa 3D",
+ "text": "Premi il pulsante avanti per aprire il tutorial"
+ },
"cesium": {
"title": "Interazioni con la mappa",
"pan": "Vista Pan",