Skip to content

Instantly share code, notes, and snippets.

@shuhei
Last active December 20, 2015 08:49
Show Gist options
  • Save shuhei/6103788 to your computer and use it in GitHub Desktop.
Save shuhei/6103788 to your computer and use it in GitHub Desktop.
Show remaining hours for each team member on Kanban page of Redmine Backlogs plugin. Works as a Chrome user script.
(function () {
if (location.href.indexOf('taskboards') === -1) return;
showResult(accumulateHours());
hookTaskRefreshed();
function hookTaskRefreshed() {
window.addEventListener('message', function (e) {
if (e.data.type === 'task:refreshed') showResult(accumulateHours());
});
injectScript("RB.Task.refreshed = function () { window.postMessage({ type: 'task:refreshed' }, '*'); };");
}
function accumulateHours() {
var tasks = Array.prototype.slice.call(document.querySelectorAll('.task'));
return tasks.map(function (task) {
return {
userName: task.querySelector('.assigned_to_id .t').innerText,
hours: parseFloat(task.querySelector('.remaining_hours').innerText) || 0
}
}).reduce(function (acc, task) {
acc[task.userName] = (acc[task.userName] || 0) + task.hours;
return acc
}, {});
}
function showResult(userHours) {
var texts = [];
var totalHours = 0;
for (var userName in userHours) {
texts.push((userName || '(全体)') + ': ' + userHours[userName] + ' 時間');
totalHours += userHours[userName];
}
texts.sort();
var boxId = 'remaining-hours-summary';
var box = document.getElementById(boxId);
if (box) {
box.innerHTML = '';
} else {
box = createBox();
box.id = boxId;
document.getElementById('taskboard').appendChild(box);
}
box.appendChild(createHeading());
box.appendChild(createList(texts));
box.appendChild(createTotal(totalHours));
}
function createBox() {
var box = document.createElement('div');
applyStyles(box, {
width: '150px',
position: 'absolute',
top: '0px',
right: '20px',
zIndex: '300',
backgroundColor: '#fcfcfc',
padding: '7px 10px',
border: '1px solid #ccc',
opacity: '0.8',
borderRadius: '3px'
});
return box;
}
function createHeading() {
var heading = document.createElement('h4');
heading.innerText = '残り時間';
applyStyles(heading, {
marginBottom: '5px'
});
return heading;
}
function createTotal(totalHours) {
var total = document.createElement('p');
total.innerText = '計 ' + totalHours + ' 時間';
applyStyles(total, {
borderTop: '1px dotted #bbb',
textAlign: 'right',
margin: '5px 0 0',
padding: '5px 0 0'
});
return total;
}
function createList(texts) {
var ul = document.createElement('ul');
texts.forEach(function (text) {
var li = document.createElement('li');
li.innerText = text;
ul.appendChild(li);
});
applyStyles(ul, {
margin: '0',
padding: '0',
listStyleType: 'none',
textAlign: 'right'
});
return ul;
}
function injectScript(scriptContent) {
var script = document.createElement('script');
script.textContent = scriptContent;
document.head.appendChild(script);
}
function applyStyles(elem, styles) {
for (var k in styles) {
elem.style[k] = styles[k];
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment