/
foult080
/
terminal-db
Обзор
Документация
Войти
/
foult080
/
terminal-db
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/ui/QueryEditor.tsx
120 строк
3 KB
foult080
fix(): save connection name
15 июл 2026, 16:08
15 июл 2026, 16:08
f9400c4
Код
Авторство
О чём код?
import { TextAttributes } from "@opentui/core" import { useEffect, useState } from "react" import type { DbQueryResult, HistoryEntry } from "../core/types/db.js" import type { ThemeColors } from "../core/themes/index.js" import type { SqlCompleter } from "../completion/SqlCompleter.js" import type { CompletionItem } from "../completion/KeywordProvider.js" import { Results } from "./Results.js" import { Editor } from "./Editor.js" import { useQueryEditorKeys } from "./hooks/useQueryEditorKeys.js" interface QueryEditorProps { theme: ThemeColors queryResult: DbQueryResult | null queryError: string | null isQueryRunning: boolean onExecuteQuery: (sql: string) => void sqlEditorText?: string keyboardActive?: boolean sqlCompleter?: SqlCompleter history?: HistoryEntry[] } export function QueryEditor({ theme, queryResult, queryError, isQueryRunning, onExecuteQuery, sqlEditorText = "", keyboardActive = true, sqlCompleter, history = [], }: QueryEditorProps) { const [sqlText, setSqlText] = useState(sqlEditorText) const [cursorPos, setCursorPos] = useState(sqlEditorText.length) const [historyIndex, setHistoryIndex] = useState<number | null>(null) const [showCompletions, setShowCompletions] = useState(false) const [completions, setCompletions] = useState<CompletionItem[]>([]) const [completionIndex, setCompletionIndex] = useState(0) useEffect(() => { setSqlText(sqlEditorText) setCursorPos(sqlEditorText.length) }, [sqlEditorText]) useQueryEditorKeys({ keyboardActive, sqlText, setSqlText, cursorPos, setCursorPos, sqlCompleter, onExecuteQuery, history, historyIndex, setHistoryIndex, showCompletions, setShowCompletions, completions, setCompletions, completionIndex, setCompletionIndex, }) return ( <box flexDirection="column" width="100%" height="100%" gap={2}> <box height={1} flexDirection="row" paddingLeft={1}> <text attributes={TextAttributes.BOLD} fg={theme.primary}> Results </text> {isQueryRunning && ( <text fg={theme.textMuted} attributes={TextAttributes.DIM}> {" "}Running... </text> )} {queryResult && ( <text fg={theme.textMuted} attributes={TextAttributes.DIM}> {" "}({queryResult.rowCount} rows in {queryResult.duration}ms) </text> )} </box> <Results theme={theme} queryResult={queryResult} queryError={queryError} flexGrow={6} /> {showCompletions && completions.length > 0 && ( <box flexDirection="column" borderStyle="single" borderColor={theme.primary} maxHeight={8}> <scrollbox width="100%" height="100%"> {completions.map((c, i) => ( <box key={c.label} height={1} paddingLeft={1}> <text fg={i === completionIndex ? theme.primary : theme.text}>{c.label}</text> </box> ))} </scrollbox> </box> )} <box height={1} flexDirection="row" paddingLeft={1}> <text attributes={TextAttributes.BOLD} fg={theme.primary}> SQL Editor </text> <box flexGrow={1} /> <text fg={theme.textMuted} attributes={TextAttributes.DIM}> Ctrl+R run | Tab complete | Esc clear </text> </box> <Editor theme={theme} sqlText={sqlText} cursorPos={cursorPos} height={6} /> </box> ) }