mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
sql editor context menu
This commit is contained in:
parent
72181e70a1
commit
670e3d127e
9
CHANGELOG.md
Normal file
9
CHANGELOG.md
Normal file
@ -0,0 +1,9 @@
|
||||
# ChangeLog
|
||||
|
||||
### 3.9.6
|
||||
- ADDED: Connect using SSH Tunnel
|
||||
- ADDED: Connect using SSL
|
||||
- ADDED: Database connection dialog redesigned
|
||||
- ADDED: #63 Ctrl+Enter runs query
|
||||
- ADDED: Published dbgate NPM package
|
||||
- ADDED: SQL editor context menu
|
@ -9,6 +9,9 @@ import useShowModal from '../modals/showModal';
|
||||
import InsertJoinModal from '../modals/InsertJoinModal';
|
||||
import { getDatabaseInfo } from '../utility/metadataLoaders';
|
||||
import useTheme from '../theme/useTheme';
|
||||
import { useShowMenu } from '../modals/showMenu';
|
||||
import SqlEditorContextMenu from './SqlEditorContextMenu';
|
||||
import sqlFormatter from 'sql-formatter';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
position: absolute;
|
||||
@ -53,10 +56,12 @@ export default function SqlEditor({
|
||||
focusOnCreate = false,
|
||||
conid = undefined,
|
||||
database = undefined,
|
||||
onExecute = undefined,
|
||||
}) {
|
||||
const [containerRef, { height, width }] = useDimensions();
|
||||
const ownEditorRef = React.useRef(null);
|
||||
const theme = useTheme();
|
||||
const showMenu = useShowMenu();
|
||||
|
||||
const currentEditorRef = editorRef || ownEditorRef;
|
||||
const showModal = useShowModal();
|
||||
@ -73,23 +78,27 @@ export default function SqlEditor({
|
||||
currentEditorRef.current.editor.focus();
|
||||
}, [tabVisible, focusOnCreate]);
|
||||
|
||||
const handleInsertJoin = async () => {
|
||||
const dbinfo = await getDatabaseInfo({ conid, database });
|
||||
showModal(modalState => (
|
||||
<InsertJoinModal
|
||||
sql={currentEditorRef.current.editor.getValue()}
|
||||
modalState={modalState}
|
||||
engine={engine}
|
||||
dbinfo={dbinfo}
|
||||
onInsert={text => {
|
||||
const editor = currentEditorRef.current.editor;
|
||||
editor.session.insert(editor.getCursorPosition(), text);
|
||||
}}
|
||||
/>
|
||||
));
|
||||
};
|
||||
|
||||
const handleKeyDown = React.useCallback(
|
||||
async (data, hash, keyString, keyCode, event) => {
|
||||
(data, hash, keyString, keyCode, event) => {
|
||||
if (keyCode == keycodes.j && event.ctrlKey && !readOnly && tabVisible) {
|
||||
event.preventDefault();
|
||||
const dbinfo = await getDatabaseInfo({ conid, database });
|
||||
showModal(modalState => (
|
||||
<InsertJoinModal
|
||||
sql={currentEditorRef.current.editor.getValue()}
|
||||
modalState={modalState}
|
||||
engine={engine}
|
||||
dbinfo={dbinfo}
|
||||
onInsert={text => {
|
||||
const editor = currentEditorRef.current.editor;
|
||||
editor.session.insert(editor.getCursorPosition(), text);
|
||||
}}
|
||||
/>
|
||||
));
|
||||
handleInsertJoin();
|
||||
}
|
||||
|
||||
if (onKeyDown) onKeyDown(data, hash, keyString, keyCode, event);
|
||||
@ -100,12 +109,40 @@ export default function SqlEditor({
|
||||
React.useEffect(() => {
|
||||
if ((onKeyDown || !readOnly) && currentEditorRef.current) {
|
||||
currentEditorRef.current.editor.keyBinding.addKeyboardHandler(handleKeyDown);
|
||||
|
||||
return () => {
|
||||
currentEditorRef.current.editor.keyBinding.removeKeyboardHandler(handleKeyDown);
|
||||
};
|
||||
}
|
||||
return () => {
|
||||
currentEditorRef.current.editor.keyBinding.removeKeyboardHandler(handleKeyDown);
|
||||
};
|
||||
}, [handleKeyDown]);
|
||||
|
||||
const handleFormatCode = () => {
|
||||
currentEditorRef.current.editor.setValue(sqlFormatter.format(editorRef.current.editor.getValue()));
|
||||
currentEditorRef.current.editor.clearSelection();
|
||||
};
|
||||
|
||||
const menuRefs = React.useRef(null);
|
||||
menuRefs.current = {
|
||||
execute: onExecute,
|
||||
insertJoin: !readOnly ? handleInsertJoin : null,
|
||||
toggleComment: !readOnly ? () => currentEditorRef.current.editor.execCommand('togglecomment') : null,
|
||||
formatCode: !readOnly ? handleFormatCode : null,
|
||||
};
|
||||
const handleContextMenu = React.useCallback(event => {
|
||||
event.preventDefault();
|
||||
showMenu(event.pageX, event.pageY, <SqlEditorContextMenu {...menuRefs.current} />);
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (currentEditorRef.current) {
|
||||
currentEditorRef.current.editor.container.addEventListener('contextmenu', handleContextMenu);
|
||||
|
||||
return () => {
|
||||
currentEditorRef.current.editor.container.removeEventListener('contextmenu', handleContextMenu);
|
||||
};
|
||||
}
|
||||
}, [handleContextMenu]);
|
||||
|
||||
return (
|
||||
<Wrapper ref={containerRef}>
|
||||
<AceEditor
|
||||
|
29
packages/web/src/sqleditor/SqlEditorContextMenu.js
Normal file
29
packages/web/src/sqleditor/SqlEditorContextMenu.js
Normal file
@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
import { DropDownMenuItem, DropDownMenuDivider } from '../modals/DropDownMenu';
|
||||
|
||||
export default function SqlEditorContextMenu({ execute, insertJoin, toggleComment, formatCode }) {
|
||||
return (
|
||||
<>
|
||||
{!!execute && (
|
||||
<DropDownMenuItem onClick={execute} keyText="F5 or Ctrl+Enter">
|
||||
Execute query
|
||||
</DropDownMenuItem>
|
||||
)}
|
||||
{!!insertJoin && (
|
||||
<DropDownMenuItem onClick={insertJoin} keyText="Ctrl+J">
|
||||
Insert SQL Join
|
||||
</DropDownMenuItem>
|
||||
)}
|
||||
{!!toggleComment && (
|
||||
<DropDownMenuItem onClick={toggleComment} keyText="Ctrl+/">
|
||||
Toggle comment
|
||||
</DropDownMenuItem>
|
||||
)}
|
||||
{!!formatCode && (
|
||||
<DropDownMenuItem onClick={formatCode} >
|
||||
Format code
|
||||
</DropDownMenuItem>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -24,6 +24,7 @@ import useExtensions from '../utility/useExtensions';
|
||||
import useTimerLabel from '../utility/useTimerLabel';
|
||||
import { StatusBarItem } from '../widgets/StatusBar';
|
||||
import ToolbarPortal from '../utility/ToolbarPortal';
|
||||
import { useShowMenu } from '../modals/showMenu';
|
||||
|
||||
function createSqlPreview(sql) {
|
||||
if (!sql) return undefined;
|
||||
@ -131,6 +132,8 @@ export default function QueryTab({
|
||||
sql: selectedText || editorData,
|
||||
});
|
||||
};
|
||||
// const handleExecuteRef = React.useRef(handleExecute);
|
||||
// handleExecuteRef.current = handleExecute;
|
||||
|
||||
// const handleCancel = () => {
|
||||
// axios.post('sessions/cancel', {
|
||||
@ -186,6 +189,7 @@ export default function QueryTab({
|
||||
editorRef={editorRef}
|
||||
conid={conid}
|
||||
database={database}
|
||||
onExecute={handleExecute}
|
||||
/>
|
||||
{visibleResultTabs && (
|
||||
<ResultTabs sessionId={sessionId} executeNumber={executeNumber}>
|
||||
|
Loading…
Reference in New Issue
Block a user