-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
124 lines (99 loc) · 4.47 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
const GITHUB_TOKEN = "";
const stylizePrList = () => {
if (!window.location.href.includes('/pulls')) return;
const headerContainer = document.querySelector(".Box-header .d-flex .flex-justify-between");
if (headerContainer.childNodes.length > 11) return;
const baseUrl = window.location.href;
const [_, __, ___, owner, repo] = baseUrl.split('/');
const getPRNumber = (element) => {
const prNumberTextElement = element.querySelector("span.opened-by");
if (prNumberTextElement) {
const prNumberText = prNumberTextElement.textContent.trim();
const prNumberMatch = prNumberText.match(/#\d+/);
return prNumberMatch ? parseInt(prNumberMatch[0].substring(1), 10) : null;
}
return null;
};
const fetchPRDetails = async (prNumber) => {
const headers = {
Authorization: `Bearer ${GITHUB_TOKEN}`,
Accept: "application/vnd.github.v3+json"
};
const prUrl = `https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}`;
const reviewsUrl = `${prUrl}/reviews`;
const [prResponse, reviewsResponse] = await Promise.all([
fetch(prUrl, {headers}),
fetch(reviewsUrl, {headers})
]);
const prData = await prResponse.json();
const reviewsData = await reviewsResponse.json();
const isInReview = prData.requested_reviewers.length > 0;
const isApproved = (reviewsData[reviewsData.length - 1])?.state === "APPROVED";
const isInFeedback = reviewsData.some(review => review.state === "CHANGES_REQUESTED");
const needRebase = !prData.rebaseable;
return {prNumber, isInReview, isInFeedback, needRebase, isApproved};
};
const createWarning = (text) => {
const warning = document.createElement("p");
warning.className = "warning-badge"
warning.textContent = text;
return warning
}
const addBadge = (element, {isInReview, isInFeedback, needRebase, isApproved}) => {
const statusContainer = element.querySelector(".d-flex");
const warningContainer = element.querySelector(".flex-auto")
const statusColumn = document.createElement("div");
statusColumn.style = "display: flex; justify-content: center; align-items: center;";
statusColumn.style.width = "150px";
const statusBadge = document.createElement("span");
statusBadge.className = "status-badge";
if (isApproved) {
statusBadge.className = "status-badge status-approved"
statusBadge.textContent = "Approved ✅";
} else if (isInReview) {
statusBadge.className = "status-badge status-review"
statusBadge.textContent = "Review 👀";
} else if (isInFeedback) {
statusBadge.className = "status-badge status-feedback"
statusBadge.textContent = "Feedback 🚨";
} else {
statusBadge.className = "status-badge status-wip"
statusBadge.textContent = "WIP 🚧";
}
if (needRebase) {
const warning = createWarning("Rebase needed ⛔️")
warningContainer.appendChild(warning)
}
statusColumn.appendChild(statusBadge);
statusContainer.appendChild(statusColumn);
};
const addHeader = () => {
const headerStatus = document.createElement("div");
headerStatus.className = "btn-link details-reset details-overlay d-inline-block text-center position-relative pr-3 pr-sm-0 px-3";
headerStatus.textContent = "Status";
headerStatus.style.width = "150px";
headerContainer.appendChild(headerStatus);
};
const processPRs = async () => {
const prElements = document.querySelectorAll(".js-issue-row");
addHeader();
const prDetailsPromises = Array.from(prElements).map(element => {
const prNumber = getPRNumber(element);
return prNumber ? fetchPRDetails(prNumber).then(details => ({element, details})) : null;
}).filter(p => p !== null);
const prDetails = await Promise.all(prDetailsPromises);
prDetails.forEach(({element, details}) => {
addBadge(element, details);
});
};
processPRs();
};
document.addEventListener("DOMContentLoaded", () => {
let currentUrl;
setInterval(() => {
if (!currentUrl || currentUrl !== window.location.href) {
stylizePrList()
currentUrl = window.location.href;
}
}, 1000)
})