diff --git a/apps/spruce/cypress/integration/waterfall/waterfall.ts b/apps/spruce/cypress/integration/waterfall/waterfall.ts index 236577d35..60aa8b2b8 100644 --- a/apps/spruce/cypress/integration/waterfall/waterfall.ts +++ b/apps/spruce/cypress/integration/waterfall/waterfall.ts @@ -13,17 +13,28 @@ describe("waterfall page", () => { }); describe("inactive commits", () => { - it("renders an inactive version column", () => { + it("renders an inactive version column and button", () => { cy.dataCy("version-labels") .children() .eq(2) - .should("have.attr", "data-cy", "inactive-label"); + .get("button") + .should("have.attr", "data-cy", "inactive-versions-button"); cy.dataCy("build-group") .first() .children() .eq(2) .should("have.attr", "data-cy", "inactive-column"); }); + it("clicking an inactive versions button renders a inactive versions modal", () => { + cy.dataCy("inactive-versions-button").first().click(); + cy.dataCy("inactive-versions-modal").should("be.visible"); + cy.dataCy("inactive-versions-modal").contains("1 Inactive Version"); + cy.dataCy("inactive-versions-modal").contains("e695f65"); + cy.dataCy("inactive-versions-modal").contains("Mar 2, 2022"); + cy.dataCy("inactive-versions-modal").contains( + "EVG-16356 Use Build Variant stats to fetch grouped build variants (#1106)", + ); + }); }); describe("task grid", () => { diff --git a/apps/spruce/src/gql/generated/types.ts b/apps/spruce/src/gql/generated/types.ts index bea70c31d..05862f178 100644 --- a/apps/spruce/src/gql/generated/types.ts +++ b/apps/spruce/src/gql/generated/types.ts @@ -9552,9 +9552,30 @@ export type WaterfallQuery = { }>; versions: Array<{ __typename?: "WaterfallVersion"; - inactiveVersions?: Array<{ __typename?: "Version"; id: string }> | null; + inactiveVersions?: Array<{ + __typename?: "Version"; + activated?: boolean | null; + author: string; + createTime: Date; + id: string; + message: string; + revision: string; + gitTags?: Array<{ __typename?: "GitTag"; tag: string }> | null; + upstreamProject?: { + __typename?: "UpstreamProject"; + owner: string; + project: string; + repo: string; + revision: string; + triggerID: string; + triggerType: string; + task?: { __typename?: "Task"; execution: number; id: string } | null; + version?: { __typename?: "Version"; id: string } | null; + } | null; + }> | null; version?: { __typename?: "Version"; + activated?: boolean | null; author: string; createTime: Date; id: string; diff --git a/apps/spruce/src/gql/queries/waterfall.graphql b/apps/spruce/src/gql/queries/waterfall.graphql index 7beed7d35..f721b158e 100644 --- a/apps/spruce/src/gql/queries/waterfall.graphql +++ b/apps/spruce/src/gql/queries/waterfall.graphql @@ -18,9 +18,19 @@ query Waterfall($options: WaterfallOptions!) { } versions { inactiveVersions { + activated + author + createTime + gitTags { + tag + } id + message + revision + ...UpstreamProject } version { + activated author createTime gitTags { diff --git a/apps/spruce/src/pages/waterfall/InactiveVersionsButton/index.tsx b/apps/spruce/src/pages/waterfall/InactiveVersionsButton/index.tsx new file mode 100644 index 000000000..3e94d5fc3 --- /dev/null +++ b/apps/spruce/src/pages/waterfall/InactiveVersionsButton/index.tsx @@ -0,0 +1,65 @@ +import { useState } from "react"; +import styled from "@emotion/styled"; +import Button from "@leafygreen-ui/button"; +import { palette } from "@leafygreen-ui/palette"; +import pluralize from "pluralize"; +import { DisplayModal } from "components/DisplayModal"; +import Icon from "components/Icon"; +import { size } from "constants/tokens"; +import { WaterfallQuery } from "gql/generated/types"; +import { VersionLabel } from "../VersionLabel"; + +const { gray } = palette; +interface Props { + versions: WaterfallQuery["waterfall"]["versions"][0]["inactiveVersions"]; + containerHeight: number | undefined; +} +export const InactiveVersionsButton: React.FC = ({ + containerHeight, + versions, +}) => { + const [modalOpen, setModalOpen] = useState(false); + return ( + <> + + {versions?.map((version) => ( + + ))} + + + + ); +}; + +const InactiveVersionLine = styled.div<{ containerHeight: number }>` + border-left: 2px dashed ${gray.base}; + height: ${({ containerHeight }) => `${containerHeight}px`}; + position: absolute; + margin-left: 50%; + top: 30px; + z-index: 1; +`; + +const StyledVersionLabel = styled(VersionLabel)` + padding-top: ${size.xs}; +`; diff --git a/apps/spruce/src/pages/waterfall/VersionLabel/InactiveBadge.tsx b/apps/spruce/src/pages/waterfall/VersionLabel/InactiveBadge.tsx new file mode 100644 index 000000000..75dfaf8e4 --- /dev/null +++ b/apps/spruce/src/pages/waterfall/VersionLabel/InactiveBadge.tsx @@ -0,0 +1,11 @@ +import styled from "@emotion/styled"; +import Badge, { Variant } from "@leafygreen-ui/badge"; +import { size } from "constants/tokens"; + +export const InactiveBadge = () => ( + Inactive +); + +const StyledBadge = styled(Badge)` + margin-left: ${size.xs}; +`; diff --git a/apps/spruce/src/pages/waterfall/VersionLabel.stories.tsx b/apps/spruce/src/pages/waterfall/VersionLabel/VersionLabel.stories.tsx similarity index 73% rename from apps/spruce/src/pages/waterfall/VersionLabel.stories.tsx rename to apps/spruce/src/pages/waterfall/VersionLabel/VersionLabel.stories.tsx index 017075283..bc08172bf 100644 --- a/apps/spruce/src/pages/waterfall/VersionLabel.stories.tsx +++ b/apps/spruce/src/pages/waterfall/VersionLabel/VersionLabel.stories.tsx @@ -4,7 +4,7 @@ import { getSpruceConfigMock, getUserSettingsMock, } from "gql/mocks/getSpruceConfig"; -import { VersionLabel } from "./VersionLabel"; +import { VersionLabel } from "."; export default { title: "Pages/Waterfall/VersionLabel", @@ -67,6 +67,19 @@ const versionWithUpstreamProject = { }, }; +const versionInactiveUntrimmedMessage = { + activated: false, + author: "Sophie Stadler", + createTime: new Date("2024-09-19T14:56:08Z"), + gitTags: null, + id: "evergreen_ui_aec8832bace91f0f3b6d8ad3bb3b27fb4263be83", + message: + "DEVPROD-11387: Remove CSS grid layout, plus some additional description to demonstrate the overflow capabilities of the component (#397)", + revision: "aec8832bace91f0f3b6d8ad3bb3b27fb4263be83", + upstreamProject: null, + trimMessage: false, +}; + export const Default: StoryObj = { render: (args) => ( @@ -91,6 +104,16 @@ export const UpstreamProject: StoryObj = { args: versionWithUpstreamProject, }; +export const InactiveUntrimmedMessage: StoryObj = { + ...Default, + args: versionInactiveUntrimmedMessage, +}; + +export const SmallSize: StoryObj = { + ...Default, + args: { ...version, size: "small" }, +}; + const Container = styled.div` - max-width: 200px; + max-width: 300px; `; diff --git a/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_Default.storyshot b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_Default.storyshot new file mode 100644 index 000000000..de5f5194c --- /dev/null +++ b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_Default.storyshot @@ -0,0 +1,48 @@ +
+
+
+

+ + + aec8832 + + + + 09/19/2024, 10:56 +

+

+ + Sophie Stadler + + • + + + + DEVPROD-11387 + + + : Remove CSS grid layout, plus some additional description to demonstrate the overflow capabilities of the component (#397) +

+
+
+
\ No newline at end of file diff --git a/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_GitTag.storyshot b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_GitTag.storyshot new file mode 100644 index 000000000..b5dbb62b0 --- /dev/null +++ b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_GitTag.storyshot @@ -0,0 +1,43 @@ +
+
+
+

+ + + deb77a3 + + + + 09/19/2024, 12:14 +

+

+ + Sophie Stadler + + • + + parsley/v2.1.64 +

+

+ Git Tags: + parsley/v2.1.64 +

+
+
+
\ No newline at end of file diff --git a/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_Inactive.storyshot b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_Inactive.storyshot new file mode 100644 index 000000000..a49aa2faa --- /dev/null +++ b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_Inactive.storyshot @@ -0,0 +1,53 @@ +
+
+
+

+ + + aec8832 + + + + 09/19/2024, 10:56 +

+ Inactive +
+

+

+ + Sophie Stadler + + • + + + + DEVPROD-11387 + + + : Remove CSS grid layout, plus some additional description to demonstrate the overflow capabilities of the component (#397) +

+
+
+
\ No newline at end of file diff --git a/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_InactiveUntrimmedMessage.storyshot b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_InactiveUntrimmedMessage.storyshot new file mode 100644 index 000000000..7ae37c332 --- /dev/null +++ b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_InactiveUntrimmedMessage.storyshot @@ -0,0 +1,52 @@ +
+
+
+

+ + + aec8832 + + + + 09/19/2024, 10:56 +

+ Inactive +
+

+

+ + Sophie Stadler + + • + + + + DEVPROD-11387 + + + : Remove CSS grid layout, plus some additional description to demonstrate the overflow capabilities of the component (#397) +

+
+
+
\ No newline at end of file diff --git a/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_SmallSize.storyshot b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_SmallSize.storyshot new file mode 100644 index 000000000..4bab1a87c --- /dev/null +++ b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_SmallSize.storyshot @@ -0,0 +1,48 @@ +
+
+
+

+ + + aec8832 + + + + 09/19/2024, 10:56 +

+

+ + Sophie Stadler + + • + + + + DEVPROD-11387 + + + : Remove CSS grid layout, plus some additional description to demonstrate the overflow capabilities of the component (#397) +

+
+
+
\ No newline at end of file diff --git a/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_UpstreamProject.storyshot b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_UpstreamProject.storyshot new file mode 100644 index 000000000..dd13e059c --- /dev/null +++ b/apps/spruce/src/pages/waterfall/VersionLabel/__snapshots__/VersionLabel_UpstreamProject.storyshot @@ -0,0 +1,57 @@ +
+
+
+

+ + + 1309488 + + + + 09/19/2024, 12:06 +

+

+ Triggered by: + + + + evergreen + + +

+

+ + Sophie Stadler + + • + + spruce/v4.1.87 +

+

+ Git Tags: + spruce/v4.1.87 +

+
+
+
\ No newline at end of file diff --git a/apps/spruce/src/pages/waterfall/VersionLabel.tsx b/apps/spruce/src/pages/waterfall/VersionLabel/index.tsx similarity index 68% rename from apps/spruce/src/pages/waterfall/VersionLabel.tsx rename to apps/spruce/src/pages/waterfall/VersionLabel/index.tsx index 66bfa4fae..625095e8e 100644 --- a/apps/spruce/src/pages/waterfall/VersionLabel.tsx +++ b/apps/spruce/src/pages/waterfall/VersionLabel/index.tsx @@ -8,19 +8,30 @@ import { getVersionRoute, getTriggerRoute } from "constants/routes"; import { WaterfallQuery } from "gql/generated/types"; import { useSpruceConfig, useDateFormat } from "hooks"; import { shortenGithash, jiraLinkify } from "utils/string"; -import { columnBasis } from "./styles"; +import { columnBasis } from "../styles"; +import { InactiveBadge } from "./InactiveBadge"; type VersionFields = NonNullable< Unpacked["version"] >; -export const VersionLabel: React.FC = ({ +type Props = VersionFields & { + className?: string; + trimMessage?: boolean; + size?: "small" | "default"; +}; + +export const VersionLabel: React.FC = ({ + activated, author, + className, createTime, gitTags, id, message, revision, + size = "default", + trimMessage = true, upstreamProject, }) => { const getDateCopy = useDateFormat(); @@ -31,15 +42,17 @@ export const VersionLabel: React.FC = ({ const { sendEvent } = useWaterfallAnalytics(); + const commitType = activated ? "active" : "inactive"; + return ( - + { sendEvent({ name: "Clicked commit label", - "commit.type": "active", + "commit.type": commitType, link: "githash", }); }} @@ -48,6 +61,7 @@ export const VersionLabel: React.FC = ({ {shortenGithash(revision)} {" "} {getDateCopy(createDate, { omitSeconds: true, omitTimezone: true })} + {commitType === "inactive" && } {upstreamProject && ( @@ -56,7 +70,7 @@ export const VersionLabel: React.FC = ({ onClick={() => { sendEvent({ name: "Clicked commit label", - "commit.type": "active", + "commit.type": commitType, link: "upstream project", }); }} @@ -74,12 +88,15 @@ export const VersionLabel: React.FC = ({ )} {/* @ts-expect-error */} - + {author} •{" "} {jiraLinkify(message, jiraHost, () => { sendEvent({ name: "Clicked commit label", - "commit.type": "active", + "commit.type": commitType, link: "jira", }); })} @@ -89,22 +106,32 @@ export const VersionLabel: React.FC = ({ ); }; -const VersionContainer = styled.div` +const VersionContainer = styled.div<{ size?: "small" | "default" }>` ${columnBasis} - > * { - font-size: 12px; - line-height: 1.3; - } + ${(props) => { + if (props.size === "small") { + return ` + > * { + font-size: 12px; + line-height: 1.3; + } + `; + } + }} p { ${wordBreakCss} } `; -const CommitMessage = styled(Body)` - display: -webkit-box; - -webkit-box-orient: vertical; - -webkit-line-clamp: 3; - overflow: hidden; +const CommitMessage = styled(Body)<{ trimMessage: boolean }>` + ${(props) => + props.trimMessage && + ` + overflow: hidden; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 3; + `} `; diff --git a/apps/spruce/src/pages/waterfall/WaterfallGrid.tsx b/apps/spruce/src/pages/waterfall/WaterfallGrid.tsx index bc864295c..40e42f494 100644 --- a/apps/spruce/src/pages/waterfall/WaterfallGrid.tsx +++ b/apps/spruce/src/pages/waterfall/WaterfallGrid.tsx @@ -1,8 +1,11 @@ +import { useRef } from "react"; import { useSuspenseQuery } from "@apollo/client"; import styled from "@emotion/styled"; import { WaterfallQuery, WaterfallQueryVariables } from "gql/generated/types"; import { WATERFALL } from "gql/queries"; +import { useDimensions } from "hooks/useDimensions"; import { BuildRow } from "./BuildRow"; +import { InactiveVersionsButton } from "./InactiveVersionsButton"; import { BuildVariantTitle, gridGroupCss, @@ -30,21 +33,25 @@ export const WaterfallGrid: React.FC = ({ }, }, ); - + const refEl = useRef(null); + const { height } = useDimensions( + refEl as React.MutableRefObject, + ); return ( - + - {data.waterfall.versions.map(({ inactiveVersions, version }, i) => + {data.waterfall.versions.map(({ inactiveVersions, version }) => version ? ( - + ) : ( - - inactive + + ), )} diff --git a/apps/spruce/src/pages/waterfall/styles.ts b/apps/spruce/src/pages/waterfall/styles.ts index e6d3b69d8..0f9a8c2f6 100644 --- a/apps/spruce/src/pages/waterfall/styles.ts +++ b/apps/spruce/src/pages/waterfall/styles.ts @@ -36,4 +36,5 @@ export const Row = styled.div` export const InactiveVersion = styled.div` width: ${INACTIVE_WIDTH}px; + text-align: center; `;