Skip to content

Commit

Permalink
feat: add copy icon
Browse files Browse the repository at this point in the history
  • Loading branch information
tschoffelen committed Sep 1, 2024
1 parent 2c743d1 commit 583b129
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 15 deletions.
61 changes: 56 additions & 5 deletions packages/dashboard/src/components/stats/payload-preview.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { useTheme } from "@/components/layout/theme-provider";
import { useMemo } from "react";
import { useMemo, useState } from "react";
import { JSONTree } from "react-json-tree";

import { useTheme } from "@/components/layout/theme-provider";
import { Button } from "@/components/ui/button";
import { Clipboard, ClipboardCheck, Maximize2, Minimize2 } from "lucide-react";

const theme = {
scheme: "monokai",
base00: "transparent",
Expand All @@ -22,27 +25,75 @@ const theme = {
base0F: "#cc6633",
};

const expandRootNode = (keyPath, data, level) => level === 0;

const PayloadPreviewValue = ({ value }) => {
const { value: themeValue } = useTheme();
const [expandAll, setExpandAll] = useState(false);
const [copied, setCopied] = useState(false);

const copy = () => {
navigator.clipboard.writeText(
typeof value === "string" ? value : JSON.stringify(value, null, 2),
);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};

if (typeof value === "string") {
return <pre className="font-mono text-sm p-4 px-5">{value}</pre>;
return (
<div className="group relative">
<div className="absolute top-3 right-3 gap-2 hidden group-hover:flex">
<Button variant="outline" size="miniIcon" onClick={() => copy()}>
{copied ? (
<ClipboardCheck className="size-3" />
) : (
<Clipboard className="size-3" />
)}
</Button>
</div>
<pre className="font-mono text-sm p-4 px-5">{value}</pre>
</div>
);
}

return (
<div className="mt-4 mr-5 ml-3 pb-5 font-mono text-sm">
<div className="mt-4 mr-5 ml-3 pb-5 font-mono text-sm group relative">
<div className="absolute -top-1 -right-2 gap-2 hidden group-hover:flex">
<Button variant="outline" size="miniIcon" onClick={() => copy()}>
{copied ? (
<ClipboardCheck className="size-3" />
) : (
<Clipboard className="size-3" />
)}
</Button>
<Button
variant="outline"
size="miniIcon"
onClick={() => setExpandAll(!expandAll)}
>
{expandAll ? (
<Minimize2 className="size-3" />
) : (
<Maximize2 className="size-3" />
)}
</Button>
</div>
<JSONTree
data={value}
theme={theme}
hideRoot
key={expandAll}
invertTheme={themeValue === "light"}
shouldExpandNodeInitially={expandAll ? Boolean : expandRootNode}
/>
</div>
);
};

const PayloadPreview = ({ title = "", value }) => {
const truncated = typeof value === 'string' && value?.includes("...[too long]");
const truncated =
typeof value === "string" && value?.includes("...[too long]");

const displayValue = useMemo(() => {
try {
Expand Down
49 changes: 39 additions & 10 deletions packages/dashboard/src/components/stats/transaction-details.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { useMemo } from "react";
import { CaretDownIcon } from "@radix-ui/react-icons";

import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import PayloadPreview from "@/components/stats/payload-preview";
import {
getTransactionService,
groupSpans,
useTransaction,
} from "@/lib/transaction";
import { CaretDownIcon } from "@radix-ui/react-icons";
import { cn } from "@/lib/utils";
import PayloadPreview from "@/components/stats/payload-preview";

const TransactionTitle = ({ transaction }) => {
if (transaction.info?.dynamodbMethod) {
Expand Down Expand Up @@ -85,12 +91,22 @@ const TransactionTitle = ({ transaction }) => {
const ServiceIcon = ({ transaction }) => {
const service = getTransactionService(transaction);
return (
<div
className="size-4 rounded-sm bg-gray-400 bg-cover bg-center"
style={{
backgroundImage: `url(/images/service-icons-mini/${service}.svg)`,
}}
/>
<TooltipProvider>
<Tooltip delayDuration={100}>
<TooltipTrigger>
<div
className="size-4 rounded-sm bg-gray-400 bg-cover bg-center"
title={service}
style={{
backgroundImage: `url(/images/service-icons-mini/${service}.svg)`,
}}
/>
</TooltipTrigger>
<TooltipContent>
<p>{service}</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>
);
};

Expand Down Expand Up @@ -120,7 +136,20 @@ const SpanDetails = ({ span }) => {
return <PayloadPreview value={log} />;
}

// TODO: show more detail for DynamoDB spans
if (span.info?.dynamodbMethod) {
return (
<div className="flex flex-col gap-4">
<PayloadPreview
title="Request"
value={span.info.httpInfo.request.body}
/>
<PayloadPreview
title="Response"
value={span.info.httpInfo.response.body}
/>
</div>
);
}

if (span.spanType === "http" && span.info?.httpInfo) {
return (
Expand Down Expand Up @@ -162,7 +191,7 @@ const SpanItem = ({ spans, nested = false }) => {
<details key={`${transaction.id}${transaction.started}`}>
<summary
className={cn(
"text-sm flex items-center justify-between gap-2",
"text-sm flex items-center justify-between gap-2 cursor-pointer",
nested ? "p-2" : "p-4",
)}
>
Expand Down
1 change: 1 addition & 0 deletions packages/dashboard/src/components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const buttonVariants = cva(
sm: "h-8 rounded-md px-3 text-xs",
lg: "h-10 rounded-md px-8",
icon: "h-9 w-9",
miniIcon: "h-6 w-6",
},
},
defaultVariants: {
Expand Down

0 comments on commit 583b129

Please sign in to comment.