Here's a BugMonkey script that one of our engineers, Daniel came up with:
When you install it
- You will need to activate it in the More menu.
- If you'd like to have it enabled by default, you can simply change the value of
fDefaultEnabled from false to true.
- You will need to add the 3 CSS classes at the top of the script to your site CSS in BugMonkey.
- If you don't want it to highlight cases due tomorrow or today, you can leave out those classes.
What it does
- It adds an item to the More menu on the case list page.
- It patches a built-in FogBugz function so that selecting and de-selecting items in the list works properly (instead of losing the highlight when you de-select).
- It's pretty verbose, so if you want, you can strip the comments or shrink it down significantly with closure compiler (use the "simple" optimizations to go from 3k to 1k).
Daniel tested it lightly in new versions of Firefox, Chrome, and IE. Let us know if it has any issues.
name: Highlight Overdue Cases
description: Highlights overdue cases in the case list
author: Daniel LeCheminant
version: 1.0.0.1
js:
// Settings
// Highlight the whole row, or just the Due column
var fWholeRow = true;
// Text that appears in the "More" menu
var sMenuText = "Toggle Due Date Highlighting";
// Whether the highlighting should be on or off by default
var fDefaultEnabled = false;
// If we're not looking at a bug list, we don't do anything
if (!$("#bugListContainer").length) return;
var dueClasses = {
late: "due-late",
today: "due-today",
tomorrow: "due-tomorrow"
};
var reToday = new RegExp(FB_TODAY, "i");
var reTomorrow = new RegExp(FB_TOMORROW, "i");
// Read out the cookie for the initial state, otherwise use the default
var sCookie = "fHighlightDue";
var sEnabled = getCookie(sCookie);
// Convert the string to a boolean
var fEnabled = sEnabled ? sEnabled === "true" : fDefaultEnabled;
var parseDate = (GetLocaleDate() == "dd/mm/yyyy") ?
function(s) {
return Date.parse(s.substr(3,2) + "/" + s.substr(0,2) + "/" + s.substr(6));
} :
function(s) {
return Date.parse(s);
};
var highlightDue = function(fHighlight) {
// Remove any existing highlighting
for (var dueClass in dueClasses) {
$("#bugListContainer td,tr")
.find("." + dueClasses[dueClass])
.removeClass(dueClasses[dueClass]);
};
if (fHighlight) {
// Let's find the where the Due column is
var dueClass = /col_\d+/.exec($("th:has(a[title=" + FB_DUE + "]):first").attr("class"));
// If the column isn't displayed, we can give up
if (!dueClass) return;
// Only check cells that are in the due column
var dueSel = "#bugListContainer td." + dueClass + ":contains(/)";
// Get the current time
var dtNow = new Date();
// Apply a CSS class that reflects the overdue state of the bug
$(dueSel)
.each(function() {
var sDue = $(this).text();
var dueClass =
reToday.test(sDue) ? "today" :
reTomorrow.test(sDue) ? "tomorrow" :
parseDate(sDue) < dtNow ? "late" :
null;
if (dueClass)
(fWholeRow ? $(this).parent().find("td") : $(this)).addClass(dueClasses[dueClass]);
});
}
}
// Add a link to the "More" menu
$('<a>')
.attr("href", "javascript:void(0)")
.text(sMenuText)
.appendTo("#idFilterOptInnerToolbarActions")
.wrap("<nobr>")
.click(function() {
// Toggle the highlight state, and remember it in a cookie
fEnabled = !fEnabled;
setCookie(sCookie, fEnabled);
// Apply the highlighting
highlightDue(fEnabled);
// Get rid of the "More" menu
theMgr.hideAllPopups();
})
.prepend('<img src="images/icon-clock.gif" width="16" height="16">')
// Patch the paintRow function so it doesn't screw up highlighting when the rows are
// checked/unchecked
if (window.paintRow) {
paintRow = function(row, color) {
$("td,th", row).css("background-color", (color == "#FBFBFB" || color == "#EBF0F4") ? "" : color);
}
}
highlightDue(fEnabled);
css:
tr.due-late td,td.due-late { background-color: #fbb; }
tr.due-today td,td.due-today { background-color: #fdd; }
tr.due-tomorrow td,td.due-tomorrow { background-color: #ffc; }