From c078f56541f94eaf9044b6b74e8ffe45f52935bb Mon Sep 17 00:00:00 2001 From: gabalafou Date: Fri, 9 Feb 2024 14:54:22 -0500 Subject: [PATCH] Add log link next to status message --- .../artifacts/components/ArtifactsItem.tsx | 6 +- .../metadata/components/EnvBuilds.tsx | 55 +++++++++++++++---- src/utils/helpers/parseArtifactList.ts | 10 +++- test/metadata/EnvBuilds.test.tsx | 25 +++++++++ 4 files changed, 79 insertions(+), 17 deletions(-) diff --git a/src/features/artifacts/components/ArtifactsItem.tsx b/src/features/artifacts/components/ArtifactsItem.tsx index c29b0ce6..34166d88 100644 --- a/src/features/artifacts/components/ArtifactsItem.tsx +++ b/src/features/artifacts/components/ArtifactsItem.tsx @@ -6,7 +6,7 @@ import { useTheme } from "@mui/material/styles"; import { Artifact } from "../../../common/models"; import { PrefContext } from "../../../preferences"; -import { isPathAbsolute } from "../../../utils/helpers"; +import { artifactBaseUrl } from "../../../utils/helpers"; interface IArtifactsProps { /** @@ -17,9 +17,7 @@ interface IArtifactsProps { export const ArtifactItem = ({ artifact }: IArtifactsProps) => { const pref = React.useContext(PrefContext); - const url = isPathAbsolute(pref.apiUrl) - ? pref.apiUrl - : `${window.location.origin}${pref.apiUrl}`; + const url = artifactBaseUrl(pref.apiUrl, window.location.origin); const route = new URL(artifact.route, url).toString(); const theme = useTheme(); diff --git a/src/features/metadata/components/EnvBuilds.tsx b/src/features/metadata/components/EnvBuilds.tsx index da85edcc..967cc0c8 100644 --- a/src/features/metadata/components/EnvBuilds.tsx +++ b/src/features/metadata/components/EnvBuilds.tsx @@ -4,6 +4,12 @@ import { StyledMetadataItem } from "../../../styles/StyledMetadataItem"; import { Build as IBuild } from "../../../common/models"; import { Build } from "../../../features/metadata/components"; import { buildMapper } from "../../../utils/helpers/buildMapper"; +import Link from "@mui/material/Link"; +import OpenInNewIcon from "@mui/icons-material/OpenInNew"; +import { artifactBaseUrl } from "../../../utils/helpers"; +import { PrefContext } from "../../../preferences"; +import artifactList from "../../../utils/helpers/artifact"; +import { Artifact } from "../../../common/models"; interface IData { currentBuildId: number; @@ -21,6 +27,34 @@ export const EnvBuilds = ({ const envBuilds = builds.length ? buildMapper(builds, currentBuildId) : []; const currentBuild = envBuilds.find(build => build.id === selectedBuildId); + // If the selected build is a failed build, we will render the link to the build log. + let logLink; + const showLogLink = currentBuild?.status === "Failed"; + const logArtifact: Artifact | never = artifactList(currentBuild?.id, [ + "LOGS" + ])[0]; + if (showLogLink && logArtifact) { + const pref = React.useContext(PrefContext); + const url = new URL( + logArtifact.route, + artifactBaseUrl(pref.apiUrl, window.location.origin) + ); + logLink = ( + + + Log + + ); + } + return ( <> {mode === "edit" ? "Change active environment version:" : "Builds:"} - {currentBuild && ( + {currentBuild ? ( <> Status: {""} - {currentBuild.status_info ? ( - <> - {currentBuild.status} ({currentBuild.status_info}) - - ) : ( - <>{currentBuild.status} - )} - {(currentBuild.status === "Building" || + {currentBuild.status} + {currentBuild.status_info && ` (${currentBuild.status_info})`} + {((currentBuild.status === "Building" || currentBuild.status === "Queued") && ( - )} + )) || + // If the selected build is a failed build, render the link to the build log. + (showLogLink && [". ", logLink])} - )} - {!currentBuild && ( + ) : ( { }); }; -export const isPathAbsolute = (path: string) => { +const isPathAbsolute = (path: string) => { return new RegExp("^(?:[a-z]+:)?//", "i").test(path); }; + +export const artifactBaseUrl = (apiUrl: string, baseUrl: string) => { + if (isPathAbsolute(apiUrl)) { + return apiUrl; + } else { + return `${baseUrl}${apiUrl}`; + } +}; diff --git a/test/metadata/EnvBuilds.test.tsx b/test/metadata/EnvBuilds.test.tsx index 5762536b..3f6c8c41 100644 --- a/test/metadata/EnvBuilds.test.tsx +++ b/test/metadata/EnvBuilds.test.tsx @@ -24,4 +24,29 @@ describe("", () => { const progressBar = component.getByRole("progressbar"); expect(progressBar).toBeInTheDocument(); }); + + it("should render link to log if selected build failed", () => { + const failedBuild = { ...BUILD, status: "FAILED" }; + const { getByTestId, getByRole } = render( + + + + ); + expect(getByRole("link", { name: "Log" })).toBeInTheDocument(); + expect(getByTestId("build-status")).toHaveTextContent( + /^Status: Failed\. Log$/ + ); + }); + + it("should not render log link for normal build", () => { + const { getByTestId, queryByRole } = render( + + + + ); + expect(queryByRole("link", { name: "Log" })).not.toBeInTheDocument(); + expect(getByTestId("build-status")).toHaveTextContent( + /^Status: Completed$/ + ); + }); });