All files / publisher/pages/Build Build.tsx

41.66% Statements 5/12
73.33% Branches 11/15
50% Functions 1/2
41.66% Lines 5/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                    6x 6x                                         6x         6x   6x                                                                                                                                          
import { useParams, Link } from "react-router-dom";
import { useQuery } from "react-query";
import { Strip, Row, Col, MainTable } from "@canonical/react-components";
import { formatDistanceToNow } from "date-fns";
 
import SectionNav from "../../components/SectionNav";
 
import { setPageTitle } from "../../utils";
 
function Build(): React.JSX.Element {
  const { buildId, snapId } = useParams();
  const { data, isFetched, isLoading, isFetching } = useQuery({
    queryKey: ["build", snapId, buildId],
    queryFn: async () => {
      const response = await fetch(`/api/${snapId}/builds/${buildId}`);
 
      if (!response.ok) {
        throw new Error("There was a problem trying to fetch build data");
      }
 
      const responseData = await response.json();
 
      if (!responseData.success) {
        throw new Error("There was a problem trying to fetch build data");
      }
 
      return responseData.data;
    },
    refetchOnWindowFocus: false,
  });
 
  const isDataLoading =
    isLoading ||
    isFetching ||
    !data ||
    (data.snap_build && data.snap_build.id.toString() !== buildId);
 
  setPageTitle(`Build ${buildId} for ${snapId}`);
 
  return (
    <>
      <h1 className="p-heading--4" aria-live="polite">
        <a href="/snaps">My snaps</a> / <a href={`/${snapId}`}>{snapId}</a> /{" "}
        <Link to={`/${snapId}/builds`}>Builds</Link> / Build #{buildId}
      </h1>
      <SectionNav activeTab="builds" snapName={snapId} />
      {isDataLoading && (
        <Strip shallow>
          <p>
            <i className="p-icon--spinner u-animation--spin"></i>&nbsp;Loading{" "}
            {snapId} build data
          </p>
        </Strip>
      )}
      {!isDataLoading && isFetched && data && (
        <Strip shallow>
          <MainTable
            headers={[
              { content: "id" },
              { content: "Architecture" },
              { content: "Build duration" },
              { content: "Result" },
              { content: "Build finished", className: "u-align-text--right" },
            ]}
            rows={[
              {
                columns: [
                  { content: buildId },
                  { content: data.snap_build.arch_tag },
                  { content: data.snap_build.duration },
                  { content: data.snap_build.status },
                  {
                    content: formatDistanceToNow(data.snap_build.datebuilt, {
                      addSuffix: true,
                    }),
                    className: "u-align--right",
                  },
                ],
              },
            ]}
          />
          <Row>
            <Col size={6}>
              <h2 className="p-heading--4">Build log</h2>
            </Col>
            <Col size={6} className="u-align-text--right">
              <a className="p-button--base" href="#footer">
                Scroll to bottom
              </a>
              <a
                target="_blank"
                href={data.snap_build.logs}
                className="p-button"
                rel="noreferrer"
              >
                View raw
              </a>
            </Col>
          </Row>
          <pre>{data.raw_logs}</pre>
        </Strip>
      )}
      <div id="footer"></div>
    </>
  );
}
 
export default Build;