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 theWorkItem
children, looking up for the earlieststart_date
and the latestdue_date
from a childWorkItem
or associated Milestone - On create
- When a
start_date
is provided, we save these values and mark them asstart_date_is_fixed
(same fordue_date
)
- When a
- 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 providestart_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
- When the
- To calculate the earliest
start_date
and the latestdue_date
we use theWorkItems::Widgets::RolledupDatesFinder
, which query an union of children's Work Item's start/due date fields, the children'sWorkItems::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 toWorkItems::DatesSource
, for this reason we need to check on both places for now.
- We're planning to migrate the
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:
- Recommendations:
✅ Looks good - Explain summary: https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/25410/commands/80482
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:
- Recommendations:
✅ Looks good - Explain summary: https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/25410/commands/80483
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