Skip to content

Add filter argument to linkedItems field

Related to #416776 (closed)

What does this MR do and why?

This MR is part of the implementation of BE: Work Items - Linked (Related) Items (&10993 - closed) and still behind the feature flag :linked_work_items, disabled by default.

Following Add GraphQL query for linked work items (!126980 - merged) we want to add an option to filter the linked items by the link type.

The options for filtering are: RELATED, BLOCKS and BLOCKED_BY (the last two are only available on GitLab Starter license). This filter can be limited to querying all link types.

Also, this MR adds a new validation for work item links so no more than 100 items can be linked to a single work item.

Screenshots or screen recordings

This MR doesn't introduce any UI changes

Screen_Recording_2023-08-17_at_12.34.23

Query plans

In order to query linked work items by type this MR modifies Issue#related_issues** to add the link type to its query. The type param is optional and the query remains the same when omitted.

  • Existing query (type argument not provided)
SELECT
    issues.*,
    issue_links.id AS issue_link_id,
    issue_links.link_type AS issue_link_type_value,
    issue_links.target_id AS issue_link_source_id,
    issue_links.created_at AS issue_link_created_at,
    issue_links.updated_at AS issue_link_updated_at
FROM
    "issues"
    INNER JOIN issue_links ON (issue_links.source_id = issues.id
            AND issue_links.target_id = 1910)
        OR (issue_links.target_id = issues.id
            AND issue_links.source_id = 1910)
    ORDER BY
        issue_link_id
  • New queries: type is provided:
  1. work_item.related_issues(current_user, type: IssuableLink::TYPE_RELATES_TO) - query plan
Click to expand query
SELECT
    issues.*,
    issue_links.id AS issue_link_id,
    issue_links.link_type AS issue_link_type_value,
    issue_links.target_id AS issue_link_source_id,
    issue_links.created_at AS issue_link_created_at,
    issue_links.updated_at AS issue_link_updated_at
FROM
    "issues"
    INNER JOIN issue_links ON (issue_links.source_id = issues.id
            AND issue_links.target_id = 1910
            AND issue_links.link_type = 0)
        OR (issue_links.target_id = issues.id
            AND issue_links.source_id = 1910
            AND issue_links.link_type = 0)
    ORDER BY
        issue_link_id
  1. work_item.related_issues(current_user, type: IssuableLink::TYPE_BLOCKS) - query plan
Click to expand query
SELECT
    issues.*,
    issue_links.id AS issue_link_id,
    issue_links.link_type AS issue_link_type_value,
    issue_links.target_id AS issue_link_source_id,
    issue_links.created_at AS issue_link_created_at,
    issue_links.updated_at AS issue_link_updated_at
FROM
    "issues"
    INNER JOIN issue_links ON issue_links.target_id = issues.id
WHERE
    "issue_links"."source_id" = 1910
    AND "issue_links"."link_type" = 1
ORDER BY
    issue_link_id
  1. work_item.related_issues(current_user, type: IssuableLink::TYPE_IS_BLOCKED_BY) - query plan
Click to expand query
SELECT
    issues.*,
    issue_links.id AS issue_link_id,
    issue_links.link_type AS issue_link_type_value,
    issue_links.target_id AS issue_link_source_id,
    issue_links.created_at AS issue_link_created_at,
    issue_links.updated_at AS issue_link_updated_at
FROM
    "issues"
    INNER JOIN issue_links ON issue_links.source_id = issues.id
WHERE
    "issue_links"."target_id" = 1910
    AND "issue_links"."link_type" = 1
ORDER BY
    issue_link_id

We are also using one of these queries for a new validation that sets a max number of items that can be linked to a work item. For this, we need to check how many links the work item has without authorizing them:

work_item.unauthorized_linked_issues.size - query plan

Click to expand query
SELECT
    COUNT(*)
FROM
    "issues"
    INNER JOIN issue_links ON (issue_links.source_id = issues.id
            AND issue_links.target_id = 1910)
        OR (issue_links.target_id = issues.id
            AND issue_links.source_id = 1910)

** Note that work items are stored in the issues table and work item links are stored in issue_links table so these methods are shared.

How to set up and validate locally

  1. Enabled feature flag
Feature.enable(:linked_work_items)
  1. Using the Rails console, create 4 tasks and link them using the 3 different link types (take note of task's ID)
Click to expand
author, project = User.first, Project.first
wi_type = WorkItems::Type.find_by(base_type: 'task')
task = WorkItem.create!(title: "Source Task", project: project, author: author, work_item_type: wi_type)

related_task = WorkItem.create!(title: "Related Task", project: project, author: author, work_item_type: wi_type)
blocked_task = WorkItem.create!(title: "Blocked Task", project: project, author: author, work_item_type: wi_type)
blocking_task = WorkItem.create!(title: "Blocking Task", project: project, author: author, work_item_type: wi_type)

WorkItems::RelatedWorkItemLink.create!(source: task, target: related_task, link_type: 'relates_to')
WorkItems::RelatedWorkItemLink.create!(source: task, target: blocked_task, link_type: 'blocks')
WorkItems::RelatedWorkItemLink.create!(source: blocking_task, target: task, link_type: 'blocks')
  1. Visit https://gdk.test:3000/-/graphql-explorer in your GDK running locally and use the following query to fetch the linked tasks
Click to expand
query getLinkedITems {
  workItem(id: "gid://gitlab/WorkItem/<TASK_ID>") {
    widgets {
      ...on WorkItemWidgetLinkedItems {
        linkedItems(filter: RELATED) {
          edges {
            node {
              linkType
              workItem {
                title
              }
            }
          }
        }
      }
    }
  }
}
  1. Change the filter argument to BLOCKS and BLOCKED_BY and verify that only the correct link types are returned
  2. Remove the argument and verify that the response includes all link types (see screen recording for response examples).

MR acceptance checklist

This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.

Edited by Eugenia Grieff

Merge request reports