Skip to content

Instantly share code, notes, and snippets.

@gbrian
Last active March 15, 2018 07:17
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 gbrian/99d2403441b0d3c4b59c2ff5b1b4f0c7 to your computer and use it in GitHub Desktop.
Save gbrian/99d2403441b0d3c4b59c2ff5b1b4f0c7 to your computer and use it in GitHub Desktop.
Trello gamification
/**
* REFERENCES
* - https://www.cssscript.com/demo/pure-css-circular-percentage-bar/
* - http://game-icons.net
* - https://developers.trello.com/reference/
*/
Array.prototype.do = function(cb){
return this.map(function(){
var args = [].slice.call(arguments);
cb.apply(this, args);
return args[0];
});
}
function TrelloBoard(options) {
this.options = Object.assign({
baseUrl : "https://trello.com/1/boards/",
agile:{
backlog: "Backlog",
ongoing: "Ongoing",
test: "Test",
done: "Ready for Deploy",
release: "Deployed",
impediment: "Impeeded"
}
}, options);
return this;
}
TrelloBoard.prototype.G_PostEvent = function(name, data){
$(window).trigger(name, data);
};
TrelloBoard.prototype.G_SubscribeEvent = function(name, cb){
$(window).on(name, cb);
};
TrelloBoard.prototype.extend = function(target, url, key){
return $.getJSON(url)
.then(data => {
if(key) target[key] = data;
else Object.assign(target, data);
return target;
});
}
TrelloBoard.prototype.buildAgileLists = function(board){
board.agile = {
getWorkingCards: function(user){
return this.ongoing
.concat(this.test)
.filter(c => !user ||
((!c.idMembers.length && !user.id) // Anonymous
|| c.idMembers.indexOf(user.id) !== -1));
}
};
var ids = Object.keys(this.options.agile)
.map(k => ({key: k, name: this.options.agile[k]}))
.map(kv => ({key: kv.key, list: board.lists.filter(l => l.name === kv.name)[0]}))
.filter(l => l)
.do(kv => board.agile[kv.key] = board.cards.filter(c => c.idList === kv.list.id))
.map(kv => kv.list.id);
// Remove cards thar are not on the agile list
board.cards = board.cards.filter(c => ids.indexOf(c.idList) !== -1);
return board;
};
TrelloBoard.prototype.enrichCards = function(board){
board.cards
.do(c => c.labels.map(l => l.set = (c.idLabels.indexOf(l.id) !== -1)))
.do(c => c.list = board.lists.filter(l => l.id === c.idList)[0].name);
return board;
};
TrelloBoard.prototype.getCards = function(list){
return this.cards.filter(c => c.list === list);
}
/**
* Loads board members, cards, profiles and latest activity
*/
TrelloBoard.prototype.load = function () {
var oThis = this;
// Base info
return this.extend(oThis, oThis.options.baseUrl + oThis.options.token)
// Board cards
.then(board => oThis.extend(board, oThis.options.baseUrl + oThis.id + "/cards", 'cards'))
// Board lists
.then(board => oThis.extend(board, oThis.options.baseUrl + oThis.id + "/lists", 'lists'))
.then(board => oThis.buildAgileLists(board))
.then(board => oThis.enrichCards(board))
// Board members
.then(board => oThis.extend(board, oThis.options.baseUrl + oThis.id + "/members", 'members'))
// Members profile
.then(board => board.members
.map(m => board.extend(m, "https://trello.com/1/members/"+m.id)
.then(m => {
m.getProfilePic = function(){
if(this.avatarHash)
return '<img src="https://trello-avatars.s3.amazonaws.com/'+this.avatarHash+'/30.png"/>';
return '<span class="member-initials member" title="'+''+'">'+this.initials+'</span>';
};
m.history = [];
m.references = [];
m.team = m.idOrganizations.indexOf(board.options.idOrganization) !== -1 ? "pigs": "chickens";
return m;
})))
.then(promises => $.when.apply($, promises).then(() => oThis))
// Cards activity
.then(board => board.cards
.map(c => board.extend(c, "https://trello.com/1/cards/"+c.id+"/actions?filter=all", 'history')
.then(c => c.idMemberCreator =
(c.history.filter(h => h.type === "createCard")[0]||{}).idMemberCreator)))
.then(promises => $.when.apply($, promises).then(() => oThis))
// Members activity
.then(board => {
var userRef = board.members.map(m =>({user:m, ref: "@"+m.username}));
var history = board.cards.map(c => c.history).reduce((a,b) => a.concat(b));
var refs = history.filter(h => h.type === "commentCard")
.map(h => userRef.filter(ur => h.data.text.indexOf(ur.ref) !== -1)
.map(ur => Object.assign(h, {
idMemberCreator: ur.user.id,
type: "memberReferenced"
}))).reduce((a,b) => a.concat(b));
history
.concat(refs)
.filter((value, index, self) => self.find(v => v.id === value.id).date >= value.date)
.map(a => (board.members.filter(m => m.id === a.idMemberCreator)[0]||{history:[]}).history.push(a));
return board;
})
// Anonymous
.then(board => {
board.members.push({
id:null,
fullName: "Anonymous",
initials: "??",
getProfilePic : function(){
return '<img src="https://www.shareicon.net/data/128x128/2016/02/19/721756_people_512x512.png"/>';
},
history:[],
idOrganizations:[board.options.idOrganization]
});
return board;
});
};
/**
* Badges section
* http://game-icons.net
*/
function TrelloBadges(){
this.BadgesImages = {
Backlog: "http://game-icons.net/icons/faithtoken/originals/svg/card-draw.svg",
Released: "http://game-icons.net/icons/lorc/originals/svg/octopus.svg",
Tested: "http://game-icons.net/icons/lorc/originals/svg/lightning-arc.svg",
Done: "http://game-icons.net/icons/delapouite/gui/svg/checklist.svg",
BugKiller: "http://game-icons.net/icons/skoll/originals/svg/spotted-bug.svg",
King: "http://game-icons.net/icons/delapouite/originals/svg/throne-king.svg",
Impediment: "http://game-icons.net/icons/delapouite/originals/svg/handcuffed.svg",
Create: "http://game-icons.net/icons/quoting/originals/svg/card-play.svg",
Comment: "http://game-icons.net/icons/skoll/originals/svg/talk.svg",
Update: "http://game-icons.net/icons/delapouite/originals/svg/upgrade.svg",
Attachment: "http://game-icons.net/icons/delapouite/originals/svg/paper-clip.svg",
Reference: "http://game-icons.net/icons/lorc/originals/svg/psychic-waves.svg",
Uncertain: "http://game-icons.net/icons/lorc/originals/svg/surprised-skull.svg"
};
};
function TrelloBadge(data){
this.data = data;
}
TrelloBadge.prototype.render = function(){
return $('<div class="badge '+this.data.type+ ' ' + this.data.labels +
'" title="'+this.data.title.replace(/"/gm, "")+
'">'+this.data.html+'</div>');
};
TrelloBadges.prototype.distinctActions = function(entries){
return entries.reverse()
.filter((value, index, self) => !self.slice(0, index).find(a => a.data.card.name === value.data.card.name))
.reverse();
};
TrelloBadges.prototype.agileBadge = function(user, list){
if(!user.history) console.log("no history", user);
return this.distinctActions(user.history.filter(a => (a.data.listAfter||{}).name === list));
}
TrelloBadges.prototype.createCardsBadge = function(settings){
var cardNames = settings.entries.map(e => (e.date||e.dateLastActivity).replace(/[TZ]/mg, " ") + ": " + (e.name||e.data.card.name).replace(/"/gm, "")).join("\r\n");
var bad = settings.score < 0;
return new TrelloBadge(Object.assign(settings,
{
type: 'cards',
html: '<img src="'+settings.image+'" title="'+settings.title+"\r\n"+cardNames+
'"/>' + (bad || settings.score > 1 ? '<span>'+ settings.score +'</span>':'')
}));
}
TrelloBadges.prototype.createProgressBadge = function(title, total, current, labels){
var p = parseInt(100 / total * current);
return new TrelloBadge({
type: 'progress',
labels: labels,
title: title,
score: current,
html: '<div class="c100 p'+p+' small">'+
'<span>'+p+'%</span>'+
'<div class="slice">'+
'<div class="bar"></div>'+
'<div class="fill"></div>'+
'</div>'+
'</div>'
});
}
// Convection: ttttBadge_XXXX calculates a badge from a user, where tttt is the user's team
TrelloBadges.prototype.pigsBadge_Released = function(user, trelloBoard){
var entries = this.agileBadge(user, trelloBoard.options.agile.release);
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You released ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Released,
labels: 'release',
score: entries.length
});
}
TrelloBadges.prototype.pigsBadge_Tested = function(user, trelloBoard){
var entries = this.agileBadge(user, trelloBoard.options.agile.test);
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You tested ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Tested,
labels: 'test',
score: entries.length
});
}
TrelloBadges.prototype.pigsBadge_Developed = function(user, trelloBoard){
var entries = this.agileBadge(user, trelloBoard.options.agile.done);
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You developed ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Done,
labels: 'done',
score: entries.length
});
}
TrelloBadges.prototype.pigsBadge_BugKiller = function(user, trelloBoard){
var entries = this.agileBadge(user, trelloBoard.options.agile.done)
.map(e => ({e: e, _card: trelloBoard.cards.filter(c => c.id === e.data.card.id)[0]}))
.filter(e => e._card &&
e._card.labels.filter(l => l.set && l.name.toLowerCase() === "bug"))
.map(e => e.e);
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You killed ' + entries.length + ' bugs!',
entries: entries,
image: this.BadgesImages.BugKiller,
labels: 'bug',
score: entries.length
});
}
TrelloBadges.prototype.pigsBadge_Impediment = function(user, trelloBoard){
var impedimentCardIds = trelloBoard.getCards(trelloBoard.options.agile.impediment)
.map(c => c.id);
var entries = this.agileBadge(user, trelloBoard.options.agile.impediment)
.filter(a => impedimentCardIds.indexOf(a.data.card.id) !== -1);
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'Hurry up! You have ' + entries.length + ' impediment!',
entries: entries,
image: this.BadgesImages.Impediment,
labels: 'impediment',
score: -1*entries.length
});
}
/*TrelloBadges.prototype.pigsBadge_King = function(user, trelloBoard){
var entries = this.agileBadge(user, trelloBoard.options.agile.release);
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'Congrats, you are the king now!',
entries: [],
image: this.BadgesImages.King,
labels: 'king',
score: 0
});
}*/
TrelloBadges.prototype.chickensBadge_Creator = function(user, trelloBoard){
var entries = this.distinctActions(user.history.filter(h => h.type.startsWith("create")));
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You created ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Create,
labels: 'create',
score: entries.length
});
}
TrelloBadges.prototype.chickensBadge_Comment = function(user, trelloBoard){
var entries = this.distinctActions(user.history.filter(h => h.type.startsWith("comment")));
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You commented on ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Comment,
labels: 'comment',
score: entries.length
});
}
TrelloBadges.prototype.chickensBadge_Update = function(user, trelloBoard){
var entries = this.distinctActions(user.history.filter(h => h.type.startsWith("update")));
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You edited ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Update,
labels: 'update',
score: entries.length
});
}
TrelloBadges.prototype.chickensBadge_Attachemnt = function(user, trelloBoard){
var entries = this.distinctActions(user.history.filter(h => h.type.startsWith("addAttachment")));
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You added attachments to ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Attachment,
labels: 'attachment',
score: entries.length
});
}
TrelloBadges.prototype.chickensBadge_References = function(user, trelloBoard){
var entries = this.distinctActions(user.history.filter(h => h.type.startsWith("memberReferenced")));
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'You have been named in ' + entries.length + ' cards!',
entries: entries,
image: this.BadgesImages.Reference,
labels: 'reference',
score: entries.length
});
}
TrelloBadges.prototype.chickensBadge_References = function(user, trelloBoard){
var entries = trelloBoard.cards
.filter(c => c.idMemberCreator === user.id)
.map(c => ({
c:c,
chars: c.desc.length + c.name.length,
comments: c.history.filter(h => h.type === "memberReferenced")
}))
.filter(metrics => metrics.chars < 50 ||
metrics.comments > 10)
.map(a => a.c);
if(entries.length === 0) return;
return this.createCardsBadge({
title: 'Don\'t know Rick, those ' + entries.length + ' cards look unclear!',
entries: entries,
image: this.BadgesImages.Uncertain,
labels: 'uncertain',
score: -1*entries.length
});
}
TrelloBadges.prototype.calculateBoardBage = function(trelloBoard){
var badges = [];
var agileCards = [];
var backLog = trelloBoard.getCards(trelloBoard.options.agile.backlog);
agileCards.push(backLog);
badges.push(this.createCardsBadge({
title: backLog.length + ' cards waiting on your backlog!',
entries: backLog,
image: this.BadgesImages.Backlog,
score: backLog.length
}));
var entries = trelloBoard.getCards(trelloBoard.options.agile.ongoing);
agileCards.push(entries);
badges.push(this.createCardsBadge({
title: 'Working on ' + entries.length + ' cards. Keep going!',
entries: entries,
image: this.BadgesImages.Done,
score: entries.length
}));
entries = trelloBoard.getCards(trelloBoard.options.agile.test);
agileCards.push(entries);
badges.push(this.createCardsBadge({
title: 'Testing ' + entries.length + ' cards.',
entries: entries,
image: this.BadgesImages.Tested,
score: entries.length
}));
entries = trelloBoard.getCards(trelloBoard.options.agile.impediment);
agileCards.push(entries);
badges.push(this.createCardsBadge({
title: 'Hurry up!!' + entries.length + ' impediments.',
entries: entries,
image: this.BadgesImages.Impediment,
score: entries.length
}));
var releasedCards = entries = trelloBoard.getCards(trelloBoard.options.agile.release);
agileCards.push(entries);
badges.push(this.createCardsBadge({
title: entries.length + ' released. WOW, KEEP IT GOING!',
entries: entries,
image: this.BadgesImages.Released,
score: entries.length
}));
agileCards = agileCards.reduce((a,b) => a.concat(b));
entries = agileCards.filter(c => c.labels.filter(l => l.set && l.name.toLowerCase() === "bug").length !== 0);
badges.push(this.createCardsBadge({
title: entries.length + ' dammit bugs!!',
entries: entries,
image: this.BadgesImages.BugKiller,
score: entries.length
}));
badges.push(this.createProgressBadge('Sprint progress',
agileCards.length,
releasedCards.length,
'sprint'));
trelloBoard.badges = badges;
};
TrelloBadges.prototype.calculateBadges = function(trelloBoard){
trelloBoard.members.map(user => this.calculateBadge(user, trelloBoard));
this.calculateBoardBage(trelloBoard);
return trelloBoard;
};
TrelloBadges.prototype.calculateBadge = function(user, trelloBoard){
var oThis = this;
user.badges = Object.keys(TrelloBadges.prototype)
.filter(k => k.startsWith(user.team + "Badge_"))
.map(k => (oThis[k]||console.log).call(oThis, user, trelloBoard, k))
.filter(b => b != undefined);
};
function TrelloGamification(options){
this.options = options;
};
TrelloGamification.prototype.randomBG = function(){
var imgs = ["https://swarmscblog.files.wordpress.com/2017/10/db70e2875e7fabede0c8ef2b343d3b51-wallpaper-art-wallpaper-backgrounds.jpg",
"https://datagame.io/files/2016/07/survey-gamification-examples.png",
"http://fistfuloftalent.com/wp-content/uploads/2015/02/gamification-lead-generation-BG20131217141557.jpg",
"http://groupvisual.io/designinganalytics/wp-content/uploads/2015/09/Gamification-Post-Header-02-1024x406.png",
"http://qode.pro/blog/wp-content/uploads/2015/01/Gamificaci%C3%B3n.jpg",
"https://www.amazecraze.com/wp-content/uploads/2016/06/pc-gaming-wallpapers-background-1280x720.jpg",
"https://i.imgur.com/JF1f8dGr.jpg",
"https://i.imgur.com/2shdwke.jpg",
"http://hddesktopwallpapers.in/wp-content/uploads/2015/07/mario-wallpaper-elegant-1080x608.jpg"];
return imgs[Math.floor(Math.random() * imgs.length)];
};
TrelloGamification.prototype.loading = function(){
/**
* .overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000;
filter:alpha(opacity=50);
-moz-opacity:0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
z-index: 10000;
display: inline block;
}
.overlay img{
display: block;
margin: 0 auto;
padding-top:100px;
}
<div class="overlay">
<img id="my-photo-id" src="http://cdn.sstatic.net/stackexchange/img/logos/so/so-logo.png" alt="Photo" data-photo-overlay="true" />
</div>
*/
var img = this.randomBG();
$('html')
.css("background-image", 'url("'+img+'")');
$('body').css('opacity',0);
return this;
};
TrelloGamification.prototype.loadingDone = function(){
var bgimg = $('html').css("background-image");
$('.body-board-view').get(0).style= "background-image: "+bgimg;
$('body').css('opacity',1);
return this;
};
TrelloGamification.prototype.addStyle = function(){
var style ='.trello-gamification .list-header {'+
'margin: 10px 0px 0px 10px;'+
'}'+
'.trello-gamification .list-wrapper {'+
'height: inherit;'+
'float: left;'+
'margin-bottom: 10px;'+
'}'+
'.gameboard {'+
'height: 2000px;'+
'width: 68%;'+
'overflow: hidden;'+
'float: left;'+
'}'+
'.js-list {'+
'width: 250px;'+
'float: left;'+
'margin: 0px 7px 7px 0;'+
'}'+
'.chickens .list {'+
'background-color: rgba(5, 90, 140, 0.79);'+
'color: white;'+
'}'+
'.pigs .list {'+
'background-color: rgba(182, 191, 182, 0.8);'+
'}'+
'.badge img {'+
'width: 32px;'+
'border-radius: 5px;'+
'border: solid 1px #ccc;'+
'}'+
'.badge span {'+
'position: absolute;'+
'right: 0px;'+
'bottom: 0;'+
'color: #000000;'+
'background-color: white;'+
'border-radius: 3px;'+
'font-size: 12px;'+
'padding: 0px 1px 0 2px;'+
'}'+
'.trello-gamification .badge {'+
'width: 34px;'+
'height: 34px;'+
'position: relative;'+
'}'+
'.trello-gamification-badges {'+
'background: rgba(220, 220, 220, 0.4);'+
'font-weight: bold;'+
'color: black;'+
'min-height: 40px;'+
'}'+
'.trello-gamification.board-canvas {'+
'padding: 5px;'+
'}'+
'.game-goals img {'+
'width: 72px;'+
'position: absolute;'+
'}'+
'.trello-gamification .game-goals{'+
'min-height: 82px;'+
'background-color: rgba(118, 212, 255, 0.4);'+
'margin: 0px 9px 8px 0;'+
'padding: 10px;'+
'border-radius: 3px;'+
'}'+
'.game-goals .badge {'+
'width: 73px;'+
'height: 73px;'+
'}'+
'.game-goals h2 {'+
'float: left;'+
'margin-right: 10px;'+
'color: #ffff;'+
'font-size: 2em;'+
'}'+
'.badge.progress {'+
'background-color: white;'+
'border-radius: 3px;'+
'}'+
'.progress .bar {'+
'z-index: 3;'+
'}'+
'.progress span {'+
'background-color: transparent;'+
'}'+
'.c100.small {'+
'font-size: 70px;'+
'margin: 3px;'+
'}'+
'.badge.release img{'+
'filter: invert(0) sepia(1) saturate(100) hue-rotate(322deg);'+
'}'+
'.badge.test img{'+
'filter: invert(0) sepia(1) saturate(100) hue-rotate(157deg);'+
'}'+
'.badge.done img{'+
'filter: invert(0) sepia(1) saturate(100) hue-rotate(41deg);'+
'}'+
'.badge.bug img{'+
'filter: invert(0) sepia(1) saturate(100) hue-rotate(408deg);'+
'}'+
'.badge.impediment img{'+
'invert(0) sepia(10) saturate(100) hue-rotate(178deg);'+
'}'+
'.badge.uncertain img{'+
'filter: invert(0) sepia(1) saturate(100) hue-rotate(322deg);'+
'}'+
'.member img {'+
'width: 30px;'+
'}'+
'.badge.king{'+
'display: none;'+
'}'+
'.master .badge.king{'+
'display: inline;'+
'}'+
'.master .list {'+
'background-color: rgba(176, 50, 165, 0.5);'+
'color: white;'+
'}'+
'.looser .list {'+
'background-color: rgba(0, 0, 0, 0.5);'+
'color: white;'+
'}'+
'.trello-gamification .pigs .list-cards {'+
'height: 78px;'+
'overflow: hidden;'+
'};'+
'.open-card-composer::before {'+
'content: "";'+
'height: 5px;'+
'position: absolute;'+
'left: 0;'+
'top: 0;'+
'background: linear-gradient(#277b84 2px, #ffffff00);'+
'width: 100%;'+
'}';
$('head')
.append('<link rel="stylesheet" href="https://www.cssscript.com/demo/pure-css-circular-percentage-bar/css/circle.css"/>')
.append('<style>'+style+'</style>');
};
TrelloGamification.prototype.addGoals = function(){
this.board.badges.map(g => this.board_goals.append(g.render()));
}
TrelloGamification.prototype.cleanBoard = function(){
this.loading();
this.addStyle();
this.board_canvas = $('.board-canvas').hide();
this.trello_gamification_board_canvas = $('<div class="trello-gamification board-canvas"/>');
this.trello_gamification_board_canvas.append(
this.trello_gamification_pigs = $('<div class="pigs gameboard"/>'));
this.trello_gamification_board_canvas.append(
this.trello_gamification_chickens = $('<div class="chickens"/>'));
this.board_canvas.parent().append(this.trello_gamification_board_canvas);
this.board_goals = $('<div class="game-goals"><h2>Sprint review</h2></div>');
this.trello_gamification_pigs.append(this.board_goals);
return this;
};
TrelloGamification.prototype.newList = function(data){
var list = $('<div class="js-list '+data.labels.join(" ")+'" id="'+data.id+'"><div class="list js-list-content">'+
'<div class="list-header js-list-header u-clearfix is-menu-shown">'+
'<div class="list-header-target js-editing-target">'+
'<div class="member js-member-on-card-menu">'+
data.getProfilePic()+
'</div>'+
'<h2>'+data.fullName+'</h2>'+
'</div>'+
'</div>'+
'<div class="list-cards u-fancy-scrollbar u-clearfix js-list-cards js-sortable ui-sortable">'+
'</div><div class="open-card-composer trello-gamification-badges"></div></div></div>');
return list;
}
TrelloGamification.prototype.newCard = function(data){
var card = $('<a class="list-card js-member-droppable aging-level-0 aging-regular ui-droppable" '+
'href="'+data.url+'" data-cardid="'+data.id+'" title="'+data.name.replace(/"/m, "")+
'"><div class="list-card-details"><div class="list-card-labels js-card-labels">'+
data.idLabels.map(l => data.labels.filter(label => label.id === l)[0])
.map(l => '<span class="card-label card-label-'+l.color+
' mod-card-front" title="'+l.name+'">'+l.name+'</span>')
.join("")+
'</div>'+
'<span class="list-card-title js-card-name" dir="auto">'+data.name+'</span></div></a>');
return card;
};
TrelloGamification.prototype.addUserCards = function(user){
var cardList = user.list.find('.list-cards');
user.cards.map(c => cardList.append(this.newCard(c)));
};
TrelloGamification.prototype.addBadges = function(user, container){
user.badges.map(b => container.append(b.render()));
};
TrelloGamification.prototype.loadPlayers = function(){
this.board.members
.do(m => m.cards = this.board.agile.getWorkingCards(m))
.map(m => m.team)
.filter((value, index, self) => self.indexOf(value) === index) // Distinct!
.do(team =>
this.board.members
.filter(m => m.team === team &&
(m.team == "pigs" || m.badges.length))
.do(user => user.score = user.badges.length ?
Math.max(user.badges.length, user.badges.map(b => b.data.score||1).reduce((a,b) => a+b)):
user.cards.length)
.sort((a,b) => a.score >= b.score ? -1: 1)
.do(user => user.labels = (user.labels||[]))
.do((user, index) => {
if(index === 0 && user.score !== 0) user.labels.push("master");
if(user.team == "pigs" && user.badges.length === 0) user.labels.push("looser");
user.labels.push(user.team);
})
.do(user => user.list = this.newList(user))
.do(user => user.team === "pigs" && this.addUserCards(user))
.do(user => (user.team === "pigs" ?
this.trello_gamification_pigs:
this.trello_gamification_chickens).append(user.list))
.do(user => this.addBadges(user, user.list.find('.trello-gamification-badges')))
)
return this;
};
TrelloGamification.prototype.init = function(){
var _init = () => this.init.call(this);
this.options.token = window.location.href.split("/")[4];
this.board = new TrelloBoard(this.options)
.load()
.then(b => this.board = new TrelloBadges().calculateBadges(b))
.then(() => this.cleanBoard())
.then(b => this.loadPlayers())
.then(() => this.addGoals())
.then(b => this.loadingDone())
.then(() => window.setTimeout(() => _init(), 10*60*1000));
return this;
};
var tg = new TrelloGamification({
idOrganization:'5a9a57e3707b7edef82549c6'
});
tg.init();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment