-
-
Notifications
You must be signed in to change notification settings - Fork 313
Implement stargazers pagination and filtering in repo detail view #4306
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Added JavaScript functions to handle pagination and filtering of stargazers in the repository detail view. - Updated the HTML template to include a stargazers section with filter controls and pagination links, styled with Tailwind CSS. - Enhanced the backend view to fetch stargazers from the GitHub API, handling various response statuses and errors appropriately. This change improves user interaction by allowing users to navigate through stargazers efficiently and apply filters for better visibility. Stargazers now shown, Pagination and filters, User-friendly view.
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughThe changes add a "Stargazers" section to the repository detail page, displaying users who have starred the repository. Backend logic fetches and paginates stargazer data from GitHub, while frontend JavaScript enables AJAX-based pagination and filtering. The template renders the stargazers list, filters, and pagination controls within the page. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Browser
participant DjangoView
participant GitHubAPI
User->>Browser: Loads repo detail page
Browser->>DjangoView: HTTP GET /repo/<repo_id>
DjangoView->>GitHubAPI: GET /repos/{owner}/{repo}/stargazers (with pagination)
GitHubAPI-->>DjangoView: Stargazers data (paginated)
DjangoView-->>Browser: Rendered HTML with stargazers section
User->>Browser: Clicks pagination/filter link in stargazers section
Browser->>DjangoView: AJAX GET /repo/<repo_id>?page=X&filter=Y (XHR)
DjangoView->>GitHubAPI: GET /repos/{owner}/{repo}/stargazers (with pagination/filter)
GitHubAPI-->>DjangoView: Stargazers data (paginated)
DjangoView-->>Browser: Partial HTML for #stargazers-section
Browser->>Browser: Replace #stargazers-section content, update URL, rebind listeners
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15 minutes The changes span backend data fetching and pagination logic, frontend AJAX interaction, and template additions with UI components. The complexity is moderate due to integration of API calls, error handling, dynamic content replacement, and event rebinding. Assessment against linked issues
Assessment against linked issues: Out-of-scope changesNo out-of-scope changes detected. Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (6)
website/templates/projects/repo_detail.html (1)
1310-1339: Well-implemented pagination with accessibility considerationsThe pagination controls are thoughtfully implemented with:
- Clear visibility of current page
- Previous/Next buttons that appear only when relevant
- Smart handling of large page numbers with ellipses
- Maintenance of the current filter when navigating pages
Consider adding ARIA attributes to improve accessibility for screen readers.
-<div class="flex flex-col items-center space-y-4 mt-8"> +<div class="flex flex-col items-center space-y-4 mt-8" role="navigation" aria-label="Stargazers pagination">website/static/js/repo_detail.js (2)
429-455: Consider adding more robust error handling for user feedbackWhile you have console error logging, the user doesn't receive any visual feedback when an error occurs during stargazer fetching. Consider adding a user-facing error message similar to other sections of the site.
function fetchStargazers(url) { const stargazersSection = document.getElementById('stargazers-section'); if (!stargazersSection) return; // Show loading state stargazersSection.classList.add('opacity-50'); fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) throw new Error('Network response was not ok'); return response.text(); }) .then(html => { // Parse the returned HTML and extract the stargazers section const tempDiv = document.createElement('div'); tempDiv.innerHTML = html; const newSection = tempDiv.querySelector('#stargazers-section'); if (newSection) { stargazersSection.innerHTML = newSection.innerHTML; // Update URL window.history.pushState({}, '', url); // Re-attach listeners attachStargazersListeners(); } }) .catch(error => { console.error('Error fetching stargazers:', error); + // Add user-facing error message + const errorHtml = `<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"> + Failed to load stargazers. Please try again later. + </div>`; + // Insert at the top of the section, preserving existing content + const contentWrapper = stargazersSection.querySelector('.bg-white'); + if (contentWrapper) { + const errorDiv = document.createElement('div'); + errorDiv.innerHTML = errorHtml; + contentWrapper.insertBefore(errorDiv.firstChild, contentWrapper.firstChild.nextSibling); + } }) .finally(() => { stargazersSection.classList.remove('opacity-50'); }); }
425-428: Add error checking for mandatory URL parameterThe
fetchStargazersfunction doesn't verify if the URL parameter is valid. Adding a simple check would prevent potential errors.function fetchStargazers(url) { + if (!url) { + console.error('fetchStargazers called without a URL'); + return; + } const stargazersSection = document.getElementById('stargazers-section'); if (!stargazersSection) return; // Show loading state stargazersSection.classList.add('opacity-50');website/views/project.py (3)
1267-1295: Remove debug print statements before deploying to production.The code contains multiple debug print statements that should be removed or replaced with proper logging before deploying to production. These statements could expose sensitive information or clutter server logs.
- print(f"[DEBUG] repo.repo_url: {repo.repo_url}") - repo_path = repo.repo_url.split("github.com/")[-1] - print(f"[DEBUG] repo_path: {repo_path}") - owner, repo_name = repo_path.split("/") - print(f"[DEBUG] Owner: {owner}, Repo Name: {repo_name}") + repo_path = repo.repo_url.split("github.com/")[-1] + owner, repo_name = repo_path.split("/") - api_url = f"https://api.github.com/repos/{owner}/{repo_name}/stargazers" - print(f"[DEBUG] Stargazers API URL: {api_url}") + api_url = f"https://api.github.com/repos/{owner}/{repo_name}/stargazers" - print(f"[DEBUG] Stargazers API page {current_page} status: {response.status_code}") - try: - print(f"[DEBUG] Stargazers API response body (first 500 chars): {response.text[:500]}") - except Exception as debug_e: - print(f"[DEBUG] Could not print response body: {debug_e}")Consider replacing debug prints with proper logging:
import logging logger = logging.getLogger(__name__) # Then replace prints with: logger.debug(f"Stargazers API URL: {api_url}")
1322-1336: Improve filtering implementation and pagination efficiency.The current filtering implementation for "recent" stargazers simply reverses the list, which might not accurately represent recent stargazers depending on how GitHub returns the data. Consider using API parameters if GitHub supports sorting or implementing a more sophisticated filtering approach.
if "stargazers" not in context: # Apply filtering based on filter_type if filter_type == "recent": - all_stargazers.reverse() + # Option 1: If GitHub API supports sorting by starred_at date + # This would require using a different API endpoint that includes dates + # api_url = f"https://api.github.com/repos/{owner}/{repo_name}/stargazers" + # headers["Accept"] = "application/vnd.github.v3.star+json" + # Then parse the "starred_at" field from responses + + # For now, reversing is reasonable if the API returns oldest first + all_stargazers.reverse() total_stargazers = len(all_stargazers) total_pages = (total_stargazers + per_page - 1) // per_page page = max(1, min(page, total_pages)) if total_pages > 0 else 1 start_idx = (page - 1) * per_page end_idx = start_idx + per_page context["stargazers"] = all_stargazers[start_idx:end_idx]Consider using GitHub's StarredAt API for more accurate timestamp-based filtering:
# For more accurate "recent" filtering: if filter_type == "recent": # Use GitHub's StarredAt API which provides timestamps headers["Accept"] = "application/vnd.github.v3.star+json" # Then sort by the "starred_at" field in the response
1267-1345: Extract stargazers fetching into a separate method for better maintainability.The stargazers fetching logic is quite complex and would benefit from being extracted into a separate method. This would improve readability, allow easier testing, and make the
get_context_datamethod less cluttered.def fetch_repo_stargazers(self, repo, filter_type="all", page=1, per_page=10): """ Fetch stargazers for a repository with pagination and filtering. Args: repo: The repository object filter_type: Type of filter to apply ('all' or 'recent') page: Page number to fetch per_page: Number of items per page Returns: dict: Dictionary containing: - stargazers: List of stargazers for the requested page - error: Error message if any - total_stargazers: Total number of stargazers - total_pages: Total number of pages - current_page: Current page number """ try: # Extract repo info repo_path = repo.repo_url.split("github.com/")[-1] owner, repo_name = repo_path.split("/") # Set up API request api_url = f"https://api.github.com/repos/{owner}/{repo_name}/stargazers" headers = {"Accept": "application/vnd.github.v3+json"} if hasattr(settings, "GITHUB_TOKEN") and settings.GITHUB_TOKEN and settings.GITHUB_TOKEN != "blank": headers["Authorization"] = f"token {settings.GITHUB_TOKEN}" # Fetch all stargazers all_stargazers = [] current_page = 1 api_per_page = 100 max_retries = 3 # Rest of the implementation... return { "stargazers": paginated_stargazers, "error": None, "total_stargazers": total_stargazers, "total_pages": total_pages, "current_page": page } except Exception as e: logger.error(f"Error fetching stargazers: {e}", exc_info=True) return { "stargazers": [], "error": "Error fetching stargazers. Please try again later.", "total_stargazers": 0, "total_pages": 0, "current_page": 1 }Then in
get_context_data:# Fetch stargazers filter_type = self.request.GET.get("filter", "all") page = int(self.request.GET.get("page", 1)) stargazers_data = self.fetch_repo_stargazers(repo, filter_type, page) # Add to context context.update(stargazers_data) context["filter_type"] = filter_type
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting
📒 Files selected for processing (3)
website/static/js/repo_detail.js(2 hunks)website/templates/projects/repo_detail.html(1 hunks)website/views/project.py(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Run Tests
- GitHub Check: docker-test
🔇 Additional comments (4)
website/templates/projects/repo_detail.html (2)
1273-1344: Well-implemented stargazers section with responsive design and good UX patterns!The new stargazers section is well-structured with:
- Clear filter controls for toggling between all and recent stargazers
- Error handling for displaying API failures
- Responsive grid layout that adjusts based on screen size
- Well-designed pagination with ellipses for large page counts
- Fallback message when no stargazers are found
The implementation follows the same styling patterns as other sections in the page, providing a consistent user experience.
1280-1285: Good use of progressive enhancement for filter controlsThe filter links will work even if JavaScript is disabled, but will be enhanced with AJAX functionality when available. The active filter is clearly highlighted with contrasting colors.
website/static/js/repo_detail.js (2)
407-456: Effective implementation of AJAX-based pagination and filteringThe implementation properly:
- Separates concerns with dedicated functions for attaching listeners and fetching data
- Handles loading states to provide visual feedback during AJAX requests
- Updates the browser URL history for proper navigation support
- Re-attaches event listeners to dynamically loaded content
- Includes error handling and proper cleanup
499-499: Consistent initialization with the rest of the codebaseGood job adding the stargazers initialization to the existing DOM content loaded event handler, maintaining consistency with other feature initializations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR adds stargazers pagination and filtering to the repository detail view, including backend data fetching, template updates, and client-side AJAX for a smoother UX.
- Implements backend logic to fetch all stargazers via GitHub API and apply pagination/filtering.
- Updates the HTML template to render stargazers, filter controls, and pagination, styled with Tailwind CSS.
- Adds JavaScript handlers for AJAX-based pagination and filtering without full page reloads.
Reviewed Changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| website/views/project.py | Added view logic to retrieve, filter, and paginate stargazers |
| website/templates/projects/repo_detail.html | Introduced stargazers section with filters and pagination UI |
| website/static/js/repo_detail.js | Added AJAX functions to fetch and update stargazers dynamically |
Comments suppressed due to low confidence (1)
website/views/project.py:1267
- This new logic should have corresponding unit or integration tests (e.g., mocking GitHub API responses) to verify pagination, filtering, and error handling behaviors.
# Fetch stargazers for this repo (with pagination and filter)
DonnieBLT
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one change please
Fixes #3726
This change improves user interaction by allowing users to navigate through stargazers efficiently and apply filters for better visibility.
Stargazers now shown,
Pagination and filters,
User-friendly view.
Summary by CodeRabbit
New Features
Bug Fixes
Style