1

I understand that FogBugz standardized on hours, and there is a reason for this ... but for my setup, I'd really rather see things in a days/hours/mins format.

What can I do?

flag
we estimate cases with a minimum of 0.5 days.. i've had several requests from co-workers asking if we could switch the display format to days. it'd make much more sense to us than hours (25,5hours == 3 work days...). – stmax May 21 2010 at 19:48
The script makes an attempt to figure out how long your workday is (by calling GetWorkingSchedule().HoursPerDay()); if your workday was 8.5 hours long, the the script will report 3 d for fields that say 25.5 hours – Daniel LeCheminant May 21 2010 at 19:55

1 Answer

1

You can try this bugmonkey script, which attempts to convert the hours listing into days/hours/minutes:

$(document).ready(function() {
    // Don't bother if we can't see any times
    if (!$("#bugGrid,#idEstimateBlock").length) return;

    // Settings
    var sMenuText = "Toggle DHM Time Format";
    var sCookie = "useDHM";
    // Is DHM the default format?
    var fDefaultEnabled = false;
    // Should we reload the page, so the change is immediately visible?
    var fRefreshAfterChange = true;

    var sEnabled = getCookie(sCookie);
    // Convert the string to a boolean
    var fEnabled = sEnabled ? sEnabled === "true" : fDefaultEnabled;

    if ($("#idFilterOptInnerToolbarActions").length) {
        // 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);
            // Get rid of the "More" menu
            theMgr.hideAllPopups();

            if (fRefreshAfterChange) {
                window.location.reload();
            }
        })
        .prepend('<img src="images/icon-clock.gif" width="16" height="16">')
    }

    if (!fEnabled) return;

    var hoursPerDay = GetWorkingSchedule().HoursPerDay();

    var getClass = function(col) {
        return /col_\d+/.exec($(GridControl.getColFromRow($("#bugGrid tr:first")[0], col)).attr("class"));
    };

    var convertFloat = function(val) {
        return parseFloat(val.replace(",", "."));
    };

    var getHours = function(el) {
        // Only mess with entries that haven't been done yet
        if (!/hour|minute/.test($(el).text())) return;

        // If it has an hours attribute, we can just use that
        if ($(el).is("[hrs]")) return convertFloat($(el).attr("hrs"));

        // Read out the hours/minutes
        var rgT = /(?:([0-9.,]*)\s*h.*?)?\s*(?:([0-9]*)\s*m.*?)?/.exec($(el).text());
        if (rgT) return (rgT[1] ? convertFloat(rgT[1]) : 0) + (rgT[2] ? parseInt(rgT[2]) / 60 : 0);

        return null;
    };

    var fixTime = function(ix, el) {
        var hours = getHours(el);
        if (hours == null) return;

        var nDays = Math.floor(hours / hoursPerDay);
        var nHours = Math.floor(hours % hoursPerDay);
        var nMinutes = Math.floor(60 * (hours % 1));

        var sTime =
            (nDays ? nDays + "d " : "") +
            (nHours ? nHours + "h " : "") +
            ((nMinutes || (!nDays && !nHours)) ? nMinutes + "m" : "");

        // The current estimate is a link
        if ($(el).find("a").length) {
            $(el).find("a").text(sTime);
        }
        else {
            $(el).text(sTime);
        }
    };

    var updateGrid = function(target) {
        var elapsedClass = getClass(COLTYPE_ELAPSED_TIME);
        var origEstimateClass = getClass(COLTYPE_ESTIMATE_ORIGINAL);

        $(target)
        .find("fb\\:remain,fb\\:est,td." + elapsedClass + " span,td." + origEstimateClass + " span")
        .each(fixTime);
    };

    // If we are looking at a grid, update it
    if ($("#bugGrid").length) updateGrid("#bugGrid");
    // If we are looking at a bugview, update it
    if ($("#idEstimateBlock").length) $("#idEstimateBlock nobr").each(fixTime);

    // Patch updateGridRowEstimate so the time will be re-formatted after
    // the user enters a new estimate via the popup
    if (window.updateGridRowEstimate) {
        updateGridRowEstimate = (function(orig) {
            return function(elRow, a, b, c, d) {
                orig(elRow, a, b, c, d);
                updateGrid(elRow);
            };
        })(updateGridRowEstimate);
    }
});

This will add a "Toggle DHM Time Format" entry to your More menu; clicking it will switch between hours only format and D/H/M format. (Your preferences are saved in a cookie)

You could modify the script to customize the output or to change the way that things are calculated.

link|flag
Need to change: var nDays = Math.round(hours / hoursPerDay); var nHours = Math.round(hours % hoursPerDay); to: var nDays = Math.floor(hours / hoursPerDay); var nHours = Math.floor(hours % hoursPerDay); to prevent things like 20 hours being converted to 3d 4h which is off by one hour. – Mike May 22 2010 at 19:40
@Mike: Thanks; I did the same thing on the minutes to prevent a situation where you could have "60 minutes" displayed. – Daniel LeCheminant May 22 2010 at 21:43

Your Answer

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