Skip to content

Instantly share code, notes, and snippets.

@drfloob
Last active September 22, 2023 00:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drfloob/870e63b9e0ce479d88ab1d9a18886f9e to your computer and use it in GitHub Desktop.
Save drfloob/870e63b9e0ce479d88ab1d9a18886f9e to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name Github gRPC status check sort
// @namespace https://github.com/
// @version 1.0.2
// @description Sort the status checks on a PR by Required status, Success status (errors first), and then by name
// @author hork
// @match https://github.com/*/*/pull/*
// @icon https://github.githubassets.com/favicons/favicon.svg
// @grant none
// @updateURL https://gist.github.com/drfloob/870e63b9e0ce479d88ab1d9a18886f9e/raw/github-grpc-status-check-sort.user.js
// @downloadURL https://gist.github.com/drfloob/870e63b9e0ce479d88ab1d9a18886f9e/raw/github-grpc-status-check-sort.user.js
// ==/UserScript==
// Derived from https://gist.github.com/skjnldsv/eb7b894ae996affde4a7d0e00e0d80a1
// Modified for better handling of the github.com/grpc/grpc repo.
(function () {
'use strict';
const targetNode = document.querySelector('.discussion-timeline-actions')
const config = { attributes: false, childList: true, subtree: false }
const callback = (mutationList) => {
if ([...mutationList[0].removedNodes].length > 0) {
// Find all children
const container = document.querySelector('.merge-status-list > div.merge-status-item').parentElement
const children = Array.prototype.slice.call(container.querySelectorAll('div.merge-status-item'), 0)
while (container.firstChild) {
container.removeChild(container.firstChild);
}
// Identify if a check is required
function isRequired(el) {
const strongEl = el.querySelector('div span.Label--primary');
if (!strongEl) return false;
return strongEl.textContent === 'Required';
}
function isNotRequired(el) { return !isRequired(el); }
// Identify if a check was successful
function isSuccess(el) {
return el.querySelector('svg.octicon-check') !== undefined;
}
// Identify if a check is pending
function isPending(el) {
return el.querySelector('svg.hx_dot-fill-pending-icon') !== undefined;
}
// Returns the check status in a numeric sortable order
function getStatus(el) {
// valued by sort order
const Status = {
Error: 0,
Pending: 1,
Success: 2
};
if (isSuccess(el)) return Status.Success;
if (isPending(el)) return Status.Pending;
return Status.Error;
}
function statusSort(a, b) {
const aStatus = getStatus(a);
const bStatus = getStatus(b);
if (aStatus == bStatus) a.innerText.localeCompare(b.innerText);
return aStatus < bStatus;
}
container.append(...children.filter(isRequired).sort(statusSort));
container.append(...children.filter(isNotRequired).sort(statusSort));
}
}
const observer = new MutationObserver(callback)
observer.observe(targetNode, config)
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment