Skip to content

fix: normalize kanban groupBy matching for label-vs-value mismatch#450

Merged
hotlong merged 2 commits intomainfrom
copilot/fix-msw-board-data-visibility
Feb 11, 2026
Merged

fix: normalize kanban groupBy matching for label-vs-value mismatch#450
hotlong merged 2 commits intomainfrom
copilot/fix-msw-board-data-visibility

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 11, 2026

Kanban board view showed empty columns (0 cards) despite data being fetched successfully.

Root Cause

Field.select(['In Progress', 'Backlog', ...]) auto-converts option values to snake_case (in_progress, backlog). Kanban columns are generated from these options using opt.value as column ID. However, seed data stores the original labels (status: 'In Progress'). The grouping logic used exact matching, so no data matched any column:

// Column IDs:  'in_progress', 'backlog', 'todo', ...
// Data values: 'In Progress', 'Backlog', 'Todo', ...
groups[col.id]  // always undefined — no match

Fix

  • Build a case-insensitive label→id mapping from columns so 'In Progress' resolves to column 'in_progress'
  • Backwards-compatible: exact value matches still work as before
const labelToColumnId: Record<string, string> = {};
columns.forEach((col: any) => {
  if (col.id) labelToColumnId[String(col.id).toLowerCase()] = col.id;
  if (col.title) labelToColumnId[String(col.title).toLowerCase()] = col.id;
});

const rawKey = String(item[groupBy] ?? '');
const key = labelToColumnId[rawKey.toLowerCase()] ?? rawKey;

Before:

before

After:

after


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

@vercel
Copy link
Copy Markdown

vercel Bot commented Feb 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
objectui Ready Ready Preview, Comment Feb 11, 2026 1:47pm
objectui-console Building Building Preview, Comment Feb 11, 2026 1:47pm
objectui-demo Ready Ready Preview, Comment Feb 11, 2026 1:47pm
objectui-storybook Error Error Feb 11, 2026 1:47pm

Request Review

Field.select() converts option values to snake_case (e.g. 'In Progress' → 'in_progress'),
but seed data often uses the original label. The KanbanRenderer now builds a label→id
mapping so data values match column IDs regardless of casing.

Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix issue with data visibility in MSW board view fix: normalize kanban groupBy matching for label-vs-value mismatch Feb 11, 2026
Copilot AI requested a review from hotlong February 11, 2026 13:33
@hotlong hotlong marked this pull request as ready for review February 11, 2026 13:34
Copilot AI review requested due to automatic review settings February 11, 2026 13:34
@hotlong hotlong merged commit 093ab29 into main Feb 11, 2026
3 of 6 checks passed
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes Kanban groupBy grouping when record values use select labels (e.g. "In Progress") while Kanban column IDs use select option values (e.g. "in_progress"), preventing empty columns despite successful data fetches.

Changes:

  • Adds a case-insensitive label/title→columnId normalization map when grouping flat data into Kanban columns.
  • Normalizes each record’s groupBy key before assigning it to a column group.

Comment on lines +47 to +53
// Build label→id mapping so data values (labels like "In Progress")
// match column IDs (option values like "in_progress")
const labelToColumnId: Record<string, string> = {};
columns.forEach((col: any) => {
if (col.id) labelToColumnId[String(col.id).toLowerCase()] = col.id;
if (col.title) labelToColumnId[String(col.title).toLowerCase()] = col.id;
});
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The groupBy normalization is only implemented for KanbanRenderer here. The separately-registered kanban-enhanced renderer in the same file still groups by const key = item[groupBy] (exact match), so the label-vs-value mismatch will still produce empty columns when consumers use the enhanced variant. Consider reusing the same label/title→id normalization logic in the kanban-enhanced registration (ideally via a shared helper) to keep behavior consistent across both renderers.

Copilot uses AI. Check for mistakes.
Comment on lines +47 to 61
// Build label→id mapping so data values (labels like "In Progress")
// match column IDs (option values like "in_progress")
const labelToColumnId: Record<string, string> = {};
columns.forEach((col: any) => {
if (col.id) labelToColumnId[String(col.id).toLowerCase()] = col.id;
if (col.title) labelToColumnId[String(col.title).toLowerCase()] = col.id;
});

// 1. Group data by key, normalizing via label→id mapping
const groups = data.reduce((acc, item) => {
const key = item[groupBy];
const rawKey = String(item[groupBy] ?? '');
const key = labelToColumnId[rawKey.toLowerCase()] ?? rawKey;
if (!acc[key]) acc[key] = [];
acc[key].push(item);
return acc;
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new label/title→id normalization for grouping is not covered by tests. Current tests only cover exact groupBy value matches (e.g. status: 'todo'), so this regression-prone behavior change should have a unit/integration test asserting that a record with item[groupBy] equal to a column title/label (e.g. "In Progress") is grouped into the column whose id is the normalized option value (e.g. "in_progress").

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants