diff --git a/packages/web/src/commands/CommandPalette.svelte b/packages/web/src/commands/CommandPalette.svelte index e0ee22d85..3aefd5b6a 100644 --- a/packages/web/src/commands/CommandPalette.svelte +++ b/packages/web/src/commands/CommandPalette.svelte @@ -10,7 +10,7 @@ showDisabled: true, icon: 'icon menu', onClick: () => visibleCommandPalette.set(true), - enabledStore: derived(visibleCommandPalette, $visibleCommandPalette => !$visibleCommandPalette), + testEnabled: () => !getVisibleCommandPalette(), }); @@ -20,7 +20,7 @@ import _ from 'lodash'; import { derived } from 'svelte/store'; import { onMount } from 'svelte'; - import { commands, visibleCommandPalette } from '../stores'; + import { commands, getVisibleCommandPalette, visibleCommandPalette } from '../stores'; import clickOutside from '../utility/clickOutside'; import keycodes from '../utility/keycodes'; import registerCommand from './registerCommand'; diff --git a/packages/web/src/commands/invalidateCommands.ts b/packages/web/src/commands/invalidateCommands.ts new file mode 100644 index 000000000..c7446213f --- /dev/null +++ b/packages/web/src/commands/invalidateCommands.ts @@ -0,0 +1,30 @@ +import { tick } from 'svelte'; +import { commands } from '../stores'; + +let isInvalidated = false; + +export default async function invalidateCommands() { + if (isInvalidated) return; + isInvalidated = true; + await tick(); + + isInvalidated = false; + + commands.update(dct => { + let res = null; + for (const key of Object.keys(dct)) { + const command = dct[key]; + const { testEnabled } = command; + let enabled = command.enabled; + if (testEnabled) enabled = testEnabled(); + if (enabled != command.enabled) { + if (!res) res = { ...dct }; + res[key] = { + ...command, + enabled, + }; + } + } + return res || dct; + }); +} diff --git a/packages/web/src/commands/registerCommand.ts b/packages/web/src/commands/registerCommand.ts index 26547034c..0669ed9e1 100644 --- a/packages/web/src/commands/registerCommand.ts +++ b/packages/web/src/commands/registerCommand.ts @@ -13,7 +13,8 @@ export interface GlobalCommand { keyText?: string; getSubCommands?: () => SubCommand[]; onClick?: Function; - enabledStore?: any; + testEnabled?: () => boolean; + // enabledStore?: any; icon?: string; toolbar?: boolean; enabled?: boolean; @@ -24,24 +25,24 @@ export interface GlobalCommand { } export default function registerCommand(command: GlobalCommand) { - const { enabledStore } = command; + const { testEnabled } = command; commands.update(x => ({ ...x, [command.id]: { text: `${command.category}: ${command.name}`, ...command, - enabled: !enabledStore, + enabled: !testEnabled, }, })); - if (enabledStore) { - enabledStore.subscribe(value => { - commands.update(x => ({ - ...x, - [command.id]: { - ...x[command.id], - enabled: value, - }, - })); - }); - } + // if (enabledStore) { + // enabledStore.subscribe(value => { + // commands.update(x => ({ + // ...x, + // [command.id]: { + // ...x[command.id], + // enabled: value, + // }, + // })); + // }); + // } } diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index b7c781bdb..ddaeceb6d 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -1,4 +1,4 @@ -import { currentTheme, extensions, visibleToolbar } from '../stores'; +import { currentTheme, extensions, getVisibleToolbar, visibleToolbar } from '../stores'; import registerCommand from './registerCommand'; import { derived, get } from 'svelte/store'; import { ThemeDefinition } from 'dbgate-types'; @@ -34,7 +34,7 @@ registerCommand({ category: 'Toolbar', name: 'Show', onClick: () => visibleToolbar.set(1), - enabledStore: derived(visibleToolbar, $visibleToolbar => !$visibleToolbar), + testEnabled: () => !getVisibleToolbar(), }); registerCommand({ @@ -42,7 +42,7 @@ registerCommand({ category: 'Toolbar', name: 'Hide', onClick: () => visibleToolbar.set(0), - enabledStore: derived(visibleToolbar, $visibleToolbar => $visibleToolbar), + testEnabled: () => getVisibleToolbar(), }); registerCommand({ @@ -112,8 +112,7 @@ registerCommand({ export function registerFileCommands({ idPrefix, category, - editorStore, - editorStatusStore = undefined, + getCurrentEditor, folder, format, fileExtension, @@ -128,16 +127,16 @@ export function registerFileCommands({ keyText: 'Ctrl+S', icon: 'icon save', toolbar: true, - enabledStore: saveTabEnabledStore(editorStore), - onClick: () => saveTabFile(editorStore, false, folder, format, fileExtension), + testEnabled: () => getCurrentEditor() != null, + onClick: () => saveTabFile(getCurrentEditor(), false, folder, format, fileExtension), }); registerCommand({ id: idPrefix + '.saveAs', category, name: 'Save As', keyText: 'Ctrl+Shift+S', - enabledStore: saveTabEnabledStore(editorStore), - onClick: () => saveTabFile(editorStore, true, folder, format, fileExtension), + testEnabled: () => getCurrentEditor() != null, + onClick: () => saveTabFile(getCurrentEditor(), true, folder, format, fileExtension), }); if (execute) { @@ -148,11 +147,8 @@ export function registerFileCommands({ icon: 'icon run', toolbar: true, keyText: 'F5 | Ctrl+Enter', - enabledStore: derived( - [editorStore, editorStatusStore], - ([editor, status]) => editor != null && !(status as any).busy - ), - onClick: () => (get(editorStore) as any).execute(), + testEnabled: () => getCurrentEditor() != null && !getCurrentEditor()?.isBusy(), + onClick: () => getCurrentEditor().execute(), }); registerCommand({ id: idPrefix + '.kill', @@ -160,11 +156,8 @@ export function registerFileCommands({ name: 'Kill', icon: 'icon close', toolbar: true, - enabledStore: derived( - [editorStore, editorStatusStore], - ([query, status]) => query != null && status && (status as any).canKill - ), - onClick: () => (get(editorStore) as any).kill(), + testEnabled: () => getCurrentEditor() != null && getCurrentEditor()?.canKill(), + onClick: () => getCurrentEditor().kill(), }); } @@ -175,8 +168,8 @@ export function registerFileCommands({ name: 'Toggle comment', keyText: 'Ctrl+/', disableHandleKeyText: 'Ctrl+/', - enabledStore: derived(editorStore, query => query != null), - onClick: () => (get(editorStore) as any).toggleComment(), + testEnabled: () => getCurrentEditor() != null, + onClick: () => getCurrentEditor().toggleComment(), }); } @@ -186,16 +179,16 @@ export function registerFileCommands({ category, name: 'Find', keyText: 'Ctrl+F', - enabledStore: derived(editorStore, query => query != null), - onClick: () => (get(editorStore) as any).find(), + testEnabled: () => getCurrentEditor() != null, + onClick: () => getCurrentEditor().find(), }); registerCommand({ id: idPrefix + '.replace', category, keyText: 'Ctrl+H', name: 'Replace', - enabledStore: derived(editorStore, query => query != null), - onClick: () => (get(editorStore) as any).replace(), + testEnabled: () => getCurrentEditor() != null, + onClick: () => getCurrentEditor().replace(), }); } } diff --git a/packages/web/src/datagrid/DataGridCore.svelte b/packages/web/src/datagrid/DataGridCore.svelte index 2f1c15073..4b6e8664c 100644 --- a/packages/web/src/datagrid/DataGridCore.svelte +++ b/packages/web/src/datagrid/DataGridCore.svelte @@ -1,10 +1,7 @@ @@ -39,11 +38,12 @@ import AceEditor from '../query/AceEditor.svelte'; import RunnerOutputPane from '../query/RunnerOutputPane.svelte'; import useEditorData from '../query/useEditorData'; - import { activeTabId, nullStore } from '../stores'; + import { activeTabId, getActiveTabId, nullStore } from '../stores'; import axiosInstance from '../utility/axiosInstance'; import memberStore from '../utility/memberStore'; import socket from '../utility/socket'; import useEffect from '../utility/useEffect'; +import invalidateCommands from '../commands/invalidateCommands'; export let tabid; @@ -100,7 +100,10 @@ value={$editorState.value || ''} menu={createMenu()} on:input={e => setEditorData(e.detail)} - on:focus={() => lastFocusedEditor.set(instance)} + on:focus={() => { + lastFocusedEditor = instance; + invalidateCommands(); + }} bind:this={domEditor} mode="markdown" /> diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte index 060df8848..dcf62f99d 100644 --- a/packages/web/src/tabs/QueryTab.svelte +++ b/packages/web/src/tabs/QueryTab.svelte @@ -1,22 +1,19 @@ editor != null); -} +// export function saveTabEnabledStore(editorStore) { +// return derived(editorStore, editor => editor != null); +// } -export default function saveTabFile(editorStore, saveAs, folder, format, fileExtension) { - const editor: any = get(editorStore); +export default function saveTabFile(editor, saveAs, folder, format, fileExtension) { const tabs = get(openedTabs); const tabid = editor.getTabId(); const data = editor.getData(); diff --git a/packages/web/src/widgets/TabsPanel.svelte b/packages/web/src/widgets/TabsPanel.svelte index d43e40cf0..326e6f73e 100644 --- a/packages/web/src/widgets/TabsPanel.svelte +++ b/packages/web/src/widgets/TabsPanel.svelte @@ -23,7 +23,7 @@ category: 'Tabs', name: 'Next tab', keyText: 'Ctrl+Tab', - enabledStore: derived(openedTabs, tabs => tabs.filter(x => !x.closedTime).length >= 2), + 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); @@ -37,7 +37,7 @@ import registerCommand from '../commands/registerCommand'; import FontIcon from '../icons/FontIcon.svelte'; - import { currentDatabase, openedTabs } from '../stores'; + import { currentDatabase, getOpenedTabs, openedTabs } from '../stores'; import { setSelectedTab } from '../utility/common'; import contextMenu from '../utility/contextMenu';