# Replace Links

This workflow checks the list of linked issues when a new link type is added and replaces existing links to an issue if another link type is used.

| Name | @jetbrains/youtrack-workflow-replace-links |
| Auto-attached | no |
| Modules |  [Replace existing link when a link that uses a different link type is added to the same issue](#replace-links) (on-change rule)  |

## Use Case

This workflow prevents you from having two different link types for the same issue, which can create a conflict in your process.

## Modules

This on-change rule checks the list of linked issues for a link to an issue that is added as a link when the issue is updated. If the new link is duplicated by a link to the same issue with a different link type, the link is replaced with the link specified in the update.

### Replace existing link when a link that uses a different link type is added to the same issue

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

function hasAddedLinks(links) {
  return links && links.added && links.added.isNotEmpty();
}

exports.rule = entities.Issue.onChange({
  title: 'Replace existing link when a link that uses a different link type is added to the same issue',
  action: (ctx) => {
    const issue = ctx.issue;

    const relatesTo = issue.links['relates to'];

    const duplicates = issue.links.duplicates;
    const isDuplicated = issue.links['is duplicated by'];

    const dependsOn = issue.links['depends on'];
    const isRequiredFor = issue.links['is required for'];

    const subtasks = issue.links['subtask of'];
    const parent = issue.links['parent for'];

    const allLinks = [duplicates, isDuplicated, relatesTo, dependsOn, subtasks, isRequiredFor, parent];

    function cleanup(target) {
      if (hasAddedLinks(target)) {
        target.forEach(function (issue) {
          allLinks.filter(function (link) {
            return link && link !== target;
          }).forEach(function (links) {
            links.delete(issue);
          });
        });
      }
    }

    if (hasAddedLinks(duplicates) || hasAddedLinks(relatesTo) || hasAddedLinks(dependsOn) || hasAddedLinks(subtasks)) {
      cleanup(duplicates);
      cleanup(relatesTo);
      cleanup(subtasks);
      cleanup(dependsOn);
    }
  }
});
```

