1+ import Split from 'react-split'
12import Editor from '@monaco-editor/react'
23import DataGrid from '@supabase/react-data-grid'
4+ import { toJS } from 'mobx'
5+ import { CSVLink } from 'react-csv'
6+ import { debounce } from 'lodash'
7+ import { observer } from 'mobx-react-lite'
8+ import { useEffect , useRef , useState } from 'react'
39import {
410 Button ,
511 Dropdown ,
12+ IconAlertCircle ,
13+ IconCheck ,
614 IconChevronDown ,
715 IconChevronUp ,
816 IconHeart ,
17+ IconLoader ,
918 IconRefreshCcw ,
1019 Typography ,
1120} from '@supabase/ui'
12- import { useKeyboardShortcuts , useStore , useWindowDimensions } from 'hooks'
21+ import * as Tooltip from '@radix-ui/react-tooltip'
22+
23+ import { useKeyboardShortcuts , useStore , useWindowDimensions , usePrevious } from 'hooks'
24+ import Telemetry from 'lib/telemetry'
1325import { IS_PLATFORM } from 'lib/constants'
1426import { copyToClipboard , timeout } from 'lib/helpers'
15- import Telemetry from 'lib/telemetry'
1627import { useSqlStore , UTILITY_TAB_TYPES } from 'localStores/sqlEditor/SqlEditorStore'
17- import { debounce } from 'lodash'
18- import { toJS } from 'mobx'
19- import { observer } from 'mobx-react-lite'
20- import React , { useEffect , useRef , useState } from 'react'
21- import { CSVLink } from 'react-csv'
22- import Split from 'react-split'
2328import { SQL_SNIPPET_SCHEMA_VERSION } from './SqlEditor.constants'
2429
2530const TabSqlQuery = observer ( ( ) => {
@@ -264,15 +269,26 @@ const ResultsDropdown = observer(() => {
264269} )
265270
266271const SavingIndicator = observer ( ( { updateSqlSnippet } ) => {
267- const sqlEditorStore = useSqlStore ( )
268272 const { content } = useStore ( )
273+ const sqlEditorStore = useSqlStore ( )
274+ const previousState = usePrevious ( content . savingState )
275+ const [ showSavedText , setShowSavedText ] = useState ( false )
276+
277+ useEffect ( ( ) => {
278+ let cancel = false
279+
280+ if (
281+ ( previousState === 'CREATING' || previousState === 'UPDATING' ) &&
282+ content . savingState === 'IDLE'
283+ ) {
284+ setShowSavedText ( true )
285+ setTimeout ( ( ) => {
286+ if ( ! cancel ) setShowSavedText ( false )
287+ } , 3000 )
288+ }
269289
270- const dotColorClasses =
271- content . savingState === 'IDLE'
272- ? 'bg-green-900 ring-green-800'
273- : content . savingState === 'CREATING' || content . savingState === 'UPDATING'
274- ? 'bg-gray-900 ring-gray-700'
275- : 'bg-red-900 ring-red-800'
290+ return ( ) => ( cancel = true )
291+ } , [ content . savingState ] )
276292
277293 const retry = ( ) => {
278294 const [ item ] = content . list ( ( item ) => item . id === sqlEditorStore . selectedTabId )
@@ -299,16 +315,46 @@ const SavingIndicator = observer(({ updateSqlSnippet }) => {
299315 Retry
300316 </ Button >
301317 ) }
302-
303- < span
304- className = {
305- 'inline-flex h-2 w-2 rounded-full ring-1 transition-colors duration-200 ' +
306- dotColorClasses
307- }
308- />
318+ { ( content . savingState === 'CREATING' || content . savingState === 'UPDATING' ) && (
319+ < Tooltip . Root delayDuration = { 0 } >
320+ < Tooltip . Trigger >
321+ < IconLoader className = "animate-spin" size = { 14 } strokeWidth = { 2 } />
322+ </ Tooltip . Trigger >
323+ < Tooltip . Content side = "bottom" >
324+ < Tooltip . Arrow className = "radix-tooltip-arrow" />
325+ < div
326+ className = { [
327+ 'bg-scale-100 rounded py-1 px-2 leading-none shadow' ,
328+ 'border-scale-200 border' ,
329+ ] . join ( ' ' ) }
330+ >
331+ < span className = "text-scale-1200 text-xs" > Saving changes...</ span >
332+ </ div >
333+ </ Tooltip . Content >
334+ </ Tooltip . Root >
335+ ) }
336+ { ( content . savingState === 'CREATING_FAILED' || content . savingState === 'UPDATING_FAILED' ) && (
337+ < IconAlertCircle className = "text-red-900" size = { 14 } strokeWidth = { 2 } />
338+ ) }
339+ { showSavedText && (
340+ < Tooltip . Root delayDuration = { 0 } >
341+ < Tooltip . Trigger >
342+ < IconCheck className = "text-brand-800" size = { 14 } strokeWidth = { 3 } />
343+ </ Tooltip . Trigger >
344+ < Tooltip . Content side = "bottom" >
345+ < Tooltip . Arrow className = "radix-tooltip-arrow" />
346+ < div
347+ className = { [
348+ 'bg-scale-100 rounded py-1 px-2 leading-none shadow' ,
349+ 'border-scale-200 border ' ,
350+ ] . join ( ' ' ) }
351+ >
352+ < span className = "text-scale-1200 text-xs" > All changes saved</ span >
353+ </ div >
354+ </ Tooltip . Content >
355+ </ Tooltip . Root >
356+ ) }
309357 < span className = "text-scale-1000 text-sm" >
310- { content . savingState === 'IDLE' && 'All changes saved' }
311- { ( content . savingState === 'CREATING' || content . savingState === 'UPDATING' ) && 'Saving...' }
312358 { content . savingState === 'CREATING_FAILED' && 'Failed to create' }
313359 { content . savingState === 'UPDATING_FAILED' && 'Failed to save' }
314360 </ span >
0 commit comments