Skip to content

Use GraphQL to load contribution analytics data

Alex Pennells requested to merge lazy-load-contribution-analytics into master

What does this MR do and why?

Issue: #376001 (closed)

Refactors the group contribution analytics page to lazy load via GraphQL, instead of dumping the data using provide. The existing approach can cause page timeouts for large groups (such as GitLab.org).

The Pushes, Merge Requests and Issues charts were using the provide context. The table at the bottom of the page was already loading it's data async via a REST api. To prevent loading the content twice, I've also updated the table to use the GraphQL data. In the process I migrated it to GlTable to simplify the component hierarchy.


The description for the Pushes chart had to be updated, since we no longer have the total commit count metric. This wasn't added to GraphQL due to efficiency concerns, so it was removed from the description line

- 1234 pushes, more than 23456 commits by 78 contributors.
+ 1234 pushes by 78 contributors.

Screenshots or screen recordings

Loading Screenshot_2023-01-17_at_3.34.54_PM
Error Screenshot_2023-01-17_at_3.35.10_PM
Pushes Screenshot_2023-01-17_at_3.07.50_PM
MRs Screenshot_2023-01-17_at_3.08.05_PM
Issues Screenshot_2023-01-17_at_3.08.19_PM
Table Screenshot_2023-01-17_at_3.08.44_PM
Table (Mobile) Screenshot_2023-01-17_at_3.09.20_PM

How to set up and validate locally

  1. Visit any group contribution analytics page such as http://gdk.test:3000/groups/flightjs/-/contribution_analytics
  2. Validate the charts/table work as expected

Setting up analytics data

Your page may look empty, so to test easily you can mock the GraphQL response by replacing the Apollo update() callback:

-        return data.group?.contributions.nodes || [];
+        const getRandomInt = () => Math.floor(Math.random() * 1000);
+        const mockUser = () => ({
+          user: {
+            name: Math.random().toString(36).substr(2, 20),
+            webUrl: `http://gdk.test:3000/${Math.random().toString(36).substr(2, 5)}`
+          },
+          repoPushed: getRandomInt(),
+          mergeRequestsApproved: getRandomInt(),
+          mergeRequestsClosed: getRandomInt(),
+          mergeRequestsCreated: getRandomInt(),
+          mergeRequestsMerged: getRandomInt(),
+          issuesClosed: getRandomInt(),
+          issuesCreated: getRandomInt(),
+          totalEvents: getRandomInt(),
+        });
+        const result = [...Array(100)].map(() => mockUser());
+        return result;

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Alex Pennells

Merge request reports