Visually mark cards as currently blocked (having linked unresolved dependencies)

Is there any way to display some kind of information that the card you're currently looking at is currently blocked? And by blocked, I mean that its issue is linked as dependent on another issue that is not yet resolved.

I am aware that I can open the card for more details, but this is incredibly bothersome when you have many cards on your board.

I've considered using workflows, but it seems too complex for Workflow Constructor, and with pure JavaScript, it's quite error-prone while doing by hand with changing statuses/tags, and I can sense some recursion problems with trying to iterate over linked issues to take off the blocking tag/status.

0
3 comments

Hello Tiritto ,

I suppose that the best way here is to indeed use workflows. You can use this rule as an example to avoid any recursion problems. The logic is “if the current issue is not resolved and has dependant issues, add a BLOCKED tag to dependant issues”. The second workflow would be “if the current issue becomes resolved and has dependant issues, remove the BLOCKED tag from the linked issues”.

0

Okay, I've made a workflow that more or less does what I would expect. There are still some holes in it (like when trying to unresolve already resolved issue), but for the most part it does the job.

on-blocking-issue-change

const entities = require('@jetbrains/youtrack-scripting-api/entities');

exports.rule = entities.Issue.onChange({
  title: 'Update Blocked Issues on Resolution',
  guard: (ctx) => {
    return ctx.issue.links['is required for'].size > 0;
  },
  action: (ctx) => {
    const issue = ctx.issue;
    const dependencies = issue.links['is required for'];
    if (dependencies.size <= 0) return;
    
    if (issue.becomesResolved) {
      dependencies.forEach(dependency => {
        updateBlockedStatus(dependency);
      })
    }
    
    else if (issue.becomesUnresolved) {
      dependencies.forEach(dependency => {
        dependency.addTag("Blocked");
      })
    }
  }
});

function hasUnresolvedBlockers(issue) {
  let hasUnresolvedBlockersBool = false;
  issue.links['depends on'].forEach(dependency => {
  	if (!dependency.isResolved) {
      return true;
    }
  });
  return hasUnresolvedBlockersBool;
}

function updateBlockedStatus(issue) {
  if (!hasUnresolvedBlockers(issue)) {
    issue.removeTag('Blocked');
  }
}

on-blocked-issue-change

const entities = require('@jetbrains/youtrack-scripting-api/entities');

exports.rule = entities.Issue.onChange({
  title: 'Auto-tag Blocked Issues',
  action: (ctx) => {
    const issue = ctx.issue;
    const blockedByLinks = issue.links['depends on'];
    const isIssueTaggedAsBlocked = issue.hasTag('Blocked');
    
    let isBlocked = false;
    if (blockedByLinks.size > 0) {
      blockedByLinks.forEach(dependency => {
        if (!dependency.isResolved) {
          isBlocked = true;
        }
      });
    }
    
    if (isBlocked && !isIssueTaggedAsBlocked) {
        issue.addTag('Blocked');
    } else if (!isBlocked && isIssueTaggedAsBlocked) {
        issue.removeTag('Blocked');
    }
  }
});

on-resolving-blocked

const entities = require('@jetbrains/youtrack-scripting-api/entities');
const workflow = require('@jetbrains/youtrack-scripting-api/workflow');

exports.rule = entities.Issue.onChange({
  title: 'Block users from resolving blocked issues',
  guard: (ctx) => {
    return ctx.issue.hasTag('Blocked');
  },
  action: (ctx) => {
    workflow.check(ctx.becomesResolved, 'Can\'t resolve blocked issue!', null);
  }
});
0

like when trying to unresolve already resolved issue

What happens when you're trying to do that?

0

Please sign in to leave a comment.