diff --git a/src/renderer/components/QueryWorkspace/QueryWorkspace.tsx b/src/renderer/components/QueryWorkspace/QueryWorkspace.tsx index 58e5726..a1ef814 100644 --- a/src/renderer/components/QueryWorkspace/QueryWorkspace.tsx +++ b/src/renderer/components/QueryWorkspace/QueryWorkspace.tsx @@ -35,11 +35,7 @@ interface QueryWorkspaceProps { } export const QueryWorkspace = forwardRef( - ({ - connectionId, - onOpenTableTab, - onRegisterNewTabHandler -}, ref) => { + ({ connectionId, onOpenTableTab, onRegisterNewTabHandler }, ref) => { const [tabs, setTabs] = useState([ { id: '1', @@ -96,18 +92,18 @@ export const QueryWorkspace = forwardRef( } }) - editor.addAction({ - id: 'new-query-tab', - label: 'New Query Tab', - keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyN], - contextMenuGroupId: 'navigation', - contextMenuOrder: 1.6, - run: () => { - if (newTabRef.current) { - newTabRef.current() + editor.addAction({ + id: 'new-query-tab', + label: 'New Query Tab', + keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyN], + contextMenuGroupId: 'navigation', + contextMenuOrder: 1.6, + run: () => { + if (newTabRef.current) { + newTabRef.current() + } } - } - }) + }) }, []) // Tab management functions @@ -184,17 +180,17 @@ export const QueryWorkspace = forwardRef( } }, [openTableTab, onOpenTableTab]) - // Update the ref whenever handleNewTab changes - useEffect(() => { - newTabRef.current = handleNewTab - }, [handleNewTab]) + // Update the ref whenever handleNewTab changes + useEffect(() => { + newTabRef.current = handleNewTab + }, [handleNewTab]) - // Register the new tab handler with parent component - useEffect(() => { - if (onRegisterNewTabHandler) { - onRegisterNewTabHandler(handleNewTab) - } - }, [handleNewTab, onRegisterNewTabHandler]) + // Register the new tab handler with parent component + useEffect(() => { + if (onRegisterNewTabHandler) { + onRegisterNewTabHandler(handleNewTab) + } + }, [handleNewTab, onRegisterNewTabHandler]) const executeQuery = useCallback( async (queryToExecute: string, forceUnlimited = false) => { @@ -628,3 +624,4 @@ export const QueryWorkspace = forwardRef( ) } ) +QueryWorkspace.displayName = 'QueryWorkspace' diff --git a/src/renderer/components/TableView/TableView.tsx b/src/renderer/components/TableView/TableView.tsx index 8bb5a4f..fa8cfee 100644 --- a/src/renderer/components/TableView/TableView.tsx +++ b/src/renderer/components/TableView/TableView.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useRef } from 'react' +import { useState, useEffect, useRef, useCallback } from 'react' import { Box, Button, @@ -66,6 +66,7 @@ export function TableView({ connectionId, database, tableName, onFiltersChange } const [columns, setColumns] = useState([]) const [filters, setFilters] = useState([]) const [result, setResult] = useState(null) + const [changesApplied, setChangesApplied] = useState(true) const [isLoading, setIsLoading] = useState(false) const [isLoadingSchema, setIsLoadingSchema] = useState(true) const [selectedRows, setSelectedRows] = useState>(new Set()) @@ -92,10 +93,71 @@ export function TableView({ connectionId, database, tableName, onFiltersChange } loadTableSchema() }, [connectionId, database, tableName]) + const getValidFilters = useCallback(() => { + return filters.filter( + (f) => + f.column && + f.operator && + (f.value || f.operator === 'IS NULL' || f.operator === 'IS NOT NULL') + ) + }, [filters]) + + const executeQuery = useCallback(async () => { + if (filters.length === getValidFilters().length && changesApplied) { + // check if all filters are valid and if changes have been applied + try { + setIsLoading(true) + const startTime = Date.now() + const validFilters = getValidFilters() + const sessionId = uuidv4() + const queryResult = await window.api.database.queryTable( + connectionId, + { + database, + table: tableName, + filters: validFilters, + limit: pageSize, + offset: (currentPage - 1) * pageSize + }, + sessionId + ) + const executionTime = Date.now() - startTime + + setResult({ + ...queryResult, + executionTime + }) + + // Update total rows for pagination + if (queryResult.totalRows !== undefined) { + setTotalRows(queryResult.totalRows) + } + } catch (error) { + console.error('Query execution error:', error) + setResult({ + success: false, + message: 'Query execution failed', + error: error instanceof Error ? error.message : 'Unknown error' + }) + } finally { + setIsLoading(false) + } + } + }, [ + filters, + getValidFilters, + changesApplied, + connectionId, + database, + tableName, + pageSize, + currentPage + ]) + // Execute query when component mounts, filters change, or pagination changes useEffect(() => { executeQuery() - }, [connectionId, database, tableName, currentPage, pageSize]) + }, [executeQuery]) // Handle keyboard shortcuts useEffect(() => { @@ -180,56 +242,6 @@ export function TableView({ connectionId, database, tableName, onFiltersChange } } } - const getValidFilters = () => { - return filters.filter( - (f) => - f.column && - f.operator && - (f.value || f.operator === 'IS NULL' || f.operator === 'IS NOT NULL') - ) - } - - const executeQuery = async () => { - try { - setIsLoading(true) - const startTime = Date.now() - const validFilters = getValidFilters() - - const sessionId = uuidv4() - const queryResult = await window.api.database.queryTable( - connectionId, - { - database, - table: tableName, - filters: validFilters, - limit: pageSize, - offset: (currentPage - 1) * pageSize - }, - sessionId - ) - const executionTime = Date.now() - startTime - - setResult({ - ...queryResult, - executionTime - }) - - // Update total rows for pagination - if (queryResult.totalRows !== undefined) { - setTotalRows(queryResult.totalRows) - } - } catch (error) { - console.error('Query execution error:', error) - setResult({ - success: false, - message: 'Query execution failed', - error: error instanceof Error ? error.message : 'Unknown error' - }) - } finally { - setIsLoading(false) - } - } - const handlePageChange = (page: number) => { setCurrentPage(page) } @@ -253,6 +265,7 @@ export function TableView({ connectionId, database, tableName, onFiltersChange } } const updateFilter = (id: string, updates: Partial) => { + setChangesApplied(false) const newFilters = filters.map((f) => (f.id === id ? { ...f, ...updates } : f)) setFilters(newFilters) onFiltersChange(newFilters) @@ -813,9 +826,10 @@ export function TableView({ connectionId, database, tableName, onFiltersChange }