From dd36c639505cd7821964915d2ac752de1621dc0e Mon Sep 17 00:00:00 2001 From: 2160039878-cyber <285580214+2160039878-cyber@users.noreply.github.com> Date: Thu, 10 Sep 2026 11:49:48 +0800 Subject: [PATCH 1/2] feat(explorer): preview tables on double-click and refresh rows --- docs/ARCHITECTURE.md | 8 ++++ src/components/Studio.tsx | 7 +++ .../schema-explorer/SchemaExplorer.tsx | 21 ++++++++- src/components/schema-explorer/TableItem.tsx | 2 + src/components/sidebar/Sidebar.tsx | 3 ++ src/components/studio/BottomPanel.tsx | 21 +++++++++ src/hooks/use-tab-manager.ts | 1 + src/lib/types.ts | 2 + src/workspace/StudioWorkspace.tsx | 6 +++ tests/components/Studio.test.tsx | 21 +++++++++ tests/components/StudioWorkspace.test.tsx | 14 ++++++ .../schema-explorer/SchemaExplorer.test.tsx | 22 ++++++++- .../schema-explorer/TableItem.test.tsx | 28 ++++++++++++ tests/components/sidebar/Sidebar.test.tsx | 7 +++ tests/components/studio/BottomPanel.test.tsx | 45 +++++++++++++++++++ tests/hooks/use-tab-manager.test.ts | 2 + 16 files changed, 208 insertions(+), 2 deletions(-) diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 97bfa34ca..607b6e0d5 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -185,6 +185,14 @@ Multi-statement queries execute sequentially via `POST /api/db/multi-query`. - **React hooks** for UI state: tabs, active connection, execution status - **Custom hooks** extracted from Studio.tsx: `useAuth`, `useConnectionManager`, `useTabManager`, `useTransactionControl`, `useQueryExecution`, `useInlineEditing` +Double-clicking an Explorer table uses `useTabManager.handleTableClick`, the same action as +Select Top 50: it opens a new query tab and executes the provider's preview query. A session-only +`QueryTab.previewQuery` records that generated query. BottomPanel's **Refresh rows** reruns it +on the same tab through the standalone or embedded execution hook; it is hidden after query +edits and for stored agent results, and disabled during execution, pagination or pending cell +edits. **Refresh schema** separately invokes the current connection's schema fetch, including +from empty/error states, without executing a query or replacing editor tabs. + ### 4.6. Workspace Abstraction (npm package embedding) Studio ships both as a standalone app and as the `@libredb/studio` npm package consumed by libredb-platform (built with `tsup` via `build:lib`). diff --git a/src/components/Studio.tsx b/src/components/Studio.tsx index 30258b222..b2407f5dc 100644 --- a/src/components/Studio.tsx +++ b/src/components/Studio.tsx @@ -397,6 +397,10 @@ export default function Studio() { tabMgr.handleTableClick(tableName, queryExec.executeQuery); }; + const onRefreshSchema = () => { + if (conn.activeConnection) conn.fetchSchema(conn.activeConnection); + }; + const requestDeleteConnection = (id: string) => { setPendingDeleteConnectionId(id); }; @@ -494,6 +498,7 @@ export default function Studio() { }} onAddConnection={() => setIsConnectionModalOpen(true)} onTableClick={onTableClick} + onRefreshSchema={onRefreshSchema} onGenerateSelect={tabMgr.handleGenerateSelect} onCreateTableClick={() => setIsCreateTableModalOpen(true)} onShowDiagram={() => setShowDiagram(true)} @@ -623,6 +628,7 @@ export default function Studio() { onTableClick(tableName); setActiveMobileTab("editor"); }} + onRefreshSchema={onRefreshSchema} onGenerateSelect={(tableName) => { tabMgr.handleGenerateSelect(tableName); setActiveMobileTab("editor"); @@ -687,6 +693,7 @@ export default function Studio() { void; + onRefreshSchema?: () => void; onGenerateSelect?: (tableName: string) => void; onCreateTableClick?: () => void; isAdmin?: boolean; @@ -35,6 +36,7 @@ export function SchemaExplorer({ isLoadingSchema, schemaError = null, onTableClick, + onRefreshSchema, onGenerateSelect, onCreateTableClick, isAdmin = false, @@ -48,6 +50,19 @@ export function SchemaExplorer({ const capabilities = metadata?.capabilities; const [searchQuery, setSearchQuery] = useState(""); const [expandedTables, setExpandedTables] = useState>(new Set()); + const refreshButton = onRefreshSchema && ( + + ); const toggleTable = useCallback((tableName: string) => { setExpandedTables((prev) => { @@ -80,6 +95,7 @@ export function SchemaExplorer({ Scanning Schema... + {refreshButton} ); } @@ -99,6 +115,7 @@ export function SchemaExplorer({

Schema could not be read

{schemaError}

+ {refreshButton} ); } @@ -113,6 +130,7 @@ export function SchemaExplorer({

We couldn't find any tables or views in this connection.

+ {refreshButton} {capabilities?.supportsCreateTable !== false && ( + )} + ); const toggleTable = useCallback((tableName: string) => {