.ts
TypeScript
(application/typescript)
// 1st-party
import type { ReactView } from "@ethicdevs/react-monolith";
// 3rd-party
import React from "react";
// generated via script[prisma:generate]
import type { Pipeline, Stage } from "@prisma/client";
// app
import type { CommonProps } from "../../types";
import { Layout } from "../../components/Layout";
import { PageWrapper } from "../../components/PageWrapper";
import { Grid } from "../../components/Grid";
import { Card } from "../../components/Card.styled";
import { Chip } from "../../components/Chip";
import { IslandWrapper } from "../../components/IslandWrapper.styled";
import { Colors, NamedColors } from "../../utils/style";
import { AppRoute } from "../../routes.defs";
import { buildRouteLink } from "../../utils/shared";
// app islands
import Code from "../../islands/Code";
import RepositoryHero from "../../islands/RepositoryHero";

export interface PipelineDetailsViewProps extends CommonProps {
  pipeline: Pipeline & { stages: Stage[] };
  orgSlug: string;
  repoSlug: string;
}

const PipelineDetailsView: ReactView<PipelineDetailsViewProps> = ({
  commonProps,
  pipeline,
  orgSlug,
  repoSlug,
}) => {
  return (
    <Layout
      {...commonProps}
      showDrawerPrimary
      orgSlug={orgSlug}
      repoSlug={repoSlug}
    >
      <PageWrapper style={{ gap: 16 }}>
        <IslandWrapper
          style={{ position: "sticky", top: 64, zIndex: 23000 }}
          data-islandid={`${RepositoryHero.name}$$0`}
        >
          <RepositoryHero
            themeScheme={commonProps.themeScheme}
            // forkedFromRepo={repo.forkedFromRepo}
            // forksCount={repo.forks.length}
            // parentOrg={parentOrg}
            // repo={repo}
            path={`Pipeline > #${pipeline.name ?? "Unknown"}`}
            showForkButton={false}
            showNewButton
            newButtonText={"Download Artifacts"}
            newButtonUrl={buildRouteLink(
              AppRoute.REPOSITORY_PIPELINE_ARTEFACTS,
              {
                orgSlug: orgSlug,
                repoSlug: repoSlug,
                pipelineId: pipeline.id,
              },
            )}
            parentOrg={{
              id: "",
              createdAt: new Date(Date.now()),
              updatedAt: new Date(Date.now()),
              slug: orgSlug,
              ownerId: "",
              kind: "PERSONAL",
              visibility: "PUBLIC",
              avatarUri: null,
              displayName: orgSlug,
              websiteUrl: null,
            }}
            repo={{
              id: "",
              forkedFromRepoId: null,
              organizationId: "",
              slug: repoSlug,
              createdAt: new Date(Date.now()),
              updatedAt: new Date(Date.now()),
              lastPushedAt: null,
              visibility: "PUBLIC",
              isFork: false,
              keywords: [],
              avatarUri: null,
              displayName: repoSlug,
              shortDescription: null,
              websiteUrl: null,
            }}
          />
        </IslandWrapper>
        <Grid.Row fluid nowrap gap={8} alignItems={"center"}>
          <Chip
            themeScheme={commonProps.themeScheme}
            color={
              {
                PENDING: Colors.PRIMARY_01,
                RUNNING: Colors.CYAN_01,
                PASSED: Colors.GREEN_01,
                FAILED: Colors.RED_01,
                CANCELED: Colors.BLACK_01,
              }[pipeline.status]
            }
          >
            {
              {
                PENDING: "Pending",
                RUNNING: "Running",
                PASSED: "Passed",
                FAILED: "Failed",
                CANCELED: "Canceled",
              }[pipeline.status]
            }
          </Chip>
        </Grid.Row>
        <Grid.Row fluid gap={4} alignItems={"flex-start"}>
          {pipeline.stages
            .sort((a, b) => a.order - b.order)
            .map((stage) => (
              <Card
                themeScheme={commonProps.themeScheme}
                style={{ flex: 1, padding: 4 }}
              >
                <Grid.Col key={stage.id} fluid gap={4}>
                  <h3 style={{ margin: 0 }}>
                    <a
                      href={buildRouteLink(
                        AppRoute.REPOSITORY_PIPELINE_STAGE_DETAILS,
                        {
                          orgSlug,
                          repoSlug,
                          pipelineId: pipeline.id,
                          stageId: stage.id,
                        },
                      )}
                    >
                      {stage.name ?? stage.id}
                    </a>
                  </h3>
                  <Grid.Row fluid nowrap gap={4} alignItems={"center"}>
                    <div
                      style={{
                        fontSize: 11,
                        color: NamedColors.TEXT_MUTED[commonProps.themeScheme],
                      }}
                    >
                      #{stage.order}
                    </div>
                    <div
                      style={{
                        fontSize: 11,
                        color: NamedColors.TEXT_MUTED[commonProps.themeScheme],
                      }}
                    >
                      {stage.updatedAt.toLocaleString()}
                    </div>
                  </Grid.Row>
                  <Chip
                    themeScheme={commonProps.themeScheme}
                    color={
                      {
                        PENDING: Colors.PRIMARY_01,
                        RUNNING: Colors.CYAN_01,
                        PASSED: Colors.GREEN_01,
                        FAILED: Colors.RED_01,
                        CANCELED: Colors.BLACK_01,
                      }[stage.status]
                    }
                  >
                    {
                      {
                        PENDING: "Pending",
                        RUNNING: "Running",
                        PASSED: "Passed",
                        FAILED: "Failed",
                        CANCELED: "Canceled",
                      }[stage.status]
                    }
                  </Chip>
                  {/*<code>{stage.logs}</code>*/}
                </Grid.Col>
              </Card>
            ))}
        </Grid.Row>
        {pipeline.manifest && (
          <Grid.Col fluid nowrap gap={4}>
            <IslandWrapper data-islandid={`${Code.name}$$0`}>
              <Code
                themeScheme={commonProps.themeScheme}
                language={"shell"}
                code={`${orgSlug}/${repoSlug}/.gitfoss.ci`}
                whiteSpace={"pre-wrap"}
              />
            </IslandWrapper>
            <IslandWrapper data-islandid={`${Code.name}$$1`}>
              <Code
                themeScheme={commonProps.themeScheme}
                language={"yaml"}
                code={pipeline.manifest}
                whiteSpace={"pre-wrap"}
              />
            </IslandWrapper>
          </Grid.Col>
        )}
      </PageWrapper>
    </Layout>
  );
};

PipelineDetailsView.displayName = "PipelineDetailsView";
export default PipelineDetailsView;