Skip to content

Commit

Permalink
Merge pull request #14 from neubig/openhands-fix-issue-13
Browse files Browse the repository at this point in the history
Fix issue #13: Add the option to sort PRs
  • Loading branch information
neubig authored Dec 30, 2024
2 parents 9d8b0a0 + 3ccaa13 commit 42fbe3d
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 14 deletions.
15 changes: 15 additions & 0 deletions 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 package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
},
"devDependencies": {
"@eslint/js": "^9.8.0",
"@testing-library/user-event": "^14.5.2",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
Expand Down
32 changes: 32 additions & 0 deletions src/PullRequestViewer.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import PullRequestViewer from './PullRequestViewer';

describe('PullRequestViewer', () => {
Expand All @@ -16,4 +17,35 @@ describe('PullRequestViewer', () => {
const selectElement = screen.getByRole('combobox', { name: /select a repository/i });
expect(selectElement).toBeInTheDocument();
});

it('renders the sort select dropdown', () => {
render(<PullRequestViewer />);
const sortSelect = screen.getByRole('combobox', { name: /sort pull requests/i });
expect(sortSelect).toBeInTheDocument();
});

it('displays default sort option', () => {
render(<PullRequestViewer />);
const defaultOption = screen.getByText('Creation Date (Newest)');
expect(defaultOption).toBeInTheDocument();
});

it('shows all sorting options', async () => {
render(<PullRequestViewer />);
const sortSelect = screen.getByRole('combobox', { name: /sort pull requests/i });
await userEvent.click(sortSelect);

const expectedOptions = [
'Creation Date (Newest)',
'Creation Date (Oldest)',
'Last Updated (Newest)',
'Last Updated (Oldest)',
'PR Number (Highest)',
'PR Number (Lowest)',
];

expectedOptions.forEach(option => {
expect(screen.getAllByText(option)[0]).toBeInTheDocument();
});
});
});
76 changes: 62 additions & 14 deletions src/PullRequestViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@



import React, { useState, useEffect } from 'react';
import { Octokit } from '@octokit/rest';
import Select from 'react-select';
Expand All @@ -14,17 +13,36 @@ interface PullRequest {
user: {
login: string;
};
created_at: string;
updated_at: string;
number: number;
}

interface Repo {
value: string;
label: string;
}

interface SortOption {
value: keyof PullRequest | 'number' | 'created_at' | 'updated_at';
label: string;
direction: 'asc' | 'desc';
}

const sortOptions: SortOption[] = [
{ value: 'created_at', label: 'Creation Date (Newest)', direction: 'desc' },
{ value: 'created_at', label: 'Creation Date (Oldest)', direction: 'asc' },
{ value: 'updated_at', label: 'Last Updated (Newest)', direction: 'desc' },
{ value: 'updated_at', label: 'Last Updated (Oldest)', direction: 'asc' },
{ value: 'number', label: 'PR Number (Highest)', direction: 'desc' },
{ value: 'number', label: 'PR Number (Lowest)', direction: 'asc' },
];

const PullRequestViewer: React.FC = () => {
const [repos, setRepos] = useState<Repo[]>([]);
const [selectedRepo, setSelectedRepo] = useState<Repo | null>(null);
const [pullRequests, setPullRequests] = useState<PullRequest[]>([]);
const [selectedSort, setSelectedSort] = useState<SortOption>(sortOptions[0]);

useEffect(() => {
const fetchRepos = async () => {
Expand All @@ -33,7 +51,7 @@ const PullRequestViewer: React.FC = () => {
org: GITHUB_ORG,
type: 'all',
});
const repoOptions = response.data.map(repo => ({
const repoOptions = response.data.map((repo) => ({
value: repo.name,
label: repo.name,
}));
Expand All @@ -49,7 +67,7 @@ const PullRequestViewer: React.FC = () => {
const fetchPullRequests = async () => {
if (selectedRepo) {
try {
let allPullRequests: PullRequest[] = [];
const allPullRequests: PullRequest[] = [];
let page = 1;
let hasNextPage = true;

Expand All @@ -59,10 +77,10 @@ const PullRequestViewer: React.FC = () => {
repo: selectedRepo.value,
state: 'open',
per_page: 100,
page: page,
page,
});

allPullRequests = [...allPullRequests, ...response.data];
allPullRequests.push(...response.data);

if (response.data.length < 100) {
hasNextPage = false;
Expand All @@ -80,25 +98,55 @@ const PullRequestViewer: React.FC = () => {
fetchPullRequests();
}, [selectedRepo]);

const sortPullRequests = (prs: PullRequest[]) => {
return [...prs].sort((a, b) => {
const aValue = a[selectedSort.value];
const bValue = b[selectedSort.value];

if (selectedSort.direction === 'asc') {
return aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
} else {
return bValue < aValue ? -1 : bValue > aValue ? 1 : 0;
}
});
};

const sortedPullRequests = sortPullRequests(pullRequests);

return (
<div>
<h1>Pull Request Viewer</h1>
<Select
options={repos}
value={selectedRepo}
onChange={(option) => setSelectedRepo(option as Repo)}
placeholder="Select a repository"
aria-label="Select a repository"
/>
{pullRequests.length > 0 ? (
<div style={{ marginBottom: '1rem' }}>
<Select
options={repos}
value={selectedRepo}
onChange={(option) => setSelectedRepo(option as Repo)}
placeholder="Select a repository"
aria-label="Select a repository"
/>
</div>
<div style={{ marginBottom: '1rem' }}>
<Select
options={sortOptions}
value={selectedSort}
onChange={(option) => setSelectedSort(option as SortOption)}
placeholder="Sort by"
aria-label="Sort pull requests"
/>
</div>
{sortedPullRequests.length > 0 ? (
<ul>
{pullRequests.map((pr) => (
{sortedPullRequests.map((pr) => (
<li key={pr.html_url}>
<a href={pr.html_url} target="_blank" rel="noopener noreferrer">
{pr.title}
</a>
{' by '}
{pr.user.login}
{' - '}
Created: {new Date(pr.created_at).toLocaleDateString()}
{', '}
Last updated: {new Date(pr.updated_at).toLocaleDateString()}
</li>
))}
</ul>
Expand Down

0 comments on commit 42fbe3d

Please sign in to comment.