Skip to content

Instantly share code, notes, and snippets.

@avaynshtok
Created December 2, 2011 23:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save avaynshtok/1425246 to your computer and use it in GitHub Desktop.
Save avaynshtok/1425246 to your computer and use it in GitHub Desktop.
calculate card hours in trello
// 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/1425246/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.color]; })
.uniq().compact().value().concat(['total']);
};
$.ajax({
url: 'https://trello.com/1/boards/' + boardId,
data: { lists: 'all', cards: 'all' },
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 lists
* are closed to find out whether a card is ignorable.
*/
var isOpen = function(obj) { return !obj.closed; };
var openListIds = _(data.lists).chain()
.filter(isOpen).pluck('id').value();
var summedStats = _(data.cards).chain()
.filter(function(card) { // open cards in open lists
return isOpen(card) && _(openListIds).include(card.idList);
}).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);
}
});
})();
@avaynshtok
Copy link
Author

To use create a new bookmark w/ the following text: javascript:document.getElementsByTagName('head')[0].appendChild(document.createElement('script')).setAttribute('src','https://raw.github.com/gist/1425246/trello_hours.js')

@avaynshtok
Copy link
Author

this uses parseFloat, so we'll have to convert half hour tasks from [1/2] to [.5]

@jasonmp85
Copy link

So @zook-ts pointed out that this doesn't cover timeboxed hours. Forking and fixing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment