Fix GLQL status sort tie-breaking for same-category statuses
What does this MR do and why?
Fix the GLQL table Status column sort for custom statuses like "In dev" and "In review" that share the same category.
Root cause: sorterFor('status') mapped status.category to a numeric weight. When two statuses share the same category (e.g. both in_progress), the comparator returned 0, leaving their relative order non-deterministic.
Fix: Return a composite string sort key that zero-pads the category weight and appends the status name. String comparison then gives a stable, predictable order: first by category group, then alphabetically by name within each group.
// Before
case 'status':
return statusCategories[fieldValue.category];
// After
case 'status': {
// Pipeline/CiJob statuses are plain strings; fall through to the string fallback
if (typeof fieldValue !== 'object') return null;
const categoryWeight = statusCategories[fieldValue.category] ?? 99;
// Zero-pad so string comparison matches numeric order, then append lowercased name for case-insensitive tie-breaking
return `${String(categoryWeight).padStart(2, '0')}_${(fieldValue.name ?? '').toLowerCase()}`;
}This is a pure frontend fix in one function — no backend, GraphQL, or presenter changes needed.
References
Resolves #622340 (closed)
Screenshots or screen recordings
| Before | After |
|---|---|
![]() |
![]() |
How to set up and validate locally
- Create some issues with custom statuses within the same status category
- In an issue, MR, or epic add a table-based GLQL query which includes the
statuscolumn:display: table query: type = Issue fields: title, milestone, status - Sort the
statuscolumn and verify it sorts them correctly - Add a table-based GLQL query for pipelines or jobs with a
statuscolumn and verify it still sorts alphabetically
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.

