diff --git a/apps/webapp/app/components/admin/debugTooltip.tsx b/apps/webapp/app/components/admin/debugTooltip.tsx
index b4ccb74f88d..4157f898163 100644
--- a/apps/webapp/app/components/admin/debugTooltip.tsx
+++ b/apps/webapp/app/components/admin/debugTooltip.tsx
@@ -1,4 +1,5 @@
import { ShieldCheckIcon } from "@heroicons/react/20/solid";
+import { CopyableText } from "~/components/primitives/CopyableText";
import * as Property from "~/components/primitives/PropertyTable";
import {
Tooltip,
@@ -25,7 +26,10 @@ export function AdminDebugTooltip({ children }: { children?: React.ReactNode })
-
+ {/* The copy controls below pass `hideTooltip` so their own tooltips don't fire
+ Radix's global close and dismiss this panel. `pr-8` leaves room for the
+ copy button, which is absolutely positioned to the right of each value. */}
+
{children}
@@ -44,23 +48,31 @@ function Content({ children }: { children: React.ReactNode }) {
User ID
- {user.id}
+
+
+
{organization && (
Org ID
- {organization.id}
+
+
+
)}
{project && (
<>
Project ID
- {project.id}
+
+
+
Project ref
- {project.externalRef}
+
+
+
>
)}
@@ -68,7 +80,9 @@ function Content({ children }: { children: React.ReactNode }) {
<>
Environment ID
- {environment.id}
+
+
+
Environment type
@@ -81,7 +95,7 @@ function Content({ children }: { children: React.ReactNode }) {
>
)}
- {children}
+ {children && {children}
}
);
}
diff --git a/apps/webapp/app/components/primitives/CopyableText.tsx b/apps/webapp/app/components/primitives/CopyableText.tsx
index f8e19402aed..9634ad1ac01 100644
--- a/apps/webapp/app/components/primitives/CopyableText.tsx
+++ b/apps/webapp/app/components/primitives/CopyableText.tsx
@@ -11,12 +11,19 @@ export function CopyableText({
className,
asChild,
variant,
+ hideTooltip,
}: {
value: string;
copyValue?: string;
className?: string;
asChild?: boolean;
variant?: "icon-right" | "text-below";
+ /**
+ * Hide the "Copy"/"Copied" hint tooltip. Use when this is rendered inside another
+ * Radix tooltip (e.g. the admin debug panel): the nested tooltip would otherwise
+ * fire Radix's global "one tooltip open at a time" close and dismiss the parent.
+ */
+ hideTooltip?: boolean;
}) {
const [isHovered, setIsHovered] = useState(false);
const { copy, copied } = useCopy(copyValue ?? value);
@@ -24,6 +31,24 @@ export function CopyableText({
const resolvedVariant = variant ?? "icon-right";
if (resolvedVariant === "icon-right") {
+ const iconButton = (
+
+ {copied ? (
+
+ ) : (
+
+ )}
+
+ );
+
return (
-
- {copied ? (
-
- ) : (
-
- )}
-
- }
- content={copied ? "Copied!" : "Copy"}
- className="font-sans"
- disableHoverableContent
- asChild={asChild}
- />
+ {hideTooltip ? (
+ iconButton
+ ) : (
+
+ )}
);
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx
index c16e96b8f51..99c73f33849 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx
@@ -16,6 +16,7 @@ import { PlusIcon } from "~/assets/icons/PlusIcon";
import { QuestionMarkIcon } from "~/assets/icons/QuestionMarkIcon";
import { RunsIcon } from "~/assets/icons/RunsIcon";
import { TaskIcon } from "~/assets/icons/TaskIcon";
+import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
import { CodeBlock } from "~/components/code/CodeBlock";
import { InlineCode } from "~/components/code/InlineCode";
import { HasNoTasksDeployed, HasNoTasksDev } from "~/components/BlankStatePanels";
@@ -261,6 +262,7 @@ export default function Page() {
} />
+
{environment.slug}
- {environment.id}
+
+
+
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx
index 8c1de33c6f6..909a8bb6381 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.branches/route.tsx
@@ -242,7 +242,9 @@ export default function Page() {
{branches.map((branch) => (
{branch.branchName}
- {branch.id}
+
+
+
))}
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx
index 1bc359af598..e9542b5c8f5 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.concurrency/route.tsx
@@ -21,6 +21,7 @@ import { typedjson, useTypedLoaderData } from "remix-typedjson";
import simplur from "simplur";
import { z } from "zod";
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
+import { CopyableText } from "~/components/primitives/CopyableText";
import { EnvironmentCombo } from "~/components/environments/EnvironmentLabel";
import { Feedback } from "~/components/Feedback";
import {
@@ -270,7 +271,9 @@ export default function Page() {
{environment.type}{" "}
{environment.branchName ? ` (${environment.branchName})` : ""}
- {environment.id}
+
+
+
))}
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
index 20dd91d34b4..c4950277288 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.deployments.$deploymentParam/route.tsx
@@ -18,6 +18,7 @@ import { GitMetadata } from "~/components/GitMetadata";
import { VercelLink } from "~/components/integrations/VercelLink";
import { RuntimeIcon } from "~/components/RuntimeIcon";
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
+import { CopyableText } from "~/components/primitives/CopyableText";
import { EnvironmentCombo } from "~/components/environments/EnvironmentLabel";
import { Badge } from "~/components/primitives/Badge";
import { LinkButton } from "~/components/primitives/Buttons";
@@ -283,20 +284,28 @@ export default function Page() {
ID
- {deployment.id}
+
+
+
Project ID
- {deployment.projectId}
+
+
+
Org ID
- {deployment.organizationId}
+
+
+
{deployment.imageReference && (
Image
- {deployment.imageReference}
+
+
+
)}
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dev-branches/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dev-branches/route.tsx
index 9f704a54f9b..dd2679085e4 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dev-branches/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.dev-branches/route.tsx
@@ -95,7 +95,9 @@ export default function Page() {
{branches.map((branch) => (
{branch.branchName}
- {branch.id}
+
+
+
))}
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.limits/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.limits/route.tsx
index e27b11b7545..7ace6919a55 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.limits/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.limits/route.tsx
@@ -7,6 +7,7 @@ import { Gauge } from "lucide-react";
import { typedjson, useTypedLoaderData } from "remix-typedjson";
import { ConcurrencyIcon } from "~/assets/icons/ConcurrencyIcon";
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
+import { CopyableText } from "~/components/primitives/CopyableText";
import { Feedback } from "~/components/Feedback";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import { EnvironmentSelector } from "~/components/navigation/EnvironmentSelector";
@@ -125,7 +126,9 @@ export default function Page() {
Organization ID
- {data.organizationId}
+
+
+
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx
index 7992f28cc92..588647f22a7 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx
@@ -163,7 +163,9 @@ export default function Page() {
{regions.map((region) => (
{region.name}
- {region.id}
+
+
+
))}
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 dc5e8e591c1..95dbe5f7926 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
@@ -489,19 +489,27 @@ export default function Page() {
ID
- {run.id}
+
+
+
Trace ID
- {run.traceId}
+
+
+
Env ID
- {run.environment.id}
+
+
+
Org ID
- {run.environment.organizationId}
+
+
+
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 a69e3e82a97..dfb921e2691 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
@@ -11,6 +11,7 @@ import {
import { ListCheckedIcon } from "~/assets/icons/ListCheckedIcon";
import { QuestionMarkIcon } from "~/assets/icons/QuestionMarkIcon";
import { TaskIcon } from "~/assets/icons/TaskIcon";
+import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
import { DevDisconnectedBanner, useDevPresence } from "~/components/DevPresence";
import { InlineCode } from "~/components/code/InlineCode";
import { StepContentContainer } from "~/components/StepContentContainer";
@@ -166,6 +167,7 @@ export default function Page() {
)}
+
ID
- {project.id}
-
+
+
+
Org ID
- {project.organizationId}
+
+
+
diff --git a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx
index 32920a678ff..3e11636aeec 100644
--- a/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx
+++ b/apps/webapp/app/routes/_app.orgs.$organizationSlug.settings.team/route.tsx
@@ -18,6 +18,7 @@ import { z } from "zod";
import { Feedback } from "~/components/Feedback";
import { UserAvatar } from "~/components/UserProfilePhoto";
import { AdminDebugTooltip } from "~/components/admin/debugTooltip";
+import { CopyableText } from "~/components/primitives/CopyableText";
import { PageBody, PageContainer } from "~/components/layout/AppLayout";
import {
Alert,
@@ -372,7 +373,9 @@ export default function Page() {
Org ID
- {organization.id}
+
+
+
{members.map((member) => (