On a recent project, one of our developers came across the need to change the display of SLAs in JIRA Service Desk (JSD) from the hh:mm (hour) format to displaying days.
Why, you might ask, would a user want this type of display?
For most users, hours are, more often than not, perfectly suitable. In this case it was simply that the client was used to working with days as their default unit. And when you consider that SLAs can get very long, the day format can be preferable to hours (not least because it saves having to divide everything by 24...)
It seems like a pretty simple piece of functionality, but JSD doesn’t actually offer the option of changing from hours to days. (There's an enhancement request here, but it hasn’t yet been implemented). So, our developer found a solution.
Without knowing exactly how SLAs were calculated in JSD, it was assumed JSD kept the SLA value as hh:mm in its custom field.
This should have been easy: just grab the custom field value and convert to days by using a JIRA Misc Custom Fields calculated custom field (issue.get("customfield_xxxxx") / 24) = win!
Unfortunately, it wasn't that simple. When the value from from JSD's SLA custom field is extracted, all you get is a JSD class and a hash. This hash value is calculated by JSD and only rendered to become hh:mm when displayed with a JSD SLA custom field. In short, there wasn’t anything to manipulate the format in the back end. This left it to front end manipulation (and, as a result, a bit of a hack where there will likely be circumstances where it might not work).
To do this, the Message Custom Field found in the JIRA Toolkit Plugin was used so that AJS (Atlassian's take on JQuery) can be added to a web page. This is similar to how an Announcement Banner works but instead of being global it will only render the AJS for screens where you’ve added this Message Custom Field. This means you can have different AJS for different screens.
All that remained was to create an AJS script to grab the hh:ss value from what was being displayed by JSD, perform some string manipulation to convert into days then display that back on the issue view overwriting the original values.
From there, it was fairly straightforward. After locating the page elements (DOM) displaying the hh:mm value, a loop was used to find every single instance (there can be multiple SLAs). The conversion was performed - something along the lines of (mm/60 + hh)/24 - and the existing hh:mm value was overwritten in the page element. Your JSD should now be displaying values in days.
You'll find the code below...
// Version 1.0 // Can be placed in either the Announcement Banner to apply for the whole Jira instance // or placed in a Message Custom Edit field for specific project <script type="text/javascript"> AJS.$(document).ready(function($) { function modSLA() { // Search for all divs with .sla-tag // Loop through all SLAs (there can be multiple SLAs) and convert each of them to be displayed as days AJS.$(":root").find(".sla-tag").each(function( index, element ) { var dayRemaining = convertSLA($(this).find("span").text()); $(this).find("span").text(dayRemaining); }); // Search for all divs with .sla-view-info // Loop through all estimated or agreed SLAs (there can be multiple SLAs) and convert each of them to be displayed as days AJS.$(":root").find(".sla-view-info").each(function( index, element ) { var dayEstimated = convertEstimated($(this).find("span").parent().text()); $(this).find("span").parent().text("within " + dayEstimated + " days"); }); } modSLA(); // This is standard... need this upon any action to page JIRA.bind(JIRA.Events.NEW_CONTENT_ADDED, function(e, context, reason) { modSLA(); }); // Use this if you are going to use a Message Custom Edit field instead of Announcement banner AJS.$("#rowForcustomfield_10002").hide(); // Given the default text from SLA as HH:MM // This function converts it into number of days up to 2 decimal places // Probably don't require so many parsing of Float function convertSLA(textSLA) { var splitSLA = textSLA.split(":"); if (splitSLA[1] != null) { var hours = parseFloat(splitSLA[0]); var minutes = parseFloat(splitSLA[1]); var days = (hours + (minutes / 60)) / 24; var daySLA = days.toFixed(2); } else { var daySLA = textSLA; } return daySLA; } // Under each SLA you are shown the estimated or agreed SLA in number of hours, e.g. "within 72h" // This function converts it into number of days up to 2 decimal places function convertEstimated(textEst) { var splitSLA = textEst.split(" "); var daySLA = ""; if (splitSLA[1] != null) { var indexH = splitSLA[1].indexOf("h"); var hours = parseFloat(splitSLA[1].substring(0, splitSLA[1].indexOf("h"))); var days = hours / 24; daySLA = days.toFixed(2); } else { daySLA = textEst; } return daySLA; } }); </script>