-
-
Save jasonmp85/1447877 to your computer and use it in GitHub Desktop.
Calculate Sprint Hours in Trello
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// copy this to a bookmark URL to use as a bookmarklet: | |
// javascript:document.getElementsByTagName('head')[0].appendChild(document.createElement('script')).setAttribute('src','https://raw.github.com/gist/1447877/trello_hours.js') | |
(function() { | |
var boardId = _.last(location.href.split('/')); | |
/** | |
* If a card starts with a string like "[4]", this method returns the | |
* first number in the brackets. Otherwise it returns zero. | |
*/ | |
var hoursFor = function(card) { | |
var matches = /^\[{1,2}(.*)\]{1,2}/.exec(card.name); | |
var hours = parseFloat(_.isEmpty(matches) ? '' : matches[1]); | |
return ((hours > 0) ? hours : 0) | |
}; | |
/** | |
* Returns a list of categories a card should be counted towards. At | |
* minimum, always returns the category 'total', so all cards count | |
* towards the total. | |
*/ | |
var categoriesFor = function(card) { | |
var labelMap = { green: 'done', yellow: 'done', orange: 'done' }; | |
return _(card.labels).chain() | |
.map(function(label) { return labelMap[label]; }) | |
.uniq().compact().value().concat(['total']); | |
}; | |
$.ajax({ | |
url: 'https://trello.com/data/board/' + boardId + '/current', | |
context: document.body, | |
success: function(data) { | |
/** | |
* Since marking a list as closed doesn't mark its member cards, | |
* we have to go through the boring task of finding which boards | |
* and lists are closed to find out whether a card is ignorable. | |
*/ | |
var isOpen = function(obj) { return !obj.closed; }; | |
var openBoardIds = _(data.boards).chain() | |
.filter(isOpen).pluck('_id').value(); | |
var openListIds = _(data.boards).chain() | |
.pluck('lists').flatten().compact() | |
.filter(isOpen).pluck('_id').value(); | |
var summedStats = _(data.cards).chain() | |
.filter(function(card) { // open cards in open lists on open boards | |
return isOpen(card) && _(openListIds).include(card.idList) && | |
_(openBoardIds).include(card.idBoard); | |
}).reduce(function(stats, card) { | |
var hoursSpent = hoursFor(card); | |
_(categoriesFor(card)).each(function(category) { | |
var categoryHours = stats[category] || 0; | |
stats[category] = categoryHours + hoursSpent; | |
}); | |
return stats; | |
}, {}).value(); | |
var message = "Sprint statistics:\n\n" | |
_(summedStats).each(function(hours, category) { | |
message += "\t" + category.toUpperCase() + "\n\t\t" + hours + "\n\n"; | |
}); | |
alert(message); | |
} | |
}); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment