Breadcrumbs

Visual progress of sub-tasks

📚

Return a visual bar depending on each sub-task status.

Configuration

Create a Custom smart text field and use the General parsing mode.

Expression

let subtasks = issue.subtasks|| [];
if (subtasks.length == 0){
    'No sub-tasks'
  }
  else
  {
    let doneSubtasks = subtasks.filter(s => s.status.name == "Done");
    let value = (doneSubtasks.length / subtasks.length) * 100;
    let percent =  value - value % 1 + (value % 1 >= 0.5 ? 1 : 0) ;
    let totalBlocks = 10;
    let filled = (percent / 100) * totalBlocks;
  	let full = filled - filled % 1 + (filled % 1 >= 0.5 ? 1 : 0);
    let bar = '🟩'.repeat(full) + '⬜️'.repeat(totalBlocks - full);
  `${bar} ${percent}%`
 }

Please, replace the status names as well as the completion emojis with the ones of your choice.

Details

1. What does the expression do?

This expression creates a visual progress bar that shows how many sub-tasks of a work item are completed (in the "Done" status). The bar uses colored emojis to represent progress and displays the percentage of completed sub-tasks.

2. Step-by-step breakdown

Let’s break down the expression step by step:

  1. Get the list of sub-tasks:

    let subtasks = issue.subtasks || [];
    
    • This retrieves all sub-tasks for the current work item. If there are no sub-tasks, it uses an empty list.

  2. Check if there are any sub-tasks:

    if (subtasks.length == 0) {
        'No sub-tasks'
    }
    
    • If there are no sub-tasks, it simply returns the message "No sub-tasks".

  3. Filter sub-tasks that are done:

    let doneSubtasks = subtasks.filter(s => s.status.name == "Done");
    
    • This creates a new list containing only the sub-tasks whose status is "Done".

  4. Calculate the completion percentage:

    let value = (doneSubtasks.length / subtasks.length) * 100;
    let percent = value - value % 1 + (value % 1 >= 0.5 ? 1 : 0);
    
    • It divides the number of completed sub-tasks by the total number of sub-tasks, multiplies by 100, and rounds to the nearest whole number.

  5. Set up the progress bar:

    let totalBlocks = 10;
    let filled = (percent / 100) * totalBlocks;
    let full = filled - filled % 1 + (filled % 1 >= 0.5 ? 1 : 0);
    
    • The progress bar will have 10 blocks (emojis). The number of filled blocks is based on the completion percentage, rounded to the nearest whole block.

  6. Build the visual bar:

    let bar = '🟩'.repeat(full) + '⬜️'.repeat(totalBlocks - full);
    
    • It creates a string with green blocks (🟩) for completed progress and white blocks (⬜️) for the remaining.

  7. Display the result:

    `${bar} ${percent}%`
    
    • The final output is the visual bar followed by the percentage of completion (e.g., 🟩🟩🟩⬜️⬜️⬜️⬜️⬜️⬜️⬜️ 30%).

3. Examples

  • If a work item has 4 sub-tasks and 2 are "Done":

    • Completion: 2/4 = 50%

    • Bar: 🟩🟩🟩🟩🟩⬜️⬜️⬜️⬜️⬜️ 50%

  • If a work item has 5 sub-tasks and all are "Done":

    • Completion: 5/5 = 100%

    • Bar: 🟩🟩🟩🟩🟩🟩🟩🟩🟩🟩 100%

  • If there are no sub-tasks:

    • Output: No sub-tasks

4. Real-life use cases

  • Sprint tracking: Show at a glance how many sub-tasks are completed for each work item in a sprint.

  • Team analysis: Visualize progress on tasks that are broken down into smaller steps.

    be2949e8-e660-4480-a435-cdf68c0bb4b5.png