refactor(pull_requests): make the "PullRequestSourceSelect" to work@@ -1,5 +1,5 @@
{
- "_generatedAtUnix": 1665328026365,
+ "_generatedAtUnix": 1665337338713,
"_hashAlgorithm": "sha1",
"_version": 2,
"islands": {
@@ -16,7 +16,7 @@
"pathSourceMap": "./public/.islands/InstantRouterIndicator.bundle.js.map"
},
"PullRequestSourceSelect": {
- "hash": "0bf2070d8f31e61476388b8b753d1979ccda9f5d",
+ "hash": "7639a6f9840bd79911c72c89687f7cd541ca6940",
"pathSource": "./app/islands/PullRequestSourceSelect.tsx",
"pathBundle": "./public/.islands/PullRequestSourceSelect.bundle.js",
"pathSourceMap": "./public/.islands/PullRequestSourceSelect.bundle.js.map"
@@ -64,7 +64,7 @@
"pathSourceMap": "./public/.islands/RepositoryInitialSetup.bundle.js.map"
},
"RepositoryPullRequestCreateForm": {
- "hash": "8b7d27a4a368329ad810309272b7ff848395f1d2",
+ "hash": "19e66103e6c815f8770f6291759f9b557c5125bb",
"pathSource": "./app/islands/RepositoryPullRequestCreateForm.tsx",
"pathBundle": "./public/.islands/RepositoryPullRequestCreateForm.bundle.js",
"pathSourceMap": "./public/.islands/RepositoryPullRequestCreateForm.bundle.js.map"
@@ -39,7 +39,6 @@ const getRepositoryPullRequestCreateView: ReqHandler = async (
const orgService = makeOrganizationService({ request });
const repoService = makeRepositoryService({ request });
const usersService = makeUsersService({ request });
- usersService;
const parentOrg = await orgService.getOrganizationBySlug(orgSlug);
const repo = await repoService.getRepository(orgSlug, repoSlug);
@@ -49,17 +48,18 @@ const getRepositoryPullRequestCreateView: ReqHandler = async (
}
const branches = await repoService.getRepositoryBranches(repo);
+
const currentUserForks = await repoService.getCurrentUserRepositoryForks(
repo
);
- const repos = await currentUserForks.reduce(
+ const currentUserForksRepos = await currentUserForks.reduce(
async (accP, r) => {
let acc = await accP;
acc = {
...acc,
- [r.slug]: {
- repo: r as any,
+ [`${r.organization.slug}/${r.slug}`]: {
+ repo: r,
branches: await repoService.getRepositoryBranches(r),
},
};
@@ -74,14 +74,10 @@ const getRepositoryPullRequestCreateView: ReqHandler = async (
);
// Inject PR target's repository first.
- // const [personalOrg] = await usersService.getUserOrganizations(
- // request.session.data.curr_user_uid,
- // true // personalOnly
- // );
-
- // const personalRepos = {
- // [repo.slug]: { repo: repo as any, branches },
- // };
+ const [personalOrg] = await usersService.getUserOrganizations(
+ request.session.data.curr_user_uid,
+ true // personalOnly
+ );
let variant: RepositoryPullRequestCreateFormVariant;
if (from_branch == null) {
@@ -89,21 +85,23 @@ const getRepositoryPullRequestCreateView: ReqHandler = async (
state: PullRequestFormState.CONFIGURE,
data: {
sources: {
- // In case user has forks on its own, add its personal org (where forks **should** be)
- // ...(currentUserForks.length >= 1 && {
- // [personalOrg.slug]: {
- // org: personalOrg,
- // repos: personalRepos,
- // },
- // }),
// target repo's source
[parentOrg.slug]: {
org: parentOrg,
repos: {
- [repo.slug]: { repo: repo as any, branches },
- ...repos,
+ [`${parentOrg.slug}/${repo.slug}`]: {
+ repo: { ...repo, organization: parentOrg },
+ branches,
+ },
},
},
+ // In case user has forks on its own, add its personal org (where forks **should** be)
+ ...(currentUserForks.length >= 1 && {
+ [personalOrg.slug]: {
+ org: personalOrg,
+ repos: currentUserForksRepos,
+ },
+ }),
},
target: {
branch: from_branch || Const.PRIMARY_BRANCH_REF,
@@ -7,23 +7,25 @@ import { Organization } from "@prisma/client";
// app
import { RepositoryWithParentAndForkedFromRepos } from "../types";
-export interface PullRequestSourceSelectionChangeEvent {
- data: {
- selectedOrg: {
- org: Organization;
- repos: {
- [repoSlug: string]: {
- repo: RepositoryWithParentAndForkedFromRepos;
- branches: string[];
- };
+export interface PullRequestSourceSelection {
+ selectedOrg: {
+ org: Organization;
+ repos: {
+ [repoSlug: string]: {
+ repo: RepositoryWithParentAndForkedFromRepos;
+ branches: string[];
};
};
- selectedRepo: {
- repo: RepositoryWithParentAndForkedFromRepos;
- branches: string[];
- };
- selectedBranch: string;
};
+ selectedRepo: {
+ repo: RepositoryWithParentAndForkedFromRepos;
+ branches: string[];
+ };
+ selectedBranch: string;
+}
+
+export interface PullRequestSourceSelectionChangeEvent {
+ data: PullRequestSourceSelection;
}
export interface PullRequestSourceSelectProps {
@@ -36,7 +38,7 @@ export interface PullRequestSourceSelectProps {
[orgSlug: string]: {
org: Organization;
repos: {
- [repoSlug: string]: {
+ [repoKey: string]: {
repo: RepositoryWithParentAndForkedFromRepos;
branches: string[];
};
@@ -67,11 +69,11 @@ const PullRequestSourceSelect: ReactIsland<PullRequestSourceSelectProps> = ({
const allOrganizations = useMemo(() => {
const orgsBySlug = Object.entries(sources);
- return orgsBySlug.reduce((acc, [orgSlug, { org }]) => {
+ return orgsBySlug.reduce((acc, [_, { org }]) => {
acc = [
...acc,
{
- key: orgSlug,
+ key: org.slug,
value: org.displayName || org.slug,
},
];
@@ -85,11 +87,11 @@ const PullRequestSourceSelect: ReactIsland<PullRequestSourceSelectProps> = ({
if (org == null) return [];
const [_selectedOrgSlug, { repos: orgRepositories }] = org;
const reposBySlug = Object.entries(orgRepositories);
- return reposBySlug.reduce((acc, [repoSlug, { repo }]) => {
+ return reposBySlug.reduce((acc, [_, { repo }]) => {
acc = [
...acc,
{
- key: repoSlug,
+ key: repo.slug,
value: repo.displayName || repo.slug,
},
];
@@ -102,14 +104,17 @@ const PullRequestSourceSelect: ReactIsland<PullRequestSourceSelectProps> = ({
const org = orgsBySlug.find(([_, o]) => o.org.slug === selectedOrgSlug);
if (org == null) return [];
const [_selectedOrgSlug, { repos: orgRepositories }] = org;
- const reposBySlug = Object.entries(orgRepositories);
- const repo = reposBySlug.find(([_, r]) => r.repo.slug === selectedRepoSlug);
+ const reposByKey = Object.entries(orgRepositories);
+ const repo = reposByKey.find(
+ (r) =>
+ r[1].repo.organization.slug === selectedOrgSlug &&
+ r[1].repo.slug === selectedRepoSlug
+ );
if (repo == null) return [];
- const [_selectedRepoSlug, { branches: repoBranches }] = repo;
- return repoBranches.map((branch) => ({
+ return repo[1].branches.map((branch) => ({
key: branch,
value: branch,
- })) as { key: string; value: string }[];
+ }));
}, [sources, selectedOrgSlug, selectedRepoSlug]);
const selectedOrg = useMemo(() => {
@@ -125,18 +130,76 @@ const PullRequestSourceSelect: ReactIsland<PullRequestSourceSelectProps> = ({
);
if (parentOrg == null) return null;
const reposBySlug = Object.entries(parentOrg[1].repos);
- const repo = reposBySlug.find(([_, r]) => r.repo.slug === selectedRepoSlug);
- return repo != null ? repo[1] : null;
+ const repo = reposBySlug.find(
+ (r) =>
+ r[1].repo.organization.slug === selectedOrgSlug &&
+ r[1].repo.slug === selectedRepoSlug
+ );
+ if (repo == null) return null;
+ return repo[1];
}, [sources, selectedOrgSlug, selectedRepoSlug]);
+ const selectedBranchResult = useMemo(() => {
+ const orgsBySlug = Object.entries(sources);
+ const parentOrg = orgsBySlug.find(
+ ([_, o]) => o.org.slug === selectedOrgSlug
+ );
+ if (parentOrg == null) return selectedBranch;
+ const reposBySlug = Object.entries(parentOrg[1].repos);
+ const repo = reposBySlug.find(
+ (r) =>
+ r[1].repo.organization.slug === selectedOrgSlug &&
+ r[1].repo.slug === selectedRepoSlug
+ );
+ if (repo == null) return selectedBranch;
+ const { branches } = repo[1];
+ return selectedBranch || branches[0];
+ }, [sources, selectedOrgSlug, selectedRepoSlug, selectedBranch]);
+
+ const emitSelectionChangeEvent = useCallback(() => {
+ if (
+ onSelectionChange != null &&
+ typeof onSelectionChange === "function" &&
+ selectedOrg != null &&
+ selectedRepo != null &&
+ selectedBranchResult != null
+ ) {
+ onSelectionChange({
+ data: {
+ selectedOrg,
+ selectedRepo,
+ selectedBranch: selectedBranchResult,
+ },
+ });
+ }
+ }, [onSelectionChange, selectedOrg, selectedRepo, selectedBranchResult]);
+
const onOrgSlugChange = useCallback(
(ev: React.ChangeEvent<HTMLSelectElement>) => {
if (ev == null) return;
if (ev.target == null) return;
if (ev.target.value == null) return;
- setSelectedOrgSlug(ev.target.value);
+ const orgSlug = ev.target.value;
+ setSelectedOrgSlug(orgSlug);
+ if (orgSlug in sources) {
+ const { repos } = sources[orgSlug];
+ if (Object.keys(repos).length >= 1) {
+ const { repo, branches } = Object.values(repos)[0];
+ setSelectedRepoSlug(repo.slug);
+ if (branches.length >= 1) {
+ setSelectedBranch(branches[0]);
+ }
+ }
+ }
+ emitSelectionChangeEvent();
},
- [setSelectedOrgSlug]
+ [
+ emitSelectionChangeEvent,
+ sources,
+ setSelectedOrgSlug,
+ setSelectedRepoSlug,
+ setSelectedBranch,
+ ]
);
const onRepoSlugChange = useCallback(
@@ -144,9 +207,23 @@ const PullRequestSourceSelect: ReactIsland<PullRequestSourceSelectProps> = ({
if (ev == null) return;
if (ev.target == null) return;
if (ev.target.value == null) return;
- setSelectedRepoSlug(ev.target.value);
+ const repoSlug = ev.target.value;
+ setSelectedRepoSlug(repoSlug);
+ if (repoSlug in sources[selectedOrgSlug].repos) {
+ const { branches } = sources[selectedOrgSlug].repos[repoSlug];
+ if (branches.length >= 1) {
+ setSelectedBranch(branches[0]);
+ }
+ }
+ emitSelectionChangeEvent();
},
- [setSelectedRepoSlug]
+ [
+ emitSelectionChangeEvent,
+ sources,
+ selectedOrgSlug,
+ setSelectedRepoSlug,
+ setSelectedBranch,
+ ]
);
const onBranchChange = useCallback(
@@ -155,15 +232,16 @@ const PullRequestSourceSelect: ReactIsland<PullRequestSourceSelectProps> = ({
if (ev.target == null) return;
if (ev.target.value == null) return;
setSelectedBranch(ev.target.value);
+ emitSelectionChangeEvent();
},
- [setSelectedBranch]
+ [emitSelectionChangeEvent, setSelectedBranch]
);
const keyValueToOptionMapFn = useMemo(
() =>
- ({ key, value }: { key: string; value: string }) =>
+ ({ key, value }: { key: string; value: string }, idx: number) =>
(
- <option key={key} value={key}>
+ <option key={[key, idx].join(":")} value={key}>
{value}
</option>
),
@@ -171,23 +249,8 @@ const PullRequestSourceSelect: ReactIsland<PullRequestSourceSelectProps> = ({
);
useEffect(() => {
- if (selectedOrg != null && selectedRepo != null && selectedBranch != null) {
- if (
- onSelectionChange != null &&
- typeof onSelectionChange === "function" &&
- selectedOrg != null &&
- selectedRepo != null
- ) {
- onSelectionChange({
- data: {
- selectedOrg,
- selectedRepo,
- selectedBranch,
- },
- });
- }
- }
- }, [onSelectionChange, selectedOrg, selectedRepo, selectedBranch]);
+ emitSelectionChangeEvent();
+ }, []);
return (
<div>
@@ -1,7 +1,7 @@
// 1st-party
import type { ReactIsland } from "@ethicdevs/react-monolith";
// 3rd-party
-import React, { useCallback } from "react";
+import React, { useCallback, useMemo, useState } from "react";
// generated via script[generate:prisma]
import type { Organization, PullRequest, Repository } from "@prisma/client";
// app
@@ -16,6 +16,7 @@ import { IslandWrapper } from "../components/IslandWrapper.styled";
// app islands
import RepositoryFilesDiffsList from "./RepositoryFilesDiffsList";
import PullRequestSourceSelect, {
+ PullRequestSourceSelection,
PullRequestSourceSelectionChangeEvent,
} from "./PullRequestSourceSelect";
@@ -43,7 +44,7 @@ export type RepositoryPullRequestCreateFormPropsByState<
[orgSlug: string]: {
org: Organization;
repos: {
- [repoSlug: string]: {
+ [repoKey: string]: {
repo: RepositoryWithParentAndForkedFromRepos;
branches: string[];
};
@@ -138,18 +139,44 @@ const isErrorStateData = (
const RepositoryPullRequestCreateForm: ReactIsland<RepositoryPullRequestCreateFormProps> =
({ parentOrgSlug, repoSlug, themeScheme, variant: { state, data } }) => {
- /*const [selectedSourceOrgSlug, setSelectedSourceOrgSlug] =
- useState<null | string>(null);*/
+ const [selectedSource, setSelectedSource] =
+ useState<null | PullRequestSourceSelection>(null);
+ const [selectedTarget, setSelectedTarget] =
+ useState<null | PullRequestSourceSelection>(null);
const onSourceSelectionChange = useCallback(
(ev: PullRequestSourceSelectionChangeEvent) => {
- console.warn(
- `Selected: ${ev.data.selectedOrg.org.slug} / ${ev.data.selectedRepo.repo.slug} / ${ev.data.selectedBranch}`
- );
+ setSelectedSource(ev.data);
},
- []
+ [setSelectedSource]
);
+ const onTargetSelectionChange = useCallback(
+ (ev: PullRequestSourceSelectionChangeEvent) => {
+ setSelectedTarget(ev.data);
+ },
+ [setSelectedTarget]
+ ); //
+
+ const isCompareButtonEnabled = useMemo(() => {
+ console.log("selectedSource:", selectedSource);
+ console.log("selectedTarget:", selectedTarget);
+ const isSameRepoInSameOrg =
+ selectedSource != null &&
+ selectedTarget != null &&
+ selectedSource.selectedRepo.repo.organization.slug ===
+ selectedTarget.selectedRepo.repo.organization.slug &&
+ selectedSource.selectedRepo.repo.slug ===
+ selectedTarget.selectedRepo.repo.slug;
+ return !!(
+ selectedSource != null &&
+ selectedTarget != null &&
+ isSameRepoInSameOrg === false &&
+ selectedSource.selectedBranch != null &&
+ selectedTarget.selectedBranch != null
+ );
+ }, [selectedSource, selectedTarget]);
+
// PullRequestFormState.CONFIGURE
if (isConfigureState(state) && isConfigureStateData(state, data)) {
return (
@@ -167,9 +194,9 @@ const RepositoryPullRequestCreateForm: ReactIsland<RepositoryPullRequestCreateFo
value={PullRequestFormState.COMPARE}
/>
<Grid.Row fluid alignItems={"center"}>
- <div data-islandid={`${PullRequestSourceSelect.name}$$0`}>
+ <div data-islandid={`${PullRequestSourceSelect.name}$$1`}>
<PullRequestSourceSelect
- namePrefix={"source"}
+ namePrefix={"target"}
defaultSource={{
org: Object.values(data.sources)[0].org,
repo: Object.values(
@@ -180,15 +207,15 @@ const RepositoryPullRequestCreateForm: ReactIsland<RepositoryPullRequestCreateFo
)[0].branches[0],
}}
sources={data.sources}
- onSelectionChange={onSourceSelectionChange}
+ onSelectionChange={onTargetSelectionChange}
/>
</div>
<div style={{ margin: "0 8px" }}>
<span>vs.</span>
</div>
- <div data-islandid={`${PullRequestSourceSelect.name}$$1`}>
+ <div data-islandid={`${PullRequestSourceSelect.name}$$0`}>
<PullRequestSourceSelect
- namePrefix={"target"}
+ namePrefix={"source"}
defaultSource={{
org: Object.values(data.sources)[0].org,
repo: Object.values(
@@ -202,7 +229,11 @@ const RepositoryPullRequestCreateForm: ReactIsland<RepositoryPullRequestCreateFo
onSelectionChange={onSourceSelectionChange}
/>
</div>
- <button type={"submit"} style={{ marginLeft: 8 }}>
+ <button
+ disabled={isCompareButtonEnabled === false}
+ type={"submit"}
+ style={{ marginLeft: 8 }}
+ >
Compare
</button>
</Grid.Row>
@@ -216,13 +247,15 @@ const RepositoryPullRequestCreateForm: ReactIsland<RepositoryPullRequestCreateFo
if (data.fileDiffs.length <= 0) {
return (
<Grid.Col fluid nowrap>
- <h1>Nothing to request Pull from... 🤔</h1>
+ <h1>Nothing to compare from... 🤔</h1>
<p>
The source and the target you've just selected seems to be equals.
+ </p>
+ <p>
Try comparing two branches that have some differences before you
- can create a pull request from the diff.
+ can create a pull request from the produced diff.
</p>
- <a href={`/${parentOrgSlug}/${repoSlug}/pulls/new`}>Go back</a>
+ <a href={`/${parentOrgSlug}/${repoSlug}/pulls/new`}>Try again</a>
</Grid.Col>
);
}
@@ -304,7 +337,7 @@ const RepositoryPullRequestCreateForm: ReactIsland<RepositoryPullRequestCreateFo
</Grid.Col>
<Grid.Col flex={0.3} style={{ marginLeft: 16 }}>
<Card themeScheme={themeScheme} style={{ width: "100%" }}>
- <span>fuck the police</span>
+ <span></span>
</Card>
</Grid.Col>
</Grid.Row>