Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Comment thread
carderne marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export const loader = dashboardLoader(
additionalApiKeyIssuanceEnabled,
isRbacPluginAvailable,
showRevoked: searchParams.showRevoked ?? false,
loadedAt: Date.now(),
});
} catch (error) {
console.error(error);
Expand Down Expand Up @@ -308,6 +309,7 @@ export default function Page() {
hasVercelIntegration,
availableTasks,
presets,
loadedAt,
} = useTypedLoaderData<typeof loader>();

const apiKeyEnvironmentLabel = {
Expand Down Expand Up @@ -398,7 +400,7 @@ export default function Page() {
</div>
</TableCell>
<TableCell>
<ApiKeyStatus />
<ApiKeyStatus now={loadedAt} />
</TableCell>
<TableCell>
<ApiKeyAccess label="No restrictions" />
Expand All @@ -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;
Expand All @@ -445,7 +447,11 @@ export default function Page() {
<span className="font-mono text-text-dimmed">{apiKey.obfuscated}</span>
</TableCell>
<TableCell>
<ApiKeyStatus revokedAt={apiKey.revokedAt} expiresAt={apiKey.expiresAt} />
<ApiKeyStatus
revokedAt={apiKey.revokedAt}
expiresAt={apiKey.expiresAt}
now={loadedAt}
/>
</TableCell>
<TableCell>
<ApiKeyAccess
Expand Down Expand Up @@ -1338,9 +1344,11 @@ function ApiKeyAccess({
function ApiKeyStatus({
revokedAt,
expiresAt,
now,
}: {
revokedAt?: Date | string | null;
expiresAt?: Date | string | null;
now: number;
}) {
if (revokedAt) {
return (
Expand All @@ -1351,7 +1359,7 @@ function ApiKeyStatus({
);
}

if (expiresAt && new Date(expiresAt).getTime() <= Date.now()) {
if (expiresAt && new Date(expiresAt).getTime() <= now) {
return (
<div className="flex items-center gap-1 text-xs text-text-dimmed">
<ExclamationTriangleIcon className="size-4" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof loader>();
const { session, loadedAt } = useTypedLoaderData<typeof loader>();
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);
Expand Down Expand Up @@ -170,7 +167,7 @@ export default function Page() {
default="420px"
className="overflow-hidden"
>
<InspectorPane session={session} status={status} />
<InspectorPane session={session} status={status} isExpired={isExpired} />
</ResizablePanel>
</ResizablePanelGroup>
</PageBody>
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -761,7 +766,7 @@ function InspectorPane({ session, status }: { session: LoadedSession; status: Se
</div>
<div className="overflow-y-auto px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
{tab === "overview" ? (
<OverviewTab session={session} status={status} />
<OverviewTab session={session} status={status} isExpired={isExpired} />
) : tab === "runs" ? (
<RunsTab session={session} status={status} allRunsPath={allRunsPath} />
) : (
Expand All @@ -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();
Expand Down Expand Up @@ -892,9 +905,7 @@ function OverviewTab({ session, status }: { session: LoadedSession; status: Sess
</Property.Item>
{session.expiresAt ? (
<Property.Item>
<Property.Label>
{new Date(session.expiresAt).getTime() < Date.now() ? "Expired" : "Expires"}
</Property.Label>
<Property.Label>{isExpired ? "Expired" : "Expires"}</Property.Label>
<Property.Value>
<DateTime date={session.expiresAt} />
</Property.Value>
Expand Down