Map system defined statuses to custom statuses

What does this MR do and why?

When a user customizes the system defined lifecycle, we create a new lifecycle behind the scenes. We'll also create a new set of custom statuses equivalent to the system defined statuses which would then be the statuses that the user can customize.

In this MR, we add a column to store the system defined status it was converted from so that the changes take effect immediately without any migration. This also updates the code so that we account for the mapping when displaying the status.

References

How to set up and validate locally

  1. Enable the work_item_status_feature_flag feature flag.

  2. At this point, the namespace will use the system defined lifecycle. And this MR adds fallback code so that all existing issues and tasks would have the default statuses (To Do / Closed) depending on state.

  3. You can try explicitly setting the statuses so we can test the different scenarios

    Screenshot_2025-05-30_at_3.07.35_PM

  4. Create a custom lifecycle. The UI and mutations for this are still WIP so we do it via the Rails console:

     namespace = Project.find_by_full_path('flightjs/flight').root_ancestor
    
     open_status = WorkItems::Statuses::Custom::Status.create!(
       namespace: namespace,
       name: "Custom To do",
       color: "#737278",
       category: :to_do,
       converted_from_system_defined_status_identifier: 1
     )
     
     in_progress_status = WorkItems::Statuses::Custom::Status.create!(
       namespace: namespace,
       name: "Custom In Progress",
       color: "#737278",
       category: :in_progress,
       converted_from_system_defined_status_identifier: 2
     )
     
     in_review_status = WorkItems::Statuses::Custom::Status.create!(
       namespace: namespace,
       name: "Custom In Review",
       color: "#737278",
       category: :in_progress
     )
     
     closed_status = WorkItems::Statuses::Custom::Status.create!(
       namespace: namespace,
       name: "Custom done",
       color: "#108548",
       category: :done,
       converted_from_system_defined_status_identifier: 3
     )
     
     no_do_status = WorkItems::Statuses::Custom::Status.create!(
       namespace: namespace,
       name: "Custom Won't do",
       color: "#108548",
       category: :cancelled,
       converted_from_system_defined_status_identifier: 4
     )
     
     duplicate_status = WorkItems::Statuses::Custom::Status.create!(
       namespace: namespace,
       name: "Custom duplicate",
       color: "#DD2B0E",
       category: :cancelled,
       converted_from_system_defined_status_identifier: 5
     )
    
     lifecycle = WorkItems::Statuses::Custom::Lifecycle.create!(
       namespace: namespace,
       name: "Default",
       default_open_status: open_status,
       default_closed_status: closed_status,
       default_duplicate_status: duplicate_status,
       work_item_types: [WorkItems::Type.find_by(base_type: :issue), WorkItems::Type.find_by(base_type: :task)],
       statuses: [
         open_status,
         in_progress_status,
         in_review_status,
         closed_status,
         no_do_status,
         duplicate_status
       ]
     )
  5. When you reload the work item list, you should see the status names converted to the custom names for records with an explicit current status record and those that don't. You should also be able to set the new custom status values on these work items.

MR acceptance checklist

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

Edited by Heinrich Lee Yu

Merge request reports

Loading