diff --git a/.gitignore b/.gitignore index 8e1772c270..3d297a0ee3 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ web/docs .settings/ debug.log .vscode/settings.json +site diff --git a/build/BuildUtils.js b/build/BuildUtils.js new file mode 100644 index 0000000000..f4b489d8c6 --- /dev/null +++ b/build/BuildUtils.js @@ -0,0 +1,25 @@ +/* + * Copyright 2022, 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 DefinePlugin = require("webpack/lib/DefinePlugin"); +const { GitRevisionPlugin } = require('git-revision-webpack-plugin'); + +const gitRevPlugin = new GitRevisionPlugin({ + branchCommand: 'log -n1 --format=format:"Message: %s%nCommit: %H%nDate: %aD%nAuthor: %an"' +}); + +const VERSION_INFO_DEFINE_PLUGIN = new DefinePlugin({ + __COMMITHASH__: JSON.stringify(gitRevPlugin.commithash()), + __COMMIT_DATA__: JSON.stringify(gitRevPlugin.branch()) +}); + + +module.exports = { + VERSION_INFO_DEFINE_PLUGIN +}; diff --git a/build/buildConfig.js b/build/buildConfig.js index 34bcad53be..08be32482b 100644 --- a/build/buildConfig.js +++ b/build/buildConfig.js @@ -9,6 +9,10 @@ const path = require('path'); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const castArray = require('lodash/castArray'); +const { + VERSION_INFO_DEFINE_PLUGIN +} = require('./BuildUtils'); + /** * Webpack configuration builder. * Returns a webpack configuration object for the given parameters. @@ -157,6 +161,7 @@ module.exports = (...args) => mapArgumentsToObject(args, ({ } }), new DefinePlugin({ '__MAPSTORE_PROJECT_CONFIG__': JSON.stringify(projectConfig) }), + VERSION_INFO_DEFINE_PLUGIN, new DefinePlugin({ // Define relative base path in cesium for loading assets 'CESIUM_BASE_URL': JSON.stringify(cesiumBaseUrl ? cesiumBaseUrl : path.join('dist', 'cesium')) diff --git a/build/prod-webpack.config.js b/build/prod-webpack.config.js index 8306eca324..0511f6b3ee 100644 --- a/build/prod-webpack.config.js +++ b/build/prod-webpack.config.js @@ -4,8 +4,6 @@ const themeEntries = require('./themes.js').themeEntries; const extractThemesPlugin = require('./themes.js').extractThemesPlugin; const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('./moduleFederation').plugin; -const { GitRevisionPlugin } = require('git-revision-webpack-plugin'); -const DefinePlugin = require("webpack/lib/DefinePlugin"); const paths = { base: path.join(__dirname, ".."), @@ -14,9 +12,6 @@ const paths = { code: path.join(__dirname, "..", "web", "client") }; -const gitRevPlugin = new GitRevisionPlugin({ - branchCommand: 'log -n1 --format=format:"Message: %s%nCommit: %H%nDate: %aD%nAuthor: %an"' -}); module.exports = require('./buildConfig')({ bundles: { "mapstore2": path.join(paths.code, "product", "app"), @@ -27,10 +22,7 @@ module.exports = require('./buildConfig')({ }, themeEntries, paths, - plugins: [extractThemesPlugin, ModuleFederationPlugin, new DefinePlugin({ - __COMMITHASH__: JSON.stringify(gitRevPlugin.commithash()), - __COMMIT_DATA__: JSON.stringify(gitRevPlugin.branch()) - })], + plugins: [extractThemesPlugin, ModuleFederationPlugin], prod: true, prodPlugins: [ new HtmlWebpackPlugin({ diff --git a/build/testConfig.js b/build/testConfig.js index 4823abd4e1..23bf0f9c4d 100644 --- a/build/testConfig.js +++ b/build/testConfig.js @@ -3,6 +3,9 @@ const nodePath = require('path'); const webpack = require('webpack'); const ProvidePlugin = require("webpack/lib/ProvidePlugin"); const NormalModuleReplacementPlugin = require("webpack/lib/NormalModuleReplacementPlugin"); +const { + VERSION_INFO_DEFINE_PLUGIN +} = require('./BuildUtils'); module.exports = ({browsers = [ 'ChromeHeadless' ], files, path, testFile, singleRun, basePath = ".", alias = {}}) => ({ browsers, @@ -149,6 +152,7 @@ module.exports = ({browsers = [ 'ChromeHeadless' ], files, path, testFile, singl // Define relative base path in cesium for loading assets 'CESIUM_BASE_URL': JSON.stringify(nodePath.join(basePath, 'node_modules', 'cesium', 'Source')) }), + VERSION_INFO_DEFINE_PLUGIN, // it's not possible to load directly from the module name `cesium/Build/Cesium/Widgets/widgets.css` // see https://github.com/CesiumGS/cesium/issues/9212 new NormalModuleReplacementPlugin(/^cesium\/index\.css$/, nodePath.join(basePath, 'node_modules', 'cesium/Build/Cesium/Widgets/widgets.css')) diff --git a/build/webpack.config.js b/build/webpack.config.js index 293983b019..9a46a1dbc6 100644 --- a/build/webpack.config.js +++ b/build/webpack.config.js @@ -1,15 +1,10 @@ const path = require("path"); -const { GitRevisionPlugin } = require('git-revision-webpack-plugin'); -const DefinePlugin = require("webpack/lib/DefinePlugin"); const themeEntries = require('./themes.js').themeEntries; const extractThemesPlugin = require('./themes.js').extractThemesPlugin; const moduleFederationPlugin = require('./moduleFederation.js').plugin; -const gitRevPlugin = new GitRevisionPlugin({ - branchCommand: 'log -n1 --format=format:"Message: %s%nCommit: %H%nDate: %aD%nAuthor: %an"' -}); const config = require('./buildConfig')( { bundles: { @@ -26,10 +21,7 @@ const config = require('./buildConfig')( framework: path.join(__dirname, "..", "web", "client"), code: path.join(__dirname, "..", "web", "client") }, - plugins: [extractThemesPlugin, moduleFederationPlugin, new DefinePlugin({ - __COMMITHASH__: JSON.stringify(gitRevPlugin.commithash()), - __COMMIT_DATA__: JSON.stringify(gitRevPlugin.branch()) - })], + plugins: [extractThemesPlugin, moduleFederationPlugin], prod: false } ); diff --git a/docs/developer-guide/mapstore-migration-guide.md b/docs/developer-guide/mapstore-migration-guide.md index 0feb491943..a1979623cd 100644 --- a/docs/developer-guide/mapstore-migration-guide.md +++ b/docs/developer-guide/mapstore-migration-guide.md @@ -22,6 +22,34 @@ This is a list of things to check if you want to update from a previous version ## Migration from 2022.01.02 to 2022.02.00 +### Version plugin has been removed + +We no longer maintain the Version plugin since we have moved its content inside the About plugin (see [here](https://github.com/geosolutions-it/MapStore2/issues/7934#issuecomment-1201433942) for more details) + +We suggest you to clean up your project as well: + +- remove Version entry it from a local list of plugins.js +- remove Version entries it from a localConfig +- add About entry into other pages of mapstore plugins array, suggest list is: + - dashboard + - geostory + - mobile +- remove Define plugins in webpack-config.js or prod.webpack-config.js, since we have moved these definition to a more general *build/buildConfig.js* file +- check that in your package.json you have this extends rule + +```js +"eslintConfig": { + "extends": [ + "@mapstore/eslint-config-mapstore" + ], + ... +``` + +- edit the version of the *@mapstore/eslint-config-mapstore* to **1.0.5** in your package.json so that the new globals config will be inherited + +!!! note + this may fail on gha workflows, in that case we suggest to edit directly your package.json with globals taken from mapstore framework + ### Support for OpenID MapStore introduced support for OpenID for google and keycloak. In order to have this functionalities and to be aligned with the latest version of MapStore you have to update the following files in your projects: diff --git a/project/standard/templates/prod-webpack.config.js b/project/standard/templates/prod-webpack.config.js index c0ca0f51df..7342173c98 100644 --- a/project/standard/templates/prod-webpack.config.js +++ b/project/standard/templates/prod-webpack.config.js @@ -4,8 +4,6 @@ const themeEntries = require('./MapStore2/build/themes.js').themeEntries; const extractThemesPlugin = require('./MapStore2/build/themes.js').extractThemesPlugin; const ModuleFederationPlugin = require('./MapStore2/build/moduleFederation').plugin; const HtmlWebpackPlugin = require('html-webpack-plugin'); -const { GitRevisionPlugin } = require('git-revision-webpack-plugin'); -const DefinePlugin = require("webpack/lib/DefinePlugin"); const paths = { base: __dirname, @@ -13,9 +11,6 @@ const paths = { framework: path.join(__dirname, "MapStore2", "web", "client"), code: [path.join(__dirname, "js"), path.join(__dirname, "MapStore2", "web", "client")] }; -const gitRevPlugin = new GitRevisionPlugin({ - branchCommand: 'log -n1 --format=format:"Message: %s%nCommit: %H%nDate: %aD%nAuthor: %an"' -}); module.exports = require('./MapStore2/build/buildConfig')({ bundles: { '__PROJECTNAME__': path.join(__dirname, "js", "app"), @@ -26,10 +21,7 @@ module.exports = require('./MapStore2/build/buildConfig')({ }, themeEntries, paths, - plugins: [extractThemesPlugin, ModuleFederationPlugin, new DefinePlugin({ - __COMMITHASH__: JSON.stringify(gitRevPlugin.commithash()), - __COMMIT_DATA__: JSON.stringify(gitRevPlugin.branch()) - })], + plugins: [extractThemesPlugin, ModuleFederationPlugin], prod: true, publicPath: undefined, cssPrefix: '.__PROJECTNAME__', diff --git a/project/standard/templates/webpack.config.js b/project/standard/templates/webpack.config.js index f6255820b3..a0b7f19b76 100644 --- a/project/standard/templates/webpack.config.js +++ b/project/standard/templates/webpack.config.js @@ -1,14 +1,9 @@ const path = require("path"); -const { GitRevisionPlugin } = require('git-revision-webpack-plugin'); -const DefinePlugin = require("webpack/lib/DefinePlugin"); const themeEntries = require('./MapStore2/build/themes.js').themeEntries; const extractThemesPlugin = require('./MapStore2/build/themes.js').extractThemesPlugin; const ModuleFederationPlugin = require('./MapStore2/build/moduleFederation').plugin; -const gitRevPlugin = new GitRevisionPlugin({ - branchCommand: 'log -n1 --format=format:"Message: %s%nCommit: %H%nDate: %aD%nAuthor: %an"' -}); module.exports = require('./MapStore2/build/buildConfig')({ bundles: { @@ -25,10 +20,7 @@ module.exports = require('./MapStore2/build/buildConfig')({ framework: path.join(__dirname, "MapStore2", "web", "client"), code: [path.join(__dirname, "js"), path.join(__dirname, "MapStore2", "web", "client")] }, - plugins: [extractThemesPlugin, ModuleFederationPlugin, new DefinePlugin({ - __COMMITHASH__: JSON.stringify(gitRevPlugin.commithash()), - __COMMIT_DATA__: JSON.stringify(gitRevPlugin.branch()) - })], + plugins: [extractThemesPlugin, ModuleFederationPlugin], prod: false, publicPath: undefined, cssPrefix: '.__PROJECTNAME__', diff --git a/utility/eslint/index.js b/utility/eslint/index.js index 90eac871f1..8400a7232b 100644 --- a/utility/eslint/index.js +++ b/utility/eslint/index.js @@ -26,7 +26,10 @@ module.exports = { "beforeEach": false, "after": false, "afterEach": false, - "__DEVTOOLS__": false + "__DEVTOOLS__": false, + "__MAPSTORE_PROJECT_CONFIG__": false, + "__COMMITHASH__": false, + "__COMMIT_DATA__": false }, "rules": { /** diff --git a/utility/eslint/package.json b/utility/eslint/package.json index 995e54ec7a..b76c5def6e 100644 --- a/utility/eslint/package.json +++ b/utility/eslint/package.json @@ -1,6 +1,6 @@ { "name": "@mapstore/eslint-config-mapstore", - "version": "1.0.3", + "version": "1.0.5", "private": false, "description": "ESLint Configuration for MapStore project", "author": "GeoSolutions S.a.s.", diff --git a/web/client/components/Version/VersionDialog.jsx b/web/client/components/Version/VersionDialog.jsx deleted file mode 100644 index 6181c7ba73..0000000000 --- a/web/client/components/Version/VersionDialog.jsx +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2022, 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 Dialog from '../misc/Dialog'; -import { Glyphicon } from 'react-bootstrap'; -import Message from '../I18N/Message'; -import Button from '../misc/Button'; -import PropTypes from 'prop-types'; - -class VersionDialog extends React.Component { - - static propTypes = { - closeGlyph: PropTypes.string, - show: PropTypes.bool, - onClose: PropTypes.func, - version: PropTypes.string - } - static defaultProps = { - toggleControl: () => {}, - closeGlyph: "1-close", - onClose: () => {} - }; - onClose = () => { - this.props.onClose(false); - }; - - render() { - const githubUrl = "https://github.com/geosolutions-it/MapStore/tree/" + __COMMITHASH__; - const splitData = __COMMIT_DATA__.split('\n'); - const commit = splitData.find((x)=> x.toLowerCase().includes('commit:')).split(':')[1]; - const message = splitData.find((x)=> x.toLowerCase().includes('message:')).split(':')[1]; - const date = splitData.find((x)=> x.toLowerCase().includes('date:')).split(':')[1]; - const author = splitData.find((x)=> x.toLowerCase().includes('author:')).split(':')[1]; - - return ( - <div style={{ background: 'gba(0, 0, 0, 0.5)'}}> - {this.props.show && <Dialog id="mapstore-about" style={{position: 'absolute', top: '90px'}} draggable={false} modal> - <div key="header" role="header"> - <Message key="title" msgId="version.label"/> - <button key="close" onClick={this.onClose} className="close">{this.props.closeGlyph ? <Glyphicon glyph={this.props.closeGlyph}/> : <span>×</span>}</button> - </div> - <div key="body" role="body" className="version-panel"> - <ul style={{listStyleType: 'none'}}> - <li> - <span className="version-info"> - <span className="application-version-label"><Message msgId="version.label"/> - </span>:{this.props.version} - </span> - </li> - <li> - <div className="version-info"> - <div className="info-label"> - <Message msgId="version.message"/> - </div> - <div> - {message} - - </div> - </div> - <div className="version-info"> - <div className="info-label"> - <Message msgId="version.commit"/> - - </div> - <div id="commit"> - {commit} - - </div> - </div> - <div className="version-info"> - <div className="info-label"> - <Message msgId="version.date"/> - - </div> - <div id="date"> - {date} - - </div> - </div> - <div className="version-info"> - <div className="info-label"> - <Message msgId="version.author"/> - - </div> - <div id="author"> - {author} - - </div> - </div> - - </li> - <li style={{marginTop: '22px', marginLeft: '86px'}}> - <span><a href={githubUrl} target="_blank" ><Button className="btn"><Message msgId="version.githuburl"/></Button></a></span> - </li> - </ul> - </div> - </Dialog>} - </div> - ); - - } - -} - -export default VersionDialog; diff --git a/web/client/components/Version/__tests__/VersionDialog-test.js b/web/client/components/Version/__tests__/VersionDialog-test.js deleted file mode 100644 index b7380b84f9..0000000000 --- a/web/client/components/Version/__tests__/VersionDialog-test.js +++ /dev/null @@ -1,82 +0,0 @@ -/** - * Copyright 2022, 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 expect from 'expect'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import ReactTestUtils from 'react-dom/test-utils'; -import VersionDialog from '../VersionDialog'; - -describe("The VersionDialog component", () => { - beforeEach((done) => { - window.__COMMIT_DATA__ = `Message: #7934 refactor code and resolve eslint error\n - Commit: 01046133761de880aebce08a7bf11dd858117837\n - Date: Thu, 23 Jun 2022 20:00:02 +0300\n - Author: sam rubarema`; - window.__COMMITHASH__ = '123wwtwtwtttwtt'; - - document.body.innerHTML = '<div id="container"></div>'; - setTimeout(done); - }); - - afterEach((done) => { - ReactDOM.unmountComponentAtNode(document.getElementById("container")); - document.body.innerHTML = ''; - setTimeout(done); - }); - - it('is created with defaults', () => { - const cmp = ReactDOM.render(<VersionDialog/>, document.getElementById("container")); - expect(cmp).toBeTruthy(); - }); - - it('should be visible', () => { - const versionDialog = ReactDOM.render(<VersionDialog onClose={()=>{}} show version={'version'} />, document.getElementById("container")); - expect(versionDialog).toBeTruthy(); - const versionDialogDOM = ReactDOM.findDOMNode(versionDialog); - expect(versionDialogDOM).toBeTruthy(); - const innerModalDom = versionDialogDOM.children[0]; - expect(innerModalDom).toBeTruthy(); - const innerModalDomBody = innerModalDom.children[0]; - expect(innerModalDomBody).toBeTruthy(); - const infoclass = versionDialogDOM.querySelectorAll('version-info, info-label'); - expect(infoclass).toBeTruthy(); - const versionClass = versionDialogDOM.querySelector('.application-version-label'); - expect(versionClass).toBeTruthy(); - }); - - it('test close button', () => { - const handlers = { - onClose() {} - }; - let spy = expect.spyOn(handlers, "onClose"); - const vd = ReactDOM.render(<VersionDialog onClose={handlers.onClose} show version={'version'} />, document.getElementById("container")); - expect(vd).toBeTruthy(); - const dom = ReactDOM.findDOMNode(vd); - const closeBtn = dom.getElementsByClassName('close')[0]; - expect(closeBtn).toBeTruthy(); - ReactTestUtils.Simulate.click(closeBtn); - expect(spy.calls.length).toBe(1); - }); - it('test the modal output', () => { - const version = '$MapStore2'; - const vd = ReactDOM.render(<VersionDialog onClose={()=>{}} show version={version} />, document.getElementById("container")); - expect(vd).toBeTruthy(); - const versionclass = document.querySelector(".version-info"); - expect(versionclass.textContent).toBe('version.label:$MapStore2'); - const commit = document.querySelector('#commit'); - expect(commit.textContent.trim()).toBe('01046133761de880aebce08a7bf11dd858117837'); - const date = document.querySelector('#date'); - expect(date.textContent.trim()).toBe('Thu, 23 Jun 2022 20'); - const author = document.querySelector('#author'); - expect(author.textContent.trim()).toBe('sam rubarema'); - - }); - - -}); diff --git a/web/client/configs/localConfig.json b/web/client/configs/localConfig.json index fad5e346b1..c4cd49bfcd 100644 --- a/web/client/configs/localConfig.json +++ b/web/client/configs/localConfig.json @@ -196,7 +196,9 @@ } } } - }, "Version", "DrawerMenu", + }, { + "name": "About" + }, "DrawerMenu", { "name": "BackgroundSelector", "cfg": { @@ -318,7 +320,7 @@ } } } - }, "AutoMapUpdate", "HelpLink", "DrawerMenu", "Version", "Notifications", "BackgroundSelector", "Swipe", { + }, "AutoMapUpdate", "HelpLink", "DrawerMenu", "Notifications", "BackgroundSelector", "Swipe", { "name": "Annotations", "cfg": { "measurementAnnotationEdit": false @@ -410,7 +412,9 @@ "cfg": { "wrap": true } - }, "About", + }, { + "name": "About" + }, { "name": "MousePosition", "cfg": { @@ -665,7 +669,9 @@ "Dashboard", "Notifications", "Login", - "Version", + { + "name": "About" + }, "Language", "NavMenu", "DashboardSave", @@ -788,7 +794,9 @@ }, "Login", "BurgerMenu", - "Version", + { + "name": "About" + }, "Language", "NavMenu", "Attribution", diff --git a/web/client/configs/pluginsConfig.json b/web/client/configs/pluginsConfig.json index eda0ef0143..c46f681af5 100644 --- a/web/client/configs/pluginsConfig.json +++ b/web/client/configs/pluginsConfig.json @@ -154,12 +154,6 @@ "SidebarMenu" ] }, - { - "name": "Version", - "glyph": "info-sign", - "title": "plugins.Version.title", - "description": "plugins.Version.description" - }, { "name": "BackgroundSelector", "title": "plugins.BackgroundSelector.title", diff --git a/web/client/plugins/BurgerMenu.jsx b/web/client/plugins/BurgerMenu.jsx index 81cc4a9817..6c923795e3 100644 --- a/web/client/plugins/BurgerMenu.jsx +++ b/web/client/plugins/BurgerMenu.jsx @@ -6,12 +6,19 @@ * LICENSE file in the root directory of this source tree. */ import React from 'react'; - import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import assign from 'object-assign'; import { DropdownButton, Glyphicon, MenuItem } from 'react-bootstrap'; + import tooltip from "../components/misc/enhancers/tooltip"; +import ToolsContainer from './containers/ToolsContainer'; +import Message from './locale/Message'; +import { createPlugin } from '../utils/PluginsUtils'; +import {setControlProperty} from "../actions/controls"; +import {burgerMenuSelector} from "../selectors/controls"; + +import './burgermenu/burgermenu.css'; const TDropdownButton = tooltip(DropdownButton); const Container = ({children, ...props}) => ( @@ -38,13 +45,6 @@ const AnchorElement = ({children, href, target, onClick}) => ( <a href={href} target={target} onClick={onClick}>{children}</a> ); -import ToolsContainer from './containers/ToolsContainer'; -import Message from './locale/Message'; -import { createPlugin } from '../utils/PluginsUtils'; -import './burgermenu/burgermenu.css'; -import {setControlProperty} from "../actions/controls"; -import {burgerMenuSelector} from "../selectors/controls"; - class BurgerMenu extends React.Component { static propTypes = { id: PropTypes.string, diff --git a/web/client/plugins/ContentTabs.jsx b/web/client/plugins/ContentTabs.jsx index 280d36559b..50bdb1d396 100644 --- a/web/client/plugins/ContentTabs.jsx +++ b/web/client/plugins/ContentTabs.jsx @@ -99,7 +99,8 @@ class ContentTabs extends React.Component { activeStyle="default" tools={[...this.props.items].sort((a, b) => a.position - b.position).filter( ({key}, i) => (key || i) === this.props.selected)} panels={[]} - /></Col> + /> + </Col> </Row> </Grid> ); diff --git a/web/client/plugins/Version.jsx b/web/client/plugins/Version.jsx deleted file mode 100644 index 2930dea864..0000000000 --- a/web/client/plugins/Version.jsx +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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. - */ - -import React from 'react'; - -import { connect } from 'react-redux'; -import { Glyphicon } from 'react-bootstrap'; -import { versionSelector } from '../selectors/version'; -import { versionInfoSelector } from '../selectors/controls'; -import Message from '../components/I18N/Message'; -import VersionDialog from '../components/Version/VersionDialog'; - - -import assign from 'object-assign'; -import { toggleControl } from '../actions/controls'; - -/** - * Version Plugin. Shows current MapStore2 version in settings panel - * @class Version - * @memberof plugins - * @static - * - */ -const Version = connect((state) => ({ - version: versionSelector(state), - show: versionInfoSelector(state) -} -), {onClose: toggleControl.bind(null, 'version', null)})( - VersionDialog -); - -export default { - VersionPlugin: assign(Version, { - SidebarMenu: { - name: 'version', - position: 2, - priority: 1, - doNotHide: true, - tooltip: "version.label", - text: <Message msgId="version.label"/>, - icon: <Glyphicon glyph="info-sign"/>, - action: toggleControl.bind(null, 'version', null), - toggle: true - }, - BurgerMenu: { - name: 'version', - position: 4, - priority: 2, - doNotHide: true, - text: <Message msgId="version.label"/>, - tooltip: "version.label", - icon: <Glyphicon glyph="info-sign" />, - action: toggleControl.bind(null, 'version', null) - } - }), - reducers: { - version: require('../reducers/version').default - } -}; diff --git a/web/client/product/components/viewer/about/About.jsx b/web/client/product/components/viewer/about/About.jsx index 9e7d9cb743..a2880fe999 100644 --- a/web/client/product/components/viewer/about/About.jsx +++ b/web/client/product/components/viewer/about/About.jsx @@ -1,5 +1,3 @@ -import PropTypes from 'prop-types'; - /** * Copyright 2015, GeoSolutions Sas. * All rights reserved. @@ -7,15 +5,18 @@ import PropTypes from 'prop-types'; * 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 PropTypes from 'prop-types'; +import { Glyphicon } from 'react-bootstrap'; import InfoButton from '../../../../components/buttons/InfoButton'; import Dialog from '../../../../components/misc/Dialog'; -import AboutContent from './AboutContent'; import { Message } from '../../../../components/I18N/I18N'; +import AboutContent from './AboutContent'; import aboutImg from '../../../assets/img/Blank.gif'; -import assign from 'object-assign'; -import { Glyphicon } from 'react-bootstrap'; +import VersionInfo from './VersionInfo'; + class About extends React.Component { static propTypes = { @@ -23,6 +24,11 @@ class About extends React.Component { modalConfig: PropTypes.object, withButton: PropTypes.bool, enabled: PropTypes.bool, + version: PropTypes.string, + githubUrl: PropTypes.string, + commit: PropTypes.string, + message: PropTypes.string, + date: PropTypes.string, onClose: PropTypes.func }; @@ -43,32 +49,59 @@ class About extends React.Component { }; render() { - return this.props.withButton ? ( - <InfoButton - {...this.props.modalConfig} - image={aboutImg} - title={<Message msgId="about_title"/>} - btnType="image" - className="map-logo" - body={ - <AboutContent/> - }/>) : ( - <Dialog - id="mapstore-about" - style={assign({}, {zIndex: 1992, display: this.props.enabled ? "block" : "none"})} - modal - draggable - > - <span role="header"> - <span className="about-panel-title"> - <Message msgId="about_title"/> + if (this.props.enabled) { + + if (this.props.withButton) { + return ( + <InfoButton + {...this.props.modalConfig} + image={aboutImg} + title={<Message msgId="about_title"/>} + btnType="image" + className="map-logo" + body={<> + <VersionInfo + version={this.props.version} + message={this.props.message} + commit={this.props.commit} + date={this.props.date} + githubUrl={this.props.githubUrl} + /> + <AboutContent/> + </> + } + /> + ); + } + return ( + <Dialog + id="mapstore-about" + style={{zIndex: 1992}} + modal + draggable + > + <span role="header"> + <span className="about-panel-title"> + <Message msgId="about_title"/> + </span> + <button onClick={this.props.onClose} className="about-panel-close close"> + {this.props.modalConfig.closeGlyph ? <Glyphicon glyph={this.props.modalConfig.closeGlyph}/> : <span>×</span>} + </button> </span> - <button onClick={this.props.onClose} className="about-panel-close close"> - {this.props.modalConfig.closeGlyph ? <Glyphicon glyph={this.props.modalConfig.closeGlyph}/> : <span>×</span>} - </button> - </span> - <div role="body"><AboutContent/></div> - </Dialog>); + <div role="body"> + <VersionInfo + version={this.props.version} + message={this.props.message} + commit={this.props.commit} + date={this.props.date} + githubUrl={this.props.githubUrl} + /> + <AboutContent/> + </div> + </Dialog> + ); + } + return null; } } diff --git a/web/client/product/components/viewer/about/VersionInfo.jsx b/web/client/product/components/viewer/about/VersionInfo.jsx new file mode 100644 index 0000000000..4d249beee8 --- /dev/null +++ b/web/client/product/components/viewer/about/VersionInfo.jsx @@ -0,0 +1,79 @@ +/* + * Copyright 2022, 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 PropTypes from 'prop-types'; + +import Message from '../../../../components/I18N/Message'; + +class VersionInfo extends React.Component { + + static propTypes = { + githubUrl: PropTypes.string, + commit: PropTypes.string, + message: PropTypes.string, + date: PropTypes.string, + version: PropTypes.string + } + static defaultProps = { + githubUrl: "", + commit: "", + message: "", + date: "", + version: "" + }; + + render() { + return ( + <div key="body" role="body" className="version-panel"> + <h1><Message msgId="version.title"/></h1> + + <div> + <div className="version-info"> + <div className="info-label"> + <Message msgId="version.label"/> + </div> + <div className="v_version"> + {this.props.version} + </div> + </div> + </div> + <div> + <div className="version-info"> + <div className="info-label"> + <Message msgId="version.message"/> + </div> + <div className="v_message"> + {this.props.message} + </div> + </div> + <div className="version-info"> + <div className="info-label"> + <Message msgId="version.commit"/> + </div> + <div className="v_commit"> + <a href={this.props.githubUrl} target="_blank" className="v_githubUrl"> + {this.props.commit} + </a> + </div> + </div> + <div className="version-info"> + <div className="info-label"> + <Message msgId="version.date"/> + </div> + <div className="v_date"> + {this.props.date} + </div> + </div> + </div> + </div> + ); + } +} + +export default VersionInfo; diff --git a/web/client/product/components/viewer/about/__tests__/VersionInfo-test.js b/web/client/product/components/viewer/about/__tests__/VersionInfo-test.js new file mode 100644 index 0000000000..7049efc96a --- /dev/null +++ b/web/client/product/components/viewer/about/__tests__/VersionInfo-test.js @@ -0,0 +1,70 @@ +/** + * Copyright 2022, 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 expect from 'expect'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import VersionInfo from '../VersionInfo'; + +describe("The VersionInfo component", () => { + beforeEach((done) => { + document.body.innerHTML = '<div id="container"></div>'; + setTimeout(done); + }); + + afterEach((done) => { + ReactDOM.unmountComponentAtNode(document.getElementById("container")); + document.body.innerHTML = ''; + setTimeout(done); + }); + + it('is created with defaults', () => { + const cmp = ReactDOM.render(<VersionInfo/>, document.getElementById("container")); + expect(cmp).toBeTruthy(); + }); + + it('test with version info', () => { + const version = '$MapStore2'; + const message = "#7934 refactor code and resolve eslint error"; + const commit = "01046133761de880aebce08a7bf11dd858117837"; + const date = "Thu, 23 Jun 2022 20:00:02 +0300"; + const githubUrl = "https://github.com/geosolutions-it/MapStore/tree/sha_commit"; + + const vd = ReactDOM.render( + <VersionInfo + version={version} + githubUrl={githubUrl} + commit={commit} + message={message} + date={date} + />, document.getElementById("container")); + expect(vd).toBeTruthy(); + + const versionDialogDOM = ReactDOM.findDOMNode(vd); + expect(versionDialogDOM).toBeTruthy(); + const innerModalDom = versionDialogDOM.children[0]; + expect(innerModalDom).toBeTruthy(); + const innerModalDomBody = innerModalDom.children[0]; + expect(innerModalDomBody).toBeTruthy(); + const infoclass = versionDialogDOM.querySelectorAll('.version-info .info-label'); + expect(infoclass).toBeTruthy(); + + const versionValue = document.querySelector('.v_version'); + const messageValue = document.querySelector('.v_message'); + const commitValue = document.querySelector('.v_commit'); + const dateValue = document.querySelector('.v_date'); + const githubUrlValue = document.querySelector('.v_githubUrl'); + + expect(versionValue.textContent.trim()).toBe(version); + expect(messageValue.textContent.trim()).toBe(message); + expect(commitValue.textContent.trim()).toBe(commit); + expect(commitValue.innerHTML.trim()).toBe('<a href="https://github.com/geosolutions-it/MapStore/tree/sha_commit" target="_blank" class="v_githubUrl">01046133761de880aebce08a7bf11dd858117837</a>'); + expect(dateValue.textContent.trim()).toBe(date); + expect(githubUrlValue.textContent.trim()).toBe(commit); + }); +}); diff --git a/web/client/product/plugins.js b/web/client/product/plugins.js index ce40ba2622..bfcfefd27c 100644 --- a/web/client/product/plugins.js +++ b/web/client/product/plugins.js @@ -126,7 +126,6 @@ export default { UserManagerPlugin: require('../plugins/manager/UserManager').default, UserExtensionsPlugin: require('../plugins/UserExtensions').default, UserSessionPlugin: require('../plugins/UserSession').default, - VersionPlugin: require('../plugins/Version').default, WidgetsBuilderPlugin: require('../plugins/WidgetsBuilder').default, WidgetsPlugin: require('../plugins/Widgets').default, WidgetsTrayPlugin: require('../plugins/WidgetsTray').default, @@ -134,7 +133,6 @@ export default { ZoomInPlugin: require('../plugins/ZoomIn').default, ZoomOutPlugin: require('../plugins/ZoomOut').default, SidebarMenuPlugin: require('../plugins/SidebarMenu').default - }, requires: { ReactSwipe: require('react-swipeable-views').default, diff --git a/web/client/product/plugins/About.jsx b/web/client/product/plugins/About.jsx index 3c15ec337c..0f87af3140 100644 --- a/web/client/product/plugins/About.jsx +++ b/web/client/product/plugins/About.jsx @@ -14,9 +14,23 @@ import { connect } from 'react-redux'; import { toggleControl } from '../../actions/controls'; import Message from '../../components/I18N/Message'; import AboutComp from '../components/viewer/about/About'; +import version from '../../reducers/version'; +import { aboutSelector } from '../../selectors/controls'; +import { + versionSelector, + githubUrlSelector, + commitSelector, + messageSelector, + dateSelector +} from '../../selectors/version'; const About = connect((state) => ({ - enabled: state.controls && state.controls.about && state.controls.about.enabled || false, + version: versionSelector(state), + githubUrl: githubUrlSelector(state), + commit: commitSelector(state), + message: messageSelector(state), + date: dateSelector(state), + enabled: aboutSelector(state), withButton: false }), { onClose: toggleControl.bind(null, 'about', null) @@ -54,5 +68,7 @@ export default { toggle: true } }), - reducers: {} + reducers: { + version + } }; diff --git a/web/client/reducers/version.js b/web/client/reducers/version.js index 024ce2abec..e6ed9a285e 100644 --- a/web/client/reducers/version.js +++ b/web/client/reducers/version.js @@ -8,11 +8,13 @@ import { CHANGE_VERSION, LOAD_VERSION_ERROR } from '../actions/version'; -import assign from 'object-assign'; - /** * Manages the state of the version identifier - * @prop {string} current version identifier + * @prop {string} current mapstore version identifier + * @prop {string} message the commit name + * @prop {string} commit the commit sha + * @prop {string} date the date when the commit has been created + * @prop {string} githubUrl url to use as target for <a> tag inside a button * * @example *{ @@ -20,21 +22,26 @@ import assign from 'object-assign'; *} * @memberof reducers */ -function version(state = null, action) { +const splitData = __COMMIT_DATA__.split('\n'); +function version(state = { + splitData, + message: splitData.find((x)=> x.includes('Message:')).split('Message: ')[1], + commit: splitData.find((x)=> x.includes('Commit:')).split('Commit: ')[1], + date: splitData.find((x)=> x.includes('Date:')).split('Date: ')[1], + githubUrl: "https://github.com/geosolutions-it/MapStore2/tree/" + __COMMITHASH__ +}, action) { switch (action.type) { case CHANGE_VERSION: { - return assign({}, state, - { - current: action.version - } - ); + return { + ...state, + current: action.version + }; } case LOAD_VERSION_ERROR: { - return assign({}, state, - { - current: 'no-version' - } - ); + return { + ...state, + current: 'no-version' + }; } default: return state; diff --git a/web/client/selectors/controls.js b/web/client/selectors/controls.js index 5051a67947..baa111c2eb 100644 --- a/web/client/selectors/controls.js +++ b/web/client/selectors/controls.js @@ -11,6 +11,7 @@ export const createControlVariableSelector = (name, attribute) => state => get(s export const createControlEnabledSelector = name => createControlVariableSelector(name, 'enabled'); +export const aboutSelector = (state) => get(state, "controls.about.enabled", false); /** * selects the showCoordinateEditor flag from state * @memberof selectors.controls diff --git a/web/client/selectors/version.js b/web/client/selectors/version.js index 29e40ceda1..a7b6c6eeae 100644 --- a/web/client/selectors/version.js +++ b/web/client/selectors/version.js @@ -7,4 +7,8 @@ */ export const versionSelector = (state) => state.version && state.version.current || ''; +export const githubUrlSelector = (state) => state.version && state.version.githubUrl || ''; +export const commitSelector = (state) => state.version && state.version.commit || ''; +export const messageSelector = (state) => state.version && state.version.message || ''; +export const dateSelector = (state) => state.version && state.version.date || ''; export const validateVersion = version => version && version.indexOf('${mapstore2.version}') === -1 && version.indexOf('no-version') === -1 ? true : false; diff --git a/web/client/themes/default/less/version.less b/web/client/themes/default/less/version.less index b62900e1ef..09c8fd99b4 100644 --- a/web/client/themes/default/less/version.less +++ b/web/client/themes/default/less/version.less @@ -16,11 +16,22 @@ // Layout // ************** -.application-version-label { - font-weight: bold; +@media only screen and (max-width: 600px) { + #mapstore-about { + width: 100% !important; + left: auto !important; + .version-info { + display: block !important; + } + } } - .version-panel { + margin-top: -30px; + + .application-version-label { + font-weight: bold; + } + .version-info { display: grid; grid-template-columns: 0.5fr 2fr; diff --git a/web/client/translations/data.de-DE.json b/web/client/translations/data.de-DE.json index c7439935ca..fa2faecf11 100644 --- a/web/client/translations/data.de-DE.json +++ b/web/client/translations/data.de-DE.json @@ -35,12 +35,12 @@ }, "expand": "Ausklappen", "version": { - "label": "Version", - "message": "Botschaft", - "commit": "Commit", - "date": "Datum", - "author": "Autor", - "githuburl": "Öffnen Sie den Github-Baum in einem neuen Tab" + "title": "Mapstore Version", + "label": "Version", + "message": "Botschaft", + "commit": "Commit", + "date": "Datum", + "githubUrl": "Öffnen Sie den Github-Baum in einem neuen Tab" }, "errorPage": { "title":"Ups, etwas ist schief gelaufen...", diff --git a/web/client/translations/data.en-US.json b/web/client/translations/data.en-US.json index 2a53f61e00..2871994658 100644 --- a/web/client/translations/data.en-US.json +++ b/web/client/translations/data.en-US.json @@ -35,13 +35,12 @@ "message": "The layer failed to reload with a changed name" }, "version": { - "label": "Version", - "message": "Message", - "commit": "Commit", - "date": "Date", - "author": "Author", - "githuburl": "Open github tree in a new tab" - + "title": "MapStore Version", + "label": "Version", + "message": "Message", + "commit": "Commit", + "date": "Date", + "githubUrl": "Open github tree in a new tab" }, "errorPage": { "title":"Oops, something has gone wrong...", diff --git a/web/client/translations/data.es-ES.json b/web/client/translations/data.es-ES.json index 7c49d15e52..a68f0179ed 100644 --- a/web/client/translations/data.es-ES.json +++ b/web/client/translations/data.es-ES.json @@ -35,12 +35,12 @@ "message": "La capa no se pudo recargar con un nombre cambiado" }, "version": { - "label": "Versión", - "message": "Mensaje", - "commit": "Commit", - "date": "Fecha", - "author": "Autor", - "githuburl": "Abre el árbol de github en una nueva pestaña" + "title": "MapStore Versión", + "label": "Versión", + "message": "Mensaje", + "commit": "Commit", + "date": "Fecha", + "githubUrl": "Abre el árbol de github en una nueva pestaña" }, "errorPage": { "title":"Vaya, algo salió mal...", diff --git a/web/client/translations/data.fr-FR.json b/web/client/translations/data.fr-FR.json index 9dd6e664e9..a4b62b393e 100644 --- a/web/client/translations/data.fr-FR.json +++ b/web/client/translations/data.fr-FR.json @@ -35,12 +35,12 @@ "message": "Échec du rechargement de la couche avec un nom modifié" }, "version": { - "label": "Version", - "message": "Message", - "commit": "Commit", - "date": "Date", - "author": "Auteur", - "githuburl": "Ouvrir l'arborescence github dans un nouvel onglet" + "title": "MapStore Version", + "label": "Version", + "message": "Message", + "commit": "Commit", + "date": "Date", + "githubUrl": "Ouvrir l'arborescence github dans un nouvel onglet" }, "errorPage": { "title":"Oups, quelque chose a mal tourné...", diff --git a/web/client/translations/data.it-IT.json b/web/client/translations/data.it-IT.json index 1a1b7f4d20..8f8eb8acf6 100644 --- a/web/client/translations/data.it-IT.json +++ b/web/client/translations/data.it-IT.json @@ -35,12 +35,12 @@ "message": "Il livello non è stato ricaricato con un nome modificato" }, "version": { - "label": "Versione", - "message": "Testo", - "commit": "Commit", - "date": "Data", - "author": "Autore", - "githuburl": "Apri Github in una nuova scheda" + "title": "Versione di Mapstore", + "label": "Versione", + "message": "Testo", + "commit": "Commit", + "date": "Data", + "githubUrl": "Apri Github in una nuova scheda" }, "errorPage": { "title":"Ops, qualcosa è andato storto...",