import React from 'react'; import { Button, Dropdown, Tabs, Tooltip, message, type MenuProps } from 'antd'; import { BugOutlined, CloseOutlined, CopyOutlined, EyeInvisibleOutlined, RobotOutlined } from '@ant-design/icons'; import type { EditRowLocator } from '../utils/rowLocator'; import type { QueryResultPaginationState } from '../utils/queryResultPagination'; import { t as defaultTranslate } from '../i18n'; import { useOptionalI18n } from '../i18n/provider'; import DataGrid from './DataGrid'; import LogPanel from './LogPanel'; export const QUERY_EDITOR_SQL_LOG_TAB_KEY = '__gonavi_sql_execution_log__'; export type QueryEditorResultSet = { key: string; sql: string; exportSql?: string; sourceStatementIndex?: number; statementResultIndex?: number; rows: any[]; columns: string[]; messages?: string[]; resultType?: 'grid' | 'message'; tableName?: string; pkColumns: string[]; editLocator?: EditRowLocator; readOnly: boolean; showRowNumberColumn?: boolean; truncated?: boolean; pkLoading?: boolean; page?: QueryResultPaginationState & { loading?: boolean }; }; interface QueryEditorResultsPanelProps { resultSets: QueryEditorResultSet[]; activeResultKey: string; loading: boolean; executionError: string; sqlLogCount: number; darkMode: boolean; isV2Ui: boolean; currentDb: string; currentConnectionId: string; toggleShortcutLabel: string; onActiveResultKeyChange: (key: string) => void; onHide: () => void; onCloseResult: (key: string) => void; onCloseOtherResultTabs: (key: string) => void; onCloseResultTabsToLeft: (key: string) => void; onCloseResultTabsToRight: (key: string) => void; onCloseAllResultTabs: () => void; onReloadResult: (key: string, sql: string) => void; onResultPageChange: (key: string, page: number, pageSize: number) => void; onDiagnoseExecutionError: () => void; } const isAffectedRowsResult = (result: QueryEditorResultSet): boolean => result.columns.length === 1 && result.columns[0] === 'affectedRows'; const QueryEditorResultsPanel: React.FC = ({ resultSets, activeResultKey, loading, executionError, sqlLogCount, darkMode, isV2Ui, currentDb, currentConnectionId, toggleShortcutLabel, onActiveResultKeyChange, onHide, onCloseResult, onCloseOtherResultTabs, onCloseResultTabsToLeft, onCloseResultTabsToRight, onCloseAllResultTabs, onReloadResult, onResultPageChange, onDiagnoseExecutionError, }) => { const i18n = useOptionalI18n(); const t = i18n?.t ?? defaultTranslate; const shouldShowSqlLogTab = isV2Ui && (sqlLogCount > 0 || activeResultKey === QUERY_EDITOR_SQL_LOG_TAB_KEY); const logTabCountLabel = sqlLogCount > 999 ? '999+' : String(sqlLogCount); const resolvedResultSetKey = activeResultKey && resultSets.some((rs) => rs.key === activeResultKey) ? activeResultKey : (resultSets[0]?.key || ''); const hideTooltipTitle = toggleShortcutLabel ? t('query_editor.results_panel.tooltip.hide_with_shortcut', { shortcut: toggleShortcutLabel }) : t('query_editor.results_panel.tooltip.hide'); const handleMessageTextareaKeyDown = (event: React.KeyboardEvent) => { if (!(event.ctrlKey || event.metaKey) || event.altKey || event.shiftKey || event.key.toLowerCase() !== 'a') { return; } event.preventDefault(); event.stopPropagation(); event.currentTarget.focus(); event.currentTarget.select(); }; const handleCopyMessageText = async (text: string) => { const safeText = String(text || ''); if (!safeText.trim()) { return; } try { if (typeof navigator?.clipboard?.writeText !== 'function') { throw new Error(t('query_editor.results_panel.message.copy_unsupported')); } await navigator.clipboard.writeText(safeText); message.success(t('data_grid.message.copied_to_clipboard')); } catch (error: any) { message.error(t('query_editor.results_panel.message.copy_failed', { detail: error?.message || t('common.unknown'), })); } }; const renderMessageBlock = ({ text, title, fontSize, fillHeight = false, compact = false, maxWidth, color, marginTop, }: { text: string; title?: string; fontSize: string; fillHeight?: boolean; compact?: boolean; maxWidth?: number; color: string; marginTop?: number; }) => (
{title ? {title} : }