Added pr reviews to stats (#1404)

* Added pr reviews to stats

* Add 'show' query parameter

* Fix show test

* refactoring

* cleanup

* refactor: restructure stats-card code

---------

Co-authored-by: Markus <markus.tyrkko@gmail.com>
Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
Co-authored-by: rickstaa <rick.staa@outlook.com>
This commit is contained in:
Markus Tyrkkö 2023-06-15 10:35:09 +03:00 committed by GitHub
parent c86cc72df2
commit 1bb65ddc29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 112 additions and 34 deletions

View File

@ -37,6 +37,7 @@ export default async (req, res) => {
number_format,
border_color,
rank_icon,
show_total_reviews,
} = req.query;
res.setHeader("Content-Type", "image/svg+xml");
@ -95,6 +96,7 @@ export default async (req, res) => {
locale: locale ? locale.toLowerCase() : null,
disable_animations: parseBoolean(disable_animations),
rank_icon,
show_total_reviews: parseBoolean(show_total_reviews),
}),
);
} catch (err) {

View File

@ -306,6 +306,7 @@ You can provide multiple comma-separated values in the bg_color option to render
- `disable_animations` - Disables all animations in the card _(boolean)_. Default: `false`.
- `ring_color` - Color of the rank circle _(hex color)_. Defaults to the theme ring color if it exists and otherwise the title color.
- `number_format` - Switch between two available formats for displaying the card values `short` (i.e. `6.6k`) and `long` (i.e. `6626`). Default: `short`.
- `show_total_reviews` - Show total PR reviews _(boolean)_. Default: `false`.
> **Note**
> When hide_rank=`true`, the minimum card width is 270 px + the title length and padding.

View File

@ -85,6 +85,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
totalCommits,
totalIssues,
totalPRs,
totalReviews,
contributedTo,
rank,
} = stats;
@ -111,6 +112,7 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
locale,
disable_animations = false,
rank_icon = "default",
show_total_reviews = false,
} = options;
const lheight = parseInt(String(line_height), 10);
@ -136,40 +138,50 @@ const renderStatsCard = (stats = {}, options = { hide: [] }) => {
});
// Meta data for creating text nodes with createTextNode function
const STATS = {
stars: {
icon: icons.star,
label: i18n.t("statcard.totalstars"),
value: totalStars,
id: "stars",
},
commits: {
icon: icons.commits,
label: `${i18n.t("statcard.commits")}${
include_all_commits ? "" : ` (${new Date().getFullYear()})`
}`,
value: totalCommits,
id: "commits",
},
prs: {
icon: icons.prs,
label: i18n.t("statcard.prs"),
value: totalPRs,
id: "prs",
},
issues: {
icon: icons.issues,
label: i18n.t("statcard.issues"),
value: totalIssues,
id: "issues",
},
contribs: {
icon: icons.contribs,
label: i18n.t("statcard.contribs"),
value: contributedTo,
id: "contribs",
},
const STATS = {};
STATS.stars = {
icon: icons.star,
label: i18n.t("statcard.totalstars"),
value: totalStars,
id: "stars",
};
STATS.commits = {
icon: icons.commits,
label: `${i18n.t("statcard.commits")}${
include_all_commits ? "" : ` (${new Date().getFullYear()})`
}`,
value: totalCommits,
id: "commits",
};
STATS.prs = {
icon: icons.prs,
label: i18n.t("statcard.prs"),
value: totalPRs,
id: "prs",
};
STATS.issues = {
icon: icons.issues,
label: i18n.t("statcard.issues"),
value: totalIssues,
id: "issues",
};
STATS.contribs = {
icon: icons.contribs,
label: i18n.t("statcard.contribs"),
value: contributedTo,
id: "contribs",
};
// Extra stats items.
if (show_total_reviews) {
STATS.reviews = {
icon: icons.reviews,
label: i18n.t("statcard.reviews"),
value: totalReviews,
id: "reviews",
};
}
const longLocales = [
"cn",

View File

@ -27,6 +27,7 @@ export type StatCardOptions = CommonOptions & {
ring_color: string;
text_bold: boolean;
rank_icon: RankIcon;
show_total_reviews: boolean;
};
export type RepoCardOptions = CommonOptions & {

View File

@ -6,6 +6,7 @@ const icons = {
icon: `<path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"/>`,
contribs: `<path fill-rule="evenodd" d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"/>`,
fork: `<path fill-rule="evenodd" d="M5 3.25a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm0 2.122a2.25 2.25 0 10-1.5 0v.878A2.25 2.25 0 005.75 8.5h1.5v2.128a2.251 2.251 0 101.5 0V8.5h1.5a2.25 2.25 0 002.25-2.25v-.878a2.25 2.25 0 10-1.5 0v.878a.75.75 0 01-.75.75h-4.5A.75.75 0 015 6.25v-.878zm3.75 7.378a.75.75 0 11-1.5 0 .75.75 0 011.5 0zm3-8.75a.75.75 0 100-1.5.75.75 0 000 1.5z"></path>`,
reviews: `<path fill-rule="evenodd" d="M8 2c1.981 0 3.671.992 4.933 2.078 1.27 1.091 2.187 2.345 2.637 3.023a1.62 1.62 0 0 1 0 1.798c-.45.678-1.367 1.932-2.637 3.023C11.67 13.008 9.981 14 8 14c-1.981 0-3.671-.992-4.933-2.078C1.797 10.83.88 9.576.43 8.898a1.62 1.62 0 0 1 0-1.798c.45-.677 1.367-1.931 2.637-3.022C4.33 2.992 6.019 2 8 2ZM1.679 7.932a.12.12 0 0 0 0 .136c.411.622 1.241 1.75 2.366 2.717C5.176 11.758 6.527 12.5 8 12.5c1.473 0 2.825-.742 3.955-1.715 1.124-.967 1.954-2.096 2.366-2.717a.12.12 0 0 0 0-.136c-.412-.621-1.242-1.75-2.366-2.717C10.824 4.242 9.473 3.5 8 3.5c-1.473 0-2.825.742-3.955 1.715-1.124.967-1.954 2.096-2.366 2.717ZM8 10a2 2 0 1 1-.001-3.999A2 2 0 0 1 8 10Z"/>`,
};
/**

View File

@ -45,7 +45,8 @@ const GRAPHQL_STATS_QUERY = `
name
login
contributionsCollection {
totalCommitContributions
totalCommitContributions,
totalPullRequestReviewContributions
}
repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
totalCount
@ -185,6 +186,7 @@ const fetchStats = async (
const stats = {
name: "",
totalPRs: 0,
totalReviews: 0,
totalCommits: 0,
totalIssues: 0,
totalStars: 0,
@ -227,6 +229,8 @@ const fetchStats = async (
}
stats.totalPRs = user.pullRequests.totalCount;
stats.totalReviews =
user.contributionsCollection.totalPullRequestReviewContributions;
stats.totalIssues = user.openIssues.totalCount + user.closedIssues.totalCount;
stats.contributedTo = user.repositoriesContributedTo.totalCount;

View File

@ -18,6 +18,7 @@ export type RepositoryData = {
export type StatsData = {
name: string;
totalPRs: number;
totalReviews: number;
totalCommits: number;
totalIssues: number;
totalStars: number;

View File

@ -196,6 +196,32 @@ const statCardLocales = ({ name, apostrophe }) => {
vi: "Đã Đóng Góp (năm ngoái)",
se: "Bidragit till (förra året)",
},
"statcard.reviews": {
ar: "Total PR reviews",
cn: "Total PR reviews",
cs: "Total PR reviews",
de: "Total PR reviews",
en: "Total PR reviews",
bn: "Total PR reviews",
es: "Total PR reviews",
fr: "Total PR reviews",
hu: "Total PR reviews",
it: "Total PR reviews",
ja: "Total PR reviews",
kr: "Total PR reviews",
nl: "Total PR reviews",
"pt-pt": "Total PR reviews",
"pt-br": "Total PR reviews",
np: "Total PR reviews",
el: "Total PR reviews",
ru: "Total PR reviews",
"uk-ua": "Total PR reviews",
id: "Total PR reviews",
my: "Total PR reviews",
sk: "Total PR reviews",
tr: "Total PR reviews",
pl: "Total PR reviews",
},
};
};

View File

@ -12,6 +12,7 @@ const data_stats = {
repositoriesContributedTo: { totalCount: 61 },
contributionsCollection: {
totalCommitContributions: 100,
totalPullRequestReviewContributions: 50,
},
pullRequests: { totalCount: 300 },
openIssues: { totalCount: 100 },
@ -116,6 +117,7 @@ describe("Test fetchStats", () => {
totalCommits: 100,
totalIssues: 200,
totalPRs: 300,
totalReviews: 50,
totalStars: 300,
rank,
});
@ -146,6 +148,7 @@ describe("Test fetchStats", () => {
totalCommits: 100,
totalIssues: 200,
totalPRs: 300,
totalReviews: 50,
totalStars: 300,
rank,
});
@ -182,6 +185,7 @@ describe("Test fetchStats", () => {
totalCommits: 1000,
totalIssues: 200,
totalPRs: 300,
totalReviews: 50,
totalStars: 300,
rank,
});
@ -209,6 +213,7 @@ describe("Test fetchStats", () => {
totalCommits: 1000,
totalIssues: 200,
totalPRs: 300,
totalReviews: 50,
totalStars: 200,
rank,
});
@ -234,6 +239,7 @@ describe("Test fetchStats", () => {
totalCommits: 100,
totalIssues: 200,
totalPRs: 300,
totalReviews: 50,
totalStars: 400,
rank,
});
@ -259,6 +265,7 @@ describe("Test fetchStats", () => {
totalCommits: 100,
totalIssues: 200,
totalPRs: 300,
totalReviews: 50,
totalStars: 300,
rank,
});
@ -284,6 +291,7 @@ describe("Test fetchStats", () => {
totalCommits: 100,
totalIssues: 200,
totalPRs: 300,
totalReviews: 50,
totalStars: 300,
rank,
});

View File

@ -16,6 +16,7 @@ const stats = {
totalCommits: 200,
totalIssues: 300,
totalPRs: 400,
totalReviews: 50,
contributedTo: 500,
rank: { level: "A+", score: 40 },
};
@ -38,6 +39,9 @@ describe("Test renderStatsCard", () => {
expect(getByTestId(document.body, "contribs").textContent).toBe("500");
expect(queryByTestId(document.body, "card-bg")).toBeInTheDocument();
expect(queryByTestId(document.body, "rank-circle")).toBeInTheDocument();
// Default hidden stats
expect(queryByTestId(document.body, "reviews")).not.toBeInTheDocument();
});
it("should have proper name apostrophe", () => {
@ -68,6 +72,24 @@ describe("Test renderStatsCard", () => {
expect(queryByTestId(document.body, "issues")).toBeNull();
expect(queryByTestId(document.body, "prs")).toBeNull();
expect(queryByTestId(document.body, "contribs")).toBeNull();
expect(queryByTestId(document.body, "reviews")).toBeNull();
});
it("should show total reviews", () => {
document.body.innerHTML = renderStatsCard(stats, {
show_total_reviews: true,
});
expect(
document.body.getElementsByTagName("svg")[0].getAttribute("height"),
).toBe("220");
expect(queryByTestId(document.body, "stars")).toBeDefined();
expect(queryByTestId(document.body, "commits")).toBeDefined();
expect(queryByTestId(document.body, "issues")).toBeDefined();
expect(queryByTestId(document.body, "prs")).toBeDefined();
expect(queryByTestId(document.body, "contribs")).toBeDefined();
expect(queryByTestId(document.body, "reviews")).toBeDefined();
});
it("should hide_rank", () => {