command enabling refactor

This commit is contained in:
Jan Prochazka
2021-03-15 19:33:37 +01:00
parent dfa8ca6797
commit 3b3e81e3f7
13 changed files with 207 additions and 140 deletions

View File

@@ -10,7 +10,7 @@
showDisabled: true, showDisabled: true,
icon: 'icon menu', icon: 'icon menu',
onClick: () => visibleCommandPalette.set(true), onClick: () => visibleCommandPalette.set(true),
enabledStore: derived(visibleCommandPalette, $visibleCommandPalette => !$visibleCommandPalette), testEnabled: () => !getVisibleCommandPalette(),
}); });
</script> </script>
@@ -20,7 +20,7 @@
import _ from 'lodash'; import _ from 'lodash';
import { derived } from 'svelte/store'; import { derived } from 'svelte/store';
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import { commands, visibleCommandPalette } from '../stores'; import { commands, getVisibleCommandPalette, visibleCommandPalette } from '../stores';
import clickOutside from '../utility/clickOutside'; import clickOutside from '../utility/clickOutside';
import keycodes from '../utility/keycodes'; import keycodes from '../utility/keycodes';
import registerCommand from './registerCommand'; import registerCommand from './registerCommand';

View File

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

View File

@@ -13,7 +13,8 @@ export interface GlobalCommand {
keyText?: string; keyText?: string;
getSubCommands?: () => SubCommand[]; getSubCommands?: () => SubCommand[];
onClick?: Function; onClick?: Function;
enabledStore?: any; testEnabled?: () => boolean;
// enabledStore?: any;
icon?: string; icon?: string;
toolbar?: boolean; toolbar?: boolean;
enabled?: boolean; enabled?: boolean;
@@ -24,24 +25,24 @@ export interface GlobalCommand {
} }
export default function registerCommand(command: GlobalCommand) { export default function registerCommand(command: GlobalCommand) {
const { enabledStore } = command; const { testEnabled } = command;
commands.update(x => ({ commands.update(x => ({
...x, ...x,
[command.id]: { [command.id]: {
text: `${command.category}: ${command.name}`, text: `${command.category}: ${command.name}`,
...command, ...command,
enabled: !enabledStore, enabled: !testEnabled,
}, },
})); }));
if (enabledStore) { // if (enabledStore) {
enabledStore.subscribe(value => { // enabledStore.subscribe(value => {
commands.update(x => ({ // commands.update(x => ({
...x, // ...x,
[command.id]: { // [command.id]: {
...x[command.id], // ...x[command.id],
enabled: value, // enabled: value,
}, // },
})); // }));
}); // });
} // }
} }

View File

@@ -1,4 +1,4 @@
import { currentTheme, extensions, visibleToolbar } from '../stores'; import { currentTheme, extensions, getVisibleToolbar, visibleToolbar } from '../stores';
import registerCommand from './registerCommand'; 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';
@@ -34,7 +34,7 @@ registerCommand({
category: 'Toolbar', category: 'Toolbar',
name: 'Show', name: 'Show',
onClick: () => visibleToolbar.set(1), onClick: () => visibleToolbar.set(1),
enabledStore: derived(visibleToolbar, $visibleToolbar => !$visibleToolbar), testEnabled: () => !getVisibleToolbar(),
}); });
registerCommand({ registerCommand({
@@ -42,7 +42,7 @@ registerCommand({
category: 'Toolbar', category: 'Toolbar',
name: 'Hide', name: 'Hide',
onClick: () => visibleToolbar.set(0), onClick: () => visibleToolbar.set(0),
enabledStore: derived(visibleToolbar, $visibleToolbar => $visibleToolbar), testEnabled: () => getVisibleToolbar(),
}); });
registerCommand({ registerCommand({
@@ -112,8 +112,7 @@ registerCommand({
export function registerFileCommands({ export function registerFileCommands({
idPrefix, idPrefix,
category, category,
editorStore, getCurrentEditor,
editorStatusStore = undefined,
folder, folder,
format, format,
fileExtension, fileExtension,
@@ -128,16 +127,16 @@ export function registerFileCommands({
keyText: 'Ctrl+S', keyText: 'Ctrl+S',
icon: 'icon save', icon: 'icon save',
toolbar: true, toolbar: true,
enabledStore: saveTabEnabledStore(editorStore), testEnabled: () => getCurrentEditor() != null,
onClick: () => saveTabFile(editorStore, false, folder, format, fileExtension), onClick: () => saveTabFile(getCurrentEditor(), false, folder, format, fileExtension),
}); });
registerCommand({ registerCommand({
id: idPrefix + '.saveAs', id: idPrefix + '.saveAs',
category, category,
name: 'Save As', name: 'Save As',
keyText: 'Ctrl+Shift+S', keyText: 'Ctrl+Shift+S',
enabledStore: saveTabEnabledStore(editorStore), testEnabled: () => getCurrentEditor() != null,
onClick: () => saveTabFile(editorStore, true, folder, format, fileExtension), onClick: () => saveTabFile(getCurrentEditor(), true, folder, format, fileExtension),
}); });
if (execute) { if (execute) {
@@ -148,11 +147,8 @@ export function registerFileCommands({
icon: 'icon run', icon: 'icon run',
toolbar: true, toolbar: true,
keyText: 'F5 | Ctrl+Enter', keyText: 'F5 | Ctrl+Enter',
enabledStore: derived( testEnabled: () => getCurrentEditor() != null && !getCurrentEditor()?.isBusy(),
[editorStore, editorStatusStore], onClick: () => getCurrentEditor().execute(),
([editor, status]) => editor != null && !(status as any).busy
),
onClick: () => (get(editorStore) as any).execute(),
}); });
registerCommand({ registerCommand({
id: idPrefix + '.kill', id: idPrefix + '.kill',
@@ -160,11 +156,8 @@ export function registerFileCommands({
name: 'Kill', name: 'Kill',
icon: 'icon close', icon: 'icon close',
toolbar: true, toolbar: true,
enabledStore: derived( testEnabled: () => getCurrentEditor() != null && getCurrentEditor()?.canKill(),
[editorStore, editorStatusStore], onClick: () => getCurrentEditor().kill(),
([query, status]) => query != null && status && (status as any).canKill
),
onClick: () => (get(editorStore) as any).kill(),
}); });
} }
@@ -175,8 +168,8 @@ export function registerFileCommands({
name: 'Toggle comment', name: 'Toggle comment',
keyText: 'Ctrl+/', keyText: 'Ctrl+/',
disableHandleKeyText: 'Ctrl+/', disableHandleKeyText: 'Ctrl+/',
enabledStore: derived(editorStore, query => query != null), testEnabled: () => getCurrentEditor() != null,
onClick: () => (get(editorStore) as any).toggleComment(), onClick: () => getCurrentEditor().toggleComment(),
}); });
} }
@@ -186,16 +179,16 @@ export function registerFileCommands({
category, category,
name: 'Find', name: 'Find',
keyText: 'Ctrl+F', keyText: 'Ctrl+F',
enabledStore: derived(editorStore, query => query != null), testEnabled: () => getCurrentEditor() != null,
onClick: () => (get(editorStore) as any).find(), onClick: () => getCurrentEditor().find(),
}); });
registerCommand({ registerCommand({
id: idPrefix + '.replace', id: idPrefix + '.replace',
category, category,
keyText: 'Ctrl+H', keyText: 'Ctrl+H',
name: 'Replace', name: 'Replace',
enabledStore: derived(editorStore, query => query != null), testEnabled: () => getCurrentEditor() != null,
onClick: () => (get(editorStore) as any).replace(), onClick: () => getCurrentEditor().replace(),
}); });
} }
} }

View File

@@ -1,10 +1,7 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const lastFocusedDataGrid = writable(null); let lastFocusedDataGrid = null;
const currentDataGrid = derived([lastFocusedDataGrid, activeTabId], ([grid, tabid]) => const getCurrentDataGrid = () =>
grid?.getTabId && grid?.getTabId() == tabid ? grid : null lastFocusedDataGrid?.getTabId && lastFocusedDataGrid?.getTabId() == getActiveTabId() ? lastFocusedDataGrid : null;
);
const currentDataGridChangeSet = memberStore(currentDataGrid, grid => grid?.getChangeSetStore() || nullStore);
registerCommand({ registerCommand({
id: 'dataGrid.refresh', id: 'dataGrid.refresh',
@@ -13,8 +10,8 @@
keyText: 'F5', keyText: 'F5',
toolbar: true, toolbar: true,
icon: 'icon reload', icon: 'icon reload',
enabledStore: derived(currentDataGrid, grid => grid?.getDisplay()?.supportsReload), testEnabled: () => getCurrentDataGrid()?.getDisplay()?.supportsReload,
onClick: () => get(currentDataGrid).refresh(), onClick: () => getCurrentDataGrid().refresh(),
}); });
registerCommand({ registerCommand({
@@ -24,11 +21,8 @@
keyText: 'Ctrl+S', keyText: 'Ctrl+S',
toolbar: true, toolbar: true,
icon: 'icon save', icon: 'icon save',
enabledStore: derived( testEnabled: () => getCurrentDataGrid()?.getGrider()?.allowSave,
[currentDataGrid, currentDataGridChangeSet], onClick: () => getCurrentDataGrid().save(),
([grid, changeSet]) => grid?.getGeneralAllowSave() || changeSetContainsChanges((changeSet as any)?.value)
),
onClick: () => get(currentDataGrid).save(),
}); });
registerCommand({ registerCommand({
@@ -36,16 +30,16 @@
category: 'Data grid', category: 'Data grid',
name: 'Revert row changes', name: 'Revert row changes',
keyText: 'Ctrl+R', keyText: 'Ctrl+R',
enabledStore: derived(currentDataGridChangeSet, (changeSet: any) => changeSetContainsChanges(changeSet?.value)), testEnabled: () => getCurrentDataGrid()?.getGrider()?.containsChanges,
onClick: () => get(currentDataGrid).revertRowChanges(), onClick: () => getCurrentDataGrid().revertRowChanges(),
}); });
registerCommand({ registerCommand({
id: 'dataGrid.revertAllChanges', id: 'dataGrid.revertAllChanges',
category: 'Data grid', category: 'Data grid',
name: 'Revert all changes', name: 'Revert all changes',
enabledStore: derived(currentDataGridChangeSet, (changeSet: any) => changeSetContainsChanges(changeSet?.value)), testEnabled: () => getCurrentDataGrid()?.getGrider()?.containsChanges,
onClick: () => get(currentDataGrid).revertAllChanges(), onClick: () => getCurrentDataGrid().revertAllChanges(),
}); });
registerCommand({ registerCommand({
@@ -53,8 +47,8 @@
category: 'Data grid', category: 'Data grid',
name: 'Delete selected rows', name: 'Delete selected rows',
keyText: 'Ctrl+Delete', keyText: 'Ctrl+Delete',
enabledStore: derived(currentDataGrid, grid => grid?.getGrider()?.editable), testEnabled: () => getCurrentDataGrid()?.getGrider()?.editable,
onClick: () => get(currentDataGrid).deleteSelectedRows(), onClick: () => getCurrentDataGrid().deleteSelectedRows(),
}); });
registerCommand({ registerCommand({
@@ -62,8 +56,8 @@
category: 'Data grid', category: 'Data grid',
name: 'Insert new row', name: 'Insert new row',
keyText: 'Insert', keyText: 'Insert',
enabledStore: derived(currentDataGrid, grid => grid?.getGrider()?.editable), testEnabled: () => getCurrentDataGrid()?.getGrider()?.editable,
onClick: () => get(currentDataGrid).insertNewRow(), onClick: () => getCurrentDataGrid().insertNewRow(),
}); });
registerCommand({ registerCommand({
@@ -71,8 +65,8 @@
category: 'Data grid', category: 'Data grid',
name: 'Set NULL', name: 'Set NULL',
keyText: 'Ctrl+0', keyText: 'Ctrl+0',
enabledStore: derived(currentDataGrid, grid => grid?.getGrider()?.editable), testEnabled: () => getCurrentDataGrid()?.getGrider()?.editable,
onClick: () => get(currentDataGrid).setNull(), onClick: () => getCurrentDataGrid().setNull(),
}); });
registerCommand({ registerCommand({
@@ -82,8 +76,8 @@
keyText: 'Ctrl+Z', keyText: 'Ctrl+Z',
icon: 'icon undo', icon: 'icon undo',
toolbar: true, toolbar: true,
enabledStore: derived(currentDataGridChangeSet, (changeSet: any) => changeSet?.canUndo), testEnabled: () => getCurrentDataGrid()?.getGrider()?.canUndo,
onClick: () => get(currentDataGrid).undo(), onClick: () => getCurrentDataGrid().undo(),
}); });
registerCommand({ registerCommand({
@@ -91,16 +85,16 @@
category: 'Data grid', category: 'Data grid',
name: 'Redo', name: 'Redo',
keyText: 'Ctrl+Y', keyText: 'Ctrl+Y',
enabledStore: derived(currentDataGridChangeSet, (changeSet: any) => changeSet?.canRedo), testEnabled: () => getCurrentDataGrid()?.getGrider()?.canRedo,
onClick: () => get(currentDataGrid).redo(), onClick: () => getCurrentDataGrid().redo(),
}); });
registerCommand({ registerCommand({
id: 'dataGrid.reconnect', id: 'dataGrid.reconnect',
category: 'Data grid', category: 'Data grid',
name: 'Reconnect', name: 'Reconnect',
enabledStore: derived(currentDataGrid, grid => grid != null), testEnabled: () => getCurrentDataGrid() != null,
onClick: () => get(currentDataGrid).reconnect(), onClick: () => getCurrentDataGrid().reconnect(),
}); });
registerCommand({ registerCommand({
@@ -108,8 +102,8 @@
category: 'Data grid', category: 'Data grid',
name: 'Copy to clipboard', name: 'Copy to clipboard',
keyText: 'Ctrl+C', keyText: 'Ctrl+C',
enabledStore: derived(currentDataGrid, grid => grid != null), testEnabled: () => getCurrentDataGrid() != null,
onClick: () => get(currentDataGrid).copyToClipboard(), onClick: () => getCurrentDataGrid().copyToClipboard(),
}); });
registerCommand({ registerCommand({
@@ -117,8 +111,8 @@
category: 'Data grid', category: 'Data grid',
name: 'Export', name: 'Export',
keyText: 'Ctrl+E', keyText: 'Ctrl+E',
enabledStore: derived(currentDataGrid, grid => grid != null && grid.exportEnabled()), testEnabled: () => getCurrentDataGrid()?.exportEnabled(),
onClick: () => get(currentDataGrid).exportGrid(), onClick: () => getCurrentDataGrid().exportGrid(),
}); });
function getRowCountInfo(selectedCells, grider, realColumnUniqueNames, selectedRowData, allRowCount) { function getRowCountInfo(selectedCells, grider, realColumnUniqueNames, selectedRowData, allRowCount) {
@@ -175,10 +169,11 @@
import DataFilterControl from './DataFilterControl.svelte'; import DataFilterControl from './DataFilterControl.svelte';
import createReducer from '../utility/createReducer'; import createReducer from '../utility/createReducer';
import keycodes from '../utility/keycodes'; import keycodes from '../utility/keycodes';
import { activeTabId, nullStore } from '../stores'; import { activeTabId, getActiveTabId, nullStore } from '../stores';
import memberStore from '../utility/memberStore'; import memberStore from '../utility/memberStore';
import axiosInstance from '../utility/axiosInstance'; import axiosInstance from '../utility/axiosInstance';
import { copyTextToClipboard } from '../utility/clipboard'; import { copyTextToClipboard } from '../utility/clipboard';
import invalidateCommands from '../commands/invalidateCommands';
export let onLoadNextData = undefined; export let onLoadNextData = undefined;
export let grider = undefined; export let grider = undefined;
@@ -198,7 +193,7 @@
export let isLoadedAll; export let isLoadedAll;
export let loadedTime; export let loadedTime;
export let changeSetStore; export let changeSetStore;
export let generalAllowSave = false; // export let generalAllowSave = false;
const wheelRowCount = 5; const wheelRowCount = 5;
const instance = get_current_component(); const instance = get_current_component();
@@ -330,9 +325,9 @@
} }
} }
export function getGeneralAllowSave() { // export function getGeneralAllowSave() {
return generalAllowSave; // return generalAllowSave;
} // }
$: autofillMarkerCell = $: autofillMarkerCell =
selectedCells && selectedCells.length > 0 && _.uniq(selectedCells.map(x => x[0])).length == 1 selectedCells && selectedCells.length > 0 && _.uniq(selectedCells.map(x => x[0])).length == 1
@@ -891,7 +886,8 @@
bind:this={domFocusField} bind:this={domFocusField}
on:keydown={handleGridKeyDown} on:keydown={handleGridKeyDown}
on:focus={() => { on:focus={() => {
lastFocusedDataGrid.set(instance); lastFocusedDataGrid = instance;
invalidateCommands();
}} }}
on:paste={handlePaste} on:paste={handlePaste}
/> />

View File

@@ -1,5 +1,6 @@
import { writable, derived, readable } from 'svelte/store'; import { writable, derived, readable } from 'svelte/store';
import { ExtensionsDirectory } from 'dbgate-types'; import { ExtensionsDirectory } from 'dbgate-types';
import invalidateCommands from './commands/invalidateCommands';
interface TabDefinition { interface TabDefinition {
title: string; title: string;
@@ -34,6 +35,7 @@ export const visibleCommandPalette = writable(false);
export const commands = writable({}); export const commands = writable({});
export const currentTheme = writableWithStorage('theme-light', 'currentTheme'); export const currentTheme = writableWithStorage('theme-light', 'currentTheme');
export const activeTabId = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)?.tabid); export const activeTabId = derived([openedTabs], ([$openedTabs]) => $openedTabs.find(x => x.selected)?.tabid);
export const visibleToolbar = writableWithStorage(1, 'visibleToolbar'); export const visibleToolbar = writableWithStorage(1, 'visibleToolbar');
export const leftPanelWidth = writable(300); export const leftPanelWidth = writable(300);
export const currentDropDownMenu = writable(null); export const currentDropDownMenu = writable(null);
@@ -45,3 +47,31 @@ export const isFileDragActive = writable(false);
subscribeCssVariable(selectedWidget, x => (x ? 1 : 0), '--dim-visible-left-panel'); subscribeCssVariable(selectedWidget, x => (x ? 1 : 0), '--dim-visible-left-panel');
subscribeCssVariable(visibleToolbar, x => (x ? 1 : 0), '--dim-visible-toolbar'); subscribeCssVariable(visibleToolbar, x => (x ? 1 : 0), '--dim-visible-toolbar');
subscribeCssVariable(leftPanelWidth, x => `${x}px`, '--dim-left-panel-width'); subscribeCssVariable(leftPanelWidth, x => `${x}px`, '--dim-left-panel-width');
let activeTabIdValue = null;
activeTabId.subscribe(value => {
activeTabIdValue = value;
invalidateCommands();
});
export const getActiveTabId = () => activeTabIdValue;
let visibleCommandPaletteValue = null;
visibleCommandPalette.subscribe(value => {
visibleCommandPaletteValue = value;
invalidateCommands();
});
export const getVisibleCommandPalette = () => visibleCommandPaletteValue;
let visibleToolbarValue = null;
visibleToolbar.subscribe(value => {
visibleToolbarValue = value;
invalidateCommands();
});
export const getVisibleToolbar = () => visibleToolbarValue;
let openedTabsValue = null;
openedTabs.subscribe(value => {
openedTabsValue = value;
invalidateCommands();
});
export const getOpenedTabs = () => openedTabsValue;

View File

@@ -65,7 +65,6 @@
modelState={$modelState} modelState={$modelState}
{dispatchModel} {dispatchModel}
onSave={handleSave} onSave={handleSave}
generalAllowSave
focusOnVisible focusOnVisible
/> />
{/if} {/if}

View File

@@ -1,13 +1,12 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const lastFocusedEditor = writable(null); let lastFocusedEditor = null;
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) => const getCurrentEditor = () =>
editor?.getTabId && editor?.getTabId() == tabid ? editor : null lastFocusedEditor?.getTabId && lastFocusedEditor?.getTabId() == getActiveTabId() ? lastFocusedEditor : null;
);
registerFileCommands({ registerFileCommands({
idPrefix: 'markdown', idPrefix: 'markdown',
category: 'Markdown', category: 'Markdown',
editorStore: currentEditor, getCurrentEditor,
folder: 'markdown', folder: 'markdown',
format: 'text', format: 'text',
fileExtension: 'md', fileExtension: 'md',
@@ -23,8 +22,8 @@
icon: 'icon run', icon: 'icon run',
toolbar: true, toolbar: true,
keyText: 'F5 | Ctrl+Enter', keyText: 'F5 | Ctrl+Enter',
enabledStore: derived(currentEditor, query => query != null), testEnabled: () => getCurrentEditor() != null,
onClick: () => (get(currentEditor) as any).preview(), onClick: () => getCurrentEditor().preview(),
}); });
</script> </script>
@@ -39,11 +38,12 @@
import AceEditor from '../query/AceEditor.svelte'; import AceEditor from '../query/AceEditor.svelte';
import RunnerOutputPane from '../query/RunnerOutputPane.svelte'; import RunnerOutputPane from '../query/RunnerOutputPane.svelte';
import useEditorData from '../query/useEditorData'; import useEditorData from '../query/useEditorData';
import { activeTabId, nullStore } from '../stores'; import { activeTabId, getActiveTabId, nullStore } from '../stores';
import axiosInstance from '../utility/axiosInstance'; import axiosInstance from '../utility/axiosInstance';
import memberStore from '../utility/memberStore'; import memberStore from '../utility/memberStore';
import socket from '../utility/socket'; import socket from '../utility/socket';
import useEffect from '../utility/useEffect'; import useEffect from '../utility/useEffect';
import invalidateCommands from '../commands/invalidateCommands';
export let tabid; export let tabid;
@@ -100,7 +100,10 @@
value={$editorState.value || ''} value={$editorState.value || ''}
menu={createMenu()} menu={createMenu()}
on:input={e => setEditorData(e.detail)} on:input={e => setEditorData(e.detail)}
on:focus={() => lastFocusedEditor.set(instance)} on:focus={() => {
lastFocusedEditor = instance;
invalidateCommands();
}}
bind:this={domEditor} bind:this={domEditor}
mode="markdown" mode="markdown"
/> />

View File

@@ -1,22 +1,19 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const lastFocusedEditor = writable(null); let lastFocusedEditor = null;
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) => const getCurrentEditor = () =>
editor?.getTabId && editor?.getTabId() == tabid ? editor : null lastFocusedEditor?.getTabId && lastFocusedEditor?.getTabId() == getActiveTabId() ? lastFocusedEditor : null;
);
const currentEditorStatus = memberStore(currentEditor, editor => editor?.getStatus() || nullStore);
registerCommand({ registerCommand({
id: 'query.formatCode', id: 'query.formatCode',
category: 'Query', category: 'Query',
name: 'Format code', name: 'Format code',
enabledStore: derived(currentEditor, query => query != null), testEnabled: () => getCurrentEditor() != null,
onClick: () => get(currentEditor).formatCode(), onClick: () => getCurrentEditor().formatCode(),
}); });
registerFileCommands({ registerFileCommands({
idPrefix: 'query', idPrefix: 'query',
category: 'Query', category: 'Query',
editorStore: currentEditor, getCurrentEditor,
editorStatusStore: currentEditorStatus,
folder: 'sql', folder: 'sql',
format: 'text', format: 'text',
fileExtension: 'sql', fileExtension: 'sql',
@@ -38,7 +35,7 @@
import VerticalSplitter from '../elements/VerticalSplitter.svelte'; import VerticalSplitter from '../elements/VerticalSplitter.svelte';
import SqlEditor from '../query/SqlEditor.svelte'; import SqlEditor from '../query/SqlEditor.svelte';
import useEditorData from '../query/useEditorData'; import useEditorData from '../query/useEditorData';
import { activeTabId, extensions, nullStore } from '../stores'; import { activeTabId, extensions, getActiveTabId, nullStore } from '../stores';
import applySqlTemplate from '../utility/applySqlTemplate'; import applySqlTemplate from '../utility/applySqlTemplate';
import axiosInstance from '../utility/axiosInstance'; import axiosInstance from '../utility/axiosInstance';
import { changeTab } from '../utility/common'; import { changeTab } from '../utility/common';
@@ -49,6 +46,7 @@
import useEffect from '../utility/useEffect'; import useEffect from '../utility/useEffect';
import ResultTabs from '../query/ResultTabs.svelte'; import ResultTabs from '../query/ResultTabs.svelte';
import { registerFileCommands } from '../commands/stdCommands'; import { registerFileCommands } from '../commands/stdCommands';
import invalidateCommands from '../commands/invalidateCommands';
export let tabid; export let tabid;
export let conid; export let conid;
@@ -65,11 +63,6 @@
let domEditor; let domEditor;
const status = writable({
busy,
canKill: false,
});
$: connection = useConnectionInfo({ conid }); $: connection = useConnectionInfo({ conid });
$: effect = useEffect(() => { $: effect = useEffect(() => {
@@ -91,16 +84,23 @@
} }
$: { $: {
status.set({ busy;
busy, sessionId;
canKill: !!sessionId, invalidateCommands();
});
} }
$: if ($tabVisible && domEditor) { $: if ($tabVisible && domEditor) {
domEditor?.getEditor()?.focus(); domEditor?.getEditor()?.focus();
} }
export function canKill() {
return !!sessionId;
}
export function isBusy() {
return busy;
}
export function getTabId() { export function getTabId() {
return tabid; return tabid;
} }
@@ -137,9 +137,9 @@
// timerLabel.stop(); // timerLabel.stop();
} }
export function getStatus() { // export function getStatus() {
return status; // return status;
} // }
export function getData() { export function getData() {
return $editorState.value || ''; return $editorState.value || '';
@@ -207,7 +207,7 @@
value={$editorState.value || ''} value={$editorState.value || ''}
menu={createMenu()} menu={createMenu()}
on:input={e => setEditorData(e.detail)} on:input={e => setEditorData(e.detail)}
on:focus={() => lastFocusedEditor.set(instance)} on:focus={() => {lastFocusedEditor = instance; invalidateCommands(); }}
bind:this={domEditor} bind:this={domEditor}
/> />
</svelte:fragment> </svelte:fragment>

View File

@@ -1,15 +1,12 @@
<script lang="ts" context="module"> <script lang="ts" context="module">
const lastFocusedEditor = writable(null); let lastFocusedEditor = null;
const currentEditor = derived([lastFocusedEditor, activeTabId], ([editor, tabid]) => const getCurrentEditor = () =>
editor?.getTabId && editor?.getTabId() == tabid ? editor : null lastFocusedEditor?.getTabId && lastFocusedEditor?.getTabId() == getActiveTabId() ? lastFocusedEditor : null;
);
const currentEditorStatus = memberStore(currentEditor, editor => editor?.getStatus() || nullStore);
registerFileCommands({ registerFileCommands({
idPrefix: 'shell', idPrefix: 'shell',
category: 'Shell', category: 'Shell',
editorStore: currentEditor, getCurrentEditor,
editorStatusStore: currentEditorStatus,
folder: 'shell', folder: 'shell',
format: 'text', format: 'text',
fileExtension: 'js', fileExtension: 'js',
@@ -28,6 +25,7 @@
import { getContext, get_current_component } from 'svelte/internal'; import { getContext, get_current_component } from 'svelte/internal';
import { derived, writable } from 'svelte/store'; import { derived, writable } from 'svelte/store';
import invalidateCommands from '../commands/invalidateCommands';
import registerCommand from '../commands/registerCommand'; import registerCommand from '../commands/registerCommand';
import { registerFileCommands } from '../commands/stdCommands'; import { registerFileCommands } from '../commands/stdCommands';
@@ -35,7 +33,7 @@
import AceEditor from '../query/AceEditor.svelte'; import AceEditor from '../query/AceEditor.svelte';
import RunnerOutputPane from '../query/RunnerOutputPane.svelte'; import RunnerOutputPane from '../query/RunnerOutputPane.svelte';
import useEditorData from '../query/useEditorData'; import useEditorData from '../query/useEditorData';
import { activeTabId, nullStore } from '../stores'; import { activeTabId, getActiveTabId, nullStore } from '../stores';
import axiosInstance from '../utility/axiosInstance'; import axiosInstance from '../utility/axiosInstance';
import memberStore from '../utility/memberStore'; import memberStore from '../utility/memberStore';
import socket from '../utility/socket'; import socket from '../utility/socket';
@@ -54,16 +52,21 @@
let domEditor; let domEditor;
const status = writable({ // const status = writable({
busy, // busy,
canKill: false, // canKill: false,
}); // });
// $: {
// status.set({
// busy,
// canKill: busy,
// });
// }
$: { $: {
status.set({ busy;
busy, invalidateCommands();
canKill: busy,
});
} }
$: if ($tabVisible && domEditor) { $: if ($tabVisible && domEditor) {
@@ -90,9 +93,9 @@
// timerLabel.stop(); // timerLabel.stop();
} }
export function getStatus() { // export function getStatus() {
return status; // return status;
} // }
export function getData() { export function getData() {
return $editorState.value || ''; return $editorState.value || '';
@@ -114,6 +117,10 @@
return tabid; return tabid;
} }
export function isBusy() {
return busy;
}
export async function execute() { export async function execute() {
if (busy) return; if (busy) return;
executeNumber += 1; executeNumber += 1;
@@ -165,7 +172,10 @@
value={$editorState.value || ''} value={$editorState.value || ''}
menu={createMenu()} menu={createMenu()}
on:input={e => setEditorData(e.detail)} on:input={e => setEditorData(e.detail)}
on:focus={() => lastFocusedEditor.set(instance)} on:focus={() => {
lastFocusedEditor = instance;
invalidateCommands();
}}
bind:this={domEditor} bind:this={domEditor}
mode="javascript" mode="javascript"
/> />

View File

@@ -17,6 +17,7 @@
import { findEngineDriver } from 'dbgate-tools'; import { findEngineDriver } from 'dbgate-tools';
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import createUndoReducer from '../utility/createUndoReducer'; import createUndoReducer from '../utility/createUndoReducer';
import invalidateCommands from '../commands/invalidateCommands';
export let tabid; export let tabid;
export let conid; export let conid;
@@ -28,6 +29,11 @@
const cache = writable(createGridCache()); const cache = writable(createGridCache());
const [changeSetStore, dispatchChangeSet] = createUndoReducer(createChangeSet()); const [changeSetStore, dispatchChangeSet] = createUndoReducer(createChangeSet());
$: {
$changeSetStore;
invalidateCommands();
}
</script> </script>
<TableDataGrid <TableDataGrid

View File

@@ -6,12 +6,11 @@ import { changeTab } from './common';
import SaveFileModal from '../modals/SaveFileModal.svelte'; import SaveFileModal from '../modals/SaveFileModal.svelte';
import registerCommand from '../commands/registerCommand'; import registerCommand from '../commands/registerCommand';
export function saveTabEnabledStore(editorStore) { // export function saveTabEnabledStore(editorStore) {
return derived(editorStore, editor => editor != null); // return derived(editorStore, editor => editor != null);
} // }
export default function saveTabFile(editorStore, saveAs, folder, format, fileExtension) { export default function saveTabFile(editor, saveAs, folder, format, fileExtension) {
const editor: any = get(editorStore);
const tabs = get(openedTabs); const tabs = get(openedTabs);
const tabid = editor.getTabId(); const tabid = editor.getTabId();
const data = editor.getData(); const data = editor.getData();

View File

@@ -23,7 +23,7 @@
category: 'Tabs', category: 'Tabs',
name: 'Next tab', name: 'Next tab',
keyText: 'Ctrl+Tab', keyText: 'Ctrl+Tab',
enabledStore: derived(openedTabs, tabs => tabs.filter(x => !x.closedTime).length >= 2), testEnabled: () => getOpenedTabs().filter(x => !x.closedTime).length >= 2,
onClick: () => { onClick: () => {
const tabs = get(openedTabs).filter(x => x.closedTime == null); const tabs = get(openedTabs).filter(x => x.closedTime == null);
if (tabs.length >= 2) setSelectedTab(tabs[tabs.length - 2].tabid); if (tabs.length >= 2) setSelectedTab(tabs[tabs.length - 2].tabid);
@@ -37,7 +37,7 @@
import registerCommand from '../commands/registerCommand'; import registerCommand from '../commands/registerCommand';
import FontIcon from '../icons/FontIcon.svelte'; import FontIcon from '../icons/FontIcon.svelte';
import { currentDatabase, openedTabs } from '../stores'; import { currentDatabase, getOpenedTabs, openedTabs } from '../stores';
import { setSelectedTab } from '../utility/common'; import { setSelectedTab } from '../utility/common';
import contextMenu from '../utility/contextMenu'; import contextMenu from '../utility/contextMenu';