Skip to content

Commit 11d8a05

Browse files
authored
fix(webapp): restore admin debug tooltip on Tasks and Runs, make its IDs copyable (#4332)
Restores the debug panel on the **Tasks** and **Runs** pages, and makes the data it shows copyable. Admin/impersonation only — no change for regular users, so there's no `.server-changes` <img width="909" height="1420" alt="CleanShot 2026-07-22 at 12 05 27@2x" src="https://github.com/user-attachments/assets/ce2da167-dc23-422f-83f3-4f4aee9ed32c" />
1 parent 81eac67 commit 11d8a05

14 files changed

Lines changed: 118 additions & 51 deletions

File tree

  • apps/webapp/app
    • components
    • routes
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dev-branches
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.limits
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index
      • _app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.settings
      • _app.orgs.$organizationSlug.settings.team

apps/webapp/app/components/admin/debugTooltip.tsx

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { ShieldCheckIcon } from "@heroicons/react/20/solid";
2+
import { CopyableText } from "~/components/primitives/CopyableText";
23
import * as Property from "~/components/primitives/PropertyTable";
34
import {
45
Tooltip,
@@ -25,7 +26,10 @@ export function AdminDebugTooltip({ children }: { children?: React.ReactNode })
2526
<TooltipTrigger>
2627
<ShieldCheckIcon className="size-5" />
2728
</TooltipTrigger>
28-
<TooltipContent className="max-h-[90vh] overflow-y-auto">
29+
{/* The copy controls below pass `hideTooltip` so their own tooltips don't fire
30+
Radix's global close and dismiss this panel. `pr-8` leaves room for the
31+
copy button, which is absolutely positioned to the right of each value. */}
32+
<TooltipContent className="max-h-[90vh] overflow-y-auto pr-8">
2933
<Content>{children}</Content>
3034
</TooltipContent>
3135
</Tooltip>
@@ -44,31 +48,41 @@ function Content({ children }: { children: React.ReactNode }) {
4448
<Property.Table>
4549
<Property.Item>
4650
<Property.Label>User ID</Property.Label>
47-
<Property.Value>{user.id}</Property.Value>
51+
<Property.Value>
52+
<CopyableText value={user.id} asChild hideTooltip />
53+
</Property.Value>
4854
</Property.Item>
4955
{organization && (
5056
<Property.Item>
5157
<Property.Label>Org ID</Property.Label>
52-
<Property.Value>{organization.id}</Property.Value>
58+
<Property.Value>
59+
<CopyableText value={organization.id} asChild hideTooltip />
60+
</Property.Value>
5361
</Property.Item>
5462
)}
5563
{project && (
5664
<>
5765
<Property.Item>
5866
<Property.Label>Project ID</Property.Label>
59-
<Property.Value>{project.id}</Property.Value>
67+
<Property.Value>
68+
<CopyableText value={project.id} asChild hideTooltip />
69+
</Property.Value>
6070
</Property.Item>
6171
<Property.Item>
6272
<Property.Label>Project ref</Property.Label>
63-
<Property.Value>{project.externalRef}</Property.Value>
73+
<Property.Value>
74+
<CopyableText value={project.externalRef} asChild hideTooltip />
75+
</Property.Value>
6476
</Property.Item>
6577
</>
6678
)}
6779
{environment && (
6880
<>
6981
<Property.Item>
7082
<Property.Label>Environment ID</Property.Label>
71-
<Property.Value>{environment.id}</Property.Value>
83+
<Property.Value>
84+
<CopyableText value={environment.id} asChild hideTooltip />
85+
</Property.Value>
7286
</Property.Item>
7387
<Property.Item>
7488
<Property.Label>Environment type</Property.Label>
@@ -81,7 +95,7 @@ function Content({ children }: { children: React.ReactNode }) {
8195
</>
8296
)}
8397
</Property.Table>
84-
<div className="pt-2">{children}</div>
98+
{children && <div className="pt-2">{children}</div>}
8599
</div>
86100
);
87101
}

apps/webapp/app/components/primitives/CopyableText.tsx

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,44 @@ export function CopyableText({
1111
className,
1212
asChild,
1313
variant,
14+
hideTooltip,
1415
}: {
1516
value: string;
1617
copyValue?: string;
1718
className?: string;
1819
asChild?: boolean;
1920
variant?: "icon-right" | "text-below";
21+
/**
22+
* Hide the "Copy"/"Copied" hint tooltip. Use when this is rendered inside another
23+
* Radix tooltip (e.g. the admin debug panel): the nested tooltip would otherwise
24+
* fire Radix's global "one tooltip open at a time" close and dismiss the parent.
25+
*/
26+
hideTooltip?: boolean;
2027
}) {
2128
const [isHovered, setIsHovered] = useState(false);
2229
const { copy, copied } = useCopy(copyValue ?? value);
2330

2431
const resolvedVariant = variant ?? "icon-right";
2532

2633
if (resolvedVariant === "icon-right") {
34+
const iconButton = (
35+
<span
36+
className={cn(
37+
"ml-1 flex size-6 items-center justify-center rounded border border-border-bright bg-background-hover",
38+
asChild && "p-1",
39+
copied
40+
? "text-green-500"
41+
: "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright"
42+
)}
43+
>
44+
{copied ? (
45+
<ClipboardCheckIcon className="size-3.5" />
46+
) : (
47+
<ClipboardIcon className="size-3.5" />
48+
)}
49+
</span>
50+
);
51+
2752
return (
2853
<span
2954
className={cn("group relative inline-flex h-6 items-center", className)}
@@ -38,29 +63,17 @@ export function CopyableText({
3863
isHovered ? "flex" : "hidden"
3964
)}
4065
>
41-
<SimpleTooltip
42-
button={
43-
<span
44-
className={cn(
45-
"ml-1 flex size-6 items-center justify-center rounded border border-border-bright bg-background-hover",
46-
asChild && "p-1",
47-
copied
48-
? "text-green-500"
49-
: "text-text-dimmed hover:border-border-bright hover:bg-background-raised hover:text-text-bright"
50-
)}
51-
>
52-
{copied ? (
53-
<ClipboardCheckIcon className="size-3.5" />
54-
) : (
55-
<ClipboardIcon className="size-3.5" />
56-
)}
57-
</span>
58-
}
59-
content={copied ? "Copied!" : "Copy"}
60-
className="font-sans"
61-
disableHoverableContent
62-
asChild={asChild}
63-
/>
66+
{hideTooltip ? (
67+
iconButton
68+
) : (
69+
<SimpleTooltip
70+
button={iconButton}
71+
content={copied ? "Copied!" : "Copy"}
72+
className="font-sans"
73+
disableHoverableContent
74+
asChild={asChild}
75+
/>
76+
)}
6477
</span>
6578
</span>
6679
);

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { PlusIcon } from "~/assets/icons/PlusIcon";
1616
import { QuestionMarkIcon } from "~/assets/icons/QuestionMarkIcon";
1717
import { RunsIcon } from "~/assets/icons/RunsIcon";
1818
import { TaskIcon } from "~/assets/icons/TaskIcon";
19+
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
1920
import { CodeBlock } from "~/components/code/CodeBlock";
2021
import { InlineCode } from "~/components/code/InlineCode";
2122
import { HasNoTasksDeployed, HasNoTasksDev } from "~/components/BlankStatePanels";
@@ -261,6 +262,7 @@ export default function Page() {
261262
<NavBar>
262263
<PageTitle title="Tasks" accessory={<TasksHelpTooltip />} />
263264
<PageAccessories>
265+
<AdminDebugTooltip />
264266
<LinkButton
265267
variant={"docs/small"}
266268
LeadingIcon={BookOpenIcon}

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.apikeys/route.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { BookOpenIcon } from "@heroicons/react/20/solid";
22
import { type MetaFunction } from "@remix-run/react";
33
import { typedjson, useTypedLoaderData } from "remix-typedjson";
44
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
5+
import { CopyableText } from "~/components/primitives/CopyableText";
56
import { CodeBlock } from "~/components/code/CodeBlock";
67
import { InlineCode } from "~/components/code/InlineCode";
78
import {
@@ -113,7 +114,9 @@ export default function Page() {
113114
<Property.Table>
114115
<Property.Item key={environment.id}>
115116
<Property.Label>{environment.slug}</Property.Label>
116-
<Property.Value>{environment.id}</Property.Value>
117+
<Property.Value>
118+
<CopyableText value={environment.id} asChild hideTooltip />
119+
</Property.Value>
117120
</Property.Item>
118121
</Property.Table>
119122
</AdminDebugTooltip>

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ export default function Page() {
242242
{branches.map((branch) => (
243243
<Property.Item key={branch.id}>
244244
<Property.Label>{branch.branchName}</Property.Label>
245-
<Property.Value>{branch.id}</Property.Value>
245+
<Property.Value>
246+
<CopyableText value={branch.id} asChild hideTooltip />
247+
</Property.Value>
246248
</Property.Item>
247249
))}
248250
</Property.Table>

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { typedjson, useTypedLoaderData } from "remix-typedjson";
2121
import simplur from "simplur";
2222
import { z } from "zod";
2323
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
24+
import { CopyableText } from "~/components/primitives/CopyableText";
2425
import { EnvironmentCombo } from "~/components/environments/EnvironmentLabel";
2526
import { Feedback } from "~/components/Feedback";
2627
import {
@@ -270,7 +271,9 @@ export default function Page() {
270271
{environment.type}{" "}
271272
{environment.branchName ? ` (${environment.branchName})` : ""}
272273
</Property.Label>
273-
<Property.Value>{environment.id}</Property.Value>
274+
<Property.Value>
275+
<CopyableText value={environment.id} asChild hideTooltip />
276+
</Property.Value>
274277
</Property.Item>
275278
))}
276279
</Property.Table>

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { GitMetadata } from "~/components/GitMetadata";
1818
import { VercelLink } from "~/components/integrations/VercelLink";
1919
import { RuntimeIcon } from "~/components/RuntimeIcon";
2020
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
21+
import { CopyableText } from "~/components/primitives/CopyableText";
2122
import { EnvironmentCombo } from "~/components/environments/EnvironmentLabel";
2223
import { Badge } from "~/components/primitives/Badge";
2324
import { LinkButton } from "~/components/primitives/Buttons";
@@ -283,20 +284,28 @@ export default function Page() {
283284
<Property.Table>
284285
<Property.Item>
285286
<Property.Label>ID</Property.Label>
286-
<Property.Value>{deployment.id}</Property.Value>
287+
<Property.Value>
288+
<CopyableText value={deployment.id} asChild hideTooltip />
289+
</Property.Value>
287290
</Property.Item>
288291
<Property.Item>
289292
<Property.Label>Project ID</Property.Label>
290-
<Property.Value>{deployment.projectId}</Property.Value>
293+
<Property.Value>
294+
<CopyableText value={deployment.projectId} asChild hideTooltip />
295+
</Property.Value>
291296
</Property.Item>
292297
<Property.Item>
293298
<Property.Label>Org ID</Property.Label>
294-
<Property.Value>{deployment.organizationId}</Property.Value>
299+
<Property.Value>
300+
<CopyableText value={deployment.organizationId} asChild hideTooltip />
301+
</Property.Value>
295302
</Property.Item>
296303
{deployment.imageReference && (
297304
<Property.Item>
298305
<Property.Label>Image</Property.Label>
299-
<Property.Value>{deployment.imageReference}</Property.Value>
306+
<Property.Value>
307+
<CopyableText value={deployment.imageReference} asChild hideTooltip />
308+
</Property.Value>
300309
</Property.Item>
301310
)}
302311
<Property.Item>

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dev-branches/route.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ export default function Page() {
9595
{branches.map((branch) => (
9696
<Property.Item key={branch.id}>
9797
<Property.Label>{branch.branchName}</Property.Label>
98-
<Property.Value>{branch.id}</Property.Value>
98+
<Property.Value>
99+
<CopyableText value={branch.id} asChild hideTooltip />
100+
</Property.Value>
99101
</Property.Item>
100102
))}
101103
</Property.Table>

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.limits/route.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Gauge } from "lucide-react";
77
import { typedjson, useTypedLoaderData } from "remix-typedjson";
88
import { ConcurrencyIcon } from "~/assets/icons/ConcurrencyIcon";
99
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
10+
import { CopyableText } from "~/components/primitives/CopyableText";
1011
import { Feedback } from "~/components/Feedback";
1112
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
1213
import { EnvironmentSelector } from "~/components/navigation/EnvironmentSelector";
@@ -125,7 +126,9 @@ export default function Page() {
125126
</Property.Item>
126127
<Property.Item>
127128
<Property.Label>Organization ID</Property.Label>
128-
<Property.Value>{data.organizationId}</Property.Value>
129+
<Property.Value>
130+
<CopyableText value={data.organizationId} asChild hideTooltip />
131+
</Property.Value>
129132
</Property.Item>
130133
</Property.Table>
131134
</AdminDebugTooltip>

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ export default function Page() {
163163
{regions.map((region) => (
164164
<Property.Item key={region.id}>
165165
<Property.Label>{region.name}</Property.Label>
166-
<Property.Value>{region.id}</Property.Value>
166+
<Property.Value>
167+
<CopyableText value={region.id} asChild hideTooltip />
168+
</Property.Value>
167169
</Property.Item>
168170
))}
169171
</Property.Table>

0 commit comments

Comments
 (0)