Skip to content

Add WorkItems Rolledup Dates mutation GraphQL

What does this MR do and why?

Add WorkItems Rolledup Dates widget GraphQL mutation.

This will enable us to create the UI for using the WorkItem Rolledup Dates Widget. This widget will work similarly to Epics inheritable start/due dates:

  • This MR is just updating a single WorkItem. Another MR will follow to update the whole tree. I decided to break it to avoid a huge MR as I'm expecting to have a few events that might trigger the hierarchy of parent with the updates.
  • a fixed start/due date is when a user define the start/due date.
  • a rolledup start/due date is when the user don't define the start/due date directly on the WorkItem, instead we calculate it from the WorkItem children, looking up for the earliest start_date and the latest due_date from a child WorkItem or associated Milestone
  • On create
    • When a start_date is provided, we save these values and mark them as start_date_is_fixed (same for due_date)
  • On update
    • When the WorkItem have a fixed start/due date (start_date_is_fixed = true) and needs to update to a rolledup start/due date, the user can provide start_date_is_fixed = false.
    • When the WorkItem have a rolledup start/due date (start_date_is_fixed = false) and needs to update to a fixed start/due date
  • To calculate the earliest start_date and the latest due_date we use the WorkItems::Widgets::RolledupDatesFinder, which query an union of children's Work Item's start/due date fields, the children's WorkItems::DatesSource start/due date fields and the children's milestone's start/due date fields.
    • We're planning to migrate the WorkItem start/due date fields to WorkItems::DatesSource, for this reason we need to check on both places for now.

This is part of Improved Epic Experience on Work Items Framework (&9290)

Related to #434834 (closed)

Feature flag: work_items_rolledup_dates

Changelog: added

Queries

Minimum start date
SELECT
  "work_item_dates_sources"."start_date",
  "work_item_dates_sources"."start_date_sourcing_milestone_id",
  "work_item_dates_sources"."start_date_sourcing_work_item_id"
FROM
  (
    (
      SELECT
        "milestones"."start_date" AS start_date,
        "milestones"."id" AS start_date_sourcing_milestone_id,
        NULL AS start_date_sourcing_work_item_id
      FROM
        "issues"
        INNER JOIN "work_item_parent_links" ON "issues"."id" = "work_item_parent_links"."work_item_id"
        INNER JOIN "milestones" ON "milestones"."id" = "issues"."milestone_id"
      WHERE
        "work_item_parent_links"."work_item_parent_id" = 35
    )
    UNION
      (
        SELECT
          "work_item_dates_sources"."start_date" AS start_date,
          NULL AS start_date_sourcing_milestone_id,
          "work_item_dates_sources"."issue_id" AS start_date_sourcing_work_item_id
        FROM
          "issues"
          INNER JOIN "work_item_parent_links" ON "issues"."id" = "work_item_parent_links"."work_item_id"
          INNER JOIN "work_item_dates_sources" ON "work_item_dates_sources"."issue_id" = "issues"."id"
        WHERE
          "work_item_parent_links"."work_item_parent_id" = 35
      )
    UNION
      (
        SELECT
          "issues"."start_date" AS start_date,
          NULL AS start_date_sourcing_milestone_id,
          "issues"."id" AS start_date_sourcing_work_item_id
        FROM
          "issues"
          INNER JOIN "work_item_parent_links" ON "issues"."id" = "work_item_parent_links"."work_item_id"
        WHERE
          "work_item_parent_links"."work_item_parent_id" = 35
      )
  ) work_item_dates_sources
WHERE
  "work_item_dates_sources"."start_date" IS NOT NULL
ORDER BY
  "work_item_dates_sources"."start_date" ASC
LIMIT
  1

Explain:

Summary:
  
Time: 12.046 ms  
  - planning: 7.808 ms  
  - execution: 4.238 ms  
    - I/O read: 3.145 ms  
    - I/O write: 0.000 ms  
  
Shared buffers:  
  - hits: 9 (~72.00 KiB) from the buffer pool  
  - reads: 3 (~24.00 KiB) from the OS file cache, including disk I/O  
  - dirtied: 0  
  - writes: 0  
Maximum due date
SELECT
  "work_item_dates_sources"."due_date",
  "work_item_dates_sources"."due_date_sourcing_milestone_id",
  "work_item_dates_sources"."due_date_sourcing_work_item_id"
FROM
  (
    (
      SELECT
        "milestones"."due_date" AS due_date,
        "milestones"."id" AS due_date_sourcing_milestone_id,
        NULL AS due_date_sourcing_work_item_id
      FROM
        "issues"
        INNER JOIN "work_item_parent_links" ON "issues"."id" = "work_item_parent_links"."work_item_id"
        INNER JOIN "milestones" ON "milestones"."id" = "issues"."milestone_id"
      WHERE
        "work_item_parent_links"."work_item_parent_id" = 35
    )
    UNION
      (
        SELECT
          "work_item_dates_sources"."due_date" AS due_date,
          NULL AS due_date_sourcing_milestone_id,
          "work_item_dates_sources"."issue_id" AS due_date_sourcing_work_item_id
        FROM
          "issues"
          INNER JOIN "work_item_parent_links" ON "issues"."id" = "work_item_parent_links"."work_item_id"
          INNER JOIN "work_item_dates_sources" ON "work_item_dates_sources"."issue_id" = "issues"."id"
        WHERE
          "work_item_parent_links"."work_item_parent_id" = 35
      )
    UNION
      (
        SELECT
          "issues"."due_date" AS due_date,
          NULL AS due_date_sourcing_milestone_id,
          "issues"."id" AS due_date_sourcing_work_item_id
        FROM
          "issues"
          INNER JOIN "work_item_parent_links" ON "issues"."id" = "work_item_parent_links"."work_item_id"
        WHERE
          "work_item_parent_links"."work_item_parent_id" = 35
      )
  ) work_item_dates_sources
WHERE
  "work_item_dates_sources"."due_date" IS NOT NULL
ORDER BY
  "work_item_dates_sources"."due_date" DESC
LIMIT
  1

Explain:

Summary:
  
  
Time: 10.081 ms  
  - planning: 9.615 ms  
  - execution: 0.466 ms  
    - I/O read: 0.000 ms  
    - I/O write: 0.000 ms  
  
Shared buffers:  
  - hits: 12 (~96.00 KiB) from the buffer pool  
  - reads: 0 from the OS file cache, including disk I/O  
  - dirtied: 0  
  - writes: 0 

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Screenshots or screen recordings

Screenshots are required for UI changes, and strongly recommended for all other merge requests.

Before After

How to set up and validate locally

Numbered steps to set up and validate the change are strongly suggested.

Edited by Kassio Borges

Merge request reports