mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-18 00:56:02 +00:00
electron menu, about dialog
This commit is contained in:
@@ -63,22 +63,7 @@ function buildMenu() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
commandItem('group.save'),
|
commandItem('group.save'),
|
||||||
// {
|
commandItem('group.saveAs'),
|
||||||
// label: 'Save',
|
|
||||||
// click() {
|
|
||||||
// mainWindow.webContents.executeJavaScript(`dbgate_tabCommand('save')`);
|
|
||||||
// },
|
|
||||||
// accelerator: 'Ctrl+S',
|
|
||||||
// id: 'save',
|
|
||||||
// },
|
|
||||||
{
|
|
||||||
label: 'Save As',
|
|
||||||
click() {
|
|
||||||
mainWindow.webContents.executeJavaScript(`dbgate_tabCommand('saveAs')`);
|
|
||||||
},
|
|
||||||
accelerator: 'Ctrl+Shift+S',
|
|
||||||
id: 'saveAs',
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{ role: 'close' },
|
{ role: 'close' },
|
||||||
],
|
],
|
||||||
@@ -86,19 +71,10 @@ function buildMenu() {
|
|||||||
{
|
{
|
||||||
label: 'Window',
|
label: 'Window',
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
commandItem('new.query'),
|
||||||
label: 'New query',
|
|
||||||
click() {
|
|
||||||
mainWindow.webContents.executeJavaScript(`dbgate_newQuery()`);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
|
||||||
label: 'Close all tabs',
|
commandItem('tabs.closeAll'),
|
||||||
click() {
|
|
||||||
mainWindow.webContents.executeJavaScript('dbgate_closeAll()');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{ role: 'minimize' },
|
{ role: 'minimize' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -155,12 +131,7 @@ function buildMenu() {
|
|||||||
require('electron').shell.openExternal('https://github.com/dbgate/dbgate/issues/new');
|
require('electron').shell.openExternal('https://github.com/dbgate/dbgate/issues/new');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
commandItem('about.show'),
|
||||||
label: 'About',
|
|
||||||
click() {
|
|
||||||
mainWindow.webContents.executeJavaScript(`dbgate_showAbout()`);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import registerCommand from './registerCommand';
|
|||||||
import { derived, get } from 'svelte/store';
|
import { derived, get } from 'svelte/store';
|
||||||
import { ThemeDefinition } from 'dbgate-types';
|
import { ThemeDefinition } from 'dbgate-types';
|
||||||
import ConnectionModal from '../modals/ConnectionModal.svelte';
|
import ConnectionModal from '../modals/ConnectionModal.svelte';
|
||||||
|
import AboutModal from '../modals/AboutModal.svelte';
|
||||||
import { showModal } from '../modals/modalTools';
|
import { showModal } from '../modals/modalTools';
|
||||||
import newQuery from '../query/newQuery';
|
import newQuery from '../query/newQuery';
|
||||||
import saveTabFile from '../utility/saveTabFile';
|
import saveTabFile from '../utility/saveTabFile';
|
||||||
@@ -45,6 +46,14 @@ registerCommand({
|
|||||||
testEnabled: () => getVisibleToolbar(),
|
testEnabled: () => getVisibleToolbar(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerCommand({
|
||||||
|
id: 'about.show',
|
||||||
|
category: 'About',
|
||||||
|
name: 'Show',
|
||||||
|
toolbarName: 'About',
|
||||||
|
onClick: () => showModal(AboutModal),
|
||||||
|
});
|
||||||
|
|
||||||
registerCommand({
|
registerCommand({
|
||||||
id: 'new.connection',
|
id: 'new.connection',
|
||||||
toolbar: true,
|
toolbar: true,
|
||||||
@@ -118,6 +127,15 @@ registerCommand({
|
|||||||
group: 'save',
|
group: 'save',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
registerCommand({
|
||||||
|
id: 'group.saveAs',
|
||||||
|
category: null,
|
||||||
|
isGroupCommand: true,
|
||||||
|
name: 'Save As',
|
||||||
|
keyText: 'Ctrl+Shift+S',
|
||||||
|
group: 'saveAs',
|
||||||
|
});
|
||||||
|
|
||||||
export function registerFileCommands({
|
export function registerFileCommands({
|
||||||
idPrefix,
|
idPrefix,
|
||||||
category,
|
category,
|
||||||
@@ -142,9 +160,9 @@ export function registerFileCommands({
|
|||||||
});
|
});
|
||||||
registerCommand({
|
registerCommand({
|
||||||
id: idPrefix + '.saveAs',
|
id: idPrefix + '.saveAs',
|
||||||
|
group: 'saveAs',
|
||||||
category,
|
category,
|
||||||
name: 'Save As',
|
name: 'Save As',
|
||||||
keyText: 'Ctrl+Shift+S',
|
|
||||||
testEnabled: () => getCurrentEditor() != null,
|
testEnabled: () => getCurrentEditor() != null,
|
||||||
onClick: () => saveTabFile(getCurrentEditor(), true, folder, format, fileExtension),
|
onClick: () => saveTabFile(getCurrentEditor(), true, folder, format, fileExtension),
|
||||||
});
|
});
|
||||||
|
|||||||
28
packages/web/src/elements/Link.svelte
Normal file
28
packages/web/src/elements/Link.svelte
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import getElectron from '../utility/getElectron';
|
||||||
|
|
||||||
|
export let href;
|
||||||
|
|
||||||
|
const electron = getElectron();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#if electron}
|
||||||
|
<a on:click={() => electron.shell.openExternal(href)}>
|
||||||
|
<slot />
|
||||||
|
</a>
|
||||||
|
{:else}
|
||||||
|
<a {href} target="_blank" rel="noopener noreferrer">
|
||||||
|
<slot />
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--theme-font-link);
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
53
packages/web/src/modals/AboutModal.svelte
Normal file
53
packages/web/src/modals/AboutModal.svelte
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import FormStyledButton from '../elements/FormStyledButton.svelte';
|
||||||
|
import { useConfig } from '../utility/metadataLoaders';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
|
import ModalBase from './ModalBase.svelte';
|
||||||
|
import { closeCurrentModal } from './modalTools';
|
||||||
|
import Link from '../elements/Link.svelte';
|
||||||
|
|
||||||
|
const config = useConfig();
|
||||||
|
$: version = $config.version;
|
||||||
|
$: buildTime = $config.buildTime;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<ModalBase {...$$restProps}>
|
||||||
|
<svelte:fragment slot="header">About DbGate</svelte:fragment>
|
||||||
|
<div class="flex">
|
||||||
|
<img src="/logo192.png" />
|
||||||
|
<div>
|
||||||
|
<div class="m-1">
|
||||||
|
Version: <span>{version}</span>
|
||||||
|
</div>
|
||||||
|
<div class="m-1">
|
||||||
|
Build date: <span>{moment(buildTime).format('YYYY-MM-DD')}</span>
|
||||||
|
</div>
|
||||||
|
<div class="m-1">
|
||||||
|
Web: <Link href="https://dbgate.org">dbgate.org</Link>
|
||||||
|
</div>
|
||||||
|
<div class="m-1">
|
||||||
|
Source codes: <Link href="https://github.com/dbgate/dbgate/">github</Link>
|
||||||
|
</div>
|
||||||
|
<div class="m-1">
|
||||||
|
Docker container: <Link href="https://hub.docker.com/r/dbgate/dbgate">docker hub</Link>
|
||||||
|
</div>
|
||||||
|
<div class="m-1">
|
||||||
|
Online demo: <Link href="https://demo.dbgate.org">demo.dbgate.org</Link>
|
||||||
|
</div>
|
||||||
|
<div class="m-1">
|
||||||
|
Search plugins: <Link href="https://www.npmjs.com/search?q=keywords:dbgateplugin">npmjs.com</Link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<svelte:fragment slot="footer">
|
||||||
|
<FormStyledButton value="Close" on:click={closeCurrentModal} />
|
||||||
|
</svelte:fragment>
|
||||||
|
</ModalBase>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
span {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,69 +1,4 @@
|
|||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
function getTabDbName(tab) {
|
|
||||||
if (tab.props && tab.props.conid && tab.props.database) return tab.props.database;
|
|
||||||
if (tab.props && tab.props.archiveFolder) return tab.props.archiveFolder;
|
|
||||||
return '(no DB)';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTabDbKey(tab) {
|
|
||||||
if (tab.props && tab.props.conid && tab.props.database)
|
|
||||||
return `database://${tab.props.database}-${tab.props.conid}`;
|
|
||||||
if (tab.props && tab.props.archiveFolder) return `archive://${tab.props.archiveFolder}`;
|
|
||||||
return '_no';
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDbIcon(key) {
|
|
||||||
if (key.startsWith('database://')) return 'icon database';
|
|
||||||
if (key.startsWith('archive://')) return 'icon archive';
|
|
||||||
return 'icon file';
|
|
||||||
}
|
|
||||||
|
|
||||||
registerCommand({
|
|
||||||
id: 'tabs.nextTab',
|
|
||||||
category: 'Tabs',
|
|
||||||
name: 'Next tab',
|
|
||||||
keyText: 'Ctrl+Tab',
|
|
||||||
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 2,
|
|
||||||
onClick: () => {
|
|
||||||
const tabs = get(openedTabs).filter(x => x.closedTime == null);
|
|
||||||
if (tabs.length >= 2) setSelectedTab(tabs[tabs.length - 2].tabid);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import _ from 'lodash';
|
|
||||||
import { derived, get } from 'svelte/store';
|
|
||||||
import registerCommand from '../commands/registerCommand';
|
|
||||||
import FontIcon from '../icons/FontIcon.svelte';
|
|
||||||
|
|
||||||
import { currentDatabase, getOpenedTabs, openedTabs } from '../stores';
|
|
||||||
import { setSelectedTab } from '../utility/common';
|
|
||||||
import contextMenu from '../utility/contextMenu';
|
|
||||||
|
|
||||||
$: currentDbKey =
|
|
||||||
$currentDatabase && $currentDatabase.name && $currentDatabase.connection
|
|
||||||
? `database://${$currentDatabase.name}-${$currentDatabase.connection._id}`
|
|
||||||
: '_no';
|
|
||||||
|
|
||||||
$: tabsWithDb = $openedTabs
|
|
||||||
.filter(x => !x.closedTime)
|
|
||||||
.map(tab => ({
|
|
||||||
...tab,
|
|
||||||
tabDbName: getTabDbName(tab),
|
|
||||||
tabDbKey: getTabDbKey(tab),
|
|
||||||
}));
|
|
||||||
|
|
||||||
$: tabsByDb = _.groupBy(tabsWithDb, 'tabDbKey');
|
|
||||||
$: dbKeys = _.keys(tabsByDb).sort();
|
|
||||||
|
|
||||||
const handleTabClick = (e, tabid) => {
|
|
||||||
if (e.target.closest('.tabCloseButton')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setSelectedTab(tabid);
|
|
||||||
};
|
|
||||||
|
|
||||||
const closeTabFunc = closeCondition => tabid => {
|
const closeTabFunc = closeCondition => tabid => {
|
||||||
openedTabs.update(files => {
|
openedTabs.update(files => {
|
||||||
const active = files.find(x => x.tabid == tabid);
|
const active = files.find(x => x.tabid == tabid);
|
||||||
@@ -109,6 +44,80 @@
|
|||||||
_.get(x, 'props.database') != _.get(active, 'props.database')
|
_.get(x, 'props.database') != _.get(active, 'props.database')
|
||||||
);
|
);
|
||||||
const closeOthers = closeTabFunc((x, active) => x.tabid != active.tabid);
|
const closeOthers = closeTabFunc((x, active) => x.tabid != active.tabid);
|
||||||
|
|
||||||
|
function getTabDbName(tab) {
|
||||||
|
if (tab.props && tab.props.conid && tab.props.database) return tab.props.database;
|
||||||
|
if (tab.props && tab.props.archiveFolder) return tab.props.archiveFolder;
|
||||||
|
return '(no DB)';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTabDbKey(tab) {
|
||||||
|
if (tab.props && tab.props.conid && tab.props.database)
|
||||||
|
return `database://${tab.props.database}-${tab.props.conid}`;
|
||||||
|
if (tab.props && tab.props.archiveFolder) return `archive://${tab.props.archiveFolder}`;
|
||||||
|
return '_no';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDbIcon(key) {
|
||||||
|
if (key.startsWith('database://')) return 'icon database';
|
||||||
|
if (key.startsWith('archive://')) return 'icon archive';
|
||||||
|
return 'icon file';
|
||||||
|
}
|
||||||
|
|
||||||
|
registerCommand({
|
||||||
|
id: 'tabs.nextTab',
|
||||||
|
category: 'Tabs',
|
||||||
|
name: 'Next tab',
|
||||||
|
keyText: 'Ctrl+Tab',
|
||||||
|
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 2,
|
||||||
|
onClick: () => {
|
||||||
|
const tabs = get(openedTabs).filter(x => x.closedTime == null);
|
||||||
|
if (tabs.length >= 2) setSelectedTab(tabs[tabs.length - 2].tabid);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
registerCommand({
|
||||||
|
id: 'tabs.closeAll',
|
||||||
|
category: 'Tabs',
|
||||||
|
name: 'Close all tabs',
|
||||||
|
testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 1,
|
||||||
|
onClick: closeAll,
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { derived, get } from 'svelte/store';
|
||||||
|
import registerCommand from '../commands/registerCommand';
|
||||||
|
import FontIcon from '../icons/FontIcon.svelte';
|
||||||
|
|
||||||
|
import { currentDatabase, getOpenedTabs, openedTabs } from '../stores';
|
||||||
|
import { setSelectedTab } from '../utility/common';
|
||||||
|
import contextMenu from '../utility/contextMenu';
|
||||||
|
|
||||||
|
$: currentDbKey =
|
||||||
|
$currentDatabase && $currentDatabase.name && $currentDatabase.connection
|
||||||
|
? `database://${$currentDatabase.name}-${$currentDatabase.connection._id}`
|
||||||
|
: '_no';
|
||||||
|
|
||||||
|
$: tabsWithDb = $openedTabs
|
||||||
|
.filter(x => !x.closedTime)
|
||||||
|
.map(tab => ({
|
||||||
|
...tab,
|
||||||
|
tabDbName: getTabDbName(tab),
|
||||||
|
tabDbKey: getTabDbKey(tab),
|
||||||
|
}));
|
||||||
|
|
||||||
|
$: tabsByDb = _.groupBy(tabsWithDb, 'tabDbKey');
|
||||||
|
$: dbKeys = _.keys(tabsByDb).sort();
|
||||||
|
|
||||||
|
const handleTabClick = (e, tabid) => {
|
||||||
|
if (e.target.closest('.tabCloseButton')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setSelectedTab(tabid);
|
||||||
|
};
|
||||||
|
|
||||||
const handleMouseUp = (e, tabid) => {
|
const handleMouseUp = (e, tabid) => {
|
||||||
if (e.button == 1) {
|
if (e.button == 1) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|||||||
Reference in New Issue
Block a user