import type { ReactView } from "@ethicdevs/react-monolith";
import React from "react";
import type { Organization, PullRequest } from "@prisma/client";
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";
import { IslandWrapper } from "../../components/IslandWrapper.styled";
import RepositoryHero from "../../islands/RepositoryHero";
type PullRequestsFilter = "all" | "open" | "closed" | "merged" | "search";
export interface RepositoryPullRequestsViewProps extends CommonProps {
parentOrg: Organization;
pullRequests: PullRequest[];
repo: RepositoryWithForkedFromRepo;
pullRequestsFilter?: PullRequestsFilter;
}
const RepositoryPullRequestsView: ReactView<
RepositoryPullRequestsViewProps
> = ({
commonProps,
parentOrg,
pullRequests,
repo,
pullRequestsFilter = "open",
}) => {
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={`Pull Requests`}
repo={repo}
showForkButton={false}
showNewButton
newButtonText={"New Pull Request"}
newButtonUrl={buildRouteLink(
AppRoute.REPOSITORY_PULL_REQUEST_CREATE,
{
orgSlug: parentOrg.slug,
repoSlug: repo.slug,
},
)}
/>
</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: pullRequestsFilter === "all" ? "bold" : "normal",
textDecoration:
pullRequestsFilter === "all" ? "underline" : "none",
}}
href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
"all" as PullRequestsFilter
}`}
>
<Grid.Row nowrap gap={8} alignItems={"center"}>
<span>All</span>
<Chip themeScheme={commonProps.themeScheme}>
{commonProps.layoutCounters!.pullsTotal}
</Chip>
</Grid.Row>
</a>
<a
style={{
fontWeight: pullRequestsFilter === "open" ? "bold" : "normal",
textDecoration:
pullRequestsFilter === "open" ? "underline" : "none",
}}
href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
"open" as PullRequestsFilter
}`}
>
<Grid.Row nowrap gap={8} alignItems={"center"}>
<span>Open</span>
<Chip themeScheme={commonProps.themeScheme}>
{commonProps.layoutCounters!.pullsOpen}
</Chip>
</Grid.Row>
</a>
<a
style={{
fontWeight: pullRequestsFilter === "merged" ? "bold" : "normal",
textDecoration:
pullRequestsFilter === "merged" ? "underline" : "none",
}}
href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
"merged" as PullRequestsFilter
}`}
>
<Grid.Row nowrap gap={8} alignItems={"center"}>
<span>Merged</span>
<Chip themeScheme={commonProps.themeScheme}>
{commonProps.layoutCounters!.pullsMerged}
</Chip>
</Grid.Row>
</a>
<a
style={{
fontWeight: pullRequestsFilter === "closed" ? "bold" : "normal",
textDecoration:
pullRequestsFilter === "closed" ? "underline" : "none",
}}
href={`/${parentOrg.slug}/${repo.slug}/pulls?filter=${
"closed" as PullRequestsFilter
}`}
>
<Grid.Row nowrap gap={8} alignItems={"center"}>
<span>Closed</span>
<Chip themeScheme={commonProps.themeScheme}>
{commonProps.layoutCounters!.pullsClosed}
</Chip>
</Grid.Row>
</a>
</Grid.Row>
</Grid.Col>
<Grid.Col fluid gap={4} style={{ marginTop: 12 }}>
{pullRequests != null && pullRequests.length >= 1 ? (
pullRequests.map((pr) => (
<Card
key={pr.id}
themeScheme={commonProps.themeScheme}
style={{ width: "100%", padding: 8 }}
>
<Grid.Col fluid>
<a
style={{ width: "100%" }}
href={buildRouteLink(
AppRoute.REPOSITORY_PULL_REQUEST_DETAILS,
{
orgSlug: parentOrg.slug,
repoSlug: repo.slug,
pullUid: pr.uid,
},
)}
>
<Grid.Row fluid alignItems={"center"} gap={4}>
<span>#{pr.uid}</span>
<span>•</span>
<span style={{ flex: 1 }}>{pr.summary}</span>
<Chip
themeScheme={commonProps.themeScheme}
color={
{
OPEN: Colors.PRIMARY_01,
CLOSE_MERGED: Colors.GREEN_01,
CLOSE_DENIED: Colors.RED_01,
}[pr.state]
}
>
{
{
OPEN: "Open",
CLOSE_MERGED: "Merged",
CLOSE_DENIED: "Closed",
}[pr.state]
}
</Chip>
</Grid.Row>
</a>
<Grid.Row
fluid
nowrap
gap={8}
alignItems={"center"}
style={{ opacity: 0.67 }}
>
wants to merge{" "}
<Chip
themeScheme={commonProps.themeScheme}
style={{ textTransform: "none" }}
>
<code>{pr.sourceBranch}</code>
</Chip>
into{" "}
<Chip
themeScheme={commonProps.themeScheme}
style={{ textTransform: "none" }}
>
<code>{pr.targetBranch}</code>
</Chip>
</Grid.Row>
<Grid.Col
fluid
gap={4}
style={{ opacity: 0.67, marginTop: 4 }}
>
{new Date(pr.createdAt).getTime() <=
new Date(pr.updatedAt).getTime() && (
<span>
{`opened on ${new Date(pr.createdAt).toLocaleString()}`}
</span>
)}
{((pr.closedAt == null &&
new Date(pr.updatedAt).getTime() >
new Date(pr.createdAt).getTime()) ||
(pr.closedAt != null &&
new Date(pr.updatedAt).getTime() <
new Date(pr.closedAt).getTime())) && (
<span>
{`updated on ${new Date(pr.updatedAt).toLocaleString()}`}
</span>
)}
{pr.closedAt != null && (
<span>
{`closed on ${new Date(pr.closedAt).toLocaleString()}`}
</span>
)}
</Grid.Col>
</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_PULL_REQUEST_CREATE,
{
orgSlug: parentOrg.slug,
repoSlug: repo.slug,
},
)}
>
open the first Pull Request
</a>
<span> to this repository 🚀.</span>
</p>
</Grid.Col>
)}
</Grid.Col>
</PageWrapper>
</Layout>
);
};
RepositoryPullRequestsView.displayName = "RepositoryPullRequestsView";
export default RepositoryPullRequestsView;