11"use client" ;
22
3- import { CommandIcon , CornerDownLeft , PauseIcon , PlayIcon } from "lucide-react" ;
3+ import { CommandIcon , CornerDownLeft , LoaderIcon , PauseIcon , PlayIcon } from "lucide-react" ;
44import { KeyCode , KeyMod , editor } from "monaco-editor/esm/vs/editor/editor.api" ;
55import { useQueryState } from "nuqs" ;
66import { useEffect , useRef , useState } from "react" ;
@@ -26,13 +26,19 @@ export function SQLEditor({ table, isLiveQuery, setIsLiveQuery }: Props) {
2626 const editorRef = useRef < editor . IStandaloneCodeEditor | null > ( null ) ;
2727 const containerRef = useRef < HTMLDivElement > ( null ) ;
2828 const [ isFocused , setIsFocused ] = useState ( false ) ;
29+ const [ isUserTriggeredRefetch , setIsUserTriggeredRefetch ] = useState ( false ) ;
2930 const [ query , setQuery ] = useQueryState ( "query" , { defaultValue : "" } ) ;
3031 const validateQuery = useQueryValidator ( table ) ;
31- const { data : tableData , refetch } = useTableDataQuery ( {
32+ const {
33+ data : tableData ,
34+ refetch,
35+ isRefetching : isTableDataRefetching ,
36+ } = useTableDataQuery ( {
3237 table,
3338 query,
3439 isLiveQuery,
3540 } ) ;
41+ const isRefetching = isTableDataRefetching && isUserTriggeredRefetch ;
3642 useMonacoSuggestions ( table ) ;
3743
3844 const form = useForm ( {
@@ -45,7 +51,9 @@ export function SQLEditor({ table, isLiveQuery, setIsLiveQuery }: Props) {
4551 const handleSubmit = form . handleSubmit ( ( data ) => {
4652 if ( validateQuery ( data . query ) ) {
4753 setQuery ( data . query ) ;
48- refetch ( ) ;
54+
55+ setIsUserTriggeredRefetch ( true ) ;
56+ refetch ( ) . finally ( ( ) => setIsUserTriggeredRefetch ( false ) ) ;
4957 }
5058 } ) ;
5159
@@ -93,6 +101,7 @@ export function SQLEditor({ table, isLiveQuery, setIsLiveQuery }: Props) {
93101 label : "Execute SQL command" ,
94102 keybindings : [ KeyMod . CtrlCmd | KeyCode . Enter ] ,
95103 run : ( ) => {
104+ console . log ( "EXECUTING SQL COMMAND" ) ;
96105 handleSubmit ( ) ;
97106 } ,
98107 } ) ;
@@ -136,27 +145,38 @@ export function SQLEditor({ table, isLiveQuery, setIsLiveQuery }: Props) {
136145 </ span >
137146
138147 < Tooltip text = { isLiveQuery ? "Pause live query" : "Start live query" } >
139- < Button variant = "outline" size = "icon" onClick = { ( ) => setIsLiveQuery ( ! isLiveQuery ) } >
148+ < Button
149+ type = "button"
150+ variant = "outline"
151+ size = "icon"
152+ onClick = { ( e ) => {
153+ e . preventDefault ( ) ;
154+ setIsLiveQuery ( ! isLiveQuery ) ;
155+ } }
156+ >
140157 { isLiveQuery ? < PauseIcon className = "h-4 w-4" /> : < PlayIcon className = "h-4 w-4" /> }
141158 </ Button >
142159 </ Tooltip >
143160 </ >
144161 ) : null }
145162
146- < Button className = "flex gap-2 pl-4 pr-3" type = "submit" >
163+ < Button className = "group relative flex gap-2 pl-4 pr-3" type = "submit" disabled = { isRefetching } >
147164 Run
148- < span className = "flex items-center gap-0.5 text-white/60" >
149- { navigator . platform . toLowerCase ( ) . includes ( "mac" ) ? (
150- < >
151- < CommandIcon className = "h-3 w-3" />
152- < CornerDownLeft className = "h-3 w-3" />
153- </ >
154- ) : (
155- < >
156- < span className = "text-xs" > CTRL</ span >
157- < CornerDownLeft className = "h-3 w-3" />
158- </ >
159- ) }
165+ < span className = "relative flex items-center gap-0.5 text-white/60" >
166+ < LoaderIcon className = "absolute h-4 w-4 animate-spin opacity-0 group-disabled:opacity-100" />
167+ < span className = "flex items-center gap-0.5 opacity-100 group-disabled:opacity-0" >
168+ { navigator . platform . toLowerCase ( ) . includes ( "mac" ) ? (
169+ < >
170+ < CommandIcon className = "h-3 w-3" />
171+ < CornerDownLeft className = "h-3 w-3" />
172+ </ >
173+ ) : (
174+ < >
175+ < span className = "text-xs" > CTRL</ span >
176+ < CornerDownLeft className = "h-3 w-3" />
177+ </ >
178+ ) }
179+ </ span >
160180 </ span >
161181 </ Button >
162182 </ div >
0 commit comments