diff --git a/docs/developer-guide/mapstore-migration-guide.md b/docs/developer-guide/mapstore-migration-guide.md
index c013eeb03d..d371132894 100644
--- a/docs/developer-guide/mapstore-migration-guide.md
+++ b/docs/developer-guide/mapstore-migration-guide.md
@@ -22,6 +22,37 @@ This is a list of things to check if you want to update from a previous version
## Migration from 2024.02.00 to 2025.01.00
+### Footer plugin configuration changes
+
+The Footer plugin has been refactored and some properties have been removed:
+
+- `cfg.logo` is not available anymore in favor of translation html snippet
+- translation message identifier `home.footerDescription` is not used anymore in the footer by default
+
+It is possible to replicate the old footer structure for existing project that want to keep the homepage footer information as before with the following configurations:
+
+1. configure the new Footer plugin in `localConfig.json` as follow:
+
+ ```js
+ {
+ "name": "Footer",
+ "cfg": {
+ "hideMenuItems": true,
+ "customFooter": true,
+ "customFooterMessageId": "home.footerDescription" // by default is using home.footerCustomHTML
+ }
+ }
+ ```
+
+2. update the `home.footerDescription` translation by adding the desired html structure, eg:
+
+ ```js
+ {
+ "home": {
+ "footerDescription": ""
+ }
+ }
+
### HomeDescription plugin configuration changes
The HomeDescription plugin has been refactored and a property has been removed:
diff --git a/web/client/configs/localConfig.json b/web/client/configs/localConfig.json
index 40af3fa1a6..981990842a 100644
--- a/web/client/configs/localConfig.json
+++ b/web/client/configs/localConfig.json
@@ -828,6 +828,7 @@
}
},
{ "name": "Footer"},
+ { "name": "About" },
{
"name": "Cookie",
"cfg": {
@@ -1094,7 +1095,7 @@
}
}
],
- "manager": ["Header", "Redirect", "Manager", "Home", "UserManager", "GroupManager", "Footer"],
- "context-manager": ["Header", "Redirect", "Home", "ContextManager", "Footer"]
+ "manager": ["Header", "Redirect", "Manager", "Home", "UserManager", "GroupManager", "Footer", { "name": "About" }],
+ "context-manager": ["Header", "Redirect", "Home", "ContextManager", "Footer", { "name": "About" }]
}
}
diff --git a/web/client/plugins/ResourcesCatalog/Footer.jsx b/web/client/plugins/ResourcesCatalog/Footer.jsx
index c05361b243..5b713b415c 100644
--- a/web/client/plugins/ResourcesCatalog/Footer.jsx
+++ b/web/client/plugins/ResourcesCatalog/Footer.jsx
@@ -6,25 +6,207 @@
* LICENSE file in the root directory of this source tree.
*/
-import React from 'react';
+import React, { useRef } from 'react';
+import PropTypes from 'prop-types';
import { createPlugin } from "../../utils/PluginsUtils";
+import Menu from './components/Menu';
+import Button from './components/Button';
+import Spinner from './components/Spinner';
+import Icon from './components/Icon';
import HTML from '../../components/I18N/HTML';
-import Text from './components/Text';
+import Message from '../../components/I18N/Message';
+import FlexBox from './components/FlexBox';
+import usePluginItems from '../../hooks/usePluginItems';
+import { withResizeDetector } from 'react-resize-detector';
+function FooterMenuItem({
+ className,
+ loading,
+ glyph,
+ iconType,
+ labelId,
+ onClick,
+ label
+}) {
+ return (
+
+
+
+ );
+}
-function Footer({
+FooterMenuItem.propTypes = {
+ className: PropTypes.string,
+ loading: PropTypes.bool,
+ glyph: PropTypes.string,
+ iconType: PropTypes.string,
+ labelId: PropTypes.string,
+ onClick: PropTypes.func
+};
-}) {
+FooterMenuItem.defaultProps = {
+ iconType: 'glyphicon',
+ onClick: () => { }
+};
+/**
+ * This plugin shows the footer
+ * @memberof plugins
+ * @class
+ * @name Footer
+ * @prop {boolean} cfg.customFooter params that can be used to render a custom html to be used instead of the default one
+ * @prop {string} cfg.customFooterMessageId replace custom footer translations message identifier
+ * @prop {object[]} cfg.menuItems list of menu items objects
+ * @prop {boolean} cfg.hideMenuItems hide menu items menu
+ * @prop {object[]} items this property contains the items injected from the other plugins,
+ * using the `containers` option in the plugin that want to inject new menu items.
+ * ```javascript
+ * const MyMenuItemComponent = connect(selector, { onActivateTool })(({
+ * component, // default component that provides a consistent UI (see BrandNavbarMenuItem in BrandNavbar plugin for props)
+ * variant, // one of style variant (primary, success, danger or warning)
+ * size, // button size
+ * className, // custom class name provided by configuration
+ * onActivateTool, // example of a custom connected action
+ * }) => {
+ * const ItemComponent = component;
+ * return (
+ * onActivateTool()}
+ * />
+ * );
+ * });
+ * createPlugin(
+ * 'MyPlugin',
+ * {
+ * containers: {
+ * Footer: {
+ * name: "TOOLNAME", // a name for the current tool.
+ * target: 'menu',
+ * Component: MyMenuItemComponent
+ * },
+ * // ...
+ * ```
+ * @example
+ * {
+ * "name": "Footer",
+ * "cfg": {
+ * "menuItems": [
+ * {
+ * "type": "link",
+ * "href": "/my-link",
+ * "target": "blank",
+ * "glyph": "heart",
+ * "labelId": "myMessageId",
+ * "variant": "default"
+ * },
+ * {
+ * "type": "logo",
+ * "href": "/my-link",
+ * "target": "blank",
+ * "src": "/my-image.jpg",
+ * "style": {}
+ * },
+ * {
+ * "type": "button",
+ * "href": "/my-link",
+ * "target": "blank",
+ * "glyph": "heart",
+ * "iconType": "glyphicon",
+ * "tooltipId": "myMessageId",
+ * "variant": "default",
+ * "square": true
+ * },
+ * {
+ * "type": "divider"
+ * },
+ * {
+ * "type": "message",
+ * "labelId": "myTranslationMessageId"
+ * }
+ * ]
+ * }
+ * }
+ */
+function Footer({
+ menuItems: menuItemsProp,
+ hideMenuItems,
+ items,
+ customFooter,
+ customFooterMessageId
+}, context) {
+ const { loadedPlugins } = context;
+ const ref = useRef();
+ const configuredItems = usePluginItems({ items, loadedPlugins });
+ const pluginMenuItems = configuredItems.filter(({ target }) => target === 'menu').map(item => ({ ...item, type: 'plugin' }));
+ const menuItems = [
+ ...menuItemsProp.map((menuItem, idx) => ({ ...menuItem, position: idx + 1 })),
+ ...pluginMenuItems
+ ].sort((a, b) => a.position - b.position);
return (
-
-
-
-
-
+ <>
+ {customFooter ? : null}
+ {!hideMenuItems || menuItems.length === 0 ? <>
+
+
+
+
+ > : false}
+ >
);
}
+Footer.propTypes = {
+ menuItems: PropTypes.array,
+ hideMenuItems: PropTypes.bool,
+ items: PropTypes.array,
+ customFooter: PropTypes.bool,
+ customFooterMessageId: PropTypes.string
+};
+
+Footer.contextTypes = {
+ loadedPlugins: PropTypes.object
+};
+
+Footer.defaultProps = {
+ menuItems: [
+ {
+ type: 'link',
+ href: "https://docs.mapstore.geosolutionsgroup.com/",
+ target: 'blank',
+ glyph: 'book',
+ labelId: 'resourcesCatalog.documentation'
+ },
+ {
+ type: 'link',
+ href: 'https://github.com/geosolutions-it/MapStore2',
+ target: 'blank',
+ label: 'GitHub',
+ glyph: 'github'
+ }
+ ],
+ customFooter: false,
+ customFooterMessageId: 'home.footerCustomHTML'
+};
+
export default createPlugin('Footer', {
- component: Footer
+ component: withResizeDetector(Footer)
});
diff --git a/web/client/plugins/ResourcesCatalog/ResourceDetails.jsx b/web/client/plugins/ResourcesCatalog/ResourceDetails.jsx
index 57aea54329..5cd1df9f22 100644
--- a/web/client/plugins/ResourcesCatalog/ResourceDetails.jsx
+++ b/web/client/plugins/ResourcesCatalog/ResourceDetails.jsx
@@ -111,7 +111,7 @@ function ResourceDetails({
targetSelector,
headerNodeSelector = '#ms-brand-navbar',
navbarNodeSelector = '',
- footerNodeSelector = '',
+ footerNodeSelector = '#ms-footer',
width,
height,
show,
diff --git a/web/client/plugins/ResourcesCatalog/ResourcesFiltersForm.jsx b/web/client/plugins/ResourcesCatalog/ResourcesFiltersForm.jsx
index 81e3e55601..c519b479ea 100644
--- a/web/client/plugins/ResourcesCatalog/ResourcesFiltersForm.jsx
+++ b/web/client/plugins/ResourcesCatalog/ResourcesFiltersForm.jsx
@@ -120,7 +120,7 @@ function ResourcesFiltersForm({
targetSelector,
headerNodeSelector = '#ms-brand-navbar',
navbarNodeSelector = '',
- footerNodeSelector = '',
+ footerNodeSelector = '#ms-footer',
width,
height,
user
diff --git a/web/client/plugins/ResourcesCatalog/components/Menu.jsx b/web/client/plugins/ResourcesCatalog/components/Menu.jsx
index b842d8fd28..8ead46f44a 100644
--- a/web/client/plugins/ResourcesCatalog/components/Menu.jsx
+++ b/web/client/plugins/ResourcesCatalog/components/Menu.jsx
@@ -11,32 +11,21 @@ import PropTypes from 'prop-types';
import MenuItem from './MenuItem';
import FlexBox from './FlexBox';
-/**
-* @module components/Menu
-*/
-
/**
* Menu component
* @name Menu
- * @prop {array} items list of menu item
- * @prop {string} containerClass css class of list container
- * @prop {string} childrenClass css class of item in list
- * @prop {string} query string to build the query url in case of link item
- * @prop {function} formatHref function to format the href in case of link item
- * @example
- *
- *
+ * @prop {object[]} items list of menu item
+ * @prop {string} className custom class name
+ * @prop {string} size button size, one of `xs`, `sm`, `md` or `xl`
+ * @prop {bool} alignRight align the dropdown menu to the right
+ * @prop {string} variant style for the button, one of `undefined`, `default` or `primary`
+ * @prop {any} menuItemComponent a default component to be passed as a prop to a custom `item.Component`
*/
const Menu = forwardRef(({
items,
- containerClass,
- childrenClass,
- query,
- formatHref,
size,
alignRight,
variant,
- resourceName,
className,
menuItemComponent,
...props
@@ -50,7 +39,6 @@ const Menu = forwardRef(({
component="ul"
ref={ref}
className={className}
- classNames={[containerClass]}
>
{items
.map((item, idx) => {
@@ -58,15 +46,9 @@ const Menu = forwardRef(({
);
@@ -76,21 +58,16 @@ const Menu = forwardRef(({
});
Menu.propTypes = {
- items: PropTypes.array.isRequired,
- containerClass: PropTypes.string,
- childrenClass: PropTypes.string,
- query: PropTypes.object,
- formatHref: PropTypes.func
-
+ items: PropTypes.array,
+ size: PropTypes.string,
+ alignRight: PropTypes.bool,
+ variant: PropTypes.string,
+ className: PropTypes.string,
+ menuItemComponent: PropTypes.any
};
Menu.defaultProps = {
- items: [],
- query: {},
- user: undefined,
- formatHref: () => '#',
- containerClass: ''
+ items: []
};
-
export default Menu;
diff --git a/web/client/plugins/ResourcesCatalog/components/MenuDropdownList.jsx b/web/client/plugins/ResourcesCatalog/components/MenuDropdownList.jsx
deleted file mode 100644
index 140d2662b0..0000000000
--- a/web/client/plugins/ResourcesCatalog/components/MenuDropdownList.jsx
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright 2024, 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.
- */
-
-import React from 'react';
-import { createPortal } from 'react-dom';
-import PropTypes from 'prop-types';
-import Message from '../../../components/I18N/Message';
-import NavLink from './MenuNavLink';
-import Icon from './Icon';
-import { Dropdown, MenuItem, Badge } from 'react-bootstrap';
-
-const isValidBadgeValue = (badge) => !!badge || badge === 0;
-
-const itemsList = (items) => (items && items.map((item, idx) => {
-
- const { labelId, href, badge, target, type, Component, className } = item;
-
- if (type === 'plugin' && Component) {
- return (
);
- }
-
- return (
- {labelId && }
- { isValidBadgeValue(badge) && {badge}}
-
- );
-} ));
-
-/**
- * DropdownList component
- * @name DropdownList
- * @memberof components.Menu.DropdownList
- * @prop {number} id to apply to toogle
- * @prop {array} items list od items of Dropdown
- * @prop {string} label label to apply to toogle
- * @prop {string} labelId alternative to label
- * @prop {string} labelId alternative to labe
- * @prop {object} toggleStyle inline style to apply to toogle comp
- * @prop {string} toggleImage image to apply to toogle comp
- * @prop {string} toggleIcon icon to apply to toogle comp
- * @prop {string} dropdownClass the css class to apply to the comp
- * @prop {number} tabIndex define navigation order
- * @prop {boolean} noCaret hide/show caret icon on the dropdown
- * @prop {number} badgeValue to apply the value to the item in list
- * @prop {node} containerNode the node to append the child element into a DOM
- * @example
- *
- *
- */
-
-
-const MenuDropdownList = ({
- id,
- items = [],
- label,
- labelId,
- toggleStyle,
- toggleImage,
- toggleIcon,
- dropdownClass,
- tabIndex,
- badgeValue,
- containerNode,
- size,
- noCaret,
- alignRight,
- variant,
- responsive
-}) => {
-
- const dropdownItems = items
- .map((itm, idx) => {
-
- if (itm.type === 'plugin' && itm.Component) {
- return (
Bitte fügen Sie benutzerdefiniertes HTML in die Übersetzungen ein, um eine benutzerdefinierte Fußzeile darzustellen
",
"examples":{
"viewer":{
@@ -4383,7 +4382,8 @@
"errorDeletingTag": "Es ist nicht möglich, das Tag zu löschen",
"removeFromFavorites": "Aus Favoriten entfernen",
"addToFavorites": "Zu Favoriten hinzufügen",
- "favorites": "Favoriten"
+ "favorites": "Favoriten",
+ "documentation": "Dokumentation"
}
}
}
diff --git a/web/client/translations/data.en-US.json b/web/client/translations/data.en-US.json
index 921039edd4..a3c7c63f38 100644
--- a/web/client/translations/data.en-US.json
+++ b/web/client/translations/data.en-US.json
@@ -386,7 +386,6 @@
"Examples": "Examples",
"LinkedinGroup": "Mapstore Linkedin Group",
"scrollTop": "Scroll to the top of the page",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"footerCustomHTML": "
Please insert custom HTML into the translations to render a custom footer
"
},
"cookiesPolicyNotification": {
@@ -4356,7 +4355,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.es-ES.json b/web/client/translations/data.es-ES.json
index 1af52bf1d0..795b740d8d 100644
--- a/web/client/translations/data.es-ES.json
+++ b/web/client/translations/data.es-ES.json
@@ -386,7 +386,6 @@
"Examples": "Ejemplos",
"LinkedinGroup": "Grupo Linkedin de Mapstore",
"scrollTop": "Volver al principio de la página",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"footerCustomHTML": "
Inserte HTML personalizado en las traducciones para generar un pie de página personalizado.
"
},
"cookiesPolicyNotification": {
@@ -4345,7 +4344,8 @@
"errorDeletingTag": "No es posible eliminar la etiqueta",
"removeFromFavorites": "Eliminar de favoritos",
"addToFavorites": "Añadir a favoritos",
- "favorites": "Favoritos"
+ "favorites": "Favoritos",
+ "documentation": "Documentación"
}
}
}
diff --git a/web/client/translations/data.fi-FI.json b/web/client/translations/data.fi-FI.json
index 066f6e43f3..800761e848 100644
--- a/web/client/translations/data.fi-FI.json
+++ b/web/client/translations/data.fi-FI.json
@@ -194,7 +194,6 @@
"Examples": "Esimerkit",
"LinkedinGroup": "Mapstore Linkedin Group",
"scrollTop": "Vieritä sivun yläosaan",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"examples": {
"viewer": {
"html": "
Viewer
Simple Viewer
"
@@ -2788,7 +2787,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.fr-FR.json b/web/client/translations/data.fr-FR.json
index 0ad1644fea..08d16d4eef 100644
--- a/web/client/translations/data.fr-FR.json
+++ b/web/client/translations/data.fr-FR.json
@@ -386,7 +386,6 @@
"Examples": "Exemples",
"LinkedinGroup": "Groupe Linkedin Mapstore",
"scrollTop": "Retour en haut de la page",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"footerCustomHTML": "
Veuillez insérer du HTML personnalisé dans les traductions pour afficher un pied de page personnalisé
"
},
"cookiesPolicyNotification": {
@@ -4345,7 +4344,8 @@
"errorDeletingTag": "Il n'est pas possible de supprimer la balise",
"removeFromFavorites": "Supprimer des favoris",
"addToFavorites": "Ajouter aux favoris",
- "favorites": "Favoris"
+ "favorites": "Favoris",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.hr-HR.json b/web/client/translations/data.hr-HR.json
index d738615a8a..0bb0a1be59 100644
--- a/web/client/translations/data.hr-HR.json
+++ b/web/client/translations/data.hr-HR.json
@@ -193,7 +193,6 @@
"Examples": "Primjeri",
"LinkedinGroup": "Mapstore Linkedin grupa",
"scrollTop": "Pomakni gore na vrh stranice",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"examples":{
"viewer":{
"html":"
Preglednik
Jednostavni preglednik
"
@@ -2186,7 +2185,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.is-IS.json b/web/client/translations/data.is-IS.json
index ee08572109..683d18bee1 100644
--- a/web/client/translations/data.is-IS.json
+++ b/web/client/translations/data.is-IS.json
@@ -340,8 +340,7 @@
"Applications": "Applications",
"Examples": "Examples",
"LinkedinGroup": "Mapstore Linkedin Group",
- "scrollTop": "Scroll to the top of the page",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com"
+ "scrollTop": "Scroll to the top of the page"
},
"cookiesPolicyNotification": {
"title": "This website uses cookies",
@@ -3997,7 +3996,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.it-IT.json b/web/client/translations/data.it-IT.json
index 2b98751224..52c1890a3a 100644
--- a/web/client/translations/data.it-IT.json
+++ b/web/client/translations/data.it-IT.json
@@ -384,7 +384,6 @@
"Examples": "Esempi",
"LinkedinGroup": "Gruppo Linkedin Mapstore",
"scrollTop": "Torna all'inizio della pagina",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"footerCustomHTML": "
Per favore, inserisci un HTML custom nelle traduzioni per renderizzare un footer personalizzato
"
},
"cookiesPolicyNotification": {
@@ -4343,7 +4342,8 @@
"errorDeletingTag": "Impossibile eliminare il tag",
"removeFromFavorites": "Rimuovi dai preferiti",
"addToFavorites": "Aggiungi ai preferiti",
- "favorites": "Preferiti"
+ "favorites": "Preferiti",
+ "documentation": "Documentazione"
}
}
}
diff --git a/web/client/translations/data.nl-NL.json b/web/client/translations/data.nl-NL.json
index 2c15c8f07a..1225d80ad0 100644
--- a/web/client/translations/data.nl-NL.json
+++ b/web/client/translations/data.nl-NL.json
@@ -373,8 +373,7 @@
"Applications": "Toepassingen",
"Examples": "Voorbeelden",
"LinkedinGroup": "Mapstore Linkedin groep",
- "scrollTop": "Terug naar boven",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com"
+ "scrollTop": "Terug naar boven"
},
"cookiesPolicyNotification": {
"title": "Deze site maakt gebruik van cookies",
@@ -4331,7 +4330,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.pt-PT.json b/web/client/translations/data.pt-PT.json
index 311f65bd05..1608d59e29 100644
--- a/web/client/translations/data.pt-PT.json
+++ b/web/client/translations/data.pt-PT.json
@@ -195,7 +195,6 @@
"Examples": "Exemplos",
"LinkedinGroup": "Grupo Mapstore no Linkedin",
"scrollTop": "Navegar para o topo da página",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"examples":{
"viewer":{
"html":"
Viewer
Visualizador Simples
"
@@ -2143,7 +2142,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.sk-SK.json b/web/client/translations/data.sk-SK.json
index 2f75397ca7..ff4f7e261e 100644
--- a/web/client/translations/data.sk-SK.json
+++ b/web/client/translations/data.sk-SK.json
@@ -284,7 +284,6 @@
"Examples": "Ukážky",
"LinkedinGroup": "Linkedin skupina MapStore",
"scrollTop": "Prejsť do hornej časti stránky",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"examples":{
"viewer":{
"html":"
Viewer
Simple Viewer
"
@@ -3503,7 +3502,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.sv-SE.json b/web/client/translations/data.sv-SE.json
index 363d452513..3da35bfece 100644
--- a/web/client/translations/data.sv-SE.json
+++ b/web/client/translations/data.sv-SE.json
@@ -291,8 +291,7 @@
"Applications": "Applikationer",
"Exempel": "Exempel",
"LinkedinGroup": "Mapstore på Linkedin",
- "scrollTop": "Bläddra till toppen av sidan",
- "footerDescription": " GeoSolutions sales@geosolutionsgroup.com "
+ "scrollTop": "Bläddra till toppen av sidan"
},
"cookiesPolicyNotification": {
"title": "Denna webbplats använder cookies",
@@ -3542,7 +3541,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.vi-VN.json b/web/client/translations/data.vi-VN.json
index eab62a4ff9..90c59d2a76 100644
--- a/web/client/translations/data.vi-VN.json
+++ b/web/client/translations/data.vi-VN.json
@@ -566,7 +566,6 @@
"html": "
Trình xem
Trình xem đơn giản
"
}
},
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"forkMeOnGitHub": "Chia đôi tôi trên GitHub",
"open": "Mở",
"scrollTop": "Cuộn lên đầu trang",
@@ -2172,7 +2171,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}
diff --git a/web/client/translations/data.zh-ZH.json b/web/client/translations/data.zh-ZH.json
index 0954b59f49..ac1a0d0140 100644
--- a/web/client/translations/data.zh-ZH.json
+++ b/web/client/translations/data.zh-ZH.json
@@ -194,7 +194,6 @@
"Examples": "例子",
"LinkedinGroup": "Mapstore Linkedin Group",
"scrollTop": "滚动到页面顶部",
- "footerDescription": "GeoSolutionssales@geosolutionsgroup.com",
"examples":{
"viewer":{
"html":"
Viewer
Simple Viewer
"
@@ -2119,7 +2118,8 @@
"errorDeletingTag": "It is not possible to delete the tag",
"removeFromFavorites": "Remove from favorites",
"addToFavorites": "Add to favorites",
- "favorites": "Favorites"
+ "favorites": "Favorites",
+ "documentation": "Documentation"
}
}
}