fix(tabs): reload missing table data

This commit is contained in:
t8y2
2026-06-01 17:18:51 +08:00
parent e515933ab3
commit 84a7ff6b92
6 changed files with 66 additions and 1 deletions
@@ -14,6 +14,7 @@ import {
TableProperties,
ChevronDown,
ChevronUp,
RefreshCcw,
} from "lucide-vue-next";
import { Splitpanes, Pane } from "splitpanes";
import "splitpanes/dist/splitpanes.css";
@@ -709,6 +710,14 @@ defineExpose({ focusSearch, refreshData, handleModRTarget });
{{ t("toolbar.stopQuery") }}
</Button>
</div>
<div v-else class="h-full flex flex-col items-center justify-center gap-3 text-muted-foreground text-sm">
<Inbox class="h-8 w-8 opacity-60" />
<div>{{ t("grid.dataUnavailable") }}</div>
<Button variant="outline" size="sm" class="h-7 gap-1.5" @click="emit('reload')">
<RefreshCcw class="h-3.5 w-3.5" />
{{ t("grid.refresh") }}
</Button>
</div>
</div>
</template>
+1
View File
@@ -602,6 +602,7 @@ export default {
tableInfoSearch: "Search...",
tableInfoNoResults: "No results",
queryError: "Query Error",
dataUnavailable: "Table data needs to be reloaded.",
refresh: "Refresh",
commit: "Commit",
rollback: "Rollback",
+1
View File
@@ -561,6 +561,7 @@ export default {
tableInfoSearch: "Buscar...",
tableInfoNoResults: "Sin resultados",
queryError: "Error de consulta",
dataUnavailable: "Los datos de la tabla deben volver a cargarse.",
refresh: "Actualizar",
commit: "Confirmar",
rollback: "Revertir",
+1
View File
@@ -597,6 +597,7 @@ export default {
tableInfoSearch: "搜索...",
tableInfoNoResults: "无匹配结果",
queryError: "查询出错",
dataUnavailable: "表数据需要重新加载。",
refresh: "刷新",
commit: "提交",
rollback: "回滚",
+10 -1
View File
@@ -1126,13 +1126,22 @@ export const useQueryStore = defineStore("query", () => {
async function reloadEvictedTab(id: string) {
const tab = tabs.value.find((t) => t.id === id);
if (!tab || !tab.resultEvicted) return;
const shouldReloadMissingDataTab = tab?.mode === "data" && !tab.result && !tab.isExecuting;
if (!tab || (!tab.resultEvicted && !shouldReloadMissingDataTab)) return;
tab.resultEvicted = false;
const sql = tab.lastExecutedSql ?? tab.sql;
if (!sql?.trim()) return;
const settingsStore = useSettingsStore();
await executeTabSql(tab.id, sql, {
resultBaseSql: tab.resultBaseSql ?? sql,
resultSortedSql: tab.resultSortedSql,
pagination:
tab.mode === "data"
? {
limit: tab.resultPageLimit ?? settingsStore.editorSettings.pageSize,
offset: tab.resultPageOffset ?? 0,
}
: undefined,
});
}
+44
View File
@@ -364,6 +364,50 @@ test("data tab execution preserves pagination offset metadata", async () => {
}
});
test("reloading an empty data tab fetches table results again", async () => {
const restoreStorage = installMemoryStorage();
setActivePinia(createPinia());
const connectionStore = useConnectionStore();
const store = useQueryStore();
const originalFetch = globalThis.fetch;
let executeBody: any;
connectionStore.addEphemeralConnection(conn("conn-1"));
const tabId = store.createTab("conn-1", "db", "users", "data", "public");
const tab = store.tabs.find((item) => item.id === tabId);
assert.ok(tab);
tab.sql = 'SELECT * FROM "public"."users" LIMIT 50 OFFSET 50;';
tab.lastExecutedSql = tab.sql;
tab.resultPageLimit = 50;
tab.resultPageOffset = 50;
globalThis.fetch = (async (input, init) => {
const url = String(input);
if (url === "/api/query/execute-multi") {
executeBody = JSON.parse(String(init?.body ?? "{}"));
return new Response(JSON.stringify([{ columns: ["id"], rows: [[51]], affected_rows: 0, execution_time_ms: 1 }]), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
return new Response("unexpected request", { status: 500 });
}) as typeof fetch;
try {
await store.reloadEvictedTab(tabId);
assert.equal(executeBody.sql, 'SELECT * FROM "public"."users" LIMIT 50 OFFSET 50;');
assert.equal(executeBody.maxRows, 50);
assert.equal(executeBody.fetchSize, 50);
assert.deepEqual(tab.result?.rows, [[51]]);
assert.equal(tab.resultPageLimit, 50);
assert.equal(tab.resultPageOffset, 50);
} finally {
globalThis.fetch = originalFetch;
restoreStorage();
}
});
test("query result export fetches every paginated page", async () => {
const restoreStorage = installMemoryStorage();
setActivePinia(createPinia());