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

type PipelinesFilter = "all" | "pending" | "running" | "failed" | "canceled";

export interface RepositoryPipelinesViewProps extends CommonProps {
  parentOrg: Organization;
  pipelines: Pipeline[];
  repo: RepositoryWithForkedFromRepo;
  pipelinesFilter?: PipelinesFilter;
}

const RepositoryPipelinesView: ReactView<RepositoryPipelinesViewProps> = ({
  commonProps,
  parentOrg,
  pipelines,
  repo,
  pipelinesFilter = "success",
}) => {
  return (
    <Layout
      {...commonProps}
      showDrawerPrimary
      orgSlug={parentOrg.slug}
      repoSlug={repo.slug}
    >
      <PageWrapper>
        <IslandWrapper data-islandid={`${RepositoryHero.name}$$0`}>
          <RepositoryHero
            themeScheme={commonProps.themeScheme}
            forkedFromRepo={repo.forkedFromRepo}
            forksCount={repo.forks.length}
            parentOrg={parentOrg}
            path={`Pipelines`}
            repo={repo}
            showForkButton={false}
            showNewButton
            newButtonText={"Trigger Pipeline"}
            // newButtonText={
            //   <>
            //     <span>New Pull Request</span>
            //     <GitPullIcon
            //       color={Colors.WHITE_01}
            //       size={24}
            //     />
            //   </>
            // }
            newButtonUrl={buildRouteLink(
              AppRoute.REPOSITORY_PIPELINE_TRIGGER_ACTION,
              {
                orgSlug: parentOrg.slug,
                repoSlug: repo.slug,
                pipelineId: "", // @fixme: ???
              },
            )}
          />
        </IslandWrapper>
        <Grid.Col
          fluid
          style={{
            padding: "12px 0",
            borderBottom: `1px solid ${NamedColors.BORDER_DEFAULT[commonProps.themeScheme]}`,
          }}
        >
          <Grid.Row
            fluid
            alignItems={"center"}
            gap={12}
            style={{ padding: "0 8px" }}
          >
            <a
              style={{
                fontWeight: pipelinesFilter === "all" ? "bold" : "normal",
                textDecoration:
                  pipelinesFilter === "all" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pipelines?filter=${
                "all" as PipelinesFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>All</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsTotal}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pipelinesFilter === "passed" ? "bold" : "normal",
                textDecoration:
                  pipelinesFilter === "passed" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pipelines?filter=${
                "passed" as PipelinesFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Passed!</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsOpen}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pipelinesFilter === "pending" ? "bold" : "normal",
                textDecoration:
                  pipelinesFilter === "pending" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pipelines?filter=${
                "pending" as PipelinesFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Pending</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsMerged}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pipelinesFilter === "running" ? "bold" : "normal",
                textDecoration:
                  pipelinesFilter === "running" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pipelines?filter=${
                "running" as PipelinesFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Closed</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsClosed}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pipelinesFilter === "failed" ? "bold" : "normal",
                textDecoration:
                  pipelinesFilter === "failed" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pipelines?filter=${
                "failed" as PipelinesFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Failed</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsClosed}
                </Chip>
              </Grid.Row>
            </a>
            <a
              style={{
                fontWeight: pipelinesFilter === "canceled" ? "bold" : "normal",
                textDecoration:
                  pipelinesFilter === "canceled" ? "underline" : "none",
              }}
              href={`/${parentOrg.slug}/${repo.slug}/pipelines?filter=${
                "canceled" as PipelinesFilter
              }`}
            >
              <Grid.Row nowrap gap={8} alignItems={"center"}>
                <span>Canceled</span>
                <Chip themeScheme={commonProps.themeScheme}>
                  {commonProps.layoutCounters!.pullsClosed}
                </Chip>
              </Grid.Row>
            </a>
          </Grid.Row>
        </Grid.Col>
        <Grid.Col fluid gap={4} style={{ marginTop: 12 }}>
          {pipelines != null && pipelines.length >= 1 ? (
            pipelines.map((pipeline) => (
              <Card
                key={pipeline.id}
                themeScheme={commonProps.themeScheme}
                style={{ width: "100%", padding: 8 }}
              >
                <Grid.Col fluid>
                  <a
                    style={{ width: "100%" }}
                    href={buildRouteLink(AppRoute.REPOSITORY_PIPELINE_DETAILS, {
                      orgSlug: parentOrg.slug,
                      repoSlug: repo.slug,
                      pipelineId: pipeline.id,
                    })}
                  >
                    <Grid.Row fluid alignItems={"center"} gap={4}>
                      <span>id: {pipeline.id}</span>
                      <span>&bull;</span>
                      <span style={{ flex: 1 }}>{pipeline.name}</span>
                      <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>
                  </a>
                  <Grid.Row
                    fluid
                    nowrap
                    gap={8}
                    alignItems={"center"}
                    style={{ opacity: 0.67 }}
                  >
                    triggered by
                    <Chip
                      themeScheme={commonProps.themeScheme}
                      style={{ textTransform: "none" }}
                    >
                      <code>{""}</code>
                    </Chip>
                  </Grid.Row>
                </Grid.Col>
              </Card>
            ))
          ) : (
            <Grid.Col
              fluid
              nowrap
              justifyContent={"center"}
              alignItems={"center"}
              style={{ minHeight: "70vh" }}
            >
              <h1 style={{ margin: 0 }}>No Pull Request Yet</h1>
              <p style={{ maxWidth: "62%", textAlign: "center" }}>
                <span>Be the change you want to see, </span>
                <a
                  href={buildRouteLink(
                    AppRoute.REPOSITORY_PIPELINE_TRIGGER_ACTION,
                    {
                      orgSlug: parentOrg.slug,
                      repoSlug: repo.slug,
                      pipelineId: "", // @fixme: ???
                    },
                  )}
                >
                  trigger the first Pipeline run
                </a>
                <span> to this repository 🚀.</span>
              </p>
            </Grid.Col>
          )}
        </Grid.Col>
      </PageWrapper>
    </Layout>
  );
};

RepositoryPipelinesView.displayName = "RepositoryPipelinesView";
export default RepositoryPipelinesView;