Configure a breadcrumb to organise your linked issues in JIRA


Posted by
Jérémie MARTINEZ

May 22, 2015

An increasing number of JIRA issues require the setting up of links across several hierarchical levels, resulting in a plethora of issues.

You can create this type of organisation with the help of some add-ons. Exocet, for example, provides operations for issue creation and tables listing links between issues. However, none of the existing solutions provide a single view of the whole picture.  If we imagine a 3-levels issue architecture, when positioned on the 3rd level issue, a link towards the 2nd level issue will be displayed (provided by JIRA or enriched with Exocet), but we won’t have any more information about the 1st level issue.

To fill this voide, let’s see how to create a dynamic ‘breadcrumb’. It will display a hierarchical view of the issue and so allow you the access to the “parents” issues.

How to create a breadcrumb ?

Pre-requisite :the free add-on Script Runner must be installed. The “Scripted Field” custom field will be used intensively in this blog.

To illustrate this case, we will take the example of expense report management :

For an ongoing IT project, a consultant can create one or several expense reports. For each one of them, the expense type will have to be specified (Restaurant, Parking, mileage expenses and so on).

From a conceptual point of view, this is what we obtain :

MCD_Blog

We will use 3 “standard” issue types so that we are not limited to the classical subtasks system, which only offers only two levels of issue.

Create your issues hierarchy

3 issues will be used to demonstrate this use case :

  • Issue WPM-27 with “Project” type will be our “level 1” :

Blog_01

  • Issue WPM-28 with “Expenses Report” type will be our “level 2” :

Blog_02

 

  • Issue WPM-30 with “Mileage expense” type will be our “level 3” :

Blog_03

These issues are linked as follows : 

  • WPM-28 is WPM-27’s “Expense report” :

Blog_04

  • WPM-30 is WPM-28’s expense type :

Blog_05

  Exocet tables are configured : 

  • An “Expense report” table displays the expense reports created for this project.

Blog_06

  • An “expense type” table displays the list of expenses for each expense report.

Blog_07

In a “real” implementation, we will have to add custom field to calculate sums at the Expense report level (Sum of the Expense report) and/or at the project level (Total sum of the Expense reports). An example of “Scoring field” is available in the following blog.

Create and configure a Scripted Field custom field

Create a “Navigation Path” custom field with “Scripted Field” Type and add it to the project’s screenviews.

Then, in the “Scripted Field” menu, associate the following script to the field you’ve just created :

import com.atlassian.jira.ComponentManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.ManagerFactory

enableCache = {-> false}

def componentManager = ComponentManager.getInstance()
def issueLinkManager = componentManager.getIssueLinkManager()

String navPath

String separator = " > "
String urlJIRA1 = "<a class='issue-link' href='http://localhost:8080/browse/"
String urlJIRA2 = "'>"
String urlJIRA3 = "</a>"

//If issue type is "Level 2" (id = 10104) and issue link is "L1 to L2" (id = 10130)
if(issue.getIssueTypeId().equals("10104")){
    issueLinkManager.getInwardLinks(issue.id).each {issueLink ->
        if (issueLink.issueLinkType.id == 10130) {
            def linkedIssue = issueLink.sourceObject
            navPath = urlJIRA1+linkedIssue.key+urlJIRA2+linkedIssue.key+urlJIRA3+separator+issue.key
        }
    }
}

//If issue type is "Level 3" (id = 10200) and issue link is "L3 to L2" (id = 10031)
if(issue.getIssueTypeId().equals("10200")){
    issueLinkManager.getInwardLinks(issue.id).each {issueLink2ndLevel ->
        //Get Issue in 2nd Level
        if (issueLink2ndLevel.issueLinkType.id == 10031) {
            def linkedIssue2ndLevel = issueLink2ndLevel.sourceObject
            //Get Issue in First level
            //If issue type is "Level 2" (id = 10104) and issue link is "L1 to L2" (id = 10130)
            if(linkedIssue2ndLevel.getIssueTypeId().equals("10104")){
                issueLinkManager.getInwardLinks(linkedIssue2ndLevel.id).each {issueLinkFirstLevel ->
                    if (issueLinkFirstLevel.issueLinkType.id == 10130) {
                        def linkedIssueFirstLevel = issueLinkFirstLevel.sourceObject
                        navPath = urlJIRA1+linkedIssueFirstLevel.key+urlJIRA2+linkedIssueFirstLevel.key+urlJIRA3+separator+urlJIRA1+linkedIssue2ndLevel.key+urlJIRA2+linkedIssue2ndLevel.key+urlJIRA3+separator+issue.key
                    }
                }
            }
        }
    }
}

return navPath
You must adapt the script depending on your own issue type ID and link type ID.

How to use your breadcrumb

Then, your breadcrumb appears in your issue’s view and is now working in level 2 and level 3 issues.

  • Example in the level 2 :

Blog_08

You can now access issue WPM-27  from issue WPM-28 :

Blog_09

  • Example in the level 3 :

Blog_10

You can also return to issue WPM-27 or to issue WPM-28 from issue WPM-30.

Blog_11

Linked issues hierarchically organised

This is a very simple example to implement in your JIRA instances to obtain the view of the extent of the linked issue and to allow your users to browse quickly and simply between issues.

Does this match one of your needs ? Feel free to try it and share your feedback and suggestions in the comment box!