Skip to content

Instantly share code, notes, and snippets.

@lovromazgon
Last active November 9, 2017 09:06
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 lovromazgon/7f2589530a36a8f355b05c087a82ee37 to your computer and use it in GitHub Desktop.
Save lovromazgon/7f2589530a36a8f355b05c087a82ee37 to your computer and use it in GitHub Desktop.
Tampermonkey script which adds the information about required vs worked hours in Tempo.io
// ==UserScript==
// @name JIRA Hours Diff
// @namespace https://github.com/lovromazgon
// @version 0.2.3
// @updateURL https://gist.github.com/lovromazgon/7f2589530a36a8f355b05c087a82ee37/raw
// @description Adds the information about required vs worked hours in Tempo.io
// @author Lovro Mažgon
// @match https://app.tempo.io/timesheets/jira/reports/*
// @grant none
// ==/UserScript==
var loadedHoursWorked = false;
var loadedHoursRequired = false;
var hoursWorked = 0;
var hoursRequired = 0;
var hoursDiff = 0;
var hoursRequiredDiv = null;
var hoursDiffDiv = null;
(function(open) {
XMLHttpRequest.prototype.open = function() {
this.addEventListener("readystatechange", function() {
if (this.readyState == 4 && this.responseURL == 'https://app.tempo.io/rest/tempo-timesheets/4/worklogs/search') {
mainWorklogs(JSON.parse(this.response));
} else if (this.readyState == 4 && this.responseURL == 'https://app.tempo.io/rest/tempo-timesheets/4/private/days/search') {
mainDays(JSON.parse(this.response)[0].days);
}
}, false);
open.apply(this, arguments);
};
})(XMLHttpRequest.prototype.open);
function mainWorklogs(worklogs) {
var secondsWorked = 0;
for (i = 0; i < worklogs.length; i++) {
secondsWorked += worklogs[i].timeSpentSeconds;
}
hoursWorked = secondsToHours(secondsWorked);
loadedHoursWorked = true;
main();
}
function mainDays(days) {
var secondsRequired = 0;
for (i = 0; i < days.length; i++) {
secondsRequired += days[i].requiredSeconds;
}
hoursRequired = secondsToHours(secondsRequired);
loadedHoursRequired = true;
main();
}
function main() {
if (!loadedHoursRequired || !loadedHoursWorked) {
return;
}
hoursDiff = Math.round((hoursWorked - hoursRequired) * 10) / 10;
console.log('I worked ' + hoursWorked + ' hours');
console.log('I should have worked ' + hoursRequired + ' hours');
console.log('Difference is ' + hoursDiff + ' hours');
var headerActions = getHeaderActions();
displayHoursRequired(headerActions);
displayHoursDiff(headerActions);
}
function getHeaderActions() {
var el = document.getElementsByClassName('tempo-header-wrapper')[0];
var childIndex = 1; // in the first round use 1 to get the second element
while (true) {
var child = null;
if (el.children.length === 0) {
// no children
break;
} else if (el.children.length == 1) {
// if it is the only child use it
child = el.children[0];
} else {
// in the first round use 1 to get the second element
// all other rounds use 0 to get the first element
child = el.children[childIndex];
childIndex = 0;
}
if (child.tagName == 'DIV') {
el = child;
} else {
break;
}
}
return el;
}
function displayHoursRequired(headerActions) {
if (!hoursRequiredDiv) {
hoursRequiredDiv = headerActions.lastChild.cloneNode(true);
headerActions.appendChild(hoursRequiredDiv);
}
hoursRequiredDiv.innerHTML = ' / ' + hoursRequired + 'h';
hoursRequiredDiv.style.color = 'grey';
hoursRequiredDiv.style.margin = '0 5px';
}
function displayHoursDiff(headerActions) {
if (!hoursDiffDiv) {
hoursDiffDiv = headerActions.lastChild.cloneNode(true);
headerActions.appendChild(hoursDiffDiv);
}
var sign;
var color;
if (hoursDiff >= 0) {
sign = '+';
color = 'green';
} else {
sign = '';
color = 'red';
}
hoursDiffDiv.innerHTML = ' (' + sign + hoursDiff + ')';
hoursDiffDiv.style.color = color;
}
function secondsToHours(seconds) {
return Math.round(seconds / 60 / 60 * 10) / 10;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment