fix(grid): reset scroll for replacement query results

Closes #5950
This commit is contained in:
t8y2 committed 2026-08-12 06:17:42 +00:00
1 parent c27a4dd83d
commit 143143a88d
9 files changed
+111 -12

No files matched your search

@@ -13,6 +13,8 @@ const mocks = vi.hoisted(() => ({
getConnectionConfig: vi.fn(),
prepareQueryPaginationExecutionPlan: vi.fn(),
saveOpenTabsState: vi.fn(),
clearDataGridPendingSnapshot: vi.fn(),
clearDataGridPendingSnapshotsForTab: vi.fn(),
tabResultSnapshots: new Map<string, unknown>(),
}));
@@ -42,6 +44,11 @@ vi.mock("@/stores/settingsStore", () => ({
}),
}));
vi.mock("@/composables/useDataGridEditor", () => ({
clearDataGridPendingSnapshot: mocks.clearDataGridPendingSnapshot,
clearDataGridPendingSnapshotsForTab: mocks.clearDataGridPendingSnapshotsForTab,
}));
vi.mock("@/lib/tabs/tabResultCache", async (importOriginal) => {
const actual = await importOriginal<typeof import("@/lib/tabs/tabResultCache")>();
return {
@@ -630,6 +637,12 @@ describe("queryStore multi-statement errors", () => {
expect(tab.resultAutoSave).toBeUndefined();
expect(tab.resultRuns).toHaveLength(2);
expect(tab.activeResultRunId).toBe(tab.resultRuns?.[1]?.id);
const firstRunRevision = tab.resultRuns?.[0]?.resultGridRevision;
const secondRunRevision = tab.resultRuns?.[1]?.resultGridRevision;
expect(firstRunRevision).toBeTruthy();
expect(secondRunRevision).toBeTruthy();
expect(secondRunRevision).not.toBe(firstRunRevision);
expect(mocks.clearDataGridPendingSnapshot).toHaveBeenCalledTimes(1);
expect(await store.setActiveResultRun(tabId, tab.resultRuns![0]!.id)).toBe(true);
expect(tab.result?.rows[0]?.[0]).toBe(1);
@@ -640,6 +653,9 @@ describe("queryStore multi-statement errors", () => {
expect(tab.resultRuns).toHaveLength(2);
expect(tab.activeResultRunId).toBe(tab.resultRuns?.[1]?.id);
expect(tab.resultGridRevision).toBe(tab.resultRuns?.[1]?.resultGridRevision);
expect(tab.resultGridRevision).not.toBe(secondRunRevision);
expect(mocks.clearDataGridPendingSnapshot).toHaveBeenCalledTimes(2);
expect(await store.setActiveResultRun(tabId, tab.resultRuns![0]!.id)).toBe(true);
expect(tab.result?.rows[0]?.[0]).toBe(1);
expect(await store.setActiveResultRun(tabId, tab.resultRuns![1]!.id)).toBe(true);
+21 -6
View File
@@ -1,6 +1,6 @@
import { defineStore } from "pinia";
import { uuid } from "@/lib/common/utils";
import { computed, markRaw, onScopeDispose, reactive, ref, watch } from "vue";
import { computed, markRaw, nextTick, onScopeDispose, reactive, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import type { BatchSqlExecution, ConnectionConfig, DatabaseType, IndexInfo, ObjectBrowserViewport, QueryResult, QueryTab, TableInfoTab, TableStructureEditorTarget } from "@/types/database";
import { orderPinnedFirst } from "@/lib/app/pinnedItems";
@@ -52,10 +52,10 @@ import { normalizeResultPageSize } from "@/lib/dataGrid/paginationPageSize";
import { agentProtocolQueryResultMaxRows, capQueryResultTotal, effectiveQueryResultMaxRows, limitQueryPagination, queryResultLimitReached } from "@/lib/dataGrid/queryResultRowLimit";
import { elasticsearchRestRequestRanges, executableStatementRanges, splitSqlStatementRanges } from "@/lib/sql/sqlStatementRanges";
import { externalSqlFileDisplayTitles, normalizeExternalSqlPath } from "@/lib/sql/sqlFileOpen";
import { clearDataGridPendingSnapshotsForTab } from "@/composables/useDataGridEditor";
import { clearDataGridPendingSnapshot, clearDataGridPendingSnapshotsForTab } from "@/composables/useDataGridEditor";
import { buildTabResultSnapshot, deleteTabResultSnapshot, pruneTabResultSnapshots, readTabResultSnapshot, tabResultCacheKey, writeTabResultSnapshot } from "@/lib/tabs/tabResultCache";
import { estimateQueryResultsBytes, selectInactiveResultEvictions } from "@/lib/tabs/queryResultSize";
import { queryResultBaseSql, queryResultExecutionSql } from "@/lib/tabs/tabPresentation";
import { queryResultBaseSql, queryResultExecutionSql, resultGridInstanceKey } from "@/lib/tabs/tabPresentation";
import { isQueryExecutionErrorResult } from "@/lib/query/queryResultError";
import { decodeQueryResultArchive, encodeQueryResultArchive, type DecodedQueryResultArchive } from "@/lib/query/queryResultArchive";
import * as api from "@/lib/backend/api";
@@ -1005,6 +1005,7 @@ export const useQueryStore = defineStore("query", () => {
tab.result = run.result ?? run.results?.[activeIndex];
tab.results = run.results;
tab.activeResultIndex = run.activeResultIndex;
tab.resultGridRevision = run.resultGridRevision;
tab.batchSqlExecution = cloneBatchSqlExecution(run.batchSqlExecution);
tab.resultBaseSql = run.resultBaseSql;
tab.resultEditorFingerprint = run.resultEditorFingerprint;
@@ -1242,6 +1243,7 @@ export const useQueryStore = defineStore("query", () => {
result: tab.result,
results: tab.results,
activeResultIndex: tab.activeResultIndex,
resultGridRevision: tab.resultGridRevision,
batchSqlExecution: cloneBatchSqlExecution(tab.batchSqlExecution),
resultBaseSql: tab.resultBaseSql,
resultEditorFingerprint: tab.resultEditorFingerprint,
@@ -1339,6 +1341,7 @@ export const useQueryStore = defineStore("query", () => {
result: tab.result,
results: tab.results,
activeResultIndex: tab.activeResultIndex,
resultGridRevision: tab.resultGridRevision,
batchSqlExecution: cloneBatchSqlExecution(tab.batchSqlExecution),
resultBaseSql: tab.resultBaseSql,
resultEditorFingerprint: tab.resultEditorFingerprint,
@@ -3266,8 +3269,10 @@ export const useQueryStore = defineStore("query", () => {
}
async function executeCurrentSql(sql: string, options?: { skipRedisSafetyCheck?: boolean; sourceOffset?: number; openInNewResultTab?: boolean }) {
if (!activeTabId.value) return;
const tab = tabs.value.find((item) => item.id === activeTabId.value);
const executionTabId = activeTabId.value;
if (!executionTabId) return;
const tab = tabs.value.find((item) => item.id === executionTabId);
const previousGridKey = tab ? resultGridInstanceKey(tab) : undefined;
if (tab?.mode === "query") {
tab.resultSortColumn = undefined;
tab.resultSortColumnIndex = undefined;
@@ -3275,7 +3280,17 @@ export const useQueryStore = defineStore("query", () => {
tab.resultSortMode = undefined;
tab.resultSortedSql = undefined;
}
return await executeTabSql(activeTabId.value, sql, { resultBaseSql: sql, resultSortedSql: undefined, ...options });
const producedResult = await executeTabSql(executionTabId, sql, { resultBaseSql: sql, resultSortedSql: undefined, ...options });
if (producedResult !== false) {
const current = tabs.value.find((item) => item.id === executionTabId);
if (current?.result) {
current.resultGridRevision = uuid();
if (current.activeResultRunId) syncActiveResultRunFromDisplayed(current);
await nextTick();
if (previousGridKey && options?.openInNewResultTab !== true) clearDataGridPendingSnapshot(previousGridKey);
}
}
return producedResult;
}
type QueryMetadataPatch = Pick<QueryTab, "queryAnalysis" | "querySourceColumns" | "queryEditabilityReason" | "tableMeta">;