Skip to content

Stars and forks widgets#46

Merged
emlimlf merged 4 commits intomainfrom
improvement/stars-and-forks
Feb 25, 2025
Merged

Stars and forks widgets#46
emlimlf merged 4 commits intomainfrom
improvement/stars-and-forks

Conversation

@emlimlf
Copy link
Copy Markdown
Collaborator

@emlimlf emlimlf commented Feb 21, 2025

In this PR

  • Added stars widget under the popularity tab using mock data
  • Added forks widget under the popularity tab using mock data

Tickets

Summary by CodeRabbit

  • New Features

    • Enhanced fork and star visualization panels with new tabs for cumulative and new data.
    • Added interactive charts featuring formatted number displays and delta indicators.
    • Improved error notifications to alert users when data retrieval issues occur.
  • API Enhancements

    • Introduced endpoints providing real-time popularity metrics.
    • Integrated realistic mock data to support seamless testing and improved development.

Signed-off-by: Efren Lim <elim@linuxfoundation.org>
Signed-off-by: Efren Lim <elim@linuxfoundation.org>
Signed-off-by: Efren Lim <elim@linuxfoundation.org>
@emlimlf emlimlf requested a review from gaspergrom February 21, 2025 08:39
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 21, 2025

Walkthrough

The pull request extends project popularity functionality by enhancing the forks and stars components. Both components now display fork/star counts with delta indications, use a tabbed interface for cumulative and new data, and include enhanced error handling. New computed properties and chart configurations have been added along with TypeScript interfaces for structured popularity data. Additionally, corresponding API endpoints and mock data files are introduced for retrieving forks and stars data, and a minor layout adjustment is made to the chart configuration.

Changes

File(s) Change Summary
frontend/app/components/modules/project/components/popularity/forks.vue
frontend/app/components/modules/project/components/popularity/stars.vue
Added new sections displaying fork/star counts with delta displays, a tabbed interface for “Cumulative” and “New” data, use of useFetch, computed properties for data processing, chart configuration (including chartSeries and lineChartConfig), and error handling via a watcher.
frontend/app/components/modules/project/components/popularity/types/popularity.types.ts Introduced TypeScript interfaces (StarsData and ForksData) defining the structure for popularity data, including summaries and arrays of data points with date ranges and counts.
frontend/app/components/uikit/chart/configs/line.area.chart.ts Modified the grid configuration of the chart by adding bottom: '15%' to adjust the chart’s bottom margin.
frontend/server/api/projects/popularity/forks.get.ts
frontend/server/api/projects/popularity/stars.get.ts
Introduced new API endpoints for retrieving project popularity data for forks and stars. The endpoints use query parameters to select between “cumulative” and “new” data and return a summary along with data arrays based on dates and counts.
frontend/server/mocks/forks.mock.ts
frontend/server/mocks/stars.mock.ts
Added new mock data files exporting constants (cumulative and newStars) containing summary metrics and arrays of data points for forks and stars, respectively, to support testing and development.

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant VC as Vue Component (Forks/Stars)
  participant F as useFetch Hook
  participant API as API Endpoint
  participant CP as Computed Props/Chart

  U->>VC: Select tab / trigger data load
  VC->>F: Call useFetch with query parameters
  F->>API: Request popularity data (cumulative/new)
  API-->>F: Return JSON data
  F-->>VC: Provide data, status, error
  VC->>CP: Update computed properties and chart config
  CP-->>VC: Render updated chart and delta display
Loading

Possibly related PRs

Suggested reviewers

  • gaspergrom

Poem

I'm a rabbit hopping through this code field bright,
Forks and stars dancing in the soft moonlight.
Tabs and charts twirl with precision and cheer,
Data flows smoothly, all bugs disappear.
With a hop and a skip, our code sings anew—
A delightful change in every byte, it's true!
🥕✨

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • 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 generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

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. (Beta)
  • @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
Copy Markdown

@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: 4

🧹 Nitpick comments (8)
frontend/app/components/uikit/chart/configs/line.area.chart.ts (1)

21-22: LGTM! Consider documenting margin rationale.

The grid configuration with 15% bottom margin provides better spacing for x-axis labels and legends, improving the visibility of stars and forks widgets. The use of percentage values ensures responsive layout.

Consider adding a comment explaining the rationale for the specific margin values, particularly the asymmetric top (5%) and bottom (15%) margins, to help future maintainers understand the design decisions.

 grid: {
   top: '5%',
   left: '8%',
   right: '1%',
+  // Increased bottom margin to accommodate x-axis labels and legends
   bottom: '15%'
 },
frontend/app/components/modules/project/components/popularity/forks.vue (3)

6-6: Revisit the placeholder text to align with "Forks".
Currently, the text references "Active contributor," which doesn't match the "Forks" heading or functionality. Consider updating it to reflect the forks context more accurately.


17-21: Consider renaming lineChartConfig to barChartConfig.
You’re using getBarChartConfig to build the chart, but the computed property name is lineChartConfig. Renaming it to avoid confusion would improve maintainability.

-<lfx-chart v-if="status !== 'pending'" :config="lineChartConfig" />
+<lfx-chart v-if="status !== 'pending'" :config="barChartConfig" />

100-115: Revise error toast messaging to match "forks" context.
The watch handler references "active contributors" even though this file is for forks. Update the toast message to avoid confusion.

-  `Error fetching active contributors: ${error.value?.statusMessage}`,
+  `Error fetching fork data: ${error.value?.statusMessage}`,
frontend/app/components/modules/project/components/popularity/stars.vue (2)

6-6: Revisit the placeholder text to align with "Stars".
Similar to the forks component, referencing "Active contributor" can be misleading.


93-115: Refine the error toast content.
Similar to forks.vue, the message references "active contributors," which doesn’t match the "stars" context. Consider updating it accordingly.

-  `Error fetching active contributors: ${error.value?.statusMessage}`,
+  `Error fetching star data: ${error.value?.statusMessage}`,
frontend/server/api/projects/popularity/stars.get.ts (1)

28-39: Refactor to reduce code duplication with forks.get.ts.

Both stars.get.ts and forks.get.ts share similar logic. Consider extracting the common functionality into a shared utility.

Create a new utility file frontend/server/utils/popularity.ts:

import { H3Event } from 'h3';

interface PopularityData {
  summary: {
    current: number;
    previous: number;
    percentageChange: number;
    changeValue: number;
    periodFrom: string;
    periodTo: string;
  };
  data: Array<{
    dateFrom: string;
    dateTo: string;
    [key: string]: string | number;
  }>;
}

export const getPopularityData = (
  event: H3Event,
  cumulativeData: PopularityData,
  newData: PopularityData
) => {
  const { type, project, repository } = getQuery(event);

  if (!type || !project || !repository) {
    throw createError({
      statusCode: 400,
      message: 'Missing required query parameters: type, project, repository'
    });
  }

  if (type !== 'cumulative' && type !== 'new') {
    throw createError({
      statusCode: 400,
      message: 'Invalid type parameter. Must be either "cumulative" or "new"'
    });
  }

  return type === 'cumulative' ? cumulativeData : newData;
};

Then update both endpoints to use this utility:

 // stars.get.ts
 import { cumulative, newStars } from '~~/server/mocks/stars.mock';
+import { getPopularityData } from '~~/server/utils/popularity';

 export default defineEventHandler(async (event) => {
-  const query = getQuery(event);
-  let data;
-
-  if (query.type === 'cumulative') {
-    data = cumulative;
-  } else {
-    data = newStars;
-  }
-
-  return data;
+  return getPopularityData(event, cumulative, newStars);
 });
frontend/server/mocks/stars.mock.ts (1)

1-186: Add TypeScript interfaces for the data structure.

Consider adding TypeScript interfaces to improve type safety and documentation.

interface PopularitySummary {
  current: number;
  previous: number;
  percentageChange: number;
  changeValue: number;
  periodFrom: string;
  periodTo: string;
}

interface StarDataPoint {
  dateFrom: string;
  dateTo: string;
  stars: number;
}

interface StarsData {
  summary: PopularitySummary;
  data: StarDataPoint[];
}

export const cumulative: StarsData = {
  // ... existing data
};

export const newStars: StarsData = {
  // ... existing data
};
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eeae84a and da358ae.

📒 Files selected for processing (8)
  • frontend/app/components/modules/project/components/popularity/forks.vue (1 hunks)
  • frontend/app/components/modules/project/components/popularity/stars.vue (1 hunks)
  • frontend/app/components/modules/project/components/popularity/types/popularity.types.ts (1 hunks)
  • frontend/app/components/uikit/chart/configs/line.area.chart.ts (1 hunks)
  • frontend/server/api/projects/popularity/forks.get.ts (1 hunks)
  • frontend/server/api/projects/popularity/stars.get.ts (1 hunks)
  • frontend/server/mocks/forks.mock.ts (1 hunks)
  • frontend/server/mocks/stars.mock.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • frontend/server/mocks/forks.mock.ts
🔇 Additional comments (17)
frontend/app/components/modules/project/components/popularity/forks.vue (7)

10-10: No issues found with this change.
The <hr> usage here is appropriate for separating sections.


12-15: Ensure delta-display accounts for decreasing metrics.
If fork numbers can decrease (e.g., a user removing a fork), verify that the component handles negative deltas properly.


27-48: Imports block looks good.
All necessary dependencies for the chart, tabs, and fetch utilities are in place.


49-66: Validate timePeriod usage.
Ensure invalid or unexpected time period values don’t cause unhandled errors upstream.


68-76: No issues with computed properties.
The fork data, summary, and chart data transformations appear consistent.


78-92: Tab definitions and chart series configuration look fine.
Currently, it aligns with standard usage for toggling between "cumulative" and "new."


93-99: Configuration override is appropriate.
Using the axis label formatter for date representation ensures better readability.

frontend/app/components/modules/project/components/popularity/stars.vue (6)

10-10: No issues found with this change.
This horizontal rule is a straightforward sectional divider.


12-15: Check for negative deltas in star counts.
If star numbers can drop (un-stars), ensure the component logic correctly handles negative deltas.


17-21: Tab layout and chart display logic are sound.
Using the spinner while data is pending is a good approach to improve the user experience.


27-66: Imports and prop definition are consistent.
All references align well with your chart setup and data handling approach.


68-76: Computed properties correctly handle fetched star data.
They neatly separate the summary from the chart data.


78-92: Series configuration is correct for line/area charts.
Using getLineAreaChartConfig aligns with the chosen chart type.

frontend/app/components/modules/project/components/popularity/types/popularity.types.ts (3)

1-2: Imports look correct.
Bringing in the Summary type ensures consistency with the shared data structures.


3-10: StarsData interface is clearly defined.
It cleanly separates the summary and time-series fields. No immediate issues.


12-19: ForksData interface matches the stars structure.
This parallel structure allows consistent handling in the associated Vue files.

frontend/server/mocks/stars.mock.ts (1)

7-8:

Details

❓ Verification inconclusive

Verify the mock data values.

The mock data shows dates in the future (2024-2025) and the summary values don't match the data points:

  • Cumulative data shows current: 2000, previous: 1800, but the latest data point shows 4200 stars
  • New stars data shows current: 1200, previous: 1000, but the data points don't sum up to these values

Also applies to: 96-97


🏁 Script executed:

#!/bin/bash
# Description: Calculate the sum of new stars and verify the latest cumulative value
python3 << 'EOF'
import json
import sys

def verify_mock_data(data):
    # Verify cumulative data
    latest_stars = data['data'][-1]['stars']
    if latest_stars != data['summary']['current']:
        print(f"Error: Latest stars ({latest_stars}) doesn't match summary current ({data['summary']['current']})")
    
    # Verify new stars
    total_new_stars = sum(point['stars'] for point in data['data'])
    if total_new_stars != data['summary']['current']:
        print(f"Error: Sum of new stars ({total_new_stars}) doesn't match summary current ({data['summary']['current']})")

# Read the mock data file
with open('frontend/server/mocks/stars.mock.ts', 'r') as f:
    content = f.read()

# Extract the data objects (this is a simple parser, you might need a proper TS parser)
import re
cumulative = re.search(r'export const cumulative = ({.*?});', content, re.DOTALL).group(1)
new_stars = re.search(r'export const newStars = ({.*?});', content, re.DOTALL).group(1)

# Convert to Python objects (this is unsafe, but okay for mock data verification)
cumulative_data = eval(cumulative.replace('null', 'None'))
new_stars_data = eval(new_stars.replace('null', 'None'))

print("Verifying cumulative data:")
verify_mock_data(cumulative_data)
print("\nVerifying new stars data:")
verify_mock_data(new_stars_data)
EOF

Length of output: 163


Attention: Mock Data Verification Issue Detected

The automated verification script produced a NameError (“name 'summary' is not defined”), which indicates that the current evaluation of the TypeScript mock data is failing—likely due to unquoted object keys (e.g., summary) or other formatting issues when converting the TS object to a valid Python dictionary. This issue affects the verification in both the cumulative data (lines 7–8) and similarly at lines 96–97.

Please take the following actions:

  • Inspect the mock file (frontend/server/mocks/stars.mock.ts):
    • Ensure that the mock objects (for cumulative and newStars) use a valid JSON-like syntax (e.g., with keys properly quoted) to allow safe parsing or adjust the evaluation logic to correctly handle TS object literal syntax.
  • Verify the data values manually:
    • Confirm that the cumulative data’s summary.current matches the latest data point’s star count.
    • Verify that the aggregation of new stars data aligns with its summary values.
  • Revisit the extraction method:
    • Consider using a proper parser instead of simple regex plus eval so that keys like summary aren’t misinterpreted as standalone variables.

After making the necessary corrections, please rerun the verification to ensure consistency across both sections of the mock data.

Comment on lines +34 to +36
} else {
data = newStars;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect mock data usage in the else block.

The else block is using newStars instead of newForks, which appears to be a copy-paste error.

-    data = newStars;
+    data = newForks;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} else {
data = newStars;
}
} else {
- data = newStars;
+ data = newForks;
}

Comment on lines +28 to +39
export default defineEventHandler(async (event) => {
const query = getQuery(event);
let data;

if (query.type === 'cumulative') {
data = cumulative;
} else {
data = newStars;
}

return data;
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add query parameter validation and error handling.

The endpoint lacks validation for required query parameters and error handling for invalid inputs. Consider adding the following improvements:

  1. Validate required query parameters
  2. Add type safety for query parameters
  3. Handle invalid query parameter values
 export default defineEventHandler(async (event) => {
   const query = getQuery(event);
+  const { type, project, repository } = query;
+
+  if (!type || !project || !repository) {
+    throw createError({
+      statusCode: 400,
+      message: 'Missing required query parameters: type, project, repository'
+    });
+  }
+
+  if (type !== 'cumulative' && type !== 'new') {
+    throw createError({
+      statusCode: 400,
+      message: 'Invalid type parameter. Must be either "cumulative" or "new"'
+    });
+  }
+
   let data;

-  if (query.type === 'cumulative') {
+  if (type === 'cumulative') {
     data = cumulative;
   } else {
-    data = newStars;
+    data = newForks;
   }

   return data;
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export default defineEventHandler(async (event) => {
const query = getQuery(event);
let data;
if (query.type === 'cumulative') {
data = cumulative;
} else {
data = newStars;
}
return data;
});
export default defineEventHandler(async (event) => {
const query = getQuery(event);
const { type, project, repository } = query;
if (!type || !project || !repository) {
throw createError({
statusCode: 400,
message: 'Missing required query parameters: type, project, repository'
});
}
if (type !== 'cumulative' && type !== 'new') {
throw createError({
statusCode: 400,
message: 'Invalid type parameter. Must be either "cumulative" or "new"'
});
}
let data;
if (type === 'cumulative') {
data = cumulative;
} else {
data = newForks;
}
return data;
});

Comment on lines +135 to +142
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 240
},
{
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 600
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate date ranges in new stars data.

There are duplicate date ranges for '2024-12-23T00:00:00Z' to '2025-01-06T00:00:00Z'.

     {
       dateFrom: '2024-12-23T00:00:00Z',
       dateTo: '2025-01-06T00:00:00Z',
       stars: 240
     },
-    {
-      dateFrom: '2024-12-23T00:00:00Z',
-      dateTo: '2025-01-06T00:00:00Z',
-      stars: 600
-    },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 240
},
{
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 600
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 240
},

Comment on lines +42 to +49
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 2400
},
{
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 2600
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove duplicate date ranges in cumulative data.

There are duplicate date ranges for '2024-12-23T00:00:00Z' to '2025-01-06T00:00:00Z'.

     {
       dateFrom: '2024-12-23T00:00:00Z',
       dateTo: '2025-01-06T00:00:00Z',
       stars: 2400
     },
-    {
-      dateFrom: '2024-12-23T00:00:00Z',
-      dateTo: '2025-01-06T00:00:00Z',
-      stars: 2600
-    },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 2400
},
{
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 2600
dateFrom: '2024-12-23T00:00:00Z',
dateTo: '2025-01-06T00:00:00Z',
stars: 2400
},

@emlimlf emlimlf changed the title Improvement/stars and forks Stars and forks widgets Feb 24, 2025
@emlimlf emlimlf merged commit 5158e8c into main Feb 25, 2025
2 checks passed
@emlimlf emlimlf deleted the improvement/stars-and-forks branch February 25, 2025 01:53
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.

2 participants