diff --git a/frontend/src/components/PullRequestsSection.tsx b/frontend/src/components/PullRequestsSection.tsx index 10740fc..2742ef0 100644 --- a/frontend/src/components/PullRequestsSection.tsx +++ b/frontend/src/components/PullRequestsSection.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useState, useMemo } from 'react'; import { Card, CardContent, @@ -12,6 +12,7 @@ import { TableBody, Link, Chip, + TableSortLabel, } from '@mui/material'; import { Settings } from '@mui/icons-material'; import { PullRequest, Issue } from '../types'; @@ -34,6 +35,48 @@ export const PullRequestsSection: React.FC = ({ owner, repo, }) => { + const [sortBy, setSortBy] = useState('created_at'); + const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc'); + + // Sort pull requests based on current sort criteria + const sortedPullRequests = useMemo(() => { + return [...pullRequests].sort((a, b) => { + let aValue: any = a[sortBy]; + let bValue: any = b[sortBy]; + + // Handle special sorting cases for different data types + if (sortBy === 'created_at' || sortBy === 'closed_at' || sortBy === 'merged_at') { + aValue = aValue ? new Date(aValue).getTime() : 0; + bValue = bValue ? new Date(bValue).getTime() : 0; + } else if (sortBy === 'comments' || sortBy === 'additions' || sortBy === 'deletions') { + aValue = aValue ?? 0; + bValue = bValue ?? 0; + } else if (sortBy === 'reviewers') { + aValue = aValue?.length ?? 0; + bValue = bValue?.length ?? 0; + } else if (sortBy === 'linked_issues') { + aValue = aValue?.length ?? 0; + bValue = bValue?.length ?? 0; + } + + if (aValue < bValue) { + return sortDirection === 'asc' ? -1 : 1; + } + if (aValue > bValue) { + return sortDirection === 'asc' ? 1 : -1; + } + return 0; + }); + }, [pullRequests, sortBy, sortDirection]); + + const handleSort = (column: keyof PullRequest) => { + if (sortBy === column) { + setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc'); + } else { + setSortBy(column); + setSortDirection('asc'); + } + }; return ( @@ -61,19 +104,83 @@ export const PullRequestsSection: React.FC = ({ - PR # - Title - Status - Author - Reviewer - Comments - Linked Issue - CI + + handleSort('number')} + > + PR # + + + + handleSort('title')} + > + Title + + + + handleSort('status')} + > + Status + + + + handleSort('author')} + > + Author + + + + handleSort('reviewers')} + > + Reviewer + + + + handleSort('comments')} + > + Comments + + + + handleSort('linked_issues')} + > + Linked Issue + + + + handleSort('ci_status')} + > + CI + + Lines Changed - {pullRequests.map((pr) => { + {sortedPullRequests.map((pr) => { // Use comments directly from PR data, or fallback to deriving from linked issues let comments = pr.comments ?? 0; let linkedIssueElement = ;