diff --git a/src/components/ExpandedText/index.tsx b/src/components/ExpandedText/index.tsx index a8cc666ac2..7efcc358a4 100644 --- a/src/components/ExpandedText/index.tsx +++ b/src/components/ExpandedText/index.tsx @@ -1,25 +1,31 @@ import styled from "@emotion/styled"; import { palette } from "@leafygreen-ui/palette"; -import Tooltip, { TriggerEvent } from "@leafygreen-ui/tooltip"; +import Tooltip, { TriggerEvent, Align, Justify } from "@leafygreen-ui/tooltip"; import { Disclaimer } from "@leafygreen-ui/typography"; import { zIndex } from "constants/tokens"; const { blue } = palette; interface ExpandedTextProps { + align?: Align; + ["data-cy"]?: string; + justify?: Justify; message: string; - triggerEvent?: (typeof TriggerEvent)[keyof typeof TriggerEvent]; popoverZIndex?: number; - ["data-cy"]?: string; + triggerEvent?: (typeof TriggerEvent)[keyof typeof TriggerEvent]; } const ExpandedText: React.FC = ({ + align, "data-cy": dataCy, + justify, message, popoverZIndex = zIndex.popover, triggerEvent = TriggerEvent.Hover, }) => ( more} triggerEvent={triggerEvent} popoverZIndex={popoverZIndex} @@ -32,6 +38,8 @@ const ButtonText = styled(Disclaimer)` color: ${blue.dark2}; text-decoration: underline; cursor: default; + width: fit-content; + display: inline-block; `; const MessageWrapper = styled.div` diff --git a/src/pages/task/metadata/Metadata.test.tsx b/src/pages/task/metadata/Metadata.test.tsx index 644497c832..5c164be89a 100644 --- a/src/pages/task/metadata/Metadata.test.tsx +++ b/src/pages/task/metadata/Metadata.test.tsx @@ -2,7 +2,7 @@ import { MockedProvider } from "@apollo/client/testing"; import { addMilliseconds } from "date-fns"; import { getUserMock } from "gql/mocks/getUser"; import { taskQuery } from "gql/mocks/taskData"; -import { renderWithRouterMatch as render, screen } from "test_utils"; +import { renderWithRouterMatch as render, screen, userEvent } from "test_utils"; import { Metadata } from "./index"; const wrapper = ({ children }) => ( @@ -52,7 +52,8 @@ describe("metadata", () => { expect(screen.queryByDataCy("task-metrics-link")).toBeNull(); }); - it("renders the metadata card with a succeeded status", () => { + it("renders the metadata card with a succeeded status", async () => { + const user = userEvent.setup(); render( { expect(screen.getByDataCy("task-metadata-finished")).toBeInTheDocument(); expect(screen.getByDataCy("task-trace-link")).toBeInTheDocument(); expect(screen.getByDataCy("task-metrics-link")).toBeInTheDocument(); + + expect(screen.getByDataCy("task-metadata-description")).toBeInTheDocument(); + expect(screen.getByText("more")).toBeInTheDocument(); + await user.hover(screen.getByText("more")); + await screen.findByDataCy("task-metadata-description-tooltip"); + expect( + screen.getByDataCy("task-metadata-description-tooltip") + ).toHaveTextContent(taskSucceeded.task.details.description); }); }); @@ -94,11 +103,21 @@ const taskStarted = { status: "started", }, }; + const taskSucceeded = { task: { ...taskStarted.task, finishTime: addMilliseconds(new Date(), 1228078), status: "succeeded", - details: { ...taskStarted.task.details, traceID: "trace_abcde" }, + details: { + type: "", + status: "success", + description: + "exiting due to custom reason: long long long long long long long long long long long long long message", + traceID: "trace_abcde", + oomTracker: { + detected: false, + }, + }, }, }; diff --git a/src/pages/task/metadata/index.tsx b/src/pages/task/metadata/index.tsx index 2edc6b3744..4feafaf3dd 100644 --- a/src/pages/task/metadata/index.tsx +++ b/src/pages/task/metadata/index.tsx @@ -7,6 +7,7 @@ import { InlineCode } from "@leafygreen-ui/typography"; import Cookies from "js-cookie"; import { Link } from "react-router-dom"; import { useTaskAnalytics } from "analytics"; +import ExpandedText from "components/ExpandedText"; import { MetadataCard, MetadataItem, @@ -28,7 +29,7 @@ import { getProjectPatchesRoute, getPodRoute, } from "constants/routes"; -import { size } from "constants/tokens"; +import { size, zIndex } from "constants/tokens"; import { TaskQuery } from "gql/generated/types"; import { useDateFormat } from "hooks"; import { TaskStatus } from "types/task"; @@ -207,10 +208,13 @@ export const Metadata: React.FC = ({ error, loading, task, taskId }) => { )} - {details?.status === TaskStatus.Failed && ( - - Failing command:{" "} - {processFailingCommand(details?.description, isContainerTask)} + {details?.description && ( + + )} {details?.timeoutType && details?.timeoutType !== "" && ( @@ -393,6 +397,47 @@ export const Metadata: React.FC = ({ error, loading, task, taskId }) => { ); }; +const DetailsDescription = ({ + description, + isContainerTask, + status, +}: { + description: string; + isContainerTask: boolean; + status: string; +}) => { + const MAX_CHAR = 100; + + const fullText = + status === TaskStatus.Failed + ? `Failing command: ${processFailingCommand( + description, + isContainerTask + )}` + : `Command: ${description}`; + const shouldTruncate = fullText.length > MAX_CHAR; + const truncatedText = fullText.substring(0, MAX_CHAR).concat("..."); + + return ( + + {shouldTruncate ? ( + <> + {truncatedText}{" "} + + + ) : ( + fullText + )} + + ); +}; + const processFailingCommand = ( description: string, isContainerTask: boolean