From f9b4d25fa1d8c6e8f25789884ecf540b455de3a8 Mon Sep 17 00:00:00 2001 From: Chris Arderne Date: Wed, 19 Aug 2026 17:31:47 +0100 Subject: [PATCH] fix(webapp): derive expiry status from loader time --- .../route.tsx | 16 ++++++-- .../route.tsx | 39 ++++++++++++------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx index 0102343d136..34a2f9882f7 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx @@ -173,6 +173,7 @@ export const loader = dashboardLoader( additionalApiKeyIssuanceEnabled, isRbacPluginAvailable, showRevoked: searchParams.showRevoked ?? false, + loadedAt: Date.now(), }); } catch (error) { console.error(error); @@ -308,6 +309,7 @@ export default function Page() { hasVercelIntegration, availableTasks, presets, + loadedAt, } = useTypedLoaderData(); const apiKeyEnvironmentLabel = { @@ -398,7 +400,7 @@ export default function Page() { - + @@ -424,7 +426,7 @@ export default function Page() { {apiKeys.map((apiKey) => { const isExpired = apiKey.expiresAt - ? new Date(apiKey.expiresAt).getTime() <= Date.now() + ? new Date(apiKey.expiresAt).getTime() <= loadedAt : false; const cannotAuthenticate = Boolean(apiKey.revokedAt) || isExpired; const cannotRevoke = Boolean(apiKey.revokedAt) || isExpired; @@ -445,7 +447,11 @@ export default function Page() { {apiKey.obfuscated} - + diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx index 64326fab5bb..1880c2c1112 100644 --- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx +++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.sessions.$sessionParam/route.tsx @@ -115,21 +115,18 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => { throw new Response("Session not found", { status: 404 }); } - return typedjson({ session }); + return typedjson({ session, loadedAt: Date.now() }); }; export default function Page() { - const { session } = useTypedLoaderData(); + const { session, loadedAt } = useTypedLoaderData(); const organization = useOrganization(); const project = useProject(); const environment = useEnvironment(); + const isExpired = session.expiresAt != null && new Date(session.expiresAt).getTime() < loadedAt; const status: SessionStatus = - session.closedAt != null - ? "CLOSED" - : session.expiresAt != null && new Date(session.expiresAt).getTime() < Date.now() - ? "EXPIRED" - : "ACTIVE"; + session.closedAt != null ? "CLOSED" : isExpired ? "EXPIRED" : "ACTIVE"; const displayId = session.externalId ?? session.friendlyId; const sessionsPath = v3SessionsPath(organization, project, environment); @@ -170,7 +167,7 @@ export default function Page() { default="420px" className="overflow-hidden" > - + @@ -712,7 +709,15 @@ function MergedStreamRow({ ); } -function InspectorPane({ session, status }: { session: LoadedSession; status: SessionStatus }) { +function InspectorPane({ + session, + status, + isExpired, +}: { + session: LoadedSession; + status: SessionStatus; + isExpired: boolean; +}) { const { value, replace } = useSearchParams(); const tab = value("tab") ?? "overview"; const organization = useOrganization(); @@ -761,7 +766,7 @@ function InspectorPane({ session, status }: { session: LoadedSession; status: Se
{tab === "overview" ? ( - + ) : tab === "runs" ? ( ) : ( @@ -772,7 +777,15 @@ function InspectorPane({ session, status }: { session: LoadedSession; status: Se ); } -function OverviewTab({ session, status }: { session: LoadedSession; status: SessionStatus }) { +function OverviewTab({ + session, + status, + isExpired, +}: { + session: LoadedSession; + status: SessionStatus; + isExpired: boolean; +}) { const organization = useOrganization(); const project = useProject(); const environment = useEnvironment(); @@ -892,9 +905,7 @@ function OverviewTab({ session, status }: { session: LoadedSession; status: Sess {session.expiresAt ? ( - - {new Date(session.expiresAt).getTime() < Date.now() ? "Expired" : "Expires"} - + {isExpired ? "Expired" : "Expires"}