Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@igennova
Copy link
Contributor

@igennova igennova commented May 21, 2025

Fixes #3726

  • 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.

image

Summary by CodeRabbit

  • New Features

    • Added a "Stargazers" section to the repository detail page, displaying users who have starred the repository.
    • Introduced filtering options to view all or only recent stargazers.
    • Implemented pagination for browsing through stargazers.
    • Enabled dynamic loading and filtering of stargazers without page reloads.
  • Bug Fixes

    • Displayed error messages if stargazer data cannot be retrieved.
  • Style

    • Styled the "Stargazers" section to match the existing user interface.

- 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.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 21, 2025

Note

Other AI code review bot(s) detected

CodeRabbit 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.

Walkthrough

The 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

Cohort / File(s) Change Summary
Frontend JavaScript
website/static/js/repo_detail.js
Added AJAX-based pagination and filtering for the stargazers section. Introduced attachStargazersListeners and fetchStargazers functions to handle dynamic content loading, event binding, and browser history updates for the stargazers list.
Template Additions
website/templates/projects/repo_detail.html
Added a new "Stargazers" section to the repository detail page. This section includes a list of stargazers, filter controls (all/recent), pagination controls, error handling, and placeholder messages for empty states. The section is styled and integrated into the main content block.
Backend View Logic
website/views/project.py
Enhanced the get_context_data method of RepoDetailView to fetch stargazers from the GitHub API, handle pagination and filtering, process errors, and add relevant metadata to the template context for rendering the stargazers section. Removed some print statements related to error logging in other methods.

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
Loading

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

Objective Addressed Explanation
Show the stargazers on the repo (#3726)
Provide a way to see recent stargazers across all repos (#3726)

Assessment against linked issues: Out-of-scope changes

No 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 details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Knowledge Base: Disabled due to Reviews > Disable Knowledge Base setting

📥 Commits

Reviewing files that changed from the base of the PR and between ad2c973 and 8ec7201.

📒 Files selected for processing (1)
  • website/views/project.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • website/views/project.py
⏰ 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)
  • GitHub Check: Run Tests
  • GitHub Check: docker-test
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 considerations

The 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 feedback

While 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 parameter

The fetchStargazers function 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_data method 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

📥 Commits

Reviewing files that changed from the base of the PR and between 90b0978 and be3da29.

📒 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 controls

The 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 filtering

The 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 codebase

Good job adding the stargazers initialization to the existing DOM content loaded event handler, maintaining consistency with other feature initializations.

coderabbitai[bot]
coderabbitai bot previously approved these changes May 21, 2025
coderabbitai[bot]
coderabbitai bot previously approved these changes May 22, 2025
@DonnieBLT DonnieBLT requested review from DonnieBLT and Copilot July 3, 2025 15:57
Copy link
Contributor

Copilot AI left a 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)

Copy link
Collaborator

@DonnieBLT DonnieBLT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one change please

@igennova igennova requested a review from DonnieBLT August 4, 2025 16:26
@DonnieBLT DonnieBLT added this pull request to the merge queue Aug 7, 2025
Merged via the queue into OWASP-BLT:main with commit 5db3f48 Aug 7, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

show the stargazers on the repo and have a way to see recent stargazers across all repos

2 participants