// ==UserScript==
// @name TFS Taskboard Filters
// @description Adds coloring and filtering functions for TFS2015-16
// @namespace COMDSPDSA
// @author Dan Overlander
// @license none
// @version 9
// @include */tfs/*/TaskBoard*
// @include */tfs2/*/TaskBoard*
// @require https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @require https://greasyfork.org/scripts/23115-tampermonkey-support-library/code/Tampermonkey%20Support%20Library.js?version=730858
// @require https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js
// ==/UserScript==
// Since v08: Removes Tamper Global script dependency.
// Since v07: Tamperlibary link updated
// Since v06: moving out setTamperIcon
// Since v05: scriptName bug fixed.
// Since v04: updates for TFS2018
// Since v03: updating tm support library
// Since v02: Adds total remaining hours to top of screen
// missing } on an addGlobalStyle call
(function() {
'use strict';
var TIMEOUT = 750,
colors = {
bug: 'FF3300',
test: 'FF9D00',
analysis: '12A59C',
development: '9933FF'
},
global = {
ids: {
scriptName: 'TFS Taskboard Filters',
prefsName: 'taskboardFiltersPrefs'
},
prefs: {},
handlePrefsLocally: true,
isMouseMoved: false,
triggerElement: '.id-title-container'
},
toggle = {
isResetting: false,
areClassesAdded: false,
areButtonsAdded: false
},
page = {
initialize: function () {
setTimeout(function () {
page.addClasses();
tm.addClasses();
tm.setTamperIcon(global);
page.tagTiles();
}, TIMEOUT);
},
addClasses: function () {
if (!toggle.areClassesAdded) {
toggle.areClassesAdded = true;
// border shading for tbTiles
tm.addGlobalStyle('.witTypeBug { border-left:0px !important; backgroundremoved:#FFCBBE !important; }');
tm.addGlobalStyle('.witTypeBug .tbTileContent {border-left: 5px solid #' + colors.bug + ' !important');
tm.addGlobalStyle('.witTypeTest { border-left:0px !important; backgroundremoved:#FFE5CC !important; }');
tm.addGlobalStyle('.witTypeTest .tbTileContent {border-left: 5px solid #' + colors.test + ' !important;');
tm.addGlobalStyle('.witTypeAnalysis { border-left:0px !important; backgroundremoved:#90DAD5 !important; }');
tm.addGlobalStyle('.witTypeAnalysis .tbTileContent {border-left: 5px solid #' + colors.analysis + ' !important;');
tm.addGlobalStyle('.witTypeDevelopment { border-left:0px !important; backgroundremoved:#E3C7FF !important; }');
tm.addGlobalStyle('.witTypeDevelopment .tbTileContent {border-left: 5px solid #' + colors.development + ' !important; }');
// top-level buttons
tm.addGlobalStyle('.taskFilters a { color: black; margin-left:2em; padding: .1em .8em; border-radius: 5px; font-size: .9em; }');
tm.addGlobalStyle('.taskFilters a:hover { color:inherit; text-decoration:inherit; }');
tm.addGlobalStyle('.taskFilters a.Development { background: #9933FF; }');
tm.addGlobalStyle('.taskFilters a.Analysis { background: #12A59C; }');
tm.addGlobalStyle('.taskFilters a.Testing { background: #FF9D00; }');
tm.addGlobalStyle('.taskFilters a.Bugs { background: #FF3300; }');
tm.addGlobalStyle('.taskFilters a.Total:hover { text-decoration: none; cursor: default; }');
tm.addGlobalStyle('.taskFilters a.off { opacity:0.4; }');
}
},
tagTiles: function () {
var $taskFilters = $('.taskFilters');
if ($taskFilters.length === 0)
{
$taskFilters = $('<span class="taskFilters" />');
$('#iteration-board-title-id').append($taskFilters);
$taskFilters.empty();
var filterTasks = function() {
var taskType = $(this).data('taskType');
$(this).toggleClass('off');
$('.' + taskType).toggle();
};
$taskFilters.append($('<a title="Remaining hours assigned to existing development tasks" />')
.addClass('Development')
.data('taskType', 'witTypeDevelopment')
.append('Tasks')
.click(filterTasks));
$taskFilters.append($('<a title="case insensitive: BUG-, BUG -, Defect, [B], [D]" />')
.addClass('Bugs')
.data('taskType', 'witTypeBug')
.append('Defects')
.click(filterTasks));
$taskFilters.append($('<a title="case insensitive: Analysis, Analyze, Analyse, Discovery, SPIKE-, [A], [S]." />')
.addClass('Analysis')
.data('taskType', 'witTypeAnalysis')
.append('Analysis')
.click(filterTasks));
$taskFilters.append($('<a title="case insensitive: Test, [T]" />')
.addClass('Testing')
.data('taskType', 'witTypeTest')
.append('Testing')
.click(filterTasks));
$taskFilters.append('<a class="Total">Total</a>');
}
var devWorkRemaining = 0;
var analysisWorkRemaining = 0;
var testingWorkRemaining = 0;
var bugWorkRemaining = 0;
$(".ui-droppable .tbTile").each(function() {
var $this = $(this);
var $title = $('.title', this);
var $content = $('.tbTileContent', this);
var titleText = $title.text();
var assignedTo = $('.assignedTo', this).text();
var workRemaining = $('.witRemainingWork', this).text().replace(' h', '') * 1;
if (tm.isTagIn(titleText, ['[T]', 'test', 'SDET', 'TEST-', 'TEST - '])) {
$this.addClass('witTypeTest');
testingWorkRemaining += workRemaining;
} else if(tm.isTagIn(titleText, ['[S]', '[A]', 'SPIKE-', 'SPIKE -', 'discovery', 'analyse', 'analyze', 'analysis'])) {
$this.addClass('witTypeAnalysis');
analysisWorkRemaining += workRemaining;
} else if(tm.isTagIn(titleText, ['defect', '[D]', '[B]', 'BUG-', 'BUG - '])) {
$this.addClass('witTypeBug');
bugWorkRemaining += workRemaining;
} else {
$this.addClass('witTypeDevelopment');
devWorkRemaining += workRemaining;
}
//if (assignedTo == tfsContext.currentUser) {
// $this.addClass('witMyWork');
//}
});
$('.devWorkRemaining').remove();
$('.analysisWorkRemaining').remove();
$('.testingWorkRemaining').remove();
$('.bugWorkRemaining').remove();
$('.totalWorkRemaining').remove();
$('a.Development').append(' <span class="devWorkRemaining">[' + devWorkRemaining + ']</span>');
$('a.Analysis').append(' <span class="analysisWorkRemaining">[' + analysisWorkRemaining + ']</span>');
$('a.Testing').append(' <span class="testingWorkRemaining">[' + testingWorkRemaining + ']</span>');
$('a.Bugs').append(' <span class="bugWorkRemaining">[' + bugWorkRemaining + ']</span>');
$('a.Total').append(' <span class="totalWorkRemaining">[' + (devWorkRemaining + analysisWorkRemaining + testingWorkRemaining + bugWorkRemaining) + ']</span>');
}
};
/*
* Global functions
*/
function initScript () {
tm.getContainer({
'el': global.triggerElement,
'max': 100,
'spd': 1000
}).then(function($container){
page.initialize();
});
}
initScript();
$(document).mousemove(function(e) {
if (!global.isMouseMoved) {
global.isMouseMoved = true;
setTimeout(function() {
global.isMouseMoved = false;
}, TIMEOUT * 2);
initScript();
}
});
})();