Skip to content

Commit a957a1b

Browse files
committed
feat(data-inspector): pause auto-rerun when tab hidden, live last-run TimeAgo, themed tooltips
- auto-rerun pauses while the tab is backgrounded (Page Visibility) and resumes with an immediate catch-up run when it returns to the foreground - status bar shows a live 'ran … ago' label (@antfu/design DisplayDate) tracking the last successful query - tooltips use @antfu/design's themed floating-vue stylesheet so they follow the design tokens (surface, border, light/dark) instead of the default look
1 parent 7a79a55 commit a957a1b

4 files changed

Lines changed: 34 additions & 2 deletions

File tree

plugins/data-inspector/src/spa/App.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ function saveCurrent(input: { title?: string, description?: string, scope: Saved
8282
:stats-stale="wb.statsStale.value"
8383
:error="wb.serverError.value"
8484
:running="wb.running.value"
85+
:last-run-at="wb.lastRunAt.value"
8586
:expand="wb.expandNode"
8687
@rerun="wb.runNow()"
8788
@query-subquery="wb.applySubquery($event)"

plugins/data-inspector/src/spa/components/ResultViewer.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { NodePath, QueryStats } from '../../engine'
33
import ActionIconButton from '@antfu/design/components/Action/ActionIconButton.vue'
44
import DisplayBadge from '@antfu/design/components/Display/DisplayBadge.vue'
55
import DisplayBytes from '@antfu/design/components/Display/DisplayBytes.vue'
6+
import DisplayDate from '@antfu/design/components/Display/DisplayDate.vue'
67
import DisplayDuration from '@antfu/design/components/Display/DisplayDuration.vue'
78
import { shallowRef, watch } from 'vue'
89
import { useDiscoveryViewer } from '../composables/discovery'
@@ -16,6 +17,8 @@ const props = defineProps<{
1617
statsStale: boolean
1718
error: string | null
1819
running: boolean
20+
/** When the last successful query landed (ms epoch), or null before the first. */
21+
lastRunAt: number | null
1922
/** Lazily fetch the subtree behind a depth-truncation marker. */
2023
expand: (path: NodePath) => Promise<unknown>
2124
}>()
@@ -75,6 +78,10 @@ function copyResult(): void {
7578
<span>{{ stats.normalize.refs }} <span class="op50">refs</span></span>
7679
</template>
7780
<DisplayBadge v-if="stats.normalize.truncatedEntries || stats.normalize.truncatedDepth" :color="12" text="truncated" />
81+
<template v-if="lastRunAt">
82+
<div class="h-full border-r border-base" />
83+
<span class="flex items-center gap-1"><span class="op50">ran</span> <DisplayDate :date="lastRunAt" live /></span>
84+
</template>
7885
</template>
7986
<span v-else class="op-fade select-none">no query run yet</span>
8087
<div class="flex-1" />

plugins/data-inspector/src/spa/composables/workbench.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ export function useWorkbench() {
149149
const statsStale = ref(false)
150150
const result = shallowRef<unknown>()
151151
const hasResult = ref(false)
152+
/** When the last successful query landed — drives the "ran … ago" label. */
153+
const lastRunAt = ref<number | null>(null)
152154

153155
const suggestions = ref<SuggestItem[]>([])
154156

@@ -220,6 +222,7 @@ export function useWorkbench() {
220222
stats.value = { ...outcome.stats, rpcMs: Math.round(performance.now() - started) }
221223
result.value = outcome.result
222224
hasResult.value = true
225+
lastRunAt.value = Date.now()
223226
}
224227

225228
function scheduleRun(): void {
@@ -231,11 +234,17 @@ export function useWorkbench() {
231234
// Re-runs read the live object afresh (the whole point — watch a value
232235
// change over time). A tick is skipped while a run is in flight or the
233236
// query is syntactically broken, so the poller never piles up requests
234-
// or spams the wire with queries that can't parse.
237+
// or spams the wire with queries that can't parse. The poller also pauses
238+
// while the tab is backgrounded (no point polling an unseen page) and
239+
// resumes — with an immediate catch-up run — when it returns to the front.
235240
let autoRunTimer: ReturnType<typeof setInterval> | undefined
241+
function pageHidden(): boolean {
242+
return typeof document !== 'undefined' && document.hidden
243+
}
236244
function restartAutoRerun(): void {
237245
clearInterval(autoRunTimer)
238-
if (!autoRun.value)
246+
autoRunTimer = undefined
247+
if (!autoRun.value || pageHidden())
239248
return
240249
autoRunTimer = setInterval(() => {
241250
if (running.value || syntax.value.kind === 'error')
@@ -244,6 +253,16 @@ export function useWorkbench() {
244253
}, clampSeconds(autoRunSeconds.value) * 1000)
245254
}
246255

256+
if (typeof document !== 'undefined') {
257+
document.addEventListener('visibilitychange', () => {
258+
if (!autoRun.value)
259+
return
260+
restartAutoRerun() // clears the timer while hidden, recreates it on return
261+
if (!pageHidden() && !running.value && syntax.value.kind !== 'error')
262+
void runNow() // catch up on whatever changed while the tab was away
263+
})
264+
}
265+
247266
/**
248267
* Lazily expand a depth-truncated node: fetch a fresh, depth-limited slice
249268
* of the subtree the `$truncated: 'depth'` marker at `path` stands in for.
@@ -401,6 +420,7 @@ export function useWorkbench() {
401420
statsStale,
402421
result,
403422
hasResult,
423+
lastRunAt,
404424
suggestions,
405425
skeleton,
406426
skeletonError,

plugins/data-inspector/src/spa/main.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import { createApp } from 'vue'
22
import App from './App.vue'
33
import 'virtual:uno.css'
4+
// floating-vue's base popper/transition structure, then @antfu/design's themed
5+
// override (recolors the tooltip surface + arrow to the semantic tokens via
6+
// `--at-apply`, so tooltips match the design system in light and dark).
47
import 'floating-vue/dist/style.css'
8+
import '@antfu/design/styles/floating-vue.css'
59
import '@antfu/design/styles.css'
610
import './style.css'
711

0 commit comments

Comments
 (0)