3

1

Can anyone please suggest a BugMonkey script/css for highlighting overdue items in the task list? I'd love to do this, but having a bit of trouble getting it to work (I am not a css/javascript expert!)

Also, a script to highlight important items in some fashion would also be useful (but I can probably work that out if the first part of the question is answered)

Fog Creek Case FC1897092

flag

1 Answer

3

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; }
link|flag
If you'd like to have it enabled by default, you can simply change the value of fDefaultEnabled from false to true – Daniel LeCheminant May 17 2010 at 18:46
thanks! updated – adambox May 18 2010 at 14:49
Sorry for the delayed reply. This is great! Thank you. – ryanharris Aug 31 2010 at 17:49
This works only for US formatted dates, not for our Dutch 28-01-2010 13:57 format. Is there a generic FogBugz way to parse a date? – Michel de Ruiter Jan 20 2011 at 10:48
@Michel: Not really, but I've patched it up to work with the dd/mm/yyyy format – Daniel LeCheminant Jan 20 2011 at 15:17

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.