fix(grid): preserve local result filters

This commit is contained in:
jearhe authored and GitHub committed 2026-09-01 16:17:54 +08:00
1 parent 264f5c4836
commit cb754cd0cc
4 files changed
+112 -1

No files matched your search

@@ -55,6 +55,7 @@ interface ColumnarQueryResult {
execution_error?: true;
statement_index?: number;
column_types?: string[];
local_column_filters?: QueryResult["local_column_filters"];
columnValues: CellValue[][];
rowCount: number;
mongo_documents?: unknown[];
@@ -327,6 +328,10 @@ function clonePlain<T>(value: T): T {
}
}
function cloneLocalColumnFilters(filters: QueryResult["local_column_filters"]): QueryResult["local_column_filters"] {
return filters ? Object.fromEntries(Object.entries(filters).map(([columnIndex, values]) => [columnIndex, [...values]])) : undefined;
}
function stripSessionIds(result: QueryResult | undefined): QueryResult | undefined {
if (!result) return undefined;
return {
@@ -334,6 +339,7 @@ function stripSessionIds(result: QueryResult | undefined): QueryResult | undefin
execution_error: result.execution_error,
statement_index: result.statement_index,
column_types: result.column_types ? [...result.column_types] : undefined,
local_column_filters: cloneLocalColumnFilters(result.local_column_filters),
spatial_columns: result.spatial_columns?.map((entry) => ({ column_index: entry.column_index, srid: entry.srid })),
spatial_values: result.spatial_values?.map((row) => [...row]),
large_value_cells: result.large_value_cells?.map((cell) => ({ ...cell })),
@@ -377,6 +383,7 @@ function toColumnarResult(result: QueryResult | undefined): ColumnarQueryResult
execution_error: result.execution_error,
statement_index: result.statement_index,
column_types: result.column_types ? [...result.column_types] : undefined,
local_column_filters: cloneLocalColumnFilters(result.local_column_filters),
spatial_columns: result.spatial_columns?.map((entry) => ({ column_index: entry.column_index, srid: entry.srid })),
spatial_values: result.spatial_values?.map((row) => [...row]),
large_value_cells: result.large_value_cells?.map((cell) => ({ ...cell })),
@@ -403,6 +410,7 @@ function fromColumnarResult(result: ColumnarQueryResult | undefined): QueryResul
execution_error: result.execution_error,
statement_index: result.statement_index,
column_types: result.column_types ? [...result.column_types] : undefined,
local_column_filters: cloneLocalColumnFilters(result.local_column_filters),
spatial_columns: result.spatial_columns?.map((entry) => ({ column_index: entry.column_index, srid: entry.srid })),
spatial_values: result.spatial_values?.map((row) => [...row]),
large_value_cells: result.large_value_cells?.map((cell) => ({ ...cell })),
@@ -712,6 +720,7 @@ export function decodeTabResultSnapshot(bytes: Uint8Array | ArrayBuffer): TabRes
return undefined;
}
if (!isRecord(decoded.payload)) return undefined;
// SAFETY: The validated envelope is produced by encodeTabResultSnapshot, so its record payload has the snapshot shape expected here.
return payloadToSnapshot(decoded.payload as unknown as TabResultSnapshotPayload);
}
@@ -179,6 +179,38 @@ describe("queryStore switchTab", () => {
expect(tab.result.local_column_filters).toBeUndefined();
});
it("keeps local filters isolated across result-run switches and clearing", async () => {
const { useQueryStore } = await import("@/stores/queryStore");
const queryStore = useQueryStore();
const tabId = queryStore.createTab("pg-1", "app", "Query", "query");
const tab = queryStore.tabs.find((item) => item.id === tabId)!;
const result = (filters?: Record<string, string[]>) => ({
columns: ["id", "status"],
rows: [[1, "active"]],
affected_rows: 0,
execution_time_ms: 1,
local_column_filters: filters,
});
tab.resultRuns = [
{ id: "run-a", title: "Run A", sequence: 1, sql: "select 1", createdAt: 1, result: result() },
{ id: "run-b", title: "Run B", sequence: 2, sql: "select 2", createdAt: 2, result: result({ "1": ["str:pending"] }) },
];
expect(await queryStore.setActiveResultRun(tabId, "run-a")).toBe(true);
queryStore.updateDataGridLocalColumnFilters(tabId, { "1": ["str:active"] });
expect(tab.resultRuns?.[0]?.result?.local_column_filters).toEqual({ "1": ["str:active"] });
expect(await queryStore.setActiveResultRun(tabId, "run-b")).toBe(true);
expect(tab.result?.local_column_filters).toEqual({ "1": ["str:pending"] });
expect(await queryStore.setActiveResultRun(tabId, "run-a")).toBe(true);
expect(tab.result?.local_column_filters).toEqual({ "1": ["str:active"] });
queryStore.updateDataGridLocalColumnFilters(tabId, {});
expect(await queryStore.setActiveResultRun(tabId, "run-b")).toBe(true);
expect(await queryStore.setActiveResultRun(tabId, "run-a")).toBe(true);
expect(tab.result?.local_column_filters).toBeUndefined();
});
it("stores hidden data-grid column keys on the tab result", async () => {
const { useQueryStore } = await import("@/stores/queryStore");
const queryStore = useQueryStore();