feat(pull_request): add Pull Requests service and use in Repository one@@ -1,5 +1,5 @@
{
- "_generatedAtUnix": 1664464335694,
+ "_generatedAtUnix": 1664472419448,
"_hashAlgorithm": "sha1",
"_version": 2,
"islands": {
@@ -97,6 +97,10 @@
"hash": "52ec9a5a3fc10fe10adb2a89e0743d64d63d9516",
"pathSource": "./app/views/repository/RepositoryExploreView.tsx"
},
+ "RepositoryPullRequestsView": {
+ "hash": "444cfa015b810ffb3299a1db81a3efbb0fc032d5",
+ "pathSource": "./app/views/repository/RepositoryPullRequestsView.tsx"
+ },
"RepositoryShowObjectView": {
"hash": "6b3bfa5f7ab0fcde85f1516ddb9252955848a615",
"pathSource": "./app/views/repository/RepositoryShowObjectView.tsx"
@@ -0,0 +1,47 @@
+// 1st-party
+import type { ReqHandler } from "@ethicdevs/react-monolith";
+// app
+import { AppRoute, AppRoutesParams } from "../../routes";
+// app services
+import { makeOrganizationService } from "../../services/organization";
+import { makePullRequestService } from "../../services/pullRequest";
+import { makeRepositoryService } from "../../services/repository";
+// app views
+import RepositoryPullRequestsView, {
+ RepositoryPullRequestsViewProps,
+} from "../../views/repository/RepositoryPullRequestsView";
+
+const getRepositoryPullRequestsView: ReqHandler = async (request, reply) => {
+ const { orgSlug, repoSlug } =
+ request.params as AppRoutesParams[AppRoute.REPOSITORY_PULL_REQUESTS]["params"];
+
+ const orgService = makeOrganizationService({ request });
+ const prService = makePullRequestService({ request });
+ const repoService = makeRepositoryService({ request });
+
+ const parentOrg = await orgService.getOrganizationBySlug(orgSlug);
+
+ if (parentOrg == null) {
+ return reply.status(404).callNotFound();
+ }
+
+ const repo = await repoService.getRepository(orgSlug, repoSlug);
+
+ if (repo == null) {
+ return reply.status(404).callNotFound();
+ }
+
+ const pullRequests = await prService.getPullRequestsInRepository(repo);
+
+ const reqHandler = reply.makeRequestHandler(request, reply);
+ return reqHandler<RepositoryPullRequestsViewProps>(
+ RepositoryPullRequestsView.name,
+ {
+ parentOrg,
+ pullRequests,
+ repo,
+ }
+ );
+};
+
+export default getRepositoryPullRequestsView;
@@ -4,6 +4,7 @@ import { default as getRepositoryCompareView } from "./getRepositoryCompareView"
import { default as getRepositoryCreateView } from "./getRepositoryCreateView";
import { default as getRepositoryDetailsView } from "./getRepositoryDetailsView";
import { default as getRepositoryExploreView } from "./getRepositoryExploreView";
+import { default as getRepositoryPullRequestsView } from "./getRepositoryPullRequestsView";
import { default as getRepositoryShowObjectView } from "./getRepositoryShowObjectView";
import { default as postRepositoryCreateAction } from "./postRepositoryCreateAction";
@@ -14,6 +15,7 @@ export const RepositoryController = {
getRepositoryCreateView,
getRepositoryDetailsView,
getRepositoryExploreView,
+ getRepositoryPullRequestsView,
getRepositoryShowObjectView,
postRepositoryCreateAction,
};
@@ -34,6 +34,7 @@ export enum AppRoute {
REPOSITORY_CREATE_ACTION = "repository.create.action",
REPOSITORY_DETAILS = "repository.details",
REPOSITORY_EXPLORE = "repository.explore",
+ REPOSITORY_PULL_REQUESTS = "repository.pull_requests",
REPOSITORY_SHOW_OBJECT = "repository.show_object",
}
@@ -116,6 +117,12 @@ export interface AppRoutesParams extends IRouteParams {
"*": string;
};
};
+ [AppRoute.REPOSITORY_PULL_REQUESTS]: {
+ params: {
+ orgSlug: string;
+ repoSlug: string;
+ }
+ },
[AppRoute.REPOSITORY_SHOW_OBJECT]: {
params: {
orgSlug: string;
@@ -329,6 +336,21 @@ export const AppRoutesSchemas: Record<AppRoute, undefined | FastifySchema> = {
},
},
},
+ [AppRoute.REPOSITORY_PULL_REQUESTS]: {
+ params: {
+ type: "object",
+ required: ["orgSlug", "repoSlug"],
+ additionalProperties: false,
+ properties: {
+ orgSlug: {
+ type: "string",
+ },
+ repoSlug: {
+ type: "string",
+ },
+ },
+ },
+ },
[AppRoute.REPOSITORY_SHOW_OBJECT]: {
params: {
type: "object",
@@ -497,6 +519,13 @@ const RootAppRouter: AppRouter = () => {
schema={AppRoutesSchemas[AppRoute.REPOSITORY_BROWSER]}
handler={RepositoryController.getRepositoryBrowserView}
/>
+ <Router.Route
+ name={AppRoute.REPOSITORY_PULL_REQUESTS}
+ method={"GET"}
+ path={"/:orgSlug/:repoSlug/pulls"}
+ schema={AppRoutesSchemas[AppRoute.REPOSITORY_PULL_REQUESTS]}
+ handler={RepositoryController.getRepositoryPullRequestsView}
+ />
<Router.Route
name={AppRoute.REPOSITORY_SHOW_OBJECT}
method={"GET"}
@@ -10,12 +10,12 @@ import type {
const getPullRequest: ServiceMethodFactory<
PullRequestServiceDeps,
- [string, PullRequestSelectOrIncludes],
+ [string, PullRequestSelectOrIncludes | undefined],
Promise<PullRequest | null>
> = ({ request }) => {
return async (pullRequestId, selectOrIncludes) => {
const pullRequest = await request.prisma.pullRequest.findUnique({
- ...selectOrIncludes,
+ ...(selectOrIncludes || {}),
where: {
id: pullRequestId,
},
@@ -0,0 +1,28 @@
+// 1st-party
+import type { ServiceMethodFactory } from "@ethicdevs/react-monolith";
+// generated via script[generate:prisma]
+import type { PullRequest, Repository } from "@prisma/client";
+// service
+import type {
+ PullRequestSelectOrIncludes,
+ PullRequestServiceDeps,
+} from "./types";
+
+const getPullRequestsInRepository: ServiceMethodFactory<
+ PullRequestServiceDeps,
+ [Repository, PullRequestSelectOrIncludes | undefined],
+ Promise<PullRequest[]>
+> = ({ request }) => {
+ return async (repository, selectOrIncludes) => {
+ const pullRequestsInRepository = await request.prisma.pullRequest.findMany({
+ ...(selectOrIncludes || {}),
+ where: {
+ targetRepositoryId: repository.id,
+ },
+ });
+
+ return pullRequestsInRepository;
+ };
+};
+
+export default getPullRequestsInRepository;
@@ -5,6 +5,7 @@ import type { PullRequestServiceDeps, PullRequestServiceAPI } from "./types";
// service methods
import { default as makeCreatePullRequest } from "./createPullRequest";
import { default as makeGetPullRequest } from "./getPullRequest";
+import { default as makeGetPullRequestsInRepository } from "./getPullRequestsInRepository";
export const makePullRequestService = makeService<
PullRequestServiceAPI,
@@ -12,4 +13,5 @@ export const makePullRequestService = makeService<
>({
createPullRequest: makeCreatePullRequest,
getPullRequest: makeGetPullRequest,
+ getPullRequestsInRepository: makeGetPullRequestsInRepository,
});
@@ -24,7 +24,14 @@ export type PullRequestSelectOrIncludes =
| { includes?: Prisma.PullRequestInclude };
export interface PullRequestServiceAPI extends ServiceApiContract {
- getPullRequest(pullRequestId: string): Promise<PullRequest | null>;
+ getPullRequest(
+ pullRequestId: string,
+ selectOrIncludes?: PullRequestSelectOrIncludes
+ ): Promise<PullRequest | null>;
+ getPullRequestsInRepository(
+ repository: Repository,
+ selectOrIncludes?: PullRequestSelectOrIncludes
+ ): Promise<PullRequest[]>;
createPullRequest(dto: CreatePullRequestDTO): Promise<PullRequest>;
}
@@ -94,15 +94,11 @@ const makeGetRepositoryHead: ServiceMethodFactory<
committerTimezone,
] = committerMatches;
- if (
- commitMessageMatches == null ||
- Array.isArray(commitMessageMatches) === false
- ) {
- throw new Error("Invalid HEAD, missing commit message.");
+ let commitMessage: string = "<missing commit message>";
+ if (commitMessageMatches != null && Array.isArray(commitMessageMatches)) {
+ commitMessage = commitMessageMatches[1];
}
- const commitMessage = commitMessageMatches[1];
-
return {
treeId,
parentId,
@@ -0,0 +1,51 @@
+// 1st-party
+import type { ReactView } from "@ethicdevs/react-monolith";
+// 3rd-party
+import React from "react";
+// generated via script[generate:prisma]
+import type { Organization, PullRequest, Repository } from "@prisma/client";
+// app
+import type { CommonProps } from "../../types";
+import { Grid, Layout, PageWrapper } from "../../components";
+// app islands
+// import RepositoriesList from "../../islands/RepositoriesList";
+
+export interface RepositoryPullRequestsViewProps extends CommonProps {
+ parentOrg: Organization;
+ pullRequests: PullRequest[];
+ repo: Repository;
+}
+
+const RepositoryPullRequestsView: ReactView<
+ RepositoryPullRequestsViewProps
+> = ({ commonProps, parentOrg, pullRequests, repo }) => {
+ return (
+ <Layout {...commonProps}>
+ <PageWrapper>
+ <h1>
+ <a href={`/${parentOrg.slug}`}>
+ {parentOrg.displayName || parentOrg.slug}
+ </a>
+ {" / "}
+ <a href={`/${parentOrg.slug}/${repo.slug}`}>
+ {repo.displayName || repo.slug}
+ </a>
+ {" ∙ "}
+ <span>Pull Requests</span>
+ </h1>
+ <Grid.Row fluid style={{ marginTop: 32 }}>
+ {JSON.stringify(pullRequests, null, 2)}
+ {/*<div
+ data-islandid={`${RepositoriesList.name}$$0`}
+ style={{ width: "100%" }}
+ >
+ <RepositoriesList repositories={repositories} />
+ </div>*/}
+ </Grid.Row>
+ </PageWrapper>
+ </Layout>
+ );
+};
+
+RepositoryPullRequestsView.displayName = "RepositoryPullRequestsView";
+export default RepositoryPullRequestsView;