mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 23:45:59 +00:00
sql editor - not working
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
"@rollup/plugin-node-resolve": "^11.0.0",
|
||||
"@rollup/plugin-typescript": "^6.0.0",
|
||||
"@tsconfig/svelte": "^1.0.0",
|
||||
"ace-builds": "^1.4.8",
|
||||
"rollup": "^2.3.4",
|
||||
"rollup-plugin-copy": "^3.3.0",
|
||||
"rollup-plugin-css-only": "^3.1.0",
|
||||
|
||||
@@ -4,6 +4,7 @@ import { derived, get } from 'svelte/store';
|
||||
import { ThemeDefinition } from 'dbgate-types';
|
||||
import ConnectionModal from '../modals/ConnectionModal.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import newQuery from '../query/newQuery';
|
||||
|
||||
function themeCommand(theme: ThemeDefinition) {
|
||||
return {
|
||||
@@ -52,3 +53,14 @@ registerCommand({
|
||||
name: 'Connection',
|
||||
onClick: () => showModal(ConnectionModal),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'new.query',
|
||||
category: 'New',
|
||||
icon: 'icon file',
|
||||
toolbar: true,
|
||||
toolbarOrder: 2,
|
||||
name: 'Query',
|
||||
keyText: 'Ctrl+Q',
|
||||
onClick: () => newQuery(),
|
||||
});
|
||||
|
||||
@@ -5,9 +5,7 @@ import './commands/stdCommands';
|
||||
|
||||
const app = new App({
|
||||
target: document.body,
|
||||
props: {
|
||||
name: 'world',
|
||||
},
|
||||
props: {},
|
||||
});
|
||||
|
||||
export default app;
|
||||
|
||||
20
packages/web/src/query/AceEditor.svelte
Normal file
20
packages/web/src/query/AceEditor.svelte
Normal file
@@ -0,0 +1,20 @@
|
||||
<script>
|
||||
import AceEditorCore from './AceEditorCore.svelte';
|
||||
|
||||
let clientWidth;
|
||||
let clientHeight;
|
||||
</script>
|
||||
|
||||
<div bind:clientWidth bind:clientHeight>
|
||||
<AceEditorCore {...$$props} width={clientWidth} height={clientHeight} />
|
||||
</div>
|
||||
|
||||
<style>
|
||||
div {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
</style>
|
||||
132
packages/web/src/query/AceEditorCore.svelte
Normal file
132
packages/web/src/query/AceEditorCore.svelte
Normal file
@@ -0,0 +1,132 @@
|
||||
<script lang="ts">
|
||||
// copied from https://github.com/nateshmbhat/svelte-ace/blob/main/src/AceEditor.svelte
|
||||
import { createEventDispatcher, tick, onMount, onDestroy } from 'svelte';
|
||||
|
||||
import * as ace from 'ace-builds/src-noconflict/ace';
|
||||
|
||||
import 'ace-builds/src-noconflict/mode-sql';
|
||||
import 'ace-builds/src-noconflict/mode-mysql';
|
||||
import 'ace-builds/src-noconflict/mode-pgsql';
|
||||
import 'ace-builds/src-noconflict/mode-sqlserver';
|
||||
import 'ace-builds/src-noconflict/mode-json';
|
||||
import 'ace-builds/src-noconflict/mode-javascript';
|
||||
import 'ace-builds/src-noconflict/mode-markdown';
|
||||
import 'ace-builds/src-noconflict/theme-github';
|
||||
import 'ace-builds/src-noconflict/theme-twilight';
|
||||
import 'ace-builds/src-noconflict/ext-searchbox';
|
||||
import 'ace-builds/src-noconflict/ext-language_tools';
|
||||
|
||||
const EDITOR_ID = `svelte-ace-editor-div:${Math.floor(Math.random() * 10000000000)}`;
|
||||
const dispatch = createEventDispatcher<{
|
||||
init: ace.Editor;
|
||||
input: string;
|
||||
selectionChange: any;
|
||||
blur: void;
|
||||
changeMode: any;
|
||||
commandKey: { err: any; hashId: any; keyCode: any };
|
||||
copy: void;
|
||||
cursorChange: void;
|
||||
cut: void;
|
||||
documentChange: { data: any };
|
||||
focus: void;
|
||||
paste: string;
|
||||
}>();
|
||||
|
||||
export let height: number;
|
||||
export let width: number;
|
||||
|
||||
export let value: string = ''; // String, required
|
||||
export let mode: string = 'text'; // String
|
||||
export let theme: string = 'github'; // String
|
||||
export let options: any = {}; // Object
|
||||
|
||||
let editor: ace.Editor;
|
||||
let contentBackup: string = '';
|
||||
|
||||
const requireEditorPlugins = () => {};
|
||||
requireEditorPlugins();
|
||||
|
||||
onDestroy(() => {
|
||||
if (editor) {
|
||||
editor.destroy();
|
||||
editor.container.remove();
|
||||
}
|
||||
});
|
||||
|
||||
$: watchValue(value);
|
||||
function watchValue(val: string) {
|
||||
if (contentBackup !== val && editor && typeof val === 'string') {
|
||||
editor.session.setValue(val);
|
||||
contentBackup = val;
|
||||
}
|
||||
}
|
||||
|
||||
$: watchTheme(theme);
|
||||
function watchTheme(newTheme: string) {
|
||||
if (editor) {
|
||||
editor.setTheme('ace/theme/' + newTheme);
|
||||
}
|
||||
}
|
||||
|
||||
$: watchMode(mode);
|
||||
function watchMode(newOption: any) {
|
||||
if (editor) {
|
||||
editor.getSession().setMode('ace/mode/' + newOption);
|
||||
}
|
||||
}
|
||||
|
||||
$: watchOptions(options);
|
||||
function watchOptions(newOption: any) {
|
||||
if (editor) {
|
||||
editor.setOptions(newOption);
|
||||
}
|
||||
}
|
||||
|
||||
const resizeOnNextTick = () =>
|
||||
tick().then(() => {
|
||||
if (editor) {
|
||||
editor.resize();
|
||||
}
|
||||
});
|
||||
|
||||
$: if (height !== null && width !== null) {
|
||||
resizeOnNextTick();
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
editor = ace.edit(EDITOR_ID);
|
||||
|
||||
dispatch('init', editor);
|
||||
editor.$blockScrolling = Infinity;
|
||||
// editor.setOption("enableEmmet", true);
|
||||
editor.getSession().setMode('ace/mode/' + mode);
|
||||
editor.setTheme('ace/theme/' + theme);
|
||||
editor.setValue(value, 1);
|
||||
contentBackup = value;
|
||||
setEventCallBacks();
|
||||
if (options) {
|
||||
editor.setOptions(options);
|
||||
}
|
||||
});
|
||||
|
||||
function setEventCallBacks() {
|
||||
editor.onBlur = () => dispatch('blur');
|
||||
editor.onChangeMode = obj => dispatch('changeMode', obj);
|
||||
editor.onCommandKey = (err, hashId, keyCode) => dispatch('commandKey', { err, hashId, keyCode });
|
||||
editor.onCopy = () => dispatch('copy');
|
||||
editor.onCursorChange = () => dispatch('cursorChange');
|
||||
editor.onCut = () => dispatch('cut');
|
||||
editor.onDocumentChange = (obj: { data: any }) => dispatch('documentChange', obj);
|
||||
editor.onFocus = () => dispatch('focus');
|
||||
editor.onPaste = text => dispatch('paste', text);
|
||||
editor.onSelectionChange = obj => dispatch('selectionChange', obj);
|
||||
editor.on('change', function () {
|
||||
const content = editor.getValue();
|
||||
value = content;
|
||||
dispatch('input', content);
|
||||
contentBackup = content;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id={EDITOR_ID} style="width:{width}px;height:{height}px" />
|
||||
16
packages/web/src/query/SqlEditor.svelte
Normal file
16
packages/web/src/query/SqlEditor.svelte
Normal file
@@ -0,0 +1,16 @@
|
||||
<script lang="ts" context="module">
|
||||
const engineToMode = {
|
||||
mssql: 'sqlserver',
|
||||
mysql: 'mysql',
|
||||
postgre: 'pgsql',
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import AceEditor from './AceEditorCore.svelte';
|
||||
export let engine;
|
||||
|
||||
$: console.log('engine', engine);
|
||||
</script>
|
||||
|
||||
<AceEditor mode={engineToMode[engine] || 'sql'} />
|
||||
37
packages/web/src/query/newQuery.ts
Normal file
37
packages/web/src/query/newQuery.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import _ from 'lodash';
|
||||
import { get } from 'svelte/store';
|
||||
import { currentDatabase } from '../stores';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
|
||||
export default function newQuery({
|
||||
tabComponent = 'QueryTab',
|
||||
icon = 'img sql-file',
|
||||
title = undefined,
|
||||
initialData = undefined,
|
||||
...props
|
||||
} = {}) {
|
||||
const $currentDatabase = get(currentDatabase);
|
||||
const connection = _.get($currentDatabase, 'connection') || {};
|
||||
const database = _.get($currentDatabase, 'name');
|
||||
|
||||
const tooltip = `${connection.displayName || connection.server}\n${database}`;
|
||||
|
||||
openNewTab(
|
||||
{
|
||||
title: title || 'Query #',
|
||||
icon,
|
||||
tooltip,
|
||||
tabComponent,
|
||||
props: {
|
||||
...props,
|
||||
conid: connection._id,
|
||||
database,
|
||||
},
|
||||
},
|
||||
{ editor: initialData }
|
||||
);
|
||||
}
|
||||
|
||||
export function newQueryDesign() {
|
||||
return newQuery({ tabComponent: 'QueryDesignTab', icon: 'img query-design' });
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<script lang="ts">
|
||||
import VerticalSplitter from '../elements/VerticalSplitter.svelte';
|
||||
import SqlEditor from '../query/SqlEditor.svelte';
|
||||
import { useConnectionInfo } from '../utility/metadataLoaders';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
export let database;
|
||||
|
||||
// $: connection = useConnectionInfo({ conid });
|
||||
// engine={$connection && $connection.engine}
|
||||
</script>
|
||||
|
||||
<VerticalSplitter>
|
||||
<svelte:fragment slot="1">
|
||||
<SqlEditor />
|
||||
</svelte:fragment>
|
||||
</VerticalSplitter>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as TableDataTab from './TableDataTab.svelte';
|
||||
// import ViewDataTab from './ViewDataTab';
|
||||
// import TableStructureTab from './TableStructureTab';
|
||||
// import QueryTab from './QueryTab';
|
||||
import * as QueryTab from './QueryTab.svelte';
|
||||
// import ShellTab from './ShellTab';
|
||||
// import InfoPageTab from './InfoPageTab';
|
||||
// import ArchiveFileTab from './ArchiveFileTab';
|
||||
@@ -16,18 +16,18 @@ import * as TableDataTab from './TableDataTab.svelte';
|
||||
|
||||
export default {
|
||||
TableDataTab,
|
||||
// ViewDataTab,
|
||||
// TableStructureTab,
|
||||
// QueryTab,
|
||||
// InfoPageTab,
|
||||
// ShellTab,
|
||||
// ArchiveFileTab,
|
||||
// FreeTableTab,
|
||||
// PluginTab,
|
||||
// ChartTab,
|
||||
// MarkdownEditorTab,
|
||||
// MarkdownViewTab,
|
||||
// MarkdownPreviewTab,
|
||||
// FavoriteEditorTab,
|
||||
// QueryDesignTab,
|
||||
// ViewDataTab,
|
||||
// TableStructureTab,
|
||||
QueryTab,
|
||||
// InfoPageTab,
|
||||
// ShellTab,
|
||||
// ArchiveFileTab,
|
||||
// FreeTableTab,
|
||||
// PluginTab,
|
||||
// ChartTab,
|
||||
// MarkdownEditorTab,
|
||||
// MarkdownViewTab,
|
||||
// MarkdownPreviewTab,
|
||||
// FavoriteEditorTab,
|
||||
// QueryDesignTab,
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@ export default async function openNewTab(newTab, initialData = undefined, option
|
||||
|
||||
let existing = null;
|
||||
|
||||
|
||||
const { savedFile, savedFolder, savedFilePath } = newTab.props || {};
|
||||
if (savedFile || savedFilePath) {
|
||||
existing = oldTabs.find(
|
||||
|
||||
@@ -753,6 +753,11 @@ accepts@~1.3.4, accepts@~1.3.7:
|
||||
mime-types "~2.1.24"
|
||||
negotiator "0.6.2"
|
||||
|
||||
ace-builds@^1.4.8:
|
||||
version "1.4.12"
|
||||
resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.12.tgz#888efa386e36f4345f40b5233fcc4fe4c588fae7"
|
||||
integrity sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg==
|
||||
|
||||
acorn-globals@^4.1.0:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7"
|
||||
|
||||
Reference in New Issue
Block a user