Skip to content

Instantly share code, notes, and snippets.

@felixfbecker
Created September 16, 2021 15:50
Show Gist options
  • Select an option

  • Save felixfbecker/c87090d052c3813d7e90b500e5aed562 to your computer and use it in GitHub Desktop.

Select an option

Save felixfbecker/c87090d052c3813d7e90b500e5aed562 to your computer and use it in GitHub Desktop.

Revisions

  1. felixfbecker created this gist Sep 16, 2021.
    67 changes: 67 additions & 0 deletions github_estimate_sum.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,67 @@
    // ==UserScript==
    // @name GitHub estimate sum
    // @namespace http://tampermonkey.net/
    // @version 0.1
    // @description try to take over the world!
    // @author You
    // @match https://github.com/orgs/sourcegraph/projects/*
    // @icon https://www.google.com/s2/favicons?domain=github.com
    // @grant none
    // ==/UserScript==

    (async function() {
    'use strict';

    await new Promise(resolve => setTimeout(resolve, 1000))

    const estimateHeader = [...document.querySelectorAll('[role="columnheader"]')].find(el => /estimate/i.test(el.textContent))
    if (!estimateHeader) {
    return
    }
    const estimateColumnIndex = [...estimateHeader.parentElement.children].indexOf(estimateHeader)

    const assigneeHeader = [...document.querySelectorAll('[role="columnheader"]')].find(el => /assignee/i.test(el.textContent))
    const assigneeColumnIndex = [...assigneeHeader.parentElement.children].indexOf(assigneeHeader)

    function getSum(group) {
    const cells = [...group.querySelectorAll(`[role="cell"]:nth-child(${estimateColumnIndex + 1})`)]
    const estimatesByAssignee = { all: 0 }
    for (const cell of cells) {
    const estimate = parseFloat(cell.textContent) || 0
    const row = cell.closest('[role="row"]')
    const assigneeCell = row.querySelector(`[role="cell"]:nth-child(${assigneeColumnIndex + 1})`)
    const assignees = [...assigneeCell.querySelectorAll('img[src^="https://avatars.githubusercontent.com/"]')].map(img => img.alt)
    for (const assignee of assignees) {
    estimatesByAssignee[assignee] = estimatesByAssignee[assignee] ?? 0
    estimatesByAssignee[assignee] += estimate
    estimatesByAssignee.all += estimate
    }
    }
    return estimatesByAssignee
    }

    const groups = document.querySelectorAll('[data-test-id^="table-group-"] > .Box-nv15kw-0.dHXePK')
    for (const group of groups) {
    const estimatesByAssignee = getSum(group)
    for (const [assignee, sum] of Object.entries(estimatesByAssignee)) {
    const badge = makeSumBadge(sum, 'CounterLabel-sc-1ubx52d-0 gLeezM')
    badge.style.marginLeft = '0.25rem'
    badge.style.marginRight = '0.5rem'
    group.querySelector('[data-test-id="table-group-name"]').parentNode.append(...(assignee === 'all' ? [] : [makeAvatar(assignee), ` ${assignee}: `]), badge)
    }
    }

    function makeAvatar(username) {
    return document.querySelector(`img[alt="${username}"]`).cloneNode()
    }

    function makeSumBadge(sum, className) {
    const span = document.createElement('span')
    span.className = className
    span.textContent = sum + 'd'
    return span
    }

    estimateHeader.childNodes[0].childNodes[0].append(' ', makeSumBadge(getSum(document).all, 'Label-sc-1t3ykp0-0 eHlHiL'))

    })();