diff --git a/admin/client/routes/$queueId/$jobId/_job.$taskId/-components/Graph.tsx b/admin/client/routes/$queueId/$jobId/_job.$taskId/-components/Graph.tsx index 50352ac..03ac827 100644 --- a/admin/client/routes/$queueId/$jobId/_job.$taskId/-components/Graph.tsx +++ b/admin/client/routes/$queueId/$jobId/_job.$taskId/-components/Graph.tsx @@ -1,4 +1,4 @@ -import { Fragment, useRef, type ReactElement } from "react" +import { Fragment, useLayoutEffect, useRef, type ReactElement } from "react" import type { Step, Event, Task } from 'queue' import clsx from "clsx" import { cleanEventName } from "./utils" @@ -62,17 +62,43 @@ export function Graph({ const adjustedEnd = adjustDate(endDate) const adjustedInterval = adjustedEnd - minDate - const eventDensity = stdDev / 2 / adjustedInterval * 100 - const wAdjust = eventDensity < 1 ? (1 - eventDensity) * 150 : 0 + // const eventDensity = stdDev / 2 / adjustedInterval * 100 + const wAdjust = Math.max(adjustedInterval * 2 / stdDev, 100) // <= an interval of the size "stdDev / 2" should be at least 1% of the width const fullStep = useRef(false) + // stick to the right side + const scrollable = useRef(null) + const lastRender = useRef(false) + useLayoutEffect(() => { + const el = scrollable.current + if (!el) return + + if (lastRender.current) { + el.scrollTo({ left: el.scrollWidth - el.clientWidth, behavior: 'smooth' }) + } + + return () => { + const b = el.scrollWidth - el.clientWidth + if (!b) { + lastRender.current = false + } else { + const a = el.scrollLeft + lastRender.current = Math.abs(a - b) < 20 + } + } + }) + return ( -
setHoveredEvent([])}> +
setHoveredEvent([])} + >
{ if (fullStep.current) return @@ -101,40 +127,51 @@ export function Graph({ const width = (end - start) / adjustedInterval * 100 const isHovered = Boolean(hoveredEvent.length) && hoveredEvent.some(i => cleanEventName(data.events[i].key, job).startsWith(step.step)) const events = data.events.filter((event) => event.key.startsWith(`step/${job.job}/${step.step}/`)) - return ( - - {i > 0 && step.discovered_on !== data.steps[i - 1].discovered_on && ( -
- )} - - { - fullStep.current = true - setHoveredEvent(events.map((event) => data.events.indexOf(event))) - }} - onMouseLeave={() => { - fullStep.current = false - }} - > - minDate + adjustedInterval * .75} - /> + + let content = ( +
{ + fullStep.current = true + setHoveredEvent(events.map((event) => data.events.indexOf(event))) + }} + onMouseLeave={() => { + fullStep.current = false + }} + > + minDate + adjustedInterval * .75} + /> +
+ ) + if (step.source) { + content = ( + + + {content} {step.source} + ) + } + return ( + + {i > 0 && step.discovered_on !== data.steps[i - 1].discovered_on && ( +
+ )} + {content} ) })}