Skip to content

Instantly share code, notes, and snippets.

@eranbetzalel
Created March 25, 2020 13:31
Show Gist options
  • Save eranbetzalel/2844d1c4099522f002f5d02673d1ef1c to your computer and use it in GitHub Desktop.
Save eranbetzalel/2844d1c4099522f002f5d02673d1ef1c to your computer and use it in GitHub Desktop.
JIRA - Add Issues Sum Row (userscript)
// ==UserScript==
// @name JIRA - Add Issues Sum Row
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Calculate the sum row for JIRA issues view
// @author You
// @match https://*.atlassian.net/issues/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
function getTotalSprintTime() {
const totalSprintHours =
$('div.ghx-issue .ghx-extra-field[data-tooltip^="Σ Original"] .ghx-extra-field-content')
.map((i, x) => $(x).text())
.toArray()
.reduce((x, y) => estimateToHours(x) + estimateToHours(y), 0);
return hoursToString(totalSprintHours);
}
function hoursToString(allHours) {
const weeks = Math.floor(allHours / (5 * 8));
const days = Math.floor((allHours % (5 * 8)) / 8);
const hours = allHours % 8;
const timeStringParts = [];
if (weeks > 0) timeStringParts.push(weeks + (weeks > 1 ? ' weeks' : 'week'));
if (days > 0) timeStringParts.push(days + (days > 1 ? ' days' : 'day'));
if (hours > 0) timeStringParts.push(hours + (hours > 1 ? ' hours' : 'hour'));
return timeStringParts.join(', ');
}
function estimateToHours(estimate) {
if (!estimate) return 0;
if (Number.isInteger(estimate)) return estimate;
return estimate.split(', ').reduce((x, y) => stringToHours(x) + stringToHours(y), 0);
}
function stringToHours(str) {
if (!str) return 0;
if (Number.isInteger(str)) return str;
const parts = str.split(' ');
const duration = parseInt(parts[0]);
switch (parts[1]) {
case 'week':
case 'weeks':
return duration * 8 * 5;
case 'day':
case 'days':
return duration * 8;
case 'hour':
case 'hours':
return duration;
}
}
function addSumRow() {
const sumRow = getSumRow();
let tr = '';
for (const sumRowKey in sumRow) {
tr += `<td class="${sumRowKey}">${sumRow[sumRowKey]}</td>`
}
const trHtml = `<tr id="exSumRow">${tr}</tr>`;
$('#exSumRow').remove();
$('#issuetable tbody').append(trHtml)
}
function getSumRow() {
const cells =
$('#issuetable tr.issuerow td')
.map((j, y) => ({className: $(y).attr('class'), text: $(y).text().trim()}))
.toArray();
const sumRow = {};
for (let i = 0; i < cells.length; i++) {
const cell = cells[i];
const columnNumber = getColumnNumber(cell.className, cell.text) || 0;
sumRow[cell.className] = columnNumber + (sumRow[cell.className] || 0);
}
for (const sumRowKey in sumRow) {
switch (sumRowKey) {
case 'aggregatetimeoriginalestimate':
sumRow[sumRowKey] = hoursToString(sumRow[sumRowKey]);
break;
}
}
return sumRow;
}
function getColumnNumber(className, text) {
switch (className) {
case 'aggregatetimeoriginalestimate':
return estimateToHours(text);
default:
return Number(text);
}
}
setInterval(() => addSumRow(),1000);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment