Skip to content

Commit

Permalink
move modules into assets
Browse files Browse the repository at this point in the history
rm import
fix improper li nesting
break counts apparently
  • Loading branch information
SallyMcGrath committed Dec 6, 2024
1 parent 307b094 commit 697a88f
Show file tree
Hide file tree
Showing 2 changed files with 206 additions and 0 deletions.
80 changes: 80 additions & 0 deletions org-cyf-itp/assets/custom-scripts/reviews/common.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
export function daysToMilliseconds(days) {
return days * 24 * 60 * 60 * 1000;
}

function identifyAge(date) {
const millis = new Date() - date;
if (millis < daysToMilliseconds(7)) {
return "this week";
} else if (millis < daysToMilliseconds(7 * 4)) {
return "this month";
} else {
return "old";
}
}

// TODO: Pull these in from config.
export const modules = [
"Module-User-Focused-Data",
"Module-Structuring-And-Testing-Data",
"Module-Data-Groups",
"Module-Data-Flows",
];

class PR {
// status: one of: "Needs Review", "Reviewed", "Complete", "Closed", "Unknown"
constructor(url, number, userName, userUrl, title, module, createdAge, updatedAge, status) {
this.url = url;
this.number = number;
this.userName = userName;
this.userUrl = userUrl;
this.title = title;
this.module = module;
this.createdAge = createdAge;
this.updatedAge = updatedAge;
this.status = status;
this.comments = [];
}
}

class Comment {
constructor(userName, isPrAuthor, createdAt) {
this.userName = userName;
this.isPrAuthor = isPrAuthor;
this.createdAt = createdAt;
}
}

function getStatus(state, labels) {
// TODO: Check possibilities
if (state !== "open") {
return "Closed"
}
for (const possibleLabel of ["Needs Review", "Complete", "Reviewed"]) {
if (labels.some((label) => label.name === possibleLabel)) {
return possibleLabel;
}
}
return "Unknown";
}

export async function fetchPrs() {
const prs = [];
const responsePromises = [];
for (const module of modules) {
responsePromises.push(fetch(`https://github-issue-proxy.illicitonion.com/cached/120/repos/CodeYourFuture/${module}/pulls?state=all`).then((response) => response.json()));
}
const responsesByModule = await Promise.all(responsePromises);
for (let i = 0; i < responsesByModule.length; i++) {
const module = modules[i];
const responsePrs = responsesByModule[i];
for (const pr of responsePrs) {
const status = getStatus(pr.state, pr.labels);
const createdAt = new Date(Date.parse(pr["created_at"]));
const updatedAt = new Date(Date.parse(pr["updated_at"]));

prs.push(new PR(pr.html_url, pr.number, pr.user.login, pr.user.html_url, pr.title, module, identifyAge(createdAt), identifyAge(updatedAt), status));
}
}
return prs;
}
126 changes: 126 additions & 0 deletions org-cyf-itp/assets/custom-scripts/reviews/index.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
const awaitingReviewByAge = {};
const prsByModule = {};

// 400/700/900
function badness(name, count) {
if ((name === "old" || name == "this month") && count > 0) {
return 900;
}
if (name === "this week" && count > 20) {
return 900;
}
if (name === "this week" && count > 10) {
return 700;
}
return 400;
}

const ageToEmoji = {
"this week": "🟢",
"this month": "🟠",
old: "🔴",
};

function computeStatusClass(awaitingReview) {
const score = Math.max(
...Object.entries(awaitingReview).map(([name, count]) =>
badness(name, count)
)
);
if (score === 900) {
return "is-bad";
} else if (score === 700) {
return "is-medium";
} else {
return "is-good";
}
}

async function onLoad() {
for (const module of modules) {
awaitingReviewByAge[module] = {
"this week": 0,
"this month": 0,
old: 0,
};
prsByModule[module] = [];
}

for (const pr of (await fetchPrs()).filter(
(pr) => pr.status === "Needs Review"
)) {
awaitingReviewByAge[pr.module][pr.updatedAge]++;
prsByModule[pr.module].push(pr);
}
for (const module of modules) {
prsByModule[module].sort((l, r) => {
if (l.updatedAge > r.updatedAge) {
return 1;
} else if (l.updatedAge < r.updatedAge) {
return -1;
} else {
return l.number - r.number;
}
});
}

document.querySelector("#pr-list").innerText = "";

for (const module of modules) {
const awaitingReview = awaitingReviewByAge[module];
const totalPending = Object.values(awaitingReview).reduce(
(acc, cur) => acc + cur,
0
);

const overviewCard = document
.querySelector("template.overview-card")
.content.cloneNode(true);
overviewCard.querySelector(
".module"
).innerText = `${module} (${totalPending})`;
for (const [age, count] of Object.entries(awaitingReview)) {
const bucket = overviewCard.querySelector(
`.age-bucket.${age.replaceAll(" ", "-")} .count`
);
if (bucket) bucket.innerText = count;
if (bucket && badness(age, count) === 900) {
bucket.classList.add("problem");
}
}
overviewCard
.querySelector(".overview-card")
.classList.add(computeStatusClass(awaitingReview));
document.querySelector("#overview").appendChild(overviewCard);

if (totalPending) {
const modulePrList = document
.querySelector("template.pr-list")
.content.cloneNode(true);
modulePrList.querySelector(
".module"
).innerText = `${module} (${totalPending})`;
for (const pr of prsByModule[module]) {
const prInList = document
.querySelector("template.pr-in-list")
.content.cloneNode(true);

prInList.querySelector(".emoji").innerText = ageToEmoji[pr.updatedAge];

const prLink = prInList.querySelector("a.pr-link");
prLink.href = pr.url;
prLink.innerText = `${pr.title}`;

const userLink = prInList.querySelector("a.user-link");
userLink.href = pr.userUrl;
userLink.innerText = `${pr.userName}`;

prInList.querySelector(".pr-number").innerText = pr.number;
modulePrList.querySelector("ul.pr-list").appendChild(prInList);
}
document.querySelector("#pr-list").appendChild(modulePrList);
}
}
}

onLoad();

0 comments on commit 697a88f

Please sign in to comment.