diff --git a/.github/workflows/build-app.yaml b/.github/workflows/build-app.yaml index e1f0bba23..5bcaa8f77 100644 --- a/.github/workflows/build-app.yaml +++ b/.github/workflows/build-app.yaml @@ -33,6 +33,9 @@ jobs: - name: yarn install run: | yarn install + - name: setCurrentVersion + run: | + yarn setCurrentVersion - name: Publish run: | yarn run build:app diff --git a/.github/workflows/build-docker.yaml b/.github/workflows/build-docker.yaml index 5c56e3dc3..144ddb7ce 100644 --- a/.github/workflows/build-docker.yaml +++ b/.github/workflows/build-docker.yaml @@ -37,6 +37,9 @@ jobs: - name: yarn install run: | yarn install + - name: setCurrentVersion + run: | + yarn setCurrentVersion - name: Prepare docker image run: | yarn run prepare:docker diff --git a/app/src/electron.js b/app/src/electron.js index 45eec1844..6ca43ff11 100644 --- a/app/src/electron.js +++ b/app/src/electron.js @@ -99,6 +99,12 @@ function buildMenu() { require('electron').shell.openExternal('https://hub.docker.com/r/dbgate/dbgate'); }, }, + { + label: 'About', + click() { + mainWindow.webContents.executeJavaScript(`dbgate_showAbout()`); + }, + }, ], }, ]; diff --git a/package.json b/package.json index 77ea51284..e5c357b09 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "build:web:docker": "yarn workspace dbgate-web build:docker", "build:app:local": "cd app && yarn build:local", "start:app:local": "cd app && yarn start:local", + "setCurrentVersion": "node setCurrentVersion", "copy:docker:build": "copyfiles packages/api/dist/* docker -f && copyfiles packages/web/build/* docker -u 2 && copyfiles \"packages/web/build/**/*\" docker -u 2", "prepare:docker": "yarn build:web:docker && yarn build:api && yarn copy:docker:build", diff --git a/packages/api/src/controllers/config.js b/packages/api/src/controllers/config.js index 8110677ba..884cdf6b8 100644 --- a/packages/api/src/controllers/config.js +++ b/packages/api/src/controllers/config.js @@ -1,3 +1,5 @@ +const currentVersion = require('../currentVersion'); + module.exports = { get_meta: 'get', async get() { @@ -26,6 +28,7 @@ module.exports = { startupPages, singleDatabase, permissions, + ...currentVersion, }; }, }; diff --git a/packages/api/src/currentVersion.js b/packages/api/src/currentVersion.js new file mode 100644 index 000000000..2736eb1c7 --- /dev/null +++ b/packages/api/src/currentVersion.js @@ -0,0 +1,5 @@ + +module.exports = { + version: '3.8.6', + buildTime: '2020-12-10T11:14:01.053Z' +}; diff --git a/packages/web/src/modals/AboutModal.js b/packages/web/src/modals/AboutModal.js new file mode 100644 index 000000000..e33d3e480 --- /dev/null +++ b/packages/web/src/modals/AboutModal.js @@ -0,0 +1,95 @@ +import React from 'react'; +import ModalBase from './ModalBase'; +import ModalHeader from './ModalHeader'; +import ModalContent from './ModalContent'; +import ModalFooter from './ModalFooter'; +import { useConfig } from '../utility/metadataLoaders'; +import FormStyledButton from '../widgets/FormStyledButton'; +import moment from 'moment'; +import styled from 'styled-components'; +import getElectron from '../utility/getElectron'; +import useTheme from '../theme/useTheme'; + +const Container = styled.div` + display: flex; +`; + +const TextContainer = styled.div``; + +const StyledLine = styled.div` + margin: 5px; +`; + +const StyledValue = styled.span` + font-weight: bold; +`; + +const StyledLink = styled.a` + text-decoration: none; + cursor: pointer; + color: ${(props) => props.theme.main_background_blue[7]}; +`; + +function Line({ label, children }) { + return ( + + {label}: {children} + + ); +} + +function Link({ label, children, href }) { + const electron = getElectron(); + const theme = useTheme(); + return ( + + {label}:{' '} + {electron ? ( + electron.shell.openExternal(href)}> + {children} + + ) : ( + + {children} + + )} + + ); +} + +export default function AboutModal({ modalState }) { + const config = useConfig(); + const { version, buildTime } = config || {}; + return ( + + About DbGate + + + + + {version} + {moment(buildTime).format('YYYY-MM-DD')} + + dbgate.org + + + github + + + docker hub + + + demo.dbgate.org + + + npmjs.com + + + + + + modalState.close()} /> + + + ); +} diff --git a/packages/web/src/widgets/Toolbar.js b/packages/web/src/widgets/Toolbar.js index 0c3aade65..fbd67750a 100644 --- a/packages/web/src/widgets/Toolbar.js +++ b/packages/web/src/widgets/Toolbar.js @@ -2,7 +2,7 @@ import React from 'react'; import useModalState from '../modals/useModalState'; import ConnectionModal from '../modals/ConnectionModal'; import styled from 'styled-components'; -import ToolbarButton from './ToolbarButton'; +import ToolbarButton, { ToolbarButtonExternalImage } from './ToolbarButton'; import useNewQuery from '../query/useNewQuery'; import { useConfig } from '../utility/metadataLoaders'; import { useSetOpenedTabs, useOpenedTabs, useCurrentTheme, useSetCurrentTheme } from '../utility/globalState'; @@ -12,6 +12,8 @@ import ImportExportModal from '../modals/ImportExportModal'; import useShowModal from '../modals/showModal'; import useExtensions from '../utility/useExtensions'; import { getDefaultFileFormat } from '../utility/fileformats'; +import getElectron from '../utility/getElectron'; +import AboutModal from '../modals/AboutModal'; const ToolbarContainer = styled.div` display: flex; @@ -30,13 +32,19 @@ export default function ToolBar({ toolbarPortalRef }) { const currentTheme = useCurrentTheme(); const setCurrentTheme = useSetCurrentTheme(); const extensions = useExtensions(); + const electron = getElectron(); React.useEffect(() => { window['dbgate_createNewConnection'] = modalState.open; window['dbgate_newQuery'] = newQuery; window['dbgate_closeAll'] = () => setOpenedTabs([]); + window['dbgate_showAbout'] = showAbout; }); + const showAbout = () => { + showModal((modalState) => ); + }; + const showImport = () => { showModal((modalState) => ( + {!electron && } {toolbar.map((button) => ( openTabFromButton(button)} icon={button.icon}> {button.title} diff --git a/packages/web/src/widgets/ToolbarButton.js b/packages/web/src/widgets/ToolbarButton.js index ff54f12a6..bbaf16396 100644 --- a/packages/web/src/widgets/ToolbarButton.js +++ b/packages/web/src/widgets/ToolbarButton.js @@ -44,6 +44,11 @@ const ButtonDivInner = styled.div` white-space: nowrap; `; +const ButtonExternalImage = styled.img` + width: 20px; + height: 20px; +`; + export default function ToolbarButton({ children, onClick, icon = undefined, disabled = undefined, patchY = 2 }) { const theme = useTheme(); return ( @@ -65,3 +70,18 @@ export default function ToolbarButton({ children, onClick, icon = undefined, dis ); } + +export function ToolbarButtonExternalImage({ image, onClick, disabled = undefined }) { + const theme = useTheme(); + return ( + { + if (!disabled && onClick) onClick(); + }} + disabled={disabled} + > + + + ); +} diff --git a/setCurrentVersion.js b/setCurrentVersion.js new file mode 100644 index 000000000..65cebbd5a --- /dev/null +++ b/setCurrentVersion.js @@ -0,0 +1,12 @@ +const fs = require('fs'); +const packageJson = fs.readFileSync('app/package.json', { encoding: 'utf-8' }); +const json = JSON.parse(packageJson); + +const text = ` +module.exports = { + version: '${json.version}', + buildTime: '${new Date().toISOString()}' +}; +`; + +fs.writeFileSync('packages/api/src/currentVersion.js', text);