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 { 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, idx) => (
<Card
key={pr.id}
themeScheme={commonProps.themeScheme}
style={{ width: "100%" }}
>
<Grid.Col
key={pr.id}
fluid
style={{ marginTop: idx === 0 ? 0 : 16 }}
>
<a
href={buildRouteLink(
AppRoute.REPOSITORY_PULL_REQUEST_DETAILS,
{
orgSlug: parentOrg.slug,
repoSlug: repo.slug,
pullUid: pr.uid,
},
)}
>
#{pr.uid} - {pr.summary} [{pr.state}]
</a>
<span style={{ opacity: 0.67 }}>
wants to merge <code>{pr.sourceBranch}</code> into{" "}
<code>{pr.targetBranch}</code>
</span>
<Grid.Row
fluid
alignItems={"center"}
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.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_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;