diff --git a/app/package.json b/app/package.json
index af5a3edc..77566f39 100644
--- a/app/package.json
+++ b/app/package.json
@@ -7,6 +7,7 @@
"dependencies": {
"electron-log": "^4.4.1",
"electron-updater": "^4.6.1",
+ "lodash.clonedeepwith": "^4.5.0",
"patch-package": "^6.4.7"
},
"repository": {
diff --git a/app/src/electron.js b/app/src/electron.js
index 553f4bc4..8ab81405 100644
--- a/app/src/electron.js
+++ b/app/src/electron.js
@@ -4,6 +4,7 @@ const fs = require('fs');
const { Menu, ipcMain } = require('electron');
const { autoUpdater } = require('electron-updater');
const log = require('electron-log');
+const _cloneDeepWith = require('lodash.clonedeepwith');
// Module to control application life.
const app = electron.app;
@@ -12,6 +13,7 @@ const BrowserWindow = electron.BrowserWindow;
const path = require('path');
const url = require('url');
+const mainMenuDefinition = require('./mainMenuDefinition');
let isNativeMenu = true;
@@ -53,96 +55,105 @@ function commandItem(id) {
}
function buildMenu() {
- const template = [
- {
- label: 'File',
- submenu: [
- commandItem('new.connection'),
- commandItem('new.sqliteDatabase'),
- commandItem('new.modelCompare'),
- commandItem('new.freetable'),
- { type: 'separator' },
- commandItem('file.open'),
- commandItem('file.openArchive'),
- { type: 'separator' },
- commandItem('group.save'),
- commandItem('group.saveAs'),
- commandItem('database.search'),
- { type: 'separator' },
- commandItem('tabs.closeTab'),
- commandItem('file.exit'),
- ],
- },
- {
- label: 'Window',
- submenu: [commandItem('new.query'), { type: 'separator' }, commandItem('tabs.closeAll'), { role: 'minimize' }],
- },
+ const template = _cloneDeepWith(mainMenuDefinition, item => {
+ if (item.divider) {
+ return { type: 'separator' };
+ }
- // {
- // label: 'Edit',
- // submenu: [
- // { role: 'undo' },
- // { role: 'redo' },
- // { type: 'separator' },
- // { role: 'cut' },
- // { role: 'copy' },
- // { role: 'paste' },
- // ],
- // },
- {
- label: 'View',
- submenu: [
- { role: 'reload' },
- { role: 'forcereload' },
- { role: 'toggledevtools' },
- { type: 'separator' },
- { role: 'resetzoom' },
- { role: 'zoomin' },
- { role: 'zoomout' },
- { type: 'separator' },
- { role: 'togglefullscreen' },
- commandItem('theme.changeTheme'),
- ],
- },
- {
- role: 'help',
- submenu: [
- {
- label: 'Documentation',
- click() {
- electron.shell.openExternal('https://github.com/dbgate/dbgate/wiki');
- },
- },
- {
- label: 'DbGate web',
- click() {
- electron.shell.openExternal('https://dbgate.org');
- },
- },
- {
- label: 'Report problem or feature request',
- click() {
- electron.shell.openExternal('https://github.com/dbgate/dbgate/issues/new');
- },
- },
- {
- label: 'Become sponsor',
- click() {
- electron.shell.openExternal('https://opencollective.com/dbgate');
- },
- },
- // {
- // label: 'Discussions',
- // click() {
- // electron.shell.openExternal('https://github.com/dbgate/dbgate/discussions');
- // },
- // },
- { type: 'separator' },
- commandItem('tabs.changelog'),
- commandItem('about.show'),
- ],
- },
- ];
+ if (item.command) {
+ return commandItem(item.command);
+ }
+ });
+ // const template = [
+ // {
+ // label: 'File',
+ // submenu: [
+ // commandItem('new.connection'),
+ // commandItem('new.sqliteDatabase'),
+ // commandItem('new.modelCompare'),
+ // commandItem('new.freetable'),
+ // { type: 'separator' },
+ // commandItem('file.open'),
+ // commandItem('file.openArchive'),
+ // { type: 'separator' },
+ // commandItem('group.save'),
+ // commandItem('group.saveAs'),
+ // commandItem('database.search'),
+ // { type: 'separator' },
+ // commandItem('tabs.closeTab'),
+ // commandItem('file.exit'),
+ // ],
+ // },
+ // {
+ // label: 'Window',
+ // submenu: [commandItem('new.query'), { type: 'separator' }, commandItem('tabs.closeAll'), { role: 'minimize' }],
+ // },
+
+ // // {
+ // // label: 'Edit',
+ // // submenu: [
+ // // { role: 'undo' },
+ // // { role: 'redo' },
+ // // { type: 'separator' },
+ // // { role: 'cut' },
+ // // { role: 'copy' },
+ // // { role: 'paste' },
+ // // ],
+ // // },
+ // {
+ // label: 'View',
+ // submenu: [
+ // { role: 'reload' },
+ // { role: 'forcereload' },
+ // { role: 'toggledevtools' },
+ // { type: 'separator' },
+ // { role: 'resetzoom' },
+ // { role: 'zoomin' },
+ // { role: 'zoomout' },
+ // { type: 'separator' },
+ // { role: 'togglefullscreen' },
+ // commandItem('theme.changeTheme'),
+ // ],
+ // },
+ // {
+ // role: 'help',
+ // submenu: [
+ // {
+ // label: 'Documentation',
+ // click() {
+ // electron.shell.openExternal('https://github.com/dbgate/dbgate/wiki');
+ // },
+ // },
+ // {
+ // label: 'DbGate web',
+ // click() {
+ // electron.shell.openExternal('https://dbgate.org');
+ // },
+ // },
+ // {
+ // label: 'Report problem or feature request',
+ // click() {
+ // electron.shell.openExternal('https://github.com/dbgate/dbgate/issues/new');
+ // },
+ // },
+ // {
+ // label: 'Become sponsor',
+ // click() {
+ // electron.shell.openExternal('https://opencollective.com/dbgate');
+ // },
+ // },
+ // // {
+ // // label: 'Discussions',
+ // // click() {
+ // // electron.shell.openExternal('https://github.com/dbgate/dbgate/discussions');
+ // // },
+ // // },
+ // { type: 'separator' },
+ // commandItem('tabs.changelog'),
+ // commandItem('about.show'),
+ // ],
+ // },
+ // ];
return Menu.buildFromTemplate(template);
}
@@ -170,6 +181,9 @@ ipcMain.on('close-window', async (event, arg) => {
ipcMain.on('set-title', async (event, arg) => {
mainWindow.setTitle(arg);
});
+ipcMain.on('open-link', async (event, arg) => {
+ electron.shell.openExternal(arg);
+});
ipcMain.on('window-action', async (event, arg) => {
switch (arg) {
case 'minimize':
@@ -185,6 +199,15 @@ ipcMain.on('window-action', async (event, arg) => {
case 'close':
mainWindow.close();
break;
+ case 'fullscreen':
+ mainWindow.setFullScreen(!mainWindow.isFullScreen());
+ break;
+ case 'devtools':
+ mainWindow.webContents.toggleDevTools();
+ break;
+ case 'reload':
+ mainWindow.webContents.reloadIgnoringCache();
+ break;
}
mainWindow.setTitle(arg);
});
@@ -212,6 +235,7 @@ function createWindow() {
isNativeMenu = os.platform() == 'darwin' ? true : false;
if (initialConfig['menuStyle'] == 'native') isNativeMenu = true;
if (initialConfig['menuStyle'] == 'client') isNativeMenu = false;
+ isNativeMenu = true;
mainWindow = new BrowserWindow({
width: 1200,
diff --git a/app/src/mainMenuDefinition.js b/app/src/mainMenuDefinition.js
new file mode 100644
index 00000000..702bd008
--- /dev/null
+++ b/app/src/mainMenuDefinition.js
@@ -0,0 +1,64 @@
+module.exports = [
+ {
+ label: 'File',
+ submenu: [
+ { command: 'new.connection' },
+ { command: 'new.sqliteDatabase' },
+ { divider: true },
+ { command: 'file.open' },
+ { command: 'file.openArchive' },
+ { divider: true },
+ { command: 'group.save' },
+ { command: 'group.saveAs' },
+ { command: 'database.search' },
+ { divider: true },
+
+ { command: 'file.exit' },
+ ],
+ },
+ {
+ label: 'Window',
+ submenu: [
+ { command: 'new.query' },
+ { command: 'new.modelCompare' },
+ { command: 'new.freetable' },
+ { divider: true },
+ { command: 'tabs.closeTab' },
+ { command: 'tabs.closeAll' },
+ ],
+ },
+
+ // {
+ // label: 'Edit',
+ // submenu: [
+ // { role: 'undo' },
+ // { role: 'redo' },
+ // { type: 'separator' },
+ // { role: 'cut' },
+ // { role: 'copy' },
+ // { role: 'paste' },
+ // ],
+ // },
+ {
+ label: 'View',
+ submenu: [
+ { command: 'app.reload' },
+ { command: 'app.toggleDevTools' },
+ { command: 'app.toggleFullScreen' },
+ { command: 'app.minimize' },
+ { command: 'theme.changeTheme' },
+ ],
+ },
+ {
+ label: 'help',
+ submenu: [
+ { command: 'app.openDocs' },
+ { command: 'app.openWeb' },
+ { command: 'app.openIssue' },
+ { command: 'app.openSponsoring' },
+ { divider: true },
+ { command: 'tabs.changelog' },
+ { command: 'about.show' },
+ ],
+ },
+];
diff --git a/app/yarn.lock b/app/yarn.lock
index c7ca69a6..70eeb989 100644
--- a/app/yarn.lock
+++ b/app/yarn.lock
@@ -1455,6 +1455,11 @@ lazy-val@^1.0.4, lazy-val@^1.0.5:
resolved "https://registry.yarnpkg.com/lazy-val/-/lazy-val-1.0.5.tgz#6cf3b9f5bc31cee7ee3e369c0832b7583dcd923d"
integrity sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==
+lodash.clonedeepwith@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4"
+ integrity sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ=
+
lodash.escaperegexp@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz#64762c48618082518ac3df4ccf5d5886dae20347"
diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts
index e855e3b4..fdfb2c34 100644
--- a/packages/web/src/commands/stdCommands.ts
+++ b/packages/web/src/commands/stdCommands.ts
@@ -26,6 +26,7 @@ import { removeLocalStorage } from '../utility/storageCache';
import { showSnackbarSuccess } from '../utility/snackbar';
import { apiCall } from '../utility/api';
import runCommand from './runCommand';
+import { openWebLink } from '../utility/exportElectronFile';
function themeCommand(theme: ThemeDefinition) {
return {
@@ -552,6 +553,66 @@ export function registerFileCommands({
}
}
+registerCommand({
+ id: 'app.minimize',
+ category: 'Application',
+ name: 'Minimize',
+ testEnabled: () => getElectron() != null,
+ onClick: () => getElectron().send('window-action', 'minimize'),
+});
+
+registerCommand({
+ id: 'app.toggleFullScreen',
+ category: 'Application',
+ name: 'Toggle full screen',
+ testEnabled: () => getElectron() != null,
+ onClick: () => getElectron().send('window-action', 'fullscreen'),
+});
+
+registerCommand({
+ id: 'app.toggleDevTools',
+ category: 'Application',
+ name: 'Toggle Dev Tools',
+ testEnabled: () => getElectron() != null,
+ onClick: () => getElectron().send('window-action', 'devtools'),
+});
+
+registerCommand({
+ id: 'app.reload',
+ category: 'Application',
+ name: 'Reload',
+ testEnabled: () => getElectron() != null,
+ onClick: () => getElectron().send('window-action', 'reload'),
+});
+
+registerCommand({
+ id: 'app.openDocs',
+ category: 'Application',
+ name: 'Documentation',
+ onClick: () => openWebLink('https://github.com/dbgate/dbgate/wiki'),
+});
+
+registerCommand({
+ id: 'app.openWeb',
+ category: 'Application',
+ name: 'DbGate web',
+ onClick: () => openWebLink('https://dbgate.org'),
+});
+
+registerCommand({
+ id: 'app.openIssue',
+ category: 'Application',
+ name: 'Report problem or feature request',
+ onClick: () => openWebLink('https://github.com/dbgate/dbgate/issues/new'),
+});
+
+registerCommand({
+ id: 'app.openSponsoring',
+ category: 'Application',
+ name: 'Become sponsor',
+ onClick: () => openWebLink('https://opencollective.com/dbgate'),
+});
+
const electron = getElectron();
if (electron) {
electron.addEventListener('run-command', (e, commandId) => runCommand(commandId));
diff --git a/packages/web/src/elements/Link.svelte b/packages/web/src/elements/Link.svelte
index a1792029..b3ce281c 100644
--- a/packages/web/src/elements/Link.svelte
+++ b/packages/web/src/elements/Link.svelte
@@ -1,25 +1,18 @@
-{#if onClick}
-
-
-
-{:else if electron}
- electron.shell.openExternal(href)}>
-
-
-{:else}
-
-
-
-{/if}
+ {
+ if (onClick) onClick();
+ else openWebLink(href);
+ }}
+>
+
+