feat(query): show elapsed time while executing

This commit is contained in:
t8y2 2026-06-09 17:57:25 +08:00
parent 348f39ff35
commit 2050bee75c
4 changed files with 39 additions and 1 deletions

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import { computed, ref, defineAsyncComponent, watch, nextTick, onMounted } from "vue";
import { computed, ref, defineAsyncComponent, watch, nextTick, onMounted, onUnmounted } from "vue";
import { useI18n } from "vue-i18n";
import {
Check,
@ -220,6 +220,35 @@ const hasTabularResult = computed(() => {
return tabularResults.value.length > 0;
});
const resultsPaneOpen = ref(false);
const queryRunningElapsed = ref(0);
let queryRunningElapsedTimer: ReturnType<typeof setInterval> | undefined;
function stopQueryRunningElapsedTimer() {
clearInterval(queryRunningElapsedTimer);
queryRunningElapsedTimer = undefined;
}
function updateQueryRunningElapsed() {
const startedAt = props.activeTab.queryExecutionStartedAt;
queryRunningElapsed.value = props.activeTab.isExecuting && startedAt ? Math.max(0, Date.now() - startedAt) : 0;
}
function startQueryRunningElapsedTimer() {
stopQueryRunningElapsedTimer();
updateQueryRunningElapsed();
if (!props.activeTab.isExecuting || !props.activeTab.queryExecutionStartedAt) return;
queryRunningElapsedTimer = setInterval(updateQueryRunningElapsed, 100);
}
const queryRunningElapsedSeconds = computed(() => (queryRunningElapsed.value / 1000).toFixed(1));
watch(
() => [props.activeTab.id, props.activeTab.isExecuting, props.activeTab.queryExecutionStartedAt] as const,
startQueryRunningElapsedTimer,
{ immediate: true },
);
onUnmounted(stopQueryRunningElapsedTimer);
watch(
hasQueryOutput,
@ -749,6 +778,7 @@ defineExpose({ focusSearch, refreshData, handleModRTarget });
<div class="flex items-center">
<Loader2 class="h-5 w-5 animate-spin mr-2" />
{{ t(queryExecutionLabelKey(activeTab)) }}
<span class="ml-1 tabular-nums text-muted-foreground/80">· {{ queryRunningElapsedSeconds }}s</span>
</div>
</div>
<div
@ -1009,6 +1039,7 @@ defineExpose({ focusSearch, refreshData, handleModRTarget });
<div class="flex items-center">
<Loader2 class="h-5 w-5 animate-spin mr-2" />
{{ t(queryExecutionLabelKey(activeTab)) }}
<span class="ml-1 tabular-nums text-muted-foreground/80">· {{ queryRunningElapsedSeconds }}s</span>
</div>
<Button
variant="destructive"

View File

@ -99,6 +99,7 @@ export function restoreOpenTabsState(
mode,
isExecuting: false,
isCancelling: false,
queryExecutionStartedAt: undefined,
isExplaining: false,
resultEvicted: mode === "data" ? undefined : tab.resultEvicted,
resultCacheKey: mode === "data" ? undefined : tab.resultCacheKey,

View File

@ -640,6 +640,7 @@ export const useQueryStore = defineStore("query", () => {
const tab = tabs.value.find((t) => t.id === id);
if (!tab) return;
tab.isExecuting = isExecuting;
tab.queryExecutionStartedAt = isExecuting ? Date.now() : undefined;
if (!isExecuting) {
tab.isCancelling = false;
tab.executionId = undefined;
@ -674,6 +675,7 @@ export const useQueryStore = defineStore("query", () => {
tab.resultSessionId = undefined;
tab.isExecuting = false;
tab.isCancelling = false;
tab.queryExecutionStartedAt = undefined;
tab.executionId = undefined;
}
@ -956,6 +958,7 @@ export const useQueryStore = defineStore("query", () => {
const elapsed = () => `${Math.round(performance.now() - startedAt)}ms`;
tab.isExecuting = true;
tab.isCancelling = false;
tab.queryExecutionStartedAt = Date.now();
tab.executionId = executionId;
tab.lastExecutedSql = sql;
if (!options?.preserveTotalRowCountDuringExecution) {
@ -1345,6 +1348,7 @@ export const useQueryStore = defineStore("query", () => {
if (current?.executionId === executionId) {
current.isExecuting = false;
current.isCancelling = false;
current.queryExecutionStartedAt = undefined;
current.executionId = undefined;
console.info("[DBX][executeTabSql:finish]", { traceId, elapsed: elapsed() });
} else {
@ -1512,6 +1516,7 @@ export const useQueryStore = defineStore("query", () => {
stuck.forEach((tab) => {
tab.isExecuting = false;
tab.isCancelling = false;
tab.queryExecutionStartedAt = undefined;
tab.executionId = undefined;
tab.result = toErrorResult(new Error(t("editor.connectionMayBeLost")));
});

View File

@ -395,6 +395,7 @@ export interface QueryTab {
lastExplainedSql?: string;
isExecuting: boolean;
isCancelling?: boolean;
queryExecutionStartedAt?: number;
executionId?: string;
isExplaining?: boolean;
explainExecutionId?: string;