-
Notifications
You must be signed in to change notification settings - Fork 1
/
github_list_own_prs_in_repo.js
154 lines (145 loc) · 7.89 KB
/
github_list_own_prs_in_repo.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
// ==UserScript==
// @name GitHub - list own PRs in a repository
// @description List Your own (open) PRs in a repo with CI state for easy navigation
// @namespace https://git.sagidayan.com/sagi/greasemonkey-scripts
// @author Sagi Dayan
// @match https://github.com/*
// @version 1.0
// ==/UserScript==
(function () {
// Update These
const GITHUB_AUTH = '';
const GITHUB_USERNAME = '';
//
let currentRepo = '';
// fetch my prs
async function getPRs() {
const response = await fetch("https://api.github.com/graphql", {
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": `token ${GITHUB_AUTH}`
},
// "body": "{\"query\":\"{\\n user(login: \\\"" + GITHUB_USERNAME + "\\\") {\\n pullRequests(first: 100, states: OPEN, baseRefName:\\\"master\\\") {\\n totalCount\\n nodes {\\n createdAt\\n number\\n title\\n mergeable\\n url\\n labels(first: 10){\\n nodes{\\n color\\n description\\n name\\n \\n }\\n }\\n commits(last:1) {\\n nodes {\\n commit {\\n statusCheckRollup{\\n state\\n }\\n }\\n }\\n }\\n baseRefName\\n headRefName\\n repository{\\n nameWithOwner\\n }\\n }\\n pageInfo {\\n hasNextPage\\n endCursor\\n }\\n }\\n }\\n}\"}"
"body": "{\"query\":\"{\\n user(login: \\\"" + GITHUB_USERNAME + "\\\") {\\n pullRequests(first: 100, states: OPEN ) {\\n totalCount\\n nodes {\\n updatedAt\\n createdAt\\n number\\n title\\n mergeable\\n url\\n labels(first: 10){\\n nodes{\\n color\\n description\\n name\\n \\n }\\n }\\n commits(last:1) {\\n nodes {\\n commit {\\n statusCheckRollup{\\n state\\n contexts(last:40){\\n nodes {\\n ... on StatusContext{\\n state\\n context\\n description\\n }\\n }\\n }\\n }\\n }\\n }\\n }\\n baseRefName\\n headRefName\\n repository{\\n nameWithOwner\\n }\\n }\\n pageInfo {\\n hasNextPage\\n endCursor\\n }\\n }\\n }\\n}\"}"
});
const payload = await response.json();
const prs = payload.data.user.pullRequests.nodes.filter(pr => {
return pr.repository.nameWithOwner === currentRepo;
});
const main = document.getElementsByTagName('main')[0];
if (!main) return;
prs.forEach(pr => {
// Check if element Exists - if it does, remove and add updated one.
const prItem = document.getElementById(generatePrItemId(pr.number));
if (prItem) {
console.log('Item Found', prItem.id);
main.removeChild(prItem);
}
main.lastElementChild.insertBefore(createPrHTML(pr), main.lastElementChild.firstElementChild);
});
}
setInterval(() => {
const urlSplit = document.URL.split('/');
if (urlSplit.length !== 5) {
currentRepo = '';
return; // Not A base repo URL
}
const location = urlSplit.slice(-2).join('/')
if (location !== currentRepo) {
currentRepo = location;
getPRs();
}
}, 1000);
function createPrHTML(pr) {
const div = document.createElement('div');
const prState = pr.commits.nodes[0].commit.statusCheckRollup?.state || '';
const prStateColor = prState === 'FAILURE' ? 'red' : (prState === 'SUCCESS' ? 'green' : 'yellow');
const checksSum = pr.commits.nodes[0].commit.statusCheckRollup?.contexts.nodes.reduce((acc, check) => {
acc.total++;
if(check.state === 'SUCCESS') acc.success++;
return acc;
}, {total:0, success:0});
const checksSumStr = checksSum ? `Checks Passed: ${checksSum.success} / ${checksSum.total}` : '';
div.id = generatePrItemId(pr.number);
div.onclick = () => {
window.open(pr.url, '_blank');
}
div.className = "btn d-sm-flex Box mb-2 Box-body color-bg-secondary";
const lblElements = pr.labels.nodes.reduce((elements, lbl) => {
const colors = HexToRgbHsl(lbl.color);
return `${elements}
<a title="${pr.description}" data-name="${lbl.name}" style="--label-r:${colors.r};--label-g:${colors.g};--label-b:${colors.b};--label-h:${colors.h};--label-s:${colors.s};--label-l:${colors.l};" data-view-component="true" class="IssueLabel hx_IssueLabel width-fit mr-1">
<span class="css-truncate css-truncate-target width-fit">${lbl.name}</span>
</a>
`
}, '');
const lblInnerHtml = `
<div class="js-issue-labels flex-wrap">
${lblElements}
</div>
`
div.innerHTML = `
<div class="d-flex flex-auto">
<div class="flex-shrink-0 mr-2" >
<span title="Status" data-view-component="true" class="State" style="color:${prStateColor}">
<svg height="16" class="octicon octicon-git-pull-request" viewBox="0 0 16 16" version="1.1" width="16" aria-hidden="true"><path style="color:${prStateColor}" fill-rule="evenodd" d="M7.177 3.073L9.573.677A.25.25 0 0110 .854v4.792a.25.25 0 01-.427.177L7.177 3.427a.25.25 0 010-.354zM3.75 2.5a.75.75 0 100 1.5.75.75 0 000-1.5zm-2.25.75a2.25 2.25 0 113 2.122v5.256a2.251 2.251 0 11-1.5 0V5.372A2.25 2.25 0 011.5 3.25zM11 2.5h-1V4h1a1 1 0 011 1v5.628a2.251 2.251 0 101.5 0V5A2.5 2.5 0 0011 2.5zm1 10.25a.75.75 0 111.5 0 .75.75 0 01-1.5 0zM3.75 12a.75.75 0 100 1.5.75.75 0 000-1.5z"></path></svg> #${pr.number} - ${prState}
</span>
</div>
<p style="padding-top:5px" class="mb-0">
${pr.title}
</p>
<div class="flex-auto"></div>
${lblInnerHtml}
<div class="flex-auto"></div>
${checksSumStr}
</div>
`;
return div;
}
function generatePrItemId(prNumber) {
return `PR-${prNumber}`;
}
function HexToRgbHsl(_hex) {
let hex = _hex.replace(/#/g, '');
if (hex.length === 3) {
hex = hex.split('').map(function (hex) {
return hex + hex;
}).join('');
}
const result = /^([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})[\da-z]{0,0}$/i.exec(hex);
if (result) {
const r = parseInt(result[1], 16);
const g = parseInt(result[2], 16);
const b = parseInt(result[3], 16);
const r225 = r / 225;
const g225 = g / 225;
const b225 = b / 225;
const min = Math.min(r / 225, g / 225, b / 225);
const max = Math.max(r / 225, g / 225, b / 225);
const delta = max - min;
let h = 0, s = 0, l = 0;
if (max == min) {
h = 0;
} else if (r225 == max) {
h = (g225 - b225) / delta;
} else if (g225 == max) {
h = 2 + (b225 - r225) / delta;
} else if (b225 == max) {
h = 4 + (r225 - g225) / delta;
}
h = Math.min(h * 60, 360);
if (h < 0) h += 360;
l = (min + max) / 2;
if (max == min) s = 0;
else if (l <= 0.5) s = delta / (max + min);
else s = delta / (2 - max - min);
h = Math.round(h);
s = Math.round(s * 100);
l = Math.round(l * 100);
return { r, g, b, h, s, l };
} else {
return {};
}
}
})();