22 ArrowUturnLeftIcon ,
33 BoltSlashIcon ,
44 BookOpenIcon ,
5- ChevronUpIcon ,
65 ChevronDownIcon ,
76 ChevronRightIcon ,
87 InformationCircleIcon ,
@@ -12,6 +11,7 @@ import {
1211 MagnifyingGlassPlusIcon ,
1312 StopCircleIcon ,
1413} from "@heroicons/react/20/solid" ;
14+
1515import { useLoaderData , useRevalidator } from "@remix-run/react" ;
1616import { type LoaderFunctionArgs , type SerializeFrom , json } from "@remix-run/server-runtime" ;
1717import { type Virtualizer } from "@tanstack/react-virtual" ;
@@ -26,6 +26,8 @@ import { motion } from "framer-motion";
2626import { useCallback , useEffect , useRef , useState } from "react" ;
2727import { useHotkeys } from "react-hotkeys-hook" ;
2828import { redirect } from "remix-typedjson" ;
29+ import { ChevronExtraSmallDown } from "~/assets/icons/ChevronExtraSmallDown" ;
30+ import { ChevronExtraSmallUp } from "~/assets/icons/ChevronExtraSmallUp" ;
2931import { MoveToTopIcon } from "~/assets/icons/MoveToTopIcon" ;
3032import { MoveUpIcon } from "~/assets/icons/MoveUpIcon" ;
3133import tileBgPath from "~/assets/images/[email protected] " ; @@ -35,6 +37,7 @@ import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
3537import { PageBody } from "~/components/layout/AppLayout" ;
3638import { Badge } from "~/components/primitives/Badge" ;
3739import { Button , LinkButton } from "~/components/primitives/Buttons" ;
40+ import { CopyableText } from "~/components/primitives/CopyableText" ;
3841import { DateTimeShort } from "~/components/primitives/DateTime" ;
3942import { Dialog , DialogTrigger } from "~/components/primitives/Dialog" ;
4043import { Header3 } from "~/components/primitives/Headers" ;
@@ -62,24 +65,32 @@ import {
6265import { type NodesState } from "~/components/primitives/TreeView/reducer" ;
6366import { CancelRunDialog } from "~/components/runs/v3/CancelRunDialog" ;
6467import { ReplayRunDialog } from "~/components/runs/v3/ReplayRunDialog" ;
68+ import { getRunFiltersFromSearchParams } from "~/components/runs/v3/RunFilters" ;
6569import { RunIcon } from "~/components/runs/v3/RunIcon" ;
6670import {
6771 SpanTitle ,
6872 eventBackgroundClassName ,
6973 eventBorderClassName ,
7074} from "~/components/runs/v3/SpanTitle" ;
7175import { TaskRunStatusIcon , runStatusClassNameColor } from "~/components/runs/v3/TaskRunStatus" ;
76+ import { $replica } from "~/db.server" ;
7277import { useDebounce } from "~/hooks/useDebounce" ;
7378import { useEnvironment } from "~/hooks/useEnvironment" ;
7479import { useEventSource } from "~/hooks/useEventSource" ;
7580import { useInitialDimensions } from "~/hooks/useInitialDimensions" ;
7681import { useOrganization } from "~/hooks/useOrganizations" ;
7782import { useProject } from "~/hooks/useProject" ;
7883import { useReplaceSearchParams } from "~/hooks/useReplaceSearchParams" ;
84+ import { useSearchParams } from "~/hooks/useSearchParam" ;
7985import { type Shortcut , useShortcutKeys } from "~/hooks/useShortcutKeys" ;
8086import { useHasAdminAccess } from "~/hooks/useUser" ;
87+ import { findProjectBySlug } from "~/models/project.server" ;
88+ import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server" ;
89+ import { NextRunListPresenter } from "~/presenters/v3/NextRunListPresenter.server" ;
8190import { RunEnvironmentMismatchError , RunPresenter } from "~/presenters/v3/RunPresenter.server" ;
91+ import { clickhouseClient } from "~/services/clickhouseInstance.server" ;
8292import { getImpersonationId } from "~/services/impersonation.server" ;
93+ import { logger } from "~/services/logger.server" ;
8394import { getResizableSnapshot } from "~/services/resizablePanel.server" ;
8495import { requireUserId } from "~/services/session.server" ;
8596import { cn } from "~/utils/cn" ;
@@ -94,18 +105,9 @@ import {
94105 v3RunStreamingPath ,
95106 v3RunsPath ,
96107} from "~/utils/pathBuilder" ;
108+ import type { SpanOverride } from "~/v3/eventRepository/eventRepository.types" ;
97109import { useCurrentPlan } from "../_app.orgs.$organizationSlug/route" ;
98110import { SpanView } from "../resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam.spans.$spanParam/route" ;
99- import { useSearchParams } from "~/hooks/useSearchParam" ;
100- import { CopyableText } from "~/components/primitives/CopyableText" ;
101- import type { SpanOverride } from "~/v3/eventRepository/eventRepository.types" ;
102- import { getRunFiltersFromSearchParams } from "~/components/runs/v3/RunFilters" ;
103- import { NextRunListPresenter } from "~/presenters/v3/NextRunListPresenter.server" ;
104- import { $replica } from "~/db.server" ;
105- import { clickhouseClient } from "~/services/clickhouseInstance.server" ;
106- import { findProjectBySlug } from "~/models/project.server" ;
107- import { findEnvironmentBySlug } from "~/models/runtimeEnvironment.server" ;
108- import { logger } from "~/services/logger.server" ;
109111
110112const resizableSettings = {
111113 parent : {
@@ -210,7 +212,10 @@ async function getRunsListFromTableState({
210212 }
211213 }
212214
213- if ( currentRunIndex === currentPageResult . runs . length - 1 && currentPageResult . pagination . next ) {
215+ if (
216+ currentRunIndex === currentPageResult . runs . length - 1 &&
217+ currentPageResult . pagination . next
218+ ) {
214219 const nextPageResult = await runsListPresenter . call ( project . organizationId , environment . id , {
215220 userId,
216221 projectId : project . id ,
@@ -313,7 +318,16 @@ export default function Page() {
313318 const tabParam = value ( "tab" ) ?? undefined ;
314319 const spanParam = value ( "span" ) ?? undefined ;
315320
316- const [ previousRunPath , nextRunPath ] = useAdjacentRunPaths ( { organization, project, environment, tableState, run, runsList, tabParam, useSpan : ! ! spanParam } ) ;
321+ const [ previousRunPath , nextRunPath ] = useAdjacentRunPaths ( {
322+ organization,
323+ project,
324+ environment,
325+ tableState,
326+ run,
327+ runsList,
328+ tabParam,
329+ useSpan : ! ! spanParam ,
330+ } ) ;
317331
318332 return (
319333 < >
@@ -323,13 +337,21 @@ export default function Page() {
323337 to : v3RunsPath ( organization , project , environment , filters ) ,
324338 text : "Runs" ,
325339 } }
326- title = { < >
327- < CopyableText value = { run . friendlyId } variant = "text-below" className = "font-mono px-0 py-0 pb-[2px]" />
328- { tableState && ( < div className = "flex" >
329- < PreviousRunButton to = { previousRunPath } />
330- < NextRunButton to = { nextRunPath } />
331- </ div > ) }
332- </ > }
340+ title = {
341+ < div className = "flex items-center gap-x-0" >
342+ < CopyableText
343+ value = { run . friendlyId }
344+ variant = "text-below"
345+ className = "-ml-[0.4375rem] h-6 px-1.5 font-mono text-xs hover:text-text-bright"
346+ />
347+ { tableState && (
348+ < div className = "flex" >
349+ < PreviousRunButton to = { previousRunPath } />
350+ < NextRunButton to = { nextRunPath } />
351+ </ div >
352+ ) }
353+ </ div >
354+ }
333355 />
334356 { environment . type === "DEVELOPMENT" && < DevDisconnectedBanner isConnected = { isConnected } /> }
335357 < PageAccessories >
@@ -407,16 +429,18 @@ export default function Page() {
407429 maximumLiveReloadingSetting = { maximumLiveReloadingSetting }
408430 />
409431 ) : (
410- < NoLogsView
411- run = { run }
412- />
432+ < NoLogsView run = { run } />
413433 ) }
414434 </ PageBody >
415435 </ >
416436 ) ;
417437}
418438
419- function TraceView ( { run, trace, maximumLiveReloadingSetting } : Pick < LoaderData , "run" | "trace" | "maximumLiveReloadingSetting" > ) {
439+ function TraceView ( {
440+ run,
441+ trace,
442+ maximumLiveReloadingSetting,
443+ } : Pick < LoaderData , "run" | "trace" | "maximumLiveReloadingSetting" > ) {
420444 const organization = useOrganization ( ) ;
421445 const project = useProject ( ) ;
422446 const environment = useEnvironment ( ) ;
@@ -875,15 +899,15 @@ function TasksTreeView({
875899 </ ResizablePanelGroup >
876900 < div className = "flex items-center justify-between gap-2 border-t border-grid-dimmed px-4" >
877901 < div className = "grow @container" >
878- < div className = "hidden items-center gap-4 @[42rem ]:flex" >
902+ < div className = "hidden items-center gap-4 @[48rem ]:flex" >
879903 < KeyboardShortcuts
880904 expandAllBelowDepth = { expandAllBelowDepth }
881905 collapseAllBelowDepth = { collapseAllBelowDepth }
882906 toggleExpandLevel = { toggleExpandLevel }
883907 setShowDurations = { setShowDurations }
884908 />
885909 </ div >
886- < div className = "@[42rem ]:hidden" >
910+ < div className = "@[48rem ]:hidden" >
887911 < Popover >
888912 < PopoverArrowTrigger > Shortcuts</ PopoverArrowTrigger >
889913 < PopoverContent
@@ -1131,7 +1155,9 @@ function TimelineView({
11311155 "-ml-[0.5px] h-[0.5625rem] w-px rounded-none" ,
11321156 eventBackgroundClassName ( node . data )
11331157 ) }
1134- layoutId = { disableSpansAnimations ? undefined : `${ node . id } -${ event . name } ` }
1158+ layoutId = {
1159+ disableSpansAnimations ? undefined : `${ node . id } -${ event . name } `
1160+ }
11351161 animate = { disableSpansAnimations ? false : undefined }
11361162 />
11371163 ) }
@@ -1150,7 +1176,9 @@ function TimelineView({
11501176 "-ml-[0.1562rem] size-[0.3125rem] rounded-full border bg-background-bright" ,
11511177 eventBorderClassName ( node . data )
11521178 ) }
1153- layoutId = { disableSpansAnimations ? undefined : `${ node . id } -${ event . name } ` }
1179+ layoutId = {
1180+ disableSpansAnimations ? undefined : `${ node . id } -${ event . name } `
1181+ }
11541182 animate = { disableSpansAnimations ? false : undefined }
11551183 />
11561184 ) }
@@ -1444,7 +1472,12 @@ function SpanWithDuration({
14441472 fadeLeft,
14451473 disableAnimations,
14461474 ...props
1447- } : Timeline . SpanProps & { node : TraceEvent ; showDuration : boolean ; fadeLeft : boolean ; disableAnimations ?: boolean } ) {
1475+ } : Timeline . SpanProps & {
1476+ node : TraceEvent ;
1477+ showDuration : boolean ;
1478+ fadeLeft : boolean ;
1479+ disableAnimations ?: boolean ;
1480+ } ) {
14481481 return (
14491482 < Timeline . Span { ...props } >
14501483 < motion . div
@@ -1583,13 +1616,15 @@ function KeyboardShortcuts({
15831616}
15841617
15851618function AdjacentRunsShortcuts ( ) {
1586- return ( < div className = "flex items-center gap-0.5" >
1619+ return (
1620+ < div className = "flex items-center gap-0.5" >
15871621 < ShortcutKey shortcut = { { key : "[" } } variant = "medium" className = "ml-0 mr-0 px-1" />
15881622 < ShortcutKey shortcut = { { key : "]" } } variant = "medium" className = "ml-0 mr-0 px-1" />
15891623 < Paragraph variant = "extra-small" className = "ml-1.5 whitespace-nowrap" >
1590- Adjacent runs
1624+ Next/previous run
15911625 </ Paragraph >
1592- </ div > ) ;
1626+ </ div >
1627+ ) ;
15931628}
15941629
15951630function ArrowKeyShortcuts ( ) {
@@ -1679,13 +1714,13 @@ function useAdjacentRunPaths({
16791714 run,
16801715 runsList,
16811716 tabParam,
1682- useSpan
1717+ useSpan,
16831718} : {
16841719 organization : { slug : string } ;
16851720 project : { slug : string } ;
16861721 environment : { slug : string } ;
16871722 tableState : string ;
1688- run : { friendlyId : string , spanId : string } ;
1723+ run : { friendlyId : string ; spanId : string } ;
16891724 runsList : RunsListNavigation | null ;
16901725 tabParam ?: string ;
16911726 useSpan ?: boolean ;
@@ -1695,7 +1730,7 @@ function useAdjacentRunPaths({
16951730 }
16961731
16971732 const currentIndex = runsList . runs . findIndex ( ( r ) => r . friendlyId === run . friendlyId ) ;
1698-
1733+
16991734 if ( currentIndex === - 1 ) {
17001735 return [ null , null ] ;
17011736 }
@@ -1751,18 +1786,15 @@ function useAdjacentRunPaths({
17511786 return [ previousRunPath , nextRunPath ] ;
17521787}
17531788
1754-
17551789function PreviousRunButton ( { to } : { to : string | null } ) {
17561790 return (
17571791 < div className = { cn ( "peer/prev order-1" , ! to && "pointer-events-none" ) } >
17581792 < LinkButton
1759- to = { to ? to : '#' }
1793+ to = { to ? to : "#" }
17601794 variant = { "minimal/small" }
1761- LeadingIcon = { ChevronUpIcon }
1762- className = { cn (
1763- "flex items-center rounded-r-none border-r-0 pl-2 pr-[0.5625rem]" ,
1764- ! to && "cursor-not-allowed opacity-50"
1765- ) }
1795+ LeadingIcon = { ChevronExtraSmallUp }
1796+ leadingIconClassName = "size-3 group-hover/button:text-text-bright transition-colors"
1797+ className = { cn ( "flex size-6 max-w-6 items-center" , ! to && "cursor-not-allowed opacity-50" ) }
17661798 onClick = { ( e ) => ! to && e . preventDefault ( ) }
17671799 shortcut = { { key : "[" } }
17681800 tooltip = "Previous Run"
@@ -1777,13 +1809,11 @@ function NextRunButton({ to }: { to: string | null }) {
17771809 return (
17781810 < div className = { cn ( "peer/next order-3" , ! to && "pointer-events-none" ) } >
17791811 < LinkButton
1780- to = { to ? to : '#' }
1812+ to = { to ? to : "#" }
17811813 variant = { "minimal/small" }
1782- TrailingIcon = { ChevronDownIcon }
1783- className = { cn (
1784- "flex items-center rounded-l-none border-l-0 pl-[0.5625rem] pr-2" ,
1785- ! to && "cursor-not-allowed opacity-50"
1786- ) }
1814+ LeadingIcon = { ChevronExtraSmallDown }
1815+ leadingIconClassName = "size-3 group-hover/button:text-text-bright transition-colors"
1816+ className = { cn ( "flex size-6 max-w-6 items-center" , ! to && "cursor-not-allowed opacity-50" ) }
17871817 onClick = { ( e ) => ! to && e . preventDefault ( ) }
17881818 shortcut = { { key : "]" } }
17891819 tooltip = "Next Run"
@@ -1793,4 +1823,3 @@ function NextRunButton({ to }: { to: string | null }) {
17931823 </ div >
17941824 ) ;
17951825}
1796-
0 commit comments