Skip to content

Commit 798e260

Browse files
committed
fix: reload tables in open tabs on refresh
1 parent b53f87f commit 798e260

10 files changed

Lines changed: 114 additions & 41 deletions

File tree

apps/desktop/renderer/src/app/providers/datary-provider.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,37 @@ interface DataryProviderProps {
88
}
99

1010
export function DataryProvider({ children }: DataryProviderProps) {
11-
const [dataryReady, setDataryReady] = useState<boolean | null>(null)
11+
const [ready, setReady] = useState<boolean | null>(null)
1212

1313
useEffect(() => {
1414
const checkInterval = setInterval(() => {
15-
if ((window as any).datary) {
16-
setDataryReady(true)
15+
if (window.datary) {
16+
setReady(true)
1717
clearInterval(checkInterval)
1818
}
1919
}, 100)
2020

2121
const timeout = setTimeout(() => {
22-
if (!dataryReady) setDataryReady(false)
22+
if (!ready) setReady(false)
2323
}, 3000)
2424

2525
return () => {
2626
clearInterval(checkInterval)
2727
clearTimeout(timeout)
2828
}
29-
}, [dataryReady])
29+
}, [ready])
3030

3131
const handleReload = () => window.location.reload()
3232

33-
if (dataryReady === null) {
33+
if (ready === null) {
3434
return (
3535
<div className="bg-background text-foreground flex h-screen w-screen items-center justify-center">
3636
<Loader2 className="text-primary h-9 w-9 animate-spin" />
3737
</div>
3838
)
3939
}
4040

41-
if (!dataryReady) {
41+
if (!ready) {
4242
return (
4343
<div className="bg-background text-foreground flex h-screen w-screen flex-col items-center justify-center gap-4">
4444
<h1 className="text-2xl font-bold">Something went wrong</h1>

apps/desktop/renderer/src/app/store/table-data.store.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface TableDataState {
77
tables: Record<string, TableData>
88
loading: boolean
99
loadTable: (schema: string, table: string) => Promise<void>
10+
reset: () => void
1011
}
1112

1213
export const useTableDataStore = create<TableDataState>((set, get) => ({
@@ -34,5 +35,10 @@ export const useTableDataStore = create<TableDataState>((set, get) => ({
3435
},
3536
loading: false
3637
}))
37-
}
38+
},
39+
reset: () =>
40+
set({
41+
tables: {},
42+
loading: false
43+
})
3844
}))

apps/desktop/renderer/src/app/styles/globals.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@
120120
}
121121

122122
@layer base {
123+
123124
html,
124125
body {
125126
margin: 0;
@@ -158,4 +159,4 @@
158159

159160
*::-webkit-scrollbar-corner {
160161
background: var(--color-sidebar);
161-
}
162+
}

apps/desktop/renderer/src/modules/explorer/components/ExplorerHeader.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { LogOut, RefreshCw, Settings, Terminal } from 'lucide-react'
1+
import { LogOut, RefreshCw, Terminal } from 'lucide-react'
22

3+
import { cn } from '@/shared/lib/utils'
34
import { Button } from '@/shared/ui/button'
45

56
interface ExplorerHeaderProps {
@@ -27,9 +28,10 @@ export function ExplorerHeader({
2728
size="sm"
2829
className="gap-2 bg-transparent"
2930
onClick={onRefresh}
31+
disabled={isRefreshing}
3032
>
31-
<RefreshCw className="h-4 w-4" data-animate={isRefreshing ? 'spin' : ''} />
32-
Refresh
33+
<RefreshCw className={cn('h-4 w-4', isRefreshing && 'animate-spin')} />
34+
{isRefreshing ? 'Refreshing' : 'Refresh'}
3335
</Button>
3436

3537
<Button
@@ -42,11 +44,6 @@ export function ExplorerHeader({
4244
Query
4345
</Button>
4446

45-
<Button variant="outline" size="icon" className="h-8 w-8 bg-transparent">
46-
<Settings className="h-4 w-4" />
47-
<span className="sr-only">Settings</span>
48-
</Button>
49-
5047
<Button
5148
variant="ghost"
5249
size="icon"

apps/desktop/renderer/src/modules/explorer/components/tabs/ExplorerTabs.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { Tab } from '../../types/explorer.types'
44

55
import { TabContent } from './TabContent'
66
import { TableTabs } from '@/shared/components/table-tabs'
7+
import { cn } from '@/shared/lib/utils'
78

89
interface Props {
910
tabs: Tab[]
@@ -23,8 +24,11 @@ export function ExplorerTabs({ tabs, activeTab, onSelectTab, onCloseTab }: Props
2324
onCloseTab={onCloseTab}
2425
>
2526
{tabs.map(tab => (
26-
<div key={tab.id} className="h-full">
27-
{activeTab === tab.id && <TabContent tab={tab} />}
27+
<div
28+
key={tab.id}
29+
className={cn('h-full', activeTab === tab.id ? 'block' : 'hidden')}
30+
>
31+
<TabContent tab={tab} />
2832
</div>
2933
))}
3034
</TableTabs>
Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { useEffect } from 'react'
1+
import { useCallback, useEffect } from 'react'
22

3+
import { useTableDataStore } from '@/app/store/table-data.store'
34
import { useConnectionStore } from '@/entities/connection/model/connection.store'
45

56
export function useDatabase() {
@@ -11,30 +12,54 @@ export function useDatabase() {
1112
const databases = useConnectionStore(s => s.databases)
1213
const setDatabases = useConnectionStore(s => s.setDatabases)
1314

14-
useEffect(() => {
15-
if (!connection) return
15+
const resetTables = useTableDataStore(s => s.reset)
16+
17+
const connect = useCallback(
18+
async (dbName?: string) => {
19+
if (!connection) return
1620

17-
const init = async () => {
1821
await window.datary.db.connect({
1922
...connection,
20-
database: connection.database || 'postgres'
23+
database: dbName ?? connection.database ?? 'postgres'
2124
})
25+
2226
const dbs = await window.datary.db.loadDatabases()
2327

2428
setDatabases(dbs.map(d => d.name))
25-
setSelectedDatabase(connection.database || dbs[0].name)
26-
}
29+
setSelectedDatabase(dbName ?? connection.database ?? dbs[0]?.name)
30+
},
31+
[connection]
32+
)
2733

28-
init()
34+
useEffect(() => {
35+
if (!connection) return
36+
connect()
2937
}, [connection])
3038

3139
const selectDatabase = async (dbName: string) => {
40+
resetTables()
41+
42+
await connect(dbName)
43+
}
44+
45+
const refresh = async () => {
3246
if (!connection) return
3347

34-
await window.datary.db.connect({ ...connection, database: dbName })
48+
resetTables()
3549

36-
setSelectedDatabase(dbName)
50+
await window.datary.db.connect({
51+
...connection,
52+
database: selectedDatabase
53+
})
54+
55+
const dbs = await window.datary.db.loadDatabases()
56+
setDatabases(dbs.map(d => d.name))
3757
}
3858

39-
return { selectedDatabase, databases, selectDatabase }
59+
return {
60+
selectedDatabase,
61+
databases,
62+
selectDatabase,
63+
refresh
64+
}
4065
}

apps/desktop/renderer/src/modules/explorer/hooks/useExplorer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export function useExplorer() {
77
const sidebar = useExplorerSidebar()
88
const tabs = useExplorerTabs()
99
const database = useDatabase()
10-
const actions = useExplorerActions(tabs)
10+
const actions = useExplorerActions(tabs, database)
1111

1212
return {
1313
sidebar,

apps/desktop/renderer/src/modules/explorer/hooks/useExplorerActions.ts

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,34 @@
11
import { useState } from 'react'
2+
import toast from 'react-hot-toast'
3+
import { useNavigate } from 'react-router-dom'
24

35
import { useTableDataStore } from '@/app/store/table-data.store'
46

5-
export function useExplorerActions(tabs: any) {
7+
export function useExplorerActions(tabs: any, database: any) {
68
const loadTable = useTableDataStore(s => s.loadTable)
9+
710
const [isRefreshing, setIsRefreshing] = useState(false)
11+
const navigate = useNavigate()
812

913
const handleRefresh = async () => {
14+
if (isRefreshing) return
15+
1016
setIsRefreshing(true)
11-
await new Promise(r => setTimeout(r, 800))
12-
setIsRefreshing(false)
17+
18+
try {
19+
await database.refresh()
20+
21+
for (const tab of tabs.tabs) {
22+
if (tab.type === 'table') {
23+
await loadTable('public', tab.name)
24+
}
25+
}
26+
} catch (e: any) {
27+
toast.error(`Refresh error: ${e.message}`)
28+
console.error(e)
29+
} finally {
30+
setIsRefreshing(false)
31+
}
1332
}
1433

1534
const handleOpenQueryTab = () => tabs.addTab({ name: 'Query', type: 'query' })
@@ -20,8 +39,10 @@ export function useExplorerActions(tabs: any) {
2039
tabs.addTab({ name: tableName, type: 'table' })
2140
}
2241

23-
const handleDisconnect = () => {
24-
window.location.hash = '/'
42+
const handleDisconnect = async () => {
43+
await window.datary.db.disconnect()
44+
45+
navigate('/')
2546
}
2647

2748
return {

apps/desktop/renderer/src/modules/explorer/hooks/useExplorerTabs.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,29 @@ export function useExplorerTabs() {
1616
return id
1717
}, [])
1818

19-
const closeTab = useCallback((tabId: string) => {
20-
setTabs(prev => prev.filter(t => t.id !== tabId))
21-
setActiveTab(prevActive => (prevActive === tabId ? '' : prevActive))
22-
}, [])
19+
const closeTab = useCallback(
20+
(tabId: string) => {
21+
setTabs(prev => {
22+
const index = prev.findIndex(t => t.id === tabId)
23+
const nextTabs = prev.filter(t => t.id !== tabId)
24+
25+
if (activeTab !== tabId) {
26+
return nextTabs
27+
}
28+
29+
if (nextTabs.length === 0) {
30+
setActiveTab('')
31+
return nextTabs
32+
}
33+
34+
const nextIndex = index < nextTabs.length ? index : nextTabs.length - 1
35+
setActiveTab(nextTabs[nextIndex].id)
36+
37+
return nextTabs
38+
})
39+
},
40+
[activeTab]
41+
)
2342

2443
return { tabs, activeTab, setActiveTab, addTab, closeTab }
2544
}

apps/desktop/renderer/src/shared/components/data-table.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ export function DataTable({ data, onCellUpdate }: DataTableProps) {
334334
<SelectTrigger className="h-8 w-16">
335335
<SelectValue />
336336
</SelectTrigger>
337-
<SelectContent>
337+
<SelectContent position="popper" side="top">
338338
<SelectItem value="10">10</SelectItem>
339339
<SelectItem value="25">25</SelectItem>
340340
<SelectItem value="50">50</SelectItem>

0 commit comments

Comments
 (0)