From e9fa72285caafc72ab5cd44b33ed37c337457646 Mon Sep 17 00:00:00 2001 From: xiaoliangL Date: Thu, 2 Jul 2026 14:28:58 +0800 Subject: [PATCH] feat(grid): add auto refresh for data grid results MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 李晓亮 --- apps/desktop/src/components/grid/DataGrid.vue | 79 ++++++++++++++++++- apps/desktop/src/i18n/locales/en.ts | 5 ++ apps/desktop/src/i18n/locales/zh-CN.ts | 5 ++ 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/components/grid/DataGrid.vue b/apps/desktop/src/components/grid/DataGrid.vue index 4fe9c5ab33..549b4d0974 100644 --- a/apps/desktop/src/components/grid/DataGrid.vue +++ b/apps/desktop/src/components/grid/DataGrid.vue @@ -65,6 +65,7 @@ import { Database, Columns3, PencilRuler, + Timer, } from "@lucide/vue"; import { Button } from "@/components/ui/button"; import QueryLoadingState from "@/components/common/QueryLoadingState.vue"; @@ -237,6 +238,7 @@ const isMac = isMacOS(); const shortcutMod = isMac ? "Cmd" : "Ctrl"; const saveShortcutLabel = computed(() => formatShortcut(settingsStore.editorSettings.shortcuts.saveSql)); const DATA_GRID_COMPACT_TOPBAR_WIDTH = 900; +const AUTO_REFRESH_INTERVAL_OPTIONS = [5, 10, 30, 60, 300]; const emit = defineEmits<{ reload: [sql?: string, searchText?: string, whereInput?: string, orderBy?: string, limit?: number, offset?: number]; @@ -246,6 +248,11 @@ const emit = defineEmits<{ "update:orderByInput": [value: string]; }>(); +const autoRefreshIntervalSeconds = ref(10); +const autoRefreshEnabled = ref(false); +let autoRefreshTimer: ReturnType | undefined; +const autoRefreshLabel = computed(() => (autoRefreshEnabled.value ? t("tabs.autoRefreshEvery", { seconds: autoRefreshIntervalSeconds.value }) : t("tabs.autoRefresh"))); + console.info("[DBX][DataGrid:setup]", { traceId: dataGridTraceId, cacheKey: props.cacheKey, @@ -3822,6 +3829,36 @@ async function onToolbarRefresh() { emit("reload", props.sql, searchText.value, currentWhereInput(), currentOrderBy(), pageSize.value, 0); } +function stopAutoRefreshTimer() { + clearInterval(autoRefreshTimer); + autoRefreshTimer = undefined; +} + +function runAutoRefreshTick() { + if (!autoRefreshEnabled.value || !canAutoRefresh.value) return; + void onToolbarRefresh(); +} + +function restartAutoRefreshTimer() { + stopAutoRefreshTimer(); + if (!autoRefreshEnabled.value) return; + autoRefreshTimer = setInterval(runAutoRefreshTick, autoRefreshIntervalSeconds.value * 1000); +} + +function setAutoRefreshInterval(seconds: number) { + autoRefreshIntervalSeconds.value = seconds; + if (autoRefreshEnabled.value) restartAutoRefreshTimer(); +} + +function toggleAutoRefresh() { + autoRefreshEnabled.value = !autoRefreshEnabled.value; + if (autoRefreshEnabled.value) { + restartAutoRefreshTimer(); + } else { + stopAutoRefreshTimer(); + } +} + async function onToolbarCommit() { await saveChanges(); } @@ -5728,6 +5765,8 @@ const { exportCancelHandler, }); +const canAutoRefresh = computed(() => !isSaving.value && !props.loading); + const pageSizeMenuItems = computed(() => pageSizeOptions.value.map((size) => ({ value: String(size), @@ -7587,11 +7626,18 @@ watch( }, ); -onActivated(startLoadingElapsedTimer); -onDeactivated(stopLoadingElapsedTimer); +onActivated(() => { + startLoadingElapsedTimer(); + restartAutoRefreshTimer(); +}); +onDeactivated(() => { + stopLoadingElapsedTimer(); + stopAutoRefreshTimer(); +}); onUnmounted(() => { cleanupFrames(); + stopAutoRefreshTimer(); onSearchSplitResizeEnd(); onDdlResizeEnd(); onDetailResizeEnd(); @@ -8419,7 +8465,7 @@ const gridContextMenuItems = computed(() => { {{ t("grid.keylessEditWarningHint") }} - + + + + + + + {{ autoRefreshEnabled ? t("tabs.stopAutoRefresh") : t("tabs.startAutoRefresh") }} + + + + + {{ t("tabs.autoRefreshEvery", { seconds }) }} + + + diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index ad5713c73e..0d5b30949e 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -515,6 +515,11 @@ export default { autoKeepResults: "Auto-keep query results", autoKeepResultsEnabled: "Auto-keep results enabled", autoKeepResultsDisabled: "Auto-keep results disabled", + autoRefresh: "Auto-refresh results", + autoRefreshShort: "Auto", + autoRefreshEvery: "Refresh every {seconds}s", + startAutoRefresh: "Start auto-refresh", + stopAutoRefresh: "Stop auto-refresh", missingResultRun: "This result is no longer available", exportResultArchive: "Save Result Archive", importResultArchive: "Import Results", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index 55634c5150..1c43f7293c 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -518,6 +518,11 @@ export default withEnglishFallback({ autoKeepResults: "自动保留查询结果", autoKeepResultsEnabled: "已开启自动保留结果", autoKeepResultsDisabled: "已关闭自动保留结果", + autoRefresh: "自动刷新结果", + autoRefreshShort: "自动", + autoRefreshEvery: "每 {seconds} 秒刷新", + startAutoRefresh: "开始自动刷新", + stopAutoRefresh: "停止自动刷新", missingResultRun: "此结果已不可用", exportResultArchive: "保存结果归档", importResultArchive: "导入结果",