diff --git a/src/components/RecentActivity/LiveView/styles.ts b/src/components/RecentActivity/LiveView/styles.ts
index 4e49dbae8..247707af6 100644
--- a/src/components/RecentActivity/LiveView/styles.ts
+++ b/src/components/RecentActivity/LiveView/styles.ts
@@ -1,4 +1,5 @@
import styled from "styled-components";
+import { CopyButton } from "../../common/v3/CopyButton";
import {
AreaLegendIllustrationProps,
AxisChartContainerProps,
@@ -72,11 +73,22 @@ export const Header = styled.div`
}};
`;
+export const StyledCopyButton = styled(CopyButton)`
+ display: none;
+ padding: 0;
+`;
+
export const Title = styled.span`
display: flex;
align-items: center;
gap: 4px;
overflow: hidden;
+
+ &:hover {
+ ${StyledCopyButton} {
+ display: flex;
+ }
+ }
`;
export const SpanIconContainer = styled.span`
diff --git a/src/components/RecentActivity/RecentActivity.stories.tsx b/src/components/RecentActivity/RecentActivity.stories.tsx
index bbe21d27c..b64db9bdb 100644
--- a/src/components/RecentActivity/RecentActivity.stories.tsx
+++ b/src/components/RecentActivity/RecentActivity.stories.tsx
@@ -28,7 +28,7 @@ const data: RecentActivityData = {
environments: [
{
name: "ENV_RENDER",
- id: "ENV_RENDER",
+ id: "ENV_RENDER#ID#1",
isPending: false,
type: "Public",
token: null,
@@ -46,7 +46,7 @@ const data: RecentActivityData = {
},
{
name: "UNSET_ENV",
- id: "UNSET_ENV",
+ id: "UNSET_ENV#ID#1",
isPending: false,
type: "Public",
token: null,
@@ -733,7 +733,7 @@ export const EnableDigmathonMode: Story = {
export const OpenCongratulationsDigmathonView: Story = {
play: () => {
- setTimeout(() => {
+ window.setTimeout(() => {
window.postMessage({
type: "digma",
action: actions.SET_DIGMATHON_PROGRESS_DATA,
diff --git a/src/components/RecentActivity/RecentActivityTable/index.tsx b/src/components/RecentActivity/RecentActivityTable/index.tsx
index e190f8799..52ff14cbc 100644
--- a/src/components/RecentActivity/RecentActivityTable/index.tsx
+++ b/src/components/RecentActivity/RecentActivityTable/index.tsx
@@ -109,16 +109,18 @@ export const RecentActivityTable = (props: RecentActivityTableProps) => {
};
const renderSpanLink = (span: EntrySpan) => (
-
- {
- handleSpanLinkClick(span);
- }}
- >
- {span.displayText}
-
-
+
+
+ {
+ handleSpanLinkClick(span);
+ }}
+ >
+ {span.displayText}
+
+
+
+
);
const renderSpanLinks = (entry: ActivityEntry) => (
diff --git a/src/components/RecentActivity/RecentActivityTable/styles.ts b/src/components/RecentActivity/RecentActivityTable/styles.ts
index d98d1e845..93b51202d 100644
--- a/src/components/RecentActivity/RecentActivityTable/styles.ts
+++ b/src/components/RecentActivity/RecentActivityTable/styles.ts
@@ -1,5 +1,6 @@
import styled from "styled-components";
import { Link } from "../../common/Link";
+import { CopyButton } from "../../common/v3/CopyButton";
import { ListItemProps, TableBodyRowProps, TableHeadProps } from "./types";
export const Table = styled.div`
@@ -196,6 +197,23 @@ export const SpanLinksContainer = styled.span`
gap: 4px;
`;
+export const StyledCopyButton = styled(CopyButton)`
+ padding: 0 6px;
+ display: none;
+`;
+
+export const SpanLinkContainer = styled.span`
+ display: flex;
+ align-items: center;
+ overflow: hidden;
+
+ &:hover {
+ ${StyledCopyButton} {
+ display: flex;
+ }
+ }
+`;
+
export const SpanLink = styled(Link)`
overflow: hidden;
text-overflow: ellipsis;
diff --git a/src/components/Tests/TestTicket/index.tsx b/src/components/Tests/TestTicket/index.tsx
index ecb783aa3..21006c0b1 100644
--- a/src/components/Tests/TestTicket/index.tsx
+++ b/src/components/Tests/TestTicket/index.tsx
@@ -25,30 +25,27 @@ export const TestTicket = (props: TestTicketProps) => {
.map((x) => x.displayName)
.join("\n");
+ const description = [
+
+ {`"${name}" test failed${
+ isString(errorOrFailMessage)
+ ? ` with message:\n${errorOrFailMessage}`
+ : ""
+ }`}
+
,
+ Last run at: {new Date(runAt).toString()}
,
+ Duration: {getDurationString(duration)}
,
+ relatedSpans.length > 0 ? (
+ {`Related spans:\n${relatedSpans}`}
+ ) : null,
+
+ ].filter(Boolean) as ReactElement[];
+
const renderDescription = () => (
<>
- {intersperse(
- [
-
- {`"${name}" test failed${
- isString(errorOrFailMessage)
- ? ` with message:\n${errorOrFailMessage}`
- : ""
- }`}
-
,
- Last run at: {new Date(runAt).toString()}
,
- Duration: {getDurationString(duration)}
,
- <>
- {relatedSpans.length > 0 && (
- {`Related spans:\n${relatedSpans}`}
- )}
- >,
-
- ],
- (i: number) => (
-
- )
- )}
+ {intersperse(description, (i: number) => (
+
+ ))}
>
);
diff --git a/src/components/common/CodeSnippet/index.tsx b/src/components/common/CodeSnippet/index.tsx
index 28e68c8f9..192265dd3 100644
--- a/src/components/common/CodeSnippet/index.tsx
+++ b/src/components/common/CodeSnippet/index.tsx
@@ -1,4 +1,3 @@
-import copy from "copy-to-clipboard";
import { ForwardedRef, forwardRef, useRef } from "react";
import SyntaxHighlighter from "react-syntax-highlighter";
import {
@@ -7,9 +6,7 @@ import {
} from "react-syntax-highlighter/dist/esm/styles/hljs";
import { DefaultTheme, useTheme } from "styled-components";
import { isString } from "../../../typeGuards/isString";
-import { CopyIcon } from "../icons/16px/CopyIcon";
-import { IconButton } from "../v3/IconButton";
-import { Tooltip } from "../v3/Tooltip";
+import { CopyButton } from "../v3/CopyButton";
import * as s from "./styles";
import { CodeSnippetProps, HighlighterTheme } from "./types";
@@ -31,13 +28,9 @@ const CodeSnippetComponent = (
const highlighterTheme = getHighlighterTheme(theme);
const codeRef = useRef(null);
- const handleCopyButtonClick = () => {
- if (isString(props.text)) {
- copy(props.text);
- } else if (codeRef.current) {
- copy(codeRef.current.innerText);
- }
- };
+ const textToCopy = isString(props.text)
+ ? props.text
+ : codeRef.current?.innerText || "";
return (
@@ -59,15 +52,7 @@ const CodeSnippetComponent = (
) : (
{props.text}
)}
-
-
-
+
);
};
diff --git a/src/components/common/v3/CopyButton/index.tsx b/src/components/common/v3/CopyButton/index.tsx
new file mode 100644
index 000000000..bb3d02cc1
--- /dev/null
+++ b/src/components/common/v3/CopyButton/index.tsx
@@ -0,0 +1,23 @@
+import copy from "copy-to-clipboard";
+import { MouseEvent } from "react";
+import { CopyIcon } from "../../icons/16px/CopyIcon";
+import { IconButton } from "../IconButton";
+import { Tooltip } from "../Tooltip";
+import { CopyButtonProps } from "./types";
+
+export const CopyButton = ({ text, className }: CopyButtonProps) => {
+ const handleClick = (e: MouseEvent) => {
+ e.stopPropagation();
+ copy(text);
+ };
+
+ return (
+
+
+
+ );
+};
diff --git a/src/components/common/v3/CopyButton/types.ts b/src/components/common/v3/CopyButton/types.ts
new file mode 100644
index 000000000..5063471e6
--- /dev/null
+++ b/src/components/common/v3/CopyButton/types.ts
@@ -0,0 +1,4 @@
+export interface CopyButtonProps {
+ text: string;
+ className?: string;
+}
diff --git a/src/components/common/v3/Info/index.tsx b/src/components/common/v3/Info/index.tsx
index b782f8d12..443aa4d0c 100644
--- a/src/components/common/v3/Info/index.tsx
+++ b/src/components/common/v3/Info/index.tsx
@@ -3,9 +3,9 @@ import { Tooltip } from "../Tooltip";
import * as s from "./styles";
import { InfoProps } from "./types";
-export const Info = ({ title }: InfoProps) => (
+export const Info = ({ title, className }: InfoProps) => (
-
+
diff --git a/src/components/common/v3/Info/types.ts b/src/components/common/v3/Info/types.ts
index 44053cc2f..898bc6951 100644
--- a/src/components/common/v3/Info/types.ts
+++ b/src/components/common/v3/Info/types.ts
@@ -2,4 +2,5 @@ import { ReactNode } from "react";
export interface InfoProps {
title: ReactNode;
+ className?: string;
}