Skip to content

Commit

Permalink
[CRA-RXJS-SC] Fix PR API fetch (#580)
Browse files Browse the repository at this point in the history
* chore: init

* chore: react-paginate

* chore: fetch open/closed PRs separately to accurately get count

* chore: add pagination to PRs

* chore: format

* chore: fixed broken pull request page

---------

Co-authored-by: Jerry Hogan <[email protected]>
  • Loading branch information
kodejuice and hdJerry authored Aug 4, 2023
1 parent 53ea74c commit d8dcb74
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 129 deletions.
20 changes: 20 additions & 0 deletions cra-rxjs-styled-components/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cra-rxjs-styled-components/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"react": "^17.0.2",
"react-content-loader": "^6.2.0",
"react-dom": "^17.0.2",
"react-paginate": "^8.1.3",
"react-router-dom": "^6.2.1",
"react-scripts": "5.0.1",
"rxjs": "^7.5.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ OpenPullRequests.args = {
state: 'open',
messageCount: 0,
merged_at: null,
review_comments_url: '/',
repository_url: '/',
comments: '',
},
{
Expand All @@ -40,7 +40,7 @@ OpenPullRequests.args = {
state: 'open',
messageCount: 0,
merged_at: null,
review_comments_url: '/',
repository_url: '/',
comments: '',
},
{
Expand All @@ -51,7 +51,7 @@ OpenPullRequests.args = {
state: 'open',
messageCount: 0,
merged_at: null,
review_comments_url: '/',
repository_url: '/',
comments: '',
},
],
Expand All @@ -72,7 +72,7 @@ MergedPullRequests.args = {
messageCount: 0,
isMerged: true,
merged_at: date,
review_comments_url: '/',
repository_url: '/',
comments: '',
},
{
Expand All @@ -84,7 +84,7 @@ MergedPullRequests.args = {
messageCount: 0,
isMerged: true,
merged_at: date,
review_comments_url: '/',
repository_url: '/',
comments: '',
},
],
Expand All @@ -103,7 +103,7 @@ ClosedPullRequests.args = {
state: 'closed',
messageCount: 0,
merged_at: null,
review_comments_url: '/',
repository_url: '/',
comments: '',
},
{
Expand All @@ -114,7 +114,7 @@ ClosedPullRequests.args = {
state: 'closed',
messageCount: 0,
merged_at: null,
review_comments_url: '/',
repository_url: '/',
comments: '',
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,75 +10,115 @@ import {
import React, { useEffect, useState } from 'react';

import type { PRTabValues } from '../types';
import { PULLS_URL } from '../../../constants/url.constants';
import type { PullRequest } from './PullRequest.type';
import {
OPEN_PULLS_URL,
CLOSED_PULLS_URL,
} from '../../../constants/url.constants';
import type { PullRequest, PullRequests } from './PullRequest.type';
import PullRequestView from './PullRequest.view';
import { fromFetchWithAuth } from '../../../hooks/auth/from-fetch-with-auth';
import { useParams } from 'react-router-dom';

export default function PullRequestCtrl() {
const [activeTab, setActiveTab] = useState<PRTabValues>('open');
const [pullRequests, setPullRequests] = useState<PullRequest[]>([]);
const [openPRPage, setOpenPRPage] = useState(1);
const [closedPRPage, setClosedPRPage] = useState(1);
const setPRPage = activeTab === 'open' ? setOpenPRPage : setClosedPRPage;
const [openPullRequests, setOpenPullRequests] = useState<PullRequests>({
total_count: 0,
items: [],
});
const [closedPullRequests, setClosedPullRequests] = useState<PullRequests>({
total_count: 0,
items: [],
});

const { username, repo } = useParams();

useEffect(() => {
if (username && repo) {
const subscription: Subscription = fromFetchWithAuth<PullRequest[]>(
PULLS_URL(username, repo),
const openPRSubscription: Subscription = fromFetchWithAuth<PullRequests>(
OPEN_PULLS_URL(username, repo, openPRPage),
{
selector: async (response: Response) => {
const res = await response.json();
return res as any;
},
}
)
.pipe(
filter((pulls) => !!pulls.total_count),
switchMap((pulls: PullRequests) => {
const requests = pulls.items.map(createCommentCountRequest);
return zip(...requests).pipe(
map(mergePullRequestsWithCommentCount(pulls))
);
}),
tap(setOpenPullRequests)
)
.subscribe();

const closedPRSubscription: Subscription = fromFetchWithAuth<PullRequests>(
CLOSED_PULLS_URL(username, repo, closedPRPage),
{
selector: (response: Response) => {
return response.json();
selector: async (response: Response) => {
const res = await response.json();
return res as any;
},
}
)
.pipe(
filter((pulls) => !!pulls.length),
switchMap((pulls: PullRequest[]) => {
const requests = pulls.map(createCommentCountRequest);
filter((pulls) => !!pulls.total_count),
switchMap((pulls: PullRequests) => {
const requests = pulls.items.map(createCommentCountRequest);
return zip(...requests).pipe(
map(mergePullRequestsWithCommentCount(pulls))
);
}),
tap(setPullRequests)
tap(setClosedPullRequests)
)
.subscribe();

return () => {
subscription.unsubscribe();
openPRSubscription.unsubscribe();
closedPRSubscription.unsubscribe();
};
}
}, [username, repo]);
}, [username, repo, openPRPage, closedPRPage]);

const OPEN_PRS: PullRequest[] = pullRequests?.filter(
(pr) => pr.state === 'open'
);
const CLOSED_PRS: PullRequest[] = pullRequests?.filter(
(pr) => pr.state === 'closed'
);
const PRS =
activeTab === 'open' ? openPullRequests.items : closedPullRequests.items;

return (
<PullRequestView
pullRequests={activeTab === 'open' ? OPEN_PRS : CLOSED_PRS}
openPRCount={OPEN_PRS?.length}
closedPRCount={CLOSED_PRS?.length}
pullRequests={PRS}
openPRCount={openPullRequests.total_count}
closedPRCount={closedPullRequests.total_count}
activeTab={activeTab}
changeActiveTab={setActiveTab}
setPRPage={setPRPage}
/>
);
}

function createCommentCountRequest(pr: PullRequest): Observable<number> {
return fromFetchWithAuth<number>(pr.review_comments_url, {
const review_comments_url = `${pr.repository_url}/pulls/${pr.number}/comments`;
return fromFetchWithAuth<number>(review_comments_url, {
selector: (response: Response) => {
return response.json();
},
});
}

function mergePullRequestsWithCommentCount(pulls: PullRequest[]) {
return (counts: number[]): PullRequest[] => {
return pulls.map((p: PullRequest, index: number) => ({
function mergePullRequestsWithCommentCount(pulls: PullRequests) {
return (counts: number[]): PullRequests => {
const items = pulls.items.map((p: PullRequest, index: number) => ({
...p,
comments: counts[index],
}));
return {
total_count: pulls.total_count,
items,
};
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,100 +13,57 @@ export const Content = styled.div`
border-radius: 6px;
`;
export const PaginationContainer = styled.div`
display: flex;
justify-content: center;
padding: 10px 0;
& > span {
min-width: 32px;
padding: 5px 10px;
font-style: normal;
line-height: 20px;
color: ${colors.gray800};
text-align: center;
white-space: nowrap;
vertical-align: middle;
/* pagination */
.pagination {
display: flex;
padding: 0;
justify-content: center;
list-style: none;
cursor: pointer;
-webkit-user-select: none;
user-select: none;
border: 1px solid transparent;
border-radius: 6px;
transition: border-color 0.2s cubic-bezier(0.3, 0, 0.5, 1);
}
& .disabled {
color: ${colors.gray400};
cursor: default;
border-color: transparent;
.pagination a {
padding: 1px;
border-radius: 5px;
color: var(--default-text-color);
font-size: 14px;
padding: 5px 10px;
margin: 0 5px;
}
.pagination__link {
font-weight: bold;
}
.pagination__item a:hover {
text-decoration: none;
border: 1px solid var(--text-muted);
}
.pagination__link_end a {
color: #539bf5;
text-decoration: none;
padding: 7px 10px;
}
.pagination__link_end a:hover {
border: 1px solid var(--text-muted);
}
& > .prev {
position: relative;
&::before {
display: inline-block;
width: 16px;
height: 16px;
vertical-align: text-bottom;
content: '';
background-color: currentColor;
margin-right: 4px;
-webkit-clip-path: polygon(
9.8px 12.8px,
8.7px 12.8px,
4.5px 8.5px,
4.5px 7.5px,
8.7px 3.2px,
9.8px 4.3px,
6.1px 8px,
9.8px 11.7px,
9.8px 12.8px
);
clip-path: polygon(
9.8px 12.8px,
8.7px 12.8px,
4.5px 8.5px,
4.5px 7.5px,
8.7px 3.2px,
9.8px 4.3px,
6.1px 8px,
9.8px 11.7px,
9.8px 12.8px
);
}
.pagination__link--active a {
color: #fff;
background: #316dca;
}
.pagination__link--active a:hover {
border: none !important;
}
& > .next {
position: relative;
&::after {
display: inline-block;
width: 16px;
height: 16px;
vertical-align: text-bottom;
content: '';
background-color: currentColor;
margin-left: 4px;
-webkit-clip-path: polygon(
6.2px 3.2px,
7.3px 3.2px,
11.5px 7.5px,
11.5px 8.5px,
7.3px 12.8px,
6.2px 11.7px,
9.9px 8px,
6.2px 4.3px,
6.2px 3.2px
);
clip-path: polygon(
6.2px 3.2px,
7.3px 3.2px,
11.5px 7.5px,
11.5px 8.5px,
7.3px 12.8px,
6.2px 11.7px,
9.9px 8px,
6.2px 4.3px,
6.2px 3.2px
);
}
.pagination__link--disabled,
.pagination__link--disabled a {
color: #545d68 !important;
text-decoration: none !important;
border: none !important;
cursor: default;
}
`;
Loading

0 comments on commit d8dcb74

Please sign in to comment.