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);