diff --git a/frontend/src/lib/components/FlowStatusViewerInner.svelte b/frontend/src/lib/components/FlowStatusViewerInner.svelte
index 006016caa2..7d76cf6964 100644
--- a/frontend/src/lib/components/FlowStatusViewerInner.svelte
+++ b/frontend/src/lib/components/FlowStatusViewerInner.svelte
@@ -24,7 +24,7 @@
import ModuleStatus from './ModuleStatus.svelte'
import { clone, isScriptPreview, msToSec, readFieldsRecursively, truncateRev } from '$lib/utils'
import JobArgs from './JobArgs.svelte'
- import { ChevronDown, ExternalLink, Hourglass } from 'lucide-svelte'
+ import { ChevronDown, ExternalLink, Hourglass, Hash } from 'lucide-svelte'
import { deepEqual } from 'fast-equals'
import FlowTimeline from './FlowTimeline.svelte'
import { dfs } from './flows/dfs'
@@ -1295,6 +1295,21 @@
let totalEventsWaiting = $derived(
Object.values(suspendStatus?.val ?? {}).reduce((a, b) => a + (b?.nb ?? 0), 0)
)
+
+ // Hash navigation functions
+ function scrollToSection(sectionId: string) {
+ const element = document.getElementById(sectionId)
+ if (element) {
+ element.scrollIntoView({ behavior: 'smooth' })
+ }
+ }
+
+ function handleSectionHashClick(sectionId: string) {
+ const url = new URL(window.location.href)
+ url.hash = sectionId
+ window.history.pushState({}, '', url.toString())
+ scrollToSection(sectionId)
+ }
@@ -1375,8 +1390,20 @@
{:else}
-
Result
-
+
+
+ Result
+
+
+
+
{#if job !== undefined && (job.result_stream || (job.type == 'CompletedJob' && 'result' in job && job.result !== undefined))}
job?.raw_flow?.modules ?? [] })
@@ -354,6 +358,29 @@
}
}
+ // Hash navigation functions
+ function scrollToSection(sectionId: string) {
+ const element = document.getElementById(sectionId)
+ if (element) {
+ element.scrollIntoView({ behavior: 'smooth' })
+ }
+ }
+
+ function handleSectionHashClick(sectionId: string) {
+ const url = new URL(window.location.href)
+ url.hash = sectionId
+ window.history.pushState({}, '', url.toString())
+ currentHash = sectionId
+ scrollToSection(sectionId)
+ }
+
+ function handleHashChange() {
+ currentHash = window.location.hash.slice(1) // Remove the # symbol
+ if (currentHash) {
+ scrollToSection(currentHash)
+ }
+ }
+
$effect(() => {
job?.id && lastJobId !== job.id && untrack(() => getConcurrencyKey(job))
})
@@ -369,6 +396,19 @@
$effect(() => {
job && untrack(() => onJobLoaded())
})
+ $effect(() => {
+ // Initialize hash on mount and listen for hash changes
+ currentHash = window.location.hash.slice(1)
+ if (currentHash) {
+ // Small delay to ensure DOM is rendered
+ setTimeout(() => scrollToSection(currentHash), 100)
+ }
+
+ window.addEventListener('hashchange', handleHashChange)
+ return () => {
+ window.removeEventListener('hashchange', handleHashChange)
+ }
+ })
@@ -714,8 +754,18 @@
{/if}
-