-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from invm/results-table
feat: results table
- Loading branch information
Showing
11 changed files
with
155 additions
and
140 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
49 changes: 32 additions & 17 deletions
49
src/components/Screens/Console/Content/QueryTab/QueryTab.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,45 @@ | ||
import { createEffect, onCleanup } from "solid-js" | ||
import Split from "split.js" | ||
import { QueryTextArea } from "./QueryTextArea" | ||
import { ResultsArea } from "./ResultsArea" | ||
import { Table } from "components/UI"; | ||
import { ContentTabData } from "services/ConnectionTabs"; | ||
import { useAppSelector } from "services/Context"; | ||
import { createEffect, createSignal, onCleanup, Show } from "solid-js"; | ||
import Split from "split.js"; | ||
import { QueryTextArea } from "./QueryTextArea"; | ||
|
||
export const QueryTab = () => { | ||
const { | ||
connectionsService: { getActiveContentTab }, | ||
} = useAppSelector(); | ||
const [data, setData] = createSignal<Record<string, any>[]>([]); | ||
|
||
createEffect(() => { | ||
const q = Split(['#query', '#results'], { | ||
const tabledata = (getActiveContentTab().data as ContentTabData["QueryTab"]) | ||
.results; | ||
if (!tabledata.length) return; | ||
setData(tabledata); | ||
}); | ||
createEffect(() => { | ||
const q = Split(["#query", "#results"], { | ||
sizes: [40, 60], | ||
minSize: [100, 400], | ||
direction: 'vertical', | ||
maxSize: [500, Infinity], | ||
direction: "vertical", | ||
gutterSize: 8, | ||
}) | ||
}); | ||
onCleanup(() => { | ||
q.destroy() | ||
}) | ||
}) | ||
q.destroy(); | ||
}); | ||
}); | ||
|
||
return ( | ||
<div class="flex flex-col h-full"> | ||
<div id="query" class="flex max-h-[40%]"> | ||
<div class="flex flex-col h-full overflow-hidden"> | ||
<div id="query" class="flex"> | ||
<QueryTextArea /> | ||
</div> | ||
<div id="results" class="max-h-[60%] h-full bg-base-200 p-3 overflow-hidden"> | ||
<ResultsArea /> | ||
<div id="results" class="overflow-y-scroll"> | ||
<Show when={data().length}> | ||
<Table data={data()} /> | ||
</Show> | ||
</div> | ||
</div > | ||
) | ||
} | ||
</div> | ||
); | ||
}; |
103 changes: 68 additions & 35 deletions
103
src/components/Screens/Console/Content/QueryTab/QueryTextArea.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,69 +1,102 @@ | ||
import { createCodeMirror, createEditorControlledValue } from "solid-codemirror"; | ||
import { | ||
createCodeMirror, | ||
createEditorControlledValue, | ||
} from "solid-codemirror"; | ||
import { createEffect, createSignal } from "solid-js"; | ||
import { lineNumbers } from '@codemirror/view'; | ||
import { sql } from '@codemirror/lang-sql' | ||
import { dracula } from '@uiw/codemirror-theme-dracula' | ||
import { format } from 'sql-formatter'; | ||
import { lineNumbers } from "@codemirror/view"; | ||
import { sql } from "@codemirror/lang-sql"; | ||
import { dracula } from "@uiw/codemirror-theme-dracula"; | ||
import { format } from "sql-formatter"; | ||
import { t } from "i18next"; | ||
import { invoke } from '@tauri-apps/api'; | ||
import { invoke } from "@tauri-apps/api"; | ||
import { EditIcon, FireIcon } from "components/UI/Icons"; | ||
import { useAppSelector } from "services/Context"; | ||
import { ContentTab, ContentTabData } from "services/ConnectionTabs"; | ||
import { QueryResult } from "interfaces"; | ||
|
||
export const QueryTextArea = () => { | ||
const { connectionsService: { setActiveContentQueryTabData, contentStore, | ||
setContentStore, getActiveConnection, getActiveContentTab } } = | ||
useAppSelector() | ||
const { | ||
connectionsService: { | ||
setActiveContentQueryTabData, | ||
contentStore, | ||
setContentStore, | ||
getActiveConnection, | ||
getActiveContentTab, | ||
}, | ||
} = useAppSelector(); | ||
|
||
const updateQueryText = async (query: string) => { | ||
setContentStore('tabs', contentStore.tabs.map((t, idx) => idx === contentStore.idx ? { | ||
...t, | ||
data: { ...t.data, query } | ||
} as ContentTab<'QueryTab'> : t)) | ||
} | ||
setContentStore( | ||
"tabs", | ||
contentStore.tabs.map((t, idx) => | ||
idx === contentStore.idx | ||
? ({ | ||
...t, | ||
data: { ...t.data, query }, | ||
} as ContentTab<"QueryTab">) | ||
: t | ||
) | ||
); | ||
}; | ||
|
||
const onInput = (q: string) => { | ||
updateQueryText(q) | ||
setCode(q) | ||
} | ||
updateQueryText(q); | ||
setCode(q); | ||
}; | ||
|
||
const [code, setCode] = createSignal(''); | ||
const { ref, editorView, createExtension } = createCodeMirror({ onValueChange: onInput }); | ||
const [code, setCode] = createSignal(""); | ||
const { ref, editorView, createExtension } = createCodeMirror({ | ||
onValueChange: onInput, | ||
}); | ||
createEditorControlledValue(editorView, code); | ||
createExtension(() => lineNumbers()); | ||
createExtension(() => sql()); | ||
createExtension(dracula); | ||
|
||
const onFormat = () => { | ||
const formatted = format(code()) | ||
onInput(formatted) | ||
} | ||
const formatted = format(code()); | ||
onInput(formatted); | ||
}; | ||
|
||
const onExecute = async () => { | ||
const activeConnection = getActiveConnection() | ||
const { result } = await invoke<QueryResult>('execute_query', { connId: activeConnection.id, query: code() }) | ||
console.log(result) | ||
setActiveContentQueryTabData({ query: code(), results: result }) | ||
} | ||
const activeConnection = getActiveConnection(); | ||
const { result } = await invoke<QueryResult>("execute_query", { | ||
connId: activeConnection.id, | ||
query: code(), | ||
}); | ||
console.log(result); | ||
setActiveContentQueryTabData({ query: code(), results: result }); | ||
}; | ||
|
||
createEffect(() => { | ||
setCode((getActiveContentTab()?.data as ContentTabData['QueryTab']).query ?? '') | ||
}) | ||
setCode( | ||
(getActiveContentTab()?.data as ContentTabData["QueryTab"]).query ?? "" | ||
); | ||
}); | ||
|
||
return ( | ||
<div class="flex-1 flex flex-col"> | ||
<div class="w-full p-1 bg-base-100"> | ||
<div class="tooltip tooltip-primary" data-tip={t('components.console.actions.format')}> | ||
<button class="btn btn-ghost btn-sm mr-2" onClick={() => onFormat()}><EditIcon /></button> | ||
<div | ||
class="tooltip tooltip-primary tooltip-bottom" | ||
data-tip={t("components.console.actions.format")} | ||
> | ||
<button class="btn btn-ghost btn-sm mr-2" onClick={() => onFormat()}> | ||
<EditIcon /> | ||
</button> | ||
</div> | ||
<div class="tooltip tooltip-primary" data-tip={t('components.console.actions.execute')}> | ||
<button class="btn btn-ghost btn-sm mr-2" onClick={() => onExecute()}><FireIcon /></button> | ||
<div | ||
class="tooltip tooltip-primary tooltip-bottom" | ||
data-tip={t("components.console.actions.execute")} | ||
> | ||
<button class="btn btn-ghost btn-sm mr-2" onClick={() => onExecute()}> | ||
<FireIcon /> | ||
</button> | ||
</div> | ||
</div> | ||
<div class="overflow-hidden w-full h-full"> | ||
<div ref={ref} class="w-full h-full" /> | ||
</div> | ||
</div> | ||
) | ||
} | ||
); | ||
}; |
25 changes: 0 additions & 25 deletions
25
src/components/Screens/Console/Content/QueryTab/ResultsArea.tsx
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.