From 10ebe6955d5a3550eb4b3c3dce9222ef91bb89d1 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Mon, 31 Mar 2025 14:04:13 +0100 Subject: [PATCH 1/7] Adds DevPresenceBanner to the Run page --- .../route.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index 8fd725ee3d..19e7b32fa5 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -21,13 +21,13 @@ import { tryCatch, } from "@trigger.dev/core/v3"; import { type RuntimeEnvironmentType } from "@trigger.dev/database"; -import { motion } from "framer-motion"; +import { AnimatePresence, motion } from "framer-motion"; import { useCallback, useEffect, useRef, useState } from "react"; import { useHotkeys } from "react-hotkeys-hook"; import { DisconnectedIcon } from "~/assets/icons/ConnectionIcons"; import { ShowParentIcon, ShowParentIconSelected } from "~/assets/icons/ShowParentIcon"; import tileBgPath from "~/assets/images/error-banner-tile@2x.png"; -import { useDevPresence } from "~/components/DevPresence"; +import { DevPresenceBanner, useDevPresence } from "~/components/DevPresence"; import { AdminDebugTooltip } from "~/components/admin/debugTooltip"; import { PageBody } from "~/components/layout/AppLayout"; import { Badge } from "~/components/primitives/Badge"; @@ -195,6 +195,19 @@ export default function Page() { }} title={`Run #${run.number}`} /> + + {environment.type === "DEVELOPMENT" && ( + + + + )} + From a03c58839b308eec8794317dbf3966e255d99059 Mon Sep 17 00:00:00 2001 From: James Ritchie Date: Mon, 31 Mar 2025 14:05:03 +0100 Subject: [PATCH 2/7] Adds DevPresenceBanner to the Run list page --- .../route.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx index 2bf0ef79af..94ae39b502 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx @@ -8,6 +8,7 @@ import { ListChecks, ListX } from "lucide-react"; import { Suspense, useState } from "react"; import { TypedAwait, typeddefer, useTypedLoaderData } from "remix-typedjson"; import { TaskIcon } from "~/assets/icons/TaskIcon"; +import { DevPresenceBanner, useDevPresence } from "~/components/DevPresence"; import { StepContentContainer } from "~/components/StepContentContainer"; import { MainCenteredContainer, PageBody } from "~/components/layout/AppLayout"; import { Button, LinkButton } from "~/components/primitives/Buttons"; @@ -161,11 +162,26 @@ export default function Page() { const { data, rootOnlyDefault } = useTypedLoaderData(); const navigation = useNavigation(); const isLoading = navigation.state !== "idle"; + const { isConnected } = useDevPresence(); + const environment = useEnvironment(); return ( <> + + {environment.type === "DEVELOPMENT" && !isConnected && ( + + + + )} + Date: Mon, 31 Mar 2025 14:06:20 +0100 Subject: [PATCH 3/7] Makes the DevConnection component reusable and moves components to the DevPresence.tsx file --- apps/webapp/app/components/DevPresence.tsx | 112 +++++++++++++++ .../app/components/navigation/SideMenu.tsx | 127 +++++------------- 2 files changed, 145 insertions(+), 94 deletions(-) diff --git a/apps/webapp/app/components/DevPresence.tsx b/apps/webapp/app/components/DevPresence.tsx index 396c6ea9f6..f6f23eb062 100644 --- a/apps/webapp/app/components/DevPresence.tsx +++ b/apps/webapp/app/components/DevPresence.tsx @@ -1,8 +1,23 @@ +import { AnimatePresence, motion } from "framer-motion"; import { createContext, type ReactNode, useContext, useEffect, useMemo, useState } from "react"; +import { + CheckingConnectionIcon, + ConnectedIcon, + DisconnectedIcon, +} from "~/assets/icons/ConnectionIcons"; import { useEnvironment } from "~/hooks/useEnvironment"; import { useEventSource } from "~/hooks/useEventSource"; import { useOrganization } from "~/hooks/useOrganizations"; import { useProject } from "~/hooks/useProject"; +import { docsPath } from "~/utils/pathBuilder"; +import connectedImage from "../assets/images/cli-connected.png"; +import disconnectedImage from "../assets/images/cli-disconnected.png"; +import { InlineCode } from "./code/InlineCode"; +import { Button } from "./primitives/Buttons"; +import { Dialog, DialogContent, DialogHeader, DialogTrigger } from "./primitives/Dialog"; +import { Paragraph } from "./primitives/Paragraph"; +import { TextLink } from "./primitives/TextLink"; +import { PackageManagerProvider, TriggerDevStepV3 } from "./SetupCommands"; // Define Context types type DevPresenceContextType = { @@ -77,3 +92,100 @@ export function useDevPresence() { } return context; } + +export function ConnectionIcon({ isConnected }: { isConnected: boolean | undefined }) { + if (isConnected === undefined) { + return ; + } + return isConnected ? ( + + ) : ( + + ); +} + +export function DevConnection({ + children, +}: { + children: (props: { isConnected: boolean | undefined }) => React.ReactNode; +}) { + const { isConnected } = useDevPresence(); + + return ( + + {children({ isConnected })} + + + {isConnected === undefined + ? "Checking connection..." + : isConnected + ? "Your dev server is connected" + : "Your dev server is not connected"} + +
+
+ {isConnected + + {isConnected === undefined + ? "Checking connection..." + : isConnected + ? "Your local dev server is connected to Trigger.dev" + : "Your local dev server is not connected to Trigger.dev"} + +
+ {isConnected ? null : ( +
+ + + + + Run this CLI dev command to connect + to the Trigger.dev servers to start developing locally. Keep it running while you + develop to stay connected. Learn more in the{" "} + CLI docs. + +
+ )} +
+
+
+ ); +} + +export function DevPresenceBanner() { + const environment = useEnvironment(); + const { isConnected } = useDevPresence(); + + return ( + + {environment.type === "DEVELOPMENT" && !isConnected && ( + + + {({ isConnected }) => ( + + + + )} + + + )} + + ); +} diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index 18b9b7d5df..67a2aec277 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -20,13 +20,9 @@ import { import { useNavigation } from "@remix-run/react"; import { useEffect, useRef, useState, type ReactNode } from "react"; import simplur from "simplur"; -import { - CheckingConnectionIcon, - ConnectedIcon, - DisconnectedIcon, -} from "~/assets/icons/ConnectionIcons"; -import { RunsIconExtraSmall, RunsIconSmall } from "~/assets/icons/RunsIcon"; +import { RunsIconExtraSmall } from "~/assets/icons/RunsIcon"; import { TaskIconSmall } from "~/assets/icons/TaskIcon"; +import { WaitpointTokenIcon } from "~/assets/icons/WaitpointTokenIcon"; import { Avatar } from "~/components/primitives/Avatar"; import { type MatchedEnvironment } from "~/hooks/useEnvironment"; import { type MatchedOrganization } from "~/hooks/useOrganizations"; @@ -37,7 +33,6 @@ import { type FeedbackType } from "~/routes/resources.feedback"; import { cn } from "~/utils/cn"; import { accountPath, - docsPath, logoutPath, newOrganizationPath, newProjectPath, @@ -60,14 +55,12 @@ import { v3UsagePath, v3WaitpointTokensPath, } from "~/utils/pathBuilder"; -import connectedImage from "../../assets/images/cli-connected.png"; -import disconnectedImage from "../../assets/images/cli-disconnected.png"; + import { FreePlanUsage } from "../billing/FreePlanUsage"; -import { InlineCode } from "../code/InlineCode"; -import { useDevPresence } from "../DevPresence"; +import { ConnectionIcon, DevConnection } from "../DevPresence"; import { ImpersonationBanner } from "../ImpersonationBanner"; import { Button, ButtonContent, LinkButton } from "../primitives/Buttons"; -import { Dialog, DialogContent, DialogHeader, DialogTrigger } from "../primitives/Dialog"; +import { DialogTrigger } from "../primitives/Dialog"; import { Paragraph } from "../primitives/Paragraph"; import { Popover, @@ -78,15 +71,12 @@ import { } from "../primitives/Popover"; import { TextLink } from "../primitives/TextLink"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../primitives/Tooltip"; -import { PackageManagerProvider, TriggerDevStepV3 } from "../SetupCommands"; import { UserProfilePhoto } from "../UserProfilePhoto"; import { EnvironmentSelector } from "./EnvironmentSelector"; import { HelpAndFeedback } from "./HelpAndFeedbackPopover"; import { SideMenuHeader } from "./SideMenuHeader"; import { SideMenuItem } from "./SideMenuItem"; import { SideMenuSection } from "./SideMenuSection"; -import { WaitpointTokenIcon } from "~/assets/icons/WaitpointTokenIcon"; -import { Spinner } from "../primitives/Spinner"; type SideMenuUser = Pick & { isImpersonating: boolean }; export type SideMenuProject = Pick< @@ -163,7 +153,34 @@ export function SideMenu({ project={project} environment={environment} /> - {environment.type === "DEVELOPMENT" && } + {environment.type === "DEVELOPMENT" && ( + + {({ isConnected }) => ( + + + +
+ +
+
+ + {isConnected === undefined + ? "Checking connection..." + : isConnected + ? "Your dev server is connected" + : "Your dev server is not connected"} + +
+
+ )} +
+ )} @@ -522,81 +539,3 @@ function SelectorDivider() { ); } - -export function DevConnection() { - const { isConnected } = useDevPresence(); - - return ( - - - - -
- -
-
- - {isConnected === undefined - ? "Checking connection..." - : isConnected - ? "Your dev server is connected" - : "Your dev server is not connected"} - -
-
- - - {isConnected === undefined - ? "Checking connection..." - : isConnected - ? "Your dev server is connected" - : "Your dev server is not connected"} - -
-
- {isConnected - - {isConnected === undefined - ? "Checking connection..." - : isConnected - ? "Your local dev server is connected to Trigger.dev" - : "Your local dev server is not connected to Trigger.dev"} - -
- {isConnected ? null : ( -
- - - - - Run this CLI dev command to connect - to the Trigger.dev servers to start developing locally. Keep it running while you - develop to stay connected. Learn more in the{" "} - CLI docs. - -
- )} -
-
-
- ); -} From 2e22f0c599f15f380f815fccea6d0f545be6b00b Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 1 Apr 2025 12:39:28 +0100 Subject: [PATCH 4/7] SideMenu: only show dev presence when project engine === V2 --- apps/webapp/app/components/navigation/SideMenu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index 67a2aec277..d805730d52 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -81,7 +81,7 @@ import { SideMenuSection } from "./SideMenuSection"; type SideMenuUser = Pick & { isImpersonating: boolean }; export type SideMenuProject = Pick< MatchedProject, - "id" | "name" | "slug" | "version" | "environments" + "id" | "name" | "slug" | "version" | "environments" | "engine" >; export type SideMenuEnvironment = MatchedEnvironment; @@ -153,7 +153,7 @@ export function SideMenu({ project={project} environment={environment} /> - {environment.type === "DEVELOPMENT" && ( + {environment.type === "DEVELOPMENT" && project.engine === "V2" && ( {({ isConnected }) => ( From 9c4f9e6ded2efb960b95cdb94f9dab49ba35c2b5 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 1 Apr 2025 13:33:39 +0100 Subject: [PATCH 5/7] WIP on disconnected banner on v3 and v4 --- apps/webapp/app/components/DevPresence.tsx | 155 ++++++++++-------- .../app/components/navigation/SideMenu.tsx | 57 ++++--- .../route.tsx | 21 +-- .../route.tsx | 19 +-- 4 files changed, 127 insertions(+), 125 deletions(-) diff --git a/apps/webapp/app/components/DevPresence.tsx b/apps/webapp/app/components/DevPresence.tsx index f6f23eb062..fb4011789a 100644 --- a/apps/webapp/app/components/DevPresence.tsx +++ b/apps/webapp/app/components/DevPresence.tsx @@ -93,6 +93,38 @@ export function useDevPresence() { return context; } +/** + * We need this for the legacy v1 engine, where we show the banner after a delay if there are no events. + */ +export function useCrossEngineIsConnected({ logCount }: { logCount: number }) { + const project = useProject(); + const environment = useEnvironment(); + const { isConnected } = useDevPresence(); + const [crossEngineIsConnected, setCrossEngineIsConnected] = useState( + undefined + ); + + useEffect(() => { + if (project.engine === "V2") { + setCrossEngineIsConnected(isConnected); + return; + } + + if (project.engine === "V1") { + if (logCount <= 1) { + const timer = setTimeout(() => { + setCrossEngineIsConnected(false); + }, 5000); + return () => clearTimeout(timer); + } else { + setCrossEngineIsConnected(true); + } + } + }, [environment.type, project.engine, logCount, isConnected]); + + return crossEngineIsConnected; +} + export function ConnectionIcon({ isConnected }: { isConnected: boolean | undefined }) { if (isConnected === undefined) { return ; @@ -104,66 +136,54 @@ export function ConnectionIcon({ isConnected }: { isConnected: boolean | undefin ); } -export function DevConnection({ - children, -}: { - children: (props: { isConnected: boolean | undefined }) => React.ReactNode; -}) { - const { isConnected } = useDevPresence(); - +export function DevPresencePanel({ isConnected }: { isConnected: boolean | undefined }) { return ( - - {children({ isConnected })} - - - {isConnected === undefined - ? "Checking connection..." - : isConnected - ? "Your dev server is connected" - : "Your dev server is not connected"} - -
-
- {isConnected - - {isConnected === undefined - ? "Checking connection..." - : isConnected - ? "Your local dev server is connected to Trigger.dev" - : "Your local dev server is not connected to Trigger.dev"} + + + {isConnected === undefined + ? "Checking connection..." + : isConnected + ? "Your dev server is connected" + : "Your dev server is not connected"} + +
+
+ {isConnected + + {isConnected === undefined + ? "Checking connection..." + : isConnected + ? "Your local dev server is connected to Trigger.dev" + : "Your local dev server is not connected to Trigger.dev"} + +
+ {isConnected ? null : ( +
+ + + + + Run this CLI dev command to connect to + the Trigger.dev servers to start developing locally. Keep it running while you develop + to stay connected. Learn more in the{" "} + CLI docs.
- {isConnected ? null : ( -
- - - - - Run this CLI dev command to connect - to the Trigger.dev servers to start developing locally. Keep it running while you - develop to stay connected. Learn more in the{" "} - CLI docs. - -
- )} -
-
-
+ )} + + ); } -export function DevPresenceBanner() { - const environment = useEnvironment(); - const { isConnected } = useDevPresence(); - +export function DevDisconnectedBanner({ isConnected }: { isConnected: boolean | undefined }) { return ( - - {environment.type === "DEVELOPMENT" && !isConnected && ( + + - - {({ isConnected }) => ( - - - - )} - + {isConnected === false && ( + + + + )} - )} - + + + ); } diff --git a/apps/webapp/app/components/navigation/SideMenu.tsx b/apps/webapp/app/components/navigation/SideMenu.tsx index d805730d52..0551b80050 100644 --- a/apps/webapp/app/components/navigation/SideMenu.tsx +++ b/apps/webapp/app/components/navigation/SideMenu.tsx @@ -55,12 +55,11 @@ import { v3UsagePath, v3WaitpointTokensPath, } from "~/utils/pathBuilder"; - import { FreePlanUsage } from "../billing/FreePlanUsage"; -import { ConnectionIcon, DevConnection } from "../DevPresence"; +import { ConnectionIcon, DevPresencePanel, useDevPresence } from "../DevPresence"; import { ImpersonationBanner } from "../ImpersonationBanner"; import { Button, ButtonContent, LinkButton } from "../primitives/Buttons"; -import { DialogTrigger } from "../primitives/Dialog"; +import { Dialog, DialogTrigger } from "../primitives/Dialog"; import { Paragraph } from "../primitives/Paragraph"; import { Popover, @@ -105,6 +104,7 @@ export function SideMenu({ const borderRef = useRef(null); const [showHeaderDivider, setShowHeaderDivider] = useState(false); const currentPlan = useCurrentPlan(); + const { isConnected } = useDevPresence(); const isFreeUser = currentPlan?.v3Subscription?.isPaying === false; useEffect(() => { @@ -154,32 +154,31 @@ export function SideMenu({ environment={environment} /> {environment.type === "DEVELOPMENT" && project.engine === "V2" && ( - - {({ isConnected }) => ( - - - -
- -
-
- - {isConnected === undefined - ? "Checking connection..." - : isConnected - ? "Your dev server is connected" - : "Your dev server is not connected"} - -
-
- )} -
+ + + + +
+ +
+
+ + {isConnected === undefined + ? "Checking connection..." + : isConnected + ? "Your dev server is connected" + : "Your dev server is not connected"} + +
+
+ +
)} diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index 19e7b32fa5..26441595b1 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -27,7 +27,11 @@ import { useHotkeys } from "react-hotkeys-hook"; import { DisconnectedIcon } from "~/assets/icons/ConnectionIcons"; import { ShowParentIcon, ShowParentIconSelected } from "~/assets/icons/ShowParentIcon"; import tileBgPath from "~/assets/images/error-banner-tile@2x.png"; -import { DevPresenceBanner, useDevPresence } from "~/components/DevPresence"; +import { + DevDisconnectedBanner, + useCrossEngineIsConnected, + useDevPresence, +} from "~/components/DevPresence"; import { AdminDebugTooltip } from "~/components/admin/debugTooltip"; import { PageBody } from "~/components/layout/AppLayout"; import { Badge } from "~/components/primitives/Badge"; @@ -184,6 +188,7 @@ export default function Page() { const organization = useOrganization(); const project = useProject(); const environment = useEnvironment(); + const isConnected = useCrossEngineIsConnected({ logCount: trace?.events.length ?? 0 }); return ( <> @@ -195,19 +200,7 @@ export default function Page() { }} title={`Run #${run.number}`} /> - - {environment.type === "DEVELOPMENT" && ( - - - - )} - + {environment.type === "DEVELOPMENT" && } diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx index 94ae39b502..bcb1447e40 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/route.tsx @@ -8,7 +8,7 @@ import { ListChecks, ListX } from "lucide-react"; import { Suspense, useState } from "react"; import { TypedAwait, typeddefer, useTypedLoaderData } from "remix-typedjson"; import { TaskIcon } from "~/assets/icons/TaskIcon"; -import { DevPresenceBanner, useDevPresence } from "~/components/DevPresence"; +import { DevDisconnectedBanner, useDevPresence } from "~/components/DevPresence"; import { StepContentContainer } from "~/components/StepContentContainer"; import { MainCenteredContainer, PageBody } from "~/components/layout/AppLayout"; import { Button, LinkButton } from "~/components/primitives/Buttons"; @@ -163,25 +163,16 @@ export default function Page() { const navigation = useNavigation(); const isLoading = navigation.state !== "idle"; const { isConnected } = useDevPresence(); + const project = useProject(); const environment = useEnvironment(); return ( <> - - {environment.type === "DEVELOPMENT" && !isConnected && ( - - - - )} - + {environment.type === "DEVELOPMENT" && project.engine === "V2" && ( + + )} Date: Tue, 1 Apr 2025 13:55:55 +0100 Subject: [PATCH 6/7] v3 dev connection working. Made it slightly red --- apps/webapp/app/components/DevPresence.tsx | 23 ++++++++------- .../route.tsx | 29 ------------------- 2 files changed, 12 insertions(+), 40 deletions(-) diff --git a/apps/webapp/app/components/DevPresence.tsx b/apps/webapp/app/components/DevPresence.tsx index fb4011789a..fc81d787f2 100644 --- a/apps/webapp/app/components/DevPresence.tsx +++ b/apps/webapp/app/components/DevPresence.tsx @@ -184,25 +184,26 @@ export function DevDisconnectedBanner({ isConnected }: { isConnected: boolean | return ( - - {isConnected === false && ( + {isConnected === false && ( + - )} - + + )} diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index 26441595b1..077a0a2133 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -672,9 +672,6 @@ function TasksTreeView({ - {!isCompleted && - environmentType === "DEVELOPMENT" && - index === displayEvents.length - 1 && } )} onScroll={(scrollTop) => { @@ -1276,32 +1273,6 @@ function CurrentTimeIndicator({ ); } -function ConnectedDevWarning() { - const { isConnected } = useDevPresence(); - - return ( -
- } - className="mt-2" - > -
- - Your local dev server is not connectedr. Check you're running the CLI: - - -
-
-
- ); -} - function KeyboardShortcuts({ expandAllBelowDepth, collapseAllBelowDepth, From 934cd7f58844038ab43e9f16f034ec61bf087eb2 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Tue, 1 Apr 2025 14:07:49 +0100 Subject: [PATCH 7/7] Only show the disconnected banner on v3 if the run is not completed --- apps/webapp/app/components/DevPresence.tsx | 15 +++++++++++++-- .../route.tsx | 5 ++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/apps/webapp/app/components/DevPresence.tsx b/apps/webapp/app/components/DevPresence.tsx index fc81d787f2..7a99dab37a 100644 --- a/apps/webapp/app/components/DevPresence.tsx +++ b/apps/webapp/app/components/DevPresence.tsx @@ -96,7 +96,13 @@ export function useDevPresence() { /** * We need this for the legacy v1 engine, where we show the banner after a delay if there are no events. */ -export function useCrossEngineIsConnected({ logCount }: { logCount: number }) { +export function useCrossEngineIsConnected({ + isCompleted, + logCount, +}: { + isCompleted: boolean; + logCount: number; +}) { const project = useProject(); const environment = useEnvironment(); const { isConnected } = useDevPresence(); @@ -111,6 +117,11 @@ export function useCrossEngineIsConnected({ logCount }: { logCount: number }) { } if (project.engine === "V1") { + if (isCompleted) { + setCrossEngineIsConnected(true); + return; + } + if (logCount <= 1) { const timer = setTimeout(() => { setCrossEngineIsConnected(false); @@ -120,7 +131,7 @@ export function useCrossEngineIsConnected({ logCount }: { logCount: number }) { setCrossEngineIsConnected(true); } } - }, [environment.type, project.engine, logCount, isConnected]); + }, [environment.type, project.engine, logCount, isConnected, isCompleted]); return crossEngineIsConnected; } diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx index 077a0a2133..b0e6c981e9 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx @@ -188,7 +188,10 @@ export default function Page() { const organization = useOrganization(); const project = useProject(); const environment = useEnvironment(); - const isConnected = useCrossEngineIsConnected({ logCount: trace?.events.length ?? 0 }); + const isConnected = useCrossEngineIsConnected({ + logCount: trace?.events.length ?? 0, + isCompleted: run.completedAt !== null, + }); return ( <>