Marc Saleiko (ee9bf3a2) at 18 Mar 15:24
Allow creation of items of custom type
Marc Saleiko (b5783540) at 18 Mar 14:06
Allow creation of items of custom type
Marc Saleiko (c02c1f8c) at 18 Mar 10:21
Allow creation of items of custom type
... and 366 more commits
Updated merge commit message to Update custom work item type error messages
I think it's fine for now
Issue: #592841
This change improves the validation error messages for custom work item types. Previously, when validation errors occurred (like missing required fields), the system would return a generic "Validation failed" message. Now it returns cleaner, more user-friendly error messages by extracting just the specific validation errors without the technical "Validation failed" prefix.
The code also consolidates duplicate test cases that were checking icon validation errors into a shared test pattern, making the tests more maintainable.
Limit
| Before | After |
|---|---|
![]() |
![]() |
Reserved Names
| Before | After |
|---|---|
![]() |
![]() |
work_item_configurable_types
http://gdk.test:3000/groups/<your-group>/-/settings/work_items/#js-work-item-types-settings
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
@daniyalAD thanks for working on this
Setting to auto-merge to unblock
Fix undercoverage errors in CreateService
Follow-up to !226095 to address undercoverage errors reported in the pipeline.
Changes:
@stefanosxan
@cngo thanks for working on this
Question: @cngo to me it looks like we continue to use the type[] query param, but instead of using a string we now use the id which we'll convert into a global id which will then send a query with the workItemTypeIds filter. I think that works fine. Some thoughts:
type=issue, this will now break. Because issue is not an id, we'll construct a global id like gid://gitlab/WorkItems::Type/issue which won't work.type query param and translate it to workItemTypeIds instead of using workItemTypeIds throughout the flow? Honest question, because I might not have all the context. @cngo I think this is a valid point. It's not severe because it gives you the same result (you're only interested in the id here, right?).
The provider is the way to go in specs if you want your assertion to be namespace aware (context aware) and we'll also introduce a decorator pattern that tells you whether a type is enabled or disabled. If we only need the id, we can use the system-defined type directly instead
Marc Saleiko (0ba798a2) at 18 Mar 07:39
Merge branch 'da-handle-validation-archived-types' into 'master'
... and 1 more commit
Marc Saleiko (290cddcd) at 18 Mar 07:39
@aslota thanks for another overnight-merge
Issue: #588973
This change improves how GitLab manages work item types by making the system smarter about counting limits and handling archived items.
The main updates include:
The changes ensure that users can better manage their work item types without hitting unexpected limits, while maintaining system performance by enforcing reasonable boundaries. Archived types are now properly excluded from limit calculations, and the system provides clearer feedback when operations would violate the constraints.
| Before (Unarchiving does not respect the limit) | After (Validation error if limit exceeded) |
|---|---|
![]() |
![]() |
# For testing, temporarily change MAX_TYPE_PER_PARENT to 10 in ee/app/models/work_items/types_framework/custom/type.rb.
org = Organizations::Organization.first
# Create one active type (9 system + 1 = 10, at limit)
active = WorkItems::TypesFramework::Custom::Type.create!(
name: "Active Type",
icon_name: :work_item_feature,
organization: org,
namespace: nil
)
# Create an archived type (shouldn't count toward limit)
archived = WorkItems::TypesFramework::Custom::Type.create!(
name: "Archived Type",
icon_name: :work_item_feature,
organization: org,
namespace: nil,
archived: true
)
# Test 1: Creating new type should fail (at limit)
new_type = WorkItems::TypesFramework::Custom::Type.new(
name: "Should Fail",
icon_name: :work_item_feature,
organization: org,
namespace: nil
)
puts "New type valid: #{new_type.valid?}" # false
puts new_type.errors.full_messages # "Organization can only have a maximum of 10 work item types."
# Test 2: Archive the active type
active.update!(archived: true)
# Test 3: Now creating should succeed (archived types don't count)
new_type2 = WorkItems::TypesFramework::Custom::Type.new(
name: "Should Succeed",
icon_name: :work_item_feature,
organization: org,
namespace: nil
)
new_type2.valid? # true
# Test 4: Unarchiving should fail when at limit
new_type2.save!
archived.archived = false
archived.valid? # false
# Expected error: "Archived Cannot unarchive because the maximum limit of 10 work item types has been reached."
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Issue: #588973
This change improves how GitLab manages work item types by making the system smarter about counting limits and handling archived items.
The main updates include:
The changes ensure that users can better manage their work item types without hitting unexpected limits, while maintaining system performance by enforcing reasonable boundaries. Archived types are now properly excluded from limit calculations, and the system provides clearer feedback when operations would violate the constraints.
| Before (Unarchiving does not respect the limit) | After (Validation error if limit exceeded) |
|---|---|
![]() |
![]() |
# For testing, temporarily change MAX_TYPE_PER_PARENT to 10 in ee/app/models/work_items/types_framework/custom/type.rb.
org = Organizations::Organization.first
# Create one active type (9 system + 1 = 10, at limit)
active = WorkItems::TypesFramework::Custom::Type.create!(
name: "Active Type",
icon_name: :work_item_feature,
organization: org,
namespace: nil
)
# Create an archived type (shouldn't count toward limit)
archived = WorkItems::TypesFramework::Custom::Type.create!(
name: "Archived Type",
icon_name: :work_item_feature,
organization: org,
namespace: nil,
archived: true
)
# Test 1: Creating new type should fail (at limit)
new_type = WorkItems::TypesFramework::Custom::Type.new(
name: "Should Fail",
icon_name: :work_item_feature,
organization: org,
namespace: nil
)
puts "New type valid: #{new_type.valid?}" # false
puts new_type.errors.full_messages # "Organization can only have a maximum of 10 work item types."
# Test 2: Archive the active type
active.update!(archived: true)
# Test 3: Now creating should succeed (archived types don't count)
new_type2 = WorkItems::TypesFramework::Custom::Type.new(
name: "Should Succeed",
icon_name: :work_item_feature,
organization: org,
namespace: nil
)
new_type2.valid? # true
# Test 4: Unarchiving should fail when at limit
new_type2.save!
archived.archived = false
archived.valid? # false
# Expected error: "Archived Cannot unarchive because the maximum limit of 10 work item types has been reached."
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
@daniyalAD thanks a lot for incorporating the suggestions