Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 23 additions & 26 deletions src/renderer/components/QueryWorkspace/QueryWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,7 @@ interface QueryWorkspaceProps {
}

export const QueryWorkspace = forwardRef<any, QueryWorkspaceProps>(
({
connectionId,
onOpenTableTab,
onRegisterNewTabHandler
}, ref) => {
({ connectionId, onOpenTableTab, onRegisterNewTabHandler }, ref) => {
const [tabs, setTabs] = useState<Tab[]>([
{
id: '1',
Expand Down Expand Up @@ -96,18 +92,18 @@ export const QueryWorkspace = forwardRef<any, QueryWorkspaceProps>(
}
})

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
Expand Down Expand Up @@ -184,17 +180,17 @@ export const QueryWorkspace = forwardRef<any, QueryWorkspaceProps>(
}
}, [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) => {
Expand Down Expand Up @@ -628,3 +624,4 @@ export const QueryWorkspace = forwardRef<any, QueryWorkspaceProps>(
)
}
)
QueryWorkspace.displayName = 'QueryWorkspace'
122 changes: 68 additions & 54 deletions src/renderer/components/TableView/TableView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState, useEffect, useRef } from 'react'
import { useState, useEffect, useRef, useCallback } from 'react'
import {
Box,
Button,
Expand Down Expand Up @@ -66,6 +66,7 @@ export function TableView({ connectionId, database, tableName, onFiltersChange }
const [columns, setColumns] = useState<Column[]>([])
const [filters, setFilters] = useState<TableFilter[]>([])
const [result, setResult] = useState<QueryResult | null>(null)
const [changesApplied, setChangesApplied] = useState<boolean>(true)
const [isLoading, setIsLoading] = useState(false)
const [isLoadingSchema, setIsLoadingSchema] = useState(true)
const [selectedRows, setSelectedRows] = useState<Set<number>>(new Set())
Expand All @@ -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(() => {
Expand Down Expand Up @@ -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)
}
Expand All @@ -253,6 +265,7 @@ export function TableView({ connectionId, database, tableName, onFiltersChange }
}

const updateFilter = (id: string, updates: Partial<TableFilter>) => {
setChangesApplied(false)
const newFilters = filters.map((f) => (f.id === id ? { ...f, ...updates } : f))
setFilters(newFilters)
onFiltersChange(newFilters)
Expand Down Expand Up @@ -813,9 +826,10 @@ export function TableView({ connectionId, database, tableName, onFiltersChange }
</Button>
<Button
size="1"
onClick={() => {
onClick={async () => {
setCurrentPage(1)
executeQuery()
await executeQuery()
setChangesApplied(true)
}}
disabled={isLoading}
title="Apply filters"
Expand Down