From 2fadbf1ce29b22ad33b230ce933a995d0d2a4405 Mon Sep 17 00:00:00 2001 From: Lorenzo Natali Date: Mon, 29 May 2017 18:13:36 +0200 Subject: [PATCH] Fix #1884. Add cookie policy notification (#1890) * Fix #1884. Add cookie policy notification - Add Notification system - Add cookie policy epic to show the cookie policy notification * add missing dependency * Add documentation * last doc fixes * Removed early optimization and simplified reducers --- docma-config.json | 5 + package.json | 1 + .../actions/__tests__/notifications-test.js | 71 ++++++++++++ web/client/actions/notifications.js | 109 ++++++++++++++++++ .../notifications/NotificationContainer.jsx | 88 ++++++++++++++ .../__tests__/NotificationContainer-test.jsx | 69 +++++++++++ web/client/epics/__tests__/search-test.js | 4 +- web/client/epics/cookies.js | 58 ++++++++++ .../cesium-navigation/cesium-navigation.js | 2 +- web/client/localConfig.json | 4 +- web/client/plugins/Notifications.jsx | 30 +++++ web/client/product/app.jsx | 5 +- web/client/product/appConfig.js | 1 + web/client/product/plugins.js | 3 +- .../reducers/__tests__/notifications-test.js | 27 +++++ web/client/reducers/notifications.js | 45 ++++++++ web/client/translations/data.de-DE | 5 + web/client/translations/data.en-US | 5 + web/client/translations/data.fr-FR | 6 + web/client/translations/data.it-IT | 5 + 20 files changed, 535 insertions(+), 8 deletions(-) create mode 100644 web/client/actions/__tests__/notifications-test.js create mode 100644 web/client/actions/notifications.js create mode 100644 web/client/components/notifications/NotificationContainer.jsx create mode 100644 web/client/components/notifications/__tests__/NotificationContainer-test.jsx create mode 100644 web/client/epics/cookies.js create mode 100644 web/client/plugins/Notifications.jsx create mode 100644 web/client/reducers/__tests__/notifications-test.js create mode 100644 web/client/reducers/notifications.js diff --git a/docma-config.json b/docma-config.json index f817f6dbd2..2ee3dcf684 100644 --- a/docma-config.json +++ b/docma-config.json @@ -109,6 +109,7 @@ "web/client/components/buttons/GlobeViewSwitcherButton.jsx", "web/client/components/buttons/GoFullButton.jsx", "web/client/components/mapcontrols/search/SearchBar.jsx", + "web/client/components/notifications/NotificationContainer.jsx", "web/client/components/buttons/ToggleButton.jsx", "web/client/components/plugins/PluginsContainer.jsx", @@ -118,6 +119,7 @@ "web/client/actions/globeswitcher.js", "web/client/actions/maps.js", "web/client/actions/maptype.js", + "web/client/actions/notifications.js", "web/client/actions/search.js", "web/client/selectors/index.jsdoc", @@ -130,9 +132,11 @@ "web/client/reducers/globeswitcher.js", "web/client/reducers/maps.js", "web/client/reducers/maptype.js", + "web/client/reducers/notifications.js", "web/client/reducers/search.js", "web/client/epics/index.jsdoc", + "web/client/epics/cookies.js", "web/client/epics/fullscreen.js", "web/client/epics/globeswitcher.js", "web/client/epics/maptype.js", @@ -162,6 +166,7 @@ "web/client/plugins/Identify.jsx", "web/client/plugins/Locate.jsx", "web/client/plugins/Login.jsx", + "web/client/plugins/Notifications.jsx", "web/client/plugins/ScaleBox.jsx", "web/client/plugins/ScrollTop.jsx", "web/client/plugins/Search.jsx", diff --git a/package.json b/package.json index 0e37065b12..f66b31a565 100644 --- a/package.json +++ b/package.json @@ -130,6 +130,7 @@ "react-input-autosize": "1.1.0", "react-intl": "2.2.3", "react-joyride": "1.10.1", + "react-notification-system": "0.2.14", "react-nouislider": "1.11.0", "react-overlays": "0.6.3", "react-pdf": "1.6.1", diff --git a/web/client/actions/__tests__/notifications-test.js b/web/client/actions/__tests__/notifications-test.js new file mode 100644 index 0000000000..fca51cd439 --- /dev/null +++ b/web/client/actions/__tests__/notifications-test.js @@ -0,0 +1,71 @@ +/* + * 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. + */ + +var expect = require('expect'); +var { + SHOW_NOTIFICATION, + HIDE_NOTIFICATION, + CLEAR_NOTIFICATIONS, + show, + success, + warning, + error, + info, + hide, + clear +} = require('../notifications'); + +describe('Test correctness of the notifications actions', () => { + + it('show', () => { + const action = show({title: "test"}); + expect(action.type).toBe(SHOW_NOTIFICATION); + expect(action.title).toBe('test'); + expect(action.level).toBe('success'); + expect(action.uid).toExist(); + }); + it('hide', () => { + const action = hide("1234"); + expect(action.type).toBe(HIDE_NOTIFICATION); + expect(action.uid).toBe('1234'); + }); + it('clear', () => { + const action = clear(); + expect(action.type).toBe(CLEAR_NOTIFICATIONS); + }); + it('success', () => { + const action = success({title: "test"}); + expect(action.type).toBe(SHOW_NOTIFICATION); + expect(action.title).toBe('test'); + expect(action.level).toBe('success'); + expect(action.uid).toExist(); + }); + it('warning', () => { + const action = warning({title: "test"}); + expect(action.type).toBe(SHOW_NOTIFICATION); + expect(action.title).toBe('test'); + expect(action.level).toBe('warning'); + expect(action.uid).toExist(); + }); + it('error', () => { + const action = error({title: "test"}); + expect(action.type).toBe(SHOW_NOTIFICATION); + expect(action.title).toBe('test'); + expect(action.level).toBe('error'); + expect(action.uid).toExist(); + }); + it('info', () => { + const action = info({title: "test"}); + expect(action.type).toBe(SHOW_NOTIFICATION); + expect(action.title).toBe('test'); + expect(action.level).toBe('info'); + expect(action.uid).toExist(); + }); + + +}); diff --git a/web/client/actions/notifications.js b/web/client/actions/notifications.js new file mode 100644 index 0000000000..a13e7665c6 --- /dev/null +++ b/web/client/actions/notifications.js @@ -0,0 +1,109 @@ +const SHOW_NOTIFICATION = 'SHOW_NOTIFICATION'; +const HIDE_NOTIFICATION = 'HIDE_NOTIFICATION'; +const CLEAR_NOTIFICATIONS = 'CLEAR_NOTIFICATIONS'; +/** + * Show a notification + * @memberof actions.notifications + * @param {Object} [opts={}] the notification configuration. [Here the compete ref](https://github.com/igorprado/react-notification-system#creating-a-notification) + * ``` + * { + * title: "title.translation.path" // or the message directly + * message: "message.translation.path" // or the message directly + * uid: "1234" // a unique identifier (if not present, current time is used), + * action: { + * label: "label.translation.path" // or the message directly + * } + * } + * ``` + * @param {String} [level='success'] The level of the notification. (one of "success"|"warning"|"info"|"error") + * @return {object} action of type `SHOW_NOTIFICATION` + */ +function show(opts = {}, level = 'success') { + return { + type: SHOW_NOTIFICATION, + ...opts, + uid: opts.uid || Date.now(), + level + }; +} + +/** + * Hides (removes) the notification with the id provided + * @memberof actions.notifications + * @param {string|number} uid the identifier + * @returns {object} action of type `HIDE_NOTIFICATION` + */ +function hide(uid) { + return { + type: HIDE_NOTIFICATION, + uid + }; +} + +/** + * Show a success notification. {@see actions.notifications.show} + * @memberof actions.notifications + * @param {object} opts notification opts + * @returns {object} action of type `HIDE_NOTIFICATION` + */ +function success(opts) { + return show(opts, 'success'); +} +/** + * Show a error notification. {@see actions.notifications.show} + * @memberof actions.notifications + * @param {object} opts notification opts + * @returns {object} action of type `HIDE_NOTIFICATION` + */ +function error(opts) { + return show(opts, 'error'); +} + +/** + * Show a warning notification. {@see actions.notifications.show} + * @memberof actions.notifications + * @param {object} opts notification opts + * @returns {object} action of type `HIDE_NOTIFICATION` + */ +function warning(opts) { + return show(opts, 'warning'); +} + +/** + * Show a info notification. {@see actions.notifications.show} + * @memberof actions.notifications + * @param {object} opts notification opts + * @returns {object} action of type `HIDE_NOTIFICATION` + */ +function info(opts) { + return show(opts, 'info'); +} + +/** + * Clear all the notifications + * @memberof actions.notifications + * @returns {object} action of type `CLEAR_NOTIFICATIONS` + */ +function clear() { + return { + type: CLEAR_NOTIFICATIONS + }; +} + +/** + * actions for notifications + * @name notifications + * @memberof actions + */ +module.exports = { + SHOW_NOTIFICATION, + HIDE_NOTIFICATION, + CLEAR_NOTIFICATIONS, + show, + success, + warning, + error, + info, + hide, + clear +}; diff --git a/web/client/components/notifications/NotificationContainer.jsx b/web/client/components/notifications/NotificationContainer.jsx new file mode 100644 index 0000000000..dfe3d1706d --- /dev/null +++ b/web/client/components/notifications/NotificationContainer.jsx @@ -0,0 +1,88 @@ +/* + * 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 React = require('react'); +const NotificationSystem = require('react-notification-system'); +var LocaleUtils = require('../../utils/LocaleUtils'); +/** + * Container for Notifications. Allows to display notifications by passing + * them in the notification property + * @class + * @memberof components.notifications + * @prop {object[]} notifications the notifications. Each element have this form + * ``` + * { + * title: "title.translation.path" // or the message directly + * message: "message.translation.path" // or the message directly + * uid: "1234" // a unique identifier (if not present, current time is used), + * action: { + * label: "label.translation.path" // or the message directly + * } + * } + * ``` + * @see https://github.com/igorprado/react-notification-system#creating-a-notification for othe options + * @example + * ; + */ +const NotificationContainer = React.createClass({ + propTypes: { + notifications: React.PropTypes.array, + onRemove: React.PropTypes.func + }, + contextTypes: { + messages: React.PropTypes.object + }, + getDefaultProps() { + return { + notifications: [], + onRemove: () => {} + }; + }, + componentDidMount() { + this.updateNotifications(this.props.notifications); + }, + componentDidUpdate() { + const {notifications} = this.props || []; + this.updateNotifications(notifications); + }, + render() { + const {notifications, onRemove, ...rest} = this.props; + return (); + }, + system() { + return this.refs.notify; + }, + updateNotifications(notifications) { + const notificationIds = notifications.map(notification => notification.uid); + const systemNotifications = this.system().state.notifications || []; + // Get all active notifications from react-notification-system + // and remove all where uid is not found in the reducer + systemNotifications.forEach(notification => { + if (notificationIds.indexOf(notification.uid) < 0) { + this.system().removeNotification(notification.uid); + } + }); + notifications.forEach(notification => { + if (systemNotifications.indexOf(notification.uid) < 0) { + this.system().addNotification({ + ...notification, + title: LocaleUtils.getMessageById(this.context.messages, notification.title) || notification.title, + message: LocaleUtils.getMessageById(this.context.messages, notification.message) || notification.message, + action: notification.action && { + label: LocaleUtils.getMessageById(this.context.messages, notification.action.label) || notification.action.label + }, + onRemove: () => { + this.props.onRemove(notification.uid); + if (notification.onRemove) notification.onRemove(); + } + }); + } + }); + } +}); + +module.exports = NotificationContainer; diff --git a/web/client/components/notifications/__tests__/NotificationContainer-test.jsx b/web/client/components/notifications/__tests__/NotificationContainer-test.jsx new file mode 100644 index 0000000000..2da527c9e0 --- /dev/null +++ b/web/client/components/notifications/__tests__/NotificationContainer-test.jsx @@ -0,0 +1,69 @@ +/* + * 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 React = require('react'); +const ReactDOM = require('react-dom'); +const NotificationContainer = require('../NotificationContainer.jsx'); +const expect = require('expect'); + +const TestUtils = require('react-addons-test-utils'); +const N1 = { + uid: "1", + title: "test 1", + message: "test 1", + autodismiss: 0, + level: "success" +}; + +const N2 = { + uid: "2", + title: "test 2", + message: "test 2", + autodismiss: 0, + level: "success" +}; + +describe('NotificationContainer tests', () => { + beforeEach((done) => { + document.body.innerHTML = '
'; + setTimeout(done); + }); + + afterEach((done) => { + ReactDOM.unmountComponentAtNode(document.getElementById("container")); + document.body.innerHTML = ''; + setTimeout(done); + }); + // test DEFAULTS + it('creates the component with defaults', () => { + const item = ReactDOM.render(, document.getElementById("container")); + expect(item).toExist(); + + }); + it('creates the component with notifications', () => { + const item = ReactDOM.render(, document.getElementById("container")); + expect(item).toExist(); + let elems = TestUtils.scryRenderedDOMComponentsWithClass(item, "notifications-tr"); + expect(elems.length).toBe(1); + }); + it('update notifications', () => { + let item = ReactDOM.render(, document.getElementById("container")); + expect(item).toExist(); + let elems = TestUtils.scryRenderedDOMComponentsWithClass(item, "notification"); + expect(elems.length).toBe(1); + + // add notification + item = ReactDOM.render(, document.getElementById("container")); + elems = TestUtils.scryRenderedDOMComponentsWithClass(item, "notification"); + expect(elems.length).toBe(2); + + // remove notification + item = ReactDOM.render(, document.getElementById("container")); + elems = TestUtils.scryRenderedDOMComponentsWithClass(item, "notification").filter( (e) => e.className.indexOf("notification-hidden") < 0); + expect(elems.length).toBe(1); + }); +}); diff --git a/web/client/epics/__tests__/search-test.js b/web/client/epics/__tests__/search-test.js index 8c05136fa2..46690bfb62 100644 --- a/web/client/epics/__tests__/search-test.js +++ b/web/client/epics/__tests__/search-test.js @@ -146,7 +146,7 @@ describe('search Epics', () => { expect(actions.filter(m => m.type === TEXT_SEARCH_TEXT_CHANGE)[0].searchText).toBe(TEXT); }); - it('testing the geometry service', (done) => { + it('geometry service', (done) => { // use the done function for asynchronus calls const itemWithoutGeom = { "type": "Feature", @@ -192,6 +192,6 @@ describe('search Epics', () => { done(); // setting 0 as delay arises script error - }, 300); + }, 500); }); }); diff --git a/web/client/epics/cookies.js b/web/client/epics/cookies.js new file mode 100644 index 0000000000..6e57028788 --- /dev/null +++ b/web/client/epics/cookies.js @@ -0,0 +1,58 @@ +/* + * 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 {info, HIDE_NOTIFICATION} = require('../actions/notifications'); +const Rx = require('rxjs'); +const {head} = require('lodash'); +import { UPDATE_LOCATION } from 'react-router-redux'; + + +const COOKIE_NOTIFICATION_ID = "cookiesPolicyNotification"; +const cookieNotificationSelector = (state) => state && state.notifications && head(state.notifications.filter( n => n.uid === COOKIE_NOTIFICATION_ID)); + +/** + * Show the cookie policy notification + * @param {external:Observable} action$ triggers on "UPDATE_LOCATION" + * @param {object} store the store, to get current notifications + * @memberof epics.cookies + * @return {external:Observable} the steam of actions to trigger to display the noitification. + */ +const cookiePolicyChecker = (action$, store) => + action$.ofType(UPDATE_LOCATION) + .take(1) + .filter( () => !localStorage.getItem("cookies-policy-approved") && !cookieNotificationSelector(store.getState())) + .switchMap(() => + Rx.Observable.of(info({ + uid: COOKIE_NOTIFICATION_ID, + title: "cookiesPolicyNotification.title", + message: "cookiesPolicyNotification.message", + action: { + label: "cookiesPolicyNotification.confirm" + }, + autoDismiss: 0, + position: "bl" + })) + ); + +const cookiePolicyDismiss = (action$) => + action$.ofType(HIDE_NOTIFICATION) + .switchMap( (action) => { + if (action.uid === COOKIE_NOTIFICATION_ID ) { + localStorage.setItem("cookies-policy-approved", true); + } + return Rx.Observable.empty(); + }); + +/** + * Epics for cookies policy informations + * @name epics.cookies + * @type {Object} + */ +module.exports = { + cookiePolicyChecker, + cookiePolicyDismiss +}; diff --git a/web/client/libs/cesium-navigation/cesium-navigation.js b/web/client/libs/cesium-navigation/cesium-navigation.js index 5717db31dc..41a1a6d0ba 100644 --- a/web/client/libs/cesium-navigation/cesium-navigation.js +++ b/web/client/libs/cesium-navigation/cesium-navigation.js @@ -3777,7 +3777,7 @@ void function(e, t, n) { ; return r(Object, o("getOwnPropertyNames", function(e) { var t, n = Object(e); - if ("[object Window]" === n.toString()) + if (n && n.toString && "[object Window]" === n.toString()) try { t = s(e) } catch (r) { diff --git a/web/client/localConfig.json b/web/client/localConfig.json index 7123ece696..14f85ae19a 100644 --- a/web/client/localConfig.json +++ b/web/client/localConfig.json @@ -127,7 +127,7 @@ }, "Login", "OmniBar", "BurgerMenu", "Expander", "GlobeViewSwitcher" ], - "desktop": ["Map", "HelpLink", "Share", "DrawerMenu", "Version", {"name": "BackgroundSelector", "cfg": { "bottom": 40 } }, + "desktop": ["Map", "HelpLink", "Share", "DrawerMenu", "Version", "Notifications", {"name": "BackgroundSelector", "cfg": { "bottom": 40 } }, { "name": "Identify", "showIn": ["IdentifyBar", "Settings"], @@ -307,7 +307,7 @@ "cfg": { "className": "navbar shadow navbar-home" } - }, "ManagerMenu", "Login", "Language", "Attribution", "ScrollTop"], + }, "ManagerMenu", "Login", "Language", "Attribution", "ScrollTop", "Notifications"], "maps": ["Header", "Fork", "MapSearch", "HomeDescription", "MapType", "ThemeSwitcher", "GridContainer", "CreateNewMap", "Maps", "Examples", "Footer"], "manager": ["Header", "Redirect", "Manager", "Home", "UserManager", "GroupManager", "Footer"] } diff --git a/web/client/plugins/Notifications.jsx b/web/client/plugins/Notifications.jsx new file mode 100644 index 0000000000..effa1723cb --- /dev/null +++ b/web/client/plugins/Notifications.jsx @@ -0,0 +1,30 @@ +/* + * 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 {hide} = require('../actions/notifications'); +const {connect} = require('react-redux'); + + +/** + * Notifications Plugin. Provides support to show notifications + * @class Notifications + * @memberof plugins + * @static + * @example + * {name: "Notifications"} + * + */ +module.exports = { + NotificationsPlugin: connect( + (state) => ({ notifications: state && state.notifications}), + {onRemove: hide} + )(require('../components/notifications/NotificationContainer')), + reducers: { + notifications: require('../reducers/notifications') + } +}; diff --git a/web/client/product/app.jsx b/web/client/product/app.jsx index d445b93d7d..2270548ab0 100644 --- a/web/client/product/app.jsx +++ b/web/client/product/app.jsx @@ -18,7 +18,7 @@ const startApp = () => { const StandardApp = require('../components/app/StandardApp'); - const {pages, pluginsDef, initialState, storeOpts} = require('./appConfig'); + const {pages, pluginsDef, initialState, storeOpts, appEpics = {}} = require('./appConfig'); const StandardRouter = connect((state) => ({ locale: state.locale || {}, @@ -28,7 +28,7 @@ const startApp = () => { const appStore = require('../stores/StandardStore').bind(null, initialState, { maptype: require('../reducers/maptype'), maps: require('../reducers/maps') - }, {}); + }, appEpics); const initialActions = [ () => loadMaps(ConfigUtils.getDefaults().geoStoreUrl, ConfigUtils.getDefaults().initialMapFilter || "*"), @@ -37,6 +37,7 @@ const startApp = () => { const appConfig = { storeOpts, + appEpics, appStore, pluginsDef, initialActions, diff --git a/web/client/product/appConfig.js b/web/client/product/appConfig.js index 9bcc57547f..87c5e5231f 100644 --- a/web/client/product/appConfig.js +++ b/web/client/product/appConfig.js @@ -54,6 +54,7 @@ module.exports = { mousePosition: {enabled: true, crs: "EPSG:4326", showCenter: true} } }, + appEpics: require('../epics/cookies'), storeOpts: { persist: { whitelist: ['security'] diff --git a/web/client/product/plugins.js b/web/client/product/plugins.js index 48cd043c62..3c368ad7ed 100644 --- a/web/client/product/plugins.js +++ b/web/client/product/plugins.js @@ -70,7 +70,8 @@ module.exports = { GlobeViewSwitcherPlugin: require('../plugins/GlobeViewSwitcher'), BackgroundSelectorPlugin: require('../plugins/BackgroundSelector'), SearchServicesConfigPlugin: require('../plugins/SearchServicesConfig'), - VersionPlugin: require('../plugins/Version') + VersionPlugin: require('../plugins/Version'), + NotificationsPlugin: require('../plugins/Notifications') }, requires: { ReactSwipe: require('react-swipeable-views').default, diff --git a/web/client/reducers/__tests__/notifications-test.js b/web/client/reducers/__tests__/notifications-test.js new file mode 100644 index 0000000000..6e7d1e22af --- /dev/null +++ b/web/client/reducers/__tests__/notifications-test.js @@ -0,0 +1,27 @@ +/* + * 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. + */ +var expect = require('expect'); +const {show, hide, clear} = require('../../actions/notifications'); +const notifications = require('../notifications'); +describe('Test the notifications reducer', () => { + it('add notification', () => { + let state = notifications([], show({title: "test", uid: 1})); + expect(state).toExist(); + expect(state.length).toBe(1); + }); + it('hide notification', () => { + let state = notifications([{uid: 1}], hide(1)); + expect(state).toExist(); + expect(state.length).toBe(0); + }); + it('clear notifications', () => { + let state = notifications([{uid: 1}], clear()); + expect(state).toExist(); + expect(state.length).toBe(0); + }); +}); diff --git a/web/client/reducers/notifications.js b/web/client/reducers/notifications.js new file mode 100644 index 0000000000..b8ef846ae6 --- /dev/null +++ b/web/client/reducers/notifications.js @@ -0,0 +1,45 @@ +/* + * 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 {SHOW_NOTIFICATION, HIDE_NOTIFICATION, CLEAR_NOTIFICATIONS} = require('../actions/notifications'); +/** + * Manages the notifications. + * @memberof reducers + * @param {Array} [state=[]] the notifications array + * @param {Object} [action={}] the action. can be `SHOW_NOTIFICATION`, `HIDE_NOTIFICATION` or `CLEAR_NOTIFICATIONS` + * @return {Array} the modified state + * @example + * [{ + * uid: 1234, + * title: "My Notification", + * level: "success", + * action: { + * "label": "I Agree" + * } + * }] + */ +function notifications(state = [], action = {}) { + switch (action.type) { + case SHOW_NOTIFICATION: + const { type, ...rest } = action; + return [ + ...state, + { ...rest} + ]; + case HIDE_NOTIFICATION: + return state.filter(notification => { + return notification.uid !== action.uid; + }); + case CLEAR_NOTIFICATIONS: + return []; + default: + return state; + } + return state; +} +module.exports = notifications; diff --git a/web/client/translations/data.de-DE b/web/client/translations/data.de-DE index 273861b1c1..a84d956e15 100644 --- a/web/client/translations/data.de-DE +++ b/web/client/translations/data.de-DE @@ -130,6 +130,11 @@ } } }, + "cookiesPolicyNotification": { + "title": "Deze website maakt gebruik van cookies", + "message": "Door onze website te blijven gebruiken, accepteert u ons gebruik van cookies.", + "confirm": "Ik ben het eens" + }, "manager": { "openInANewTab":"Karte öffnen", "deleteMap":"Karte löschen", diff --git a/web/client/translations/data.en-US b/web/client/translations/data.en-US index 89a9a9cb04..3972a3ac69 100644 --- a/web/client/translations/data.en-US +++ b/web/client/translations/data.en-US @@ -130,6 +130,11 @@ } } }, + "cookiesPolicyNotification": { + "title": "This website uses cookies", + "message": "By continuing to use our website you are accepting our use of cookies.", + "confirm": "I Agree" + }, "manager": { "openInANewTab":"Open map", "deleteMap":"Delete Map", diff --git a/web/client/translations/data.fr-FR b/web/client/translations/data.fr-FR index e4208001fd..9de592ce33 100644 --- a/web/client/translations/data.fr-FR +++ b/web/client/translations/data.fr-FR @@ -1,3 +1,4 @@ + { "locale": "fr-FR", "messages": { @@ -131,6 +132,11 @@ } } }, + "cookiesPolicyNotification": { + "title": "Ce site utilise des cookies", + "message": "En continuant d'utiliser notre site Web, vous acceptez notre utilisation de cookies.", + "confirm": "Je suis d'accord" + }, "manager": { "openInANewTab":"Ouvrir la carte", "deleteMap":"Supprimer la carte", diff --git a/web/client/translations/data.it-IT b/web/client/translations/data.it-IT index 8740999a45..7c72fe4e84 100644 --- a/web/client/translations/data.it-IT +++ b/web/client/translations/data.it-IT @@ -130,6 +130,11 @@ } } }, + "cookiesPolicyNotification": { + "title": "Questo sito utilizza cookies", + "message": "Continuando a navigare sul sito accetti all'uso dei cookie", + "confirm": "Acconsento" + }, "manager": { "openInANewTab":"Apri mappa", "deleteMap":"Elimina Mappa",