Skip to content

feat(work-item): add sub-group-by (swimlanes) to project work items - #309

Merged
martian56 merged 1 commit into
Devlaner:mainfrom
cavidelizade:feat/sub-group-by
Jul 13, 2026
Merged

feat(work-item): add sub-group-by (swimlanes) to project work items#309
martian56 merged 1 commit into
Devlaner:mainfrom
cavidelizade:feat/sub-group-by

Conversation

@cavidelizade

Copy link
Copy Markdown
Contributor

Feature summary

Work-item layouts now support an optional second grouping dimension: the List nests sub-group sections inside each group, and the Board renders swimlanes.

Linked issues / discussion

Closes #177

User-facing behavior

In a project's work items, open Display. After picking a primary Group by, a new Sub-group by control appears offering every other dimension (states, priority, cycle, module, labels, assignees, created by) — it can't equal the primary group-by, and "None" turns it off.

  • List: each primary group is a section; inside it, one nested sub-section per sub-group, each with its own header + count.
  • Board: each sub-group is a horizontal swimlane; within a lane, one column per primary group. (e.g. Group by State + Sub-group by Priority → a swimlane per priority, columns per state.)

The choice persists per project (localStorage) alongside the other display options.

What changed

UI (apps/web/)

  • lib/issueListGroupAndSort.ts: new buildSubGroupedIssues + subGroupKey, layered on top of the existing buildGroupedIssues (reusing each dimension's ordering and titles). Returns null when sub-grouping doesn't apply, so callers fall back to the flat grouping.
  • lib/projectIssuesDisplay.ts + projectIssuesEvents.ts: added subGroupBy to the display state, persistence, and event payload, with a normalizeSubGroupBy guard (sub-group is cleared when it equals the primary or the primary is "None").
  • ProjectIssuesDisplayPanel.tsx: new "Sub-group by" section (hidden until a primary group is chosen; excludes the primary; gated by an enableSubGroup prop).
  • IssueLayoutList.tsx / IssueLayoutBoard.tsx: nested-section and swimlane rendering when a sub-grouping is present.
  • IssueListPage.tsx: builds and threads the sub-grouped result to both layouts.
  • ModuleDetailHeader.tsx: passes enableSubGroup={false} (the module view doesn't render swimlanes).

API / Database

  • None.

Why this design

The flat GroupedIssuesResult is consumed by several layouts (spreadsheet, gantt, calendar, …). Rather than change its shape, sub-grouping is a parallel structure that only List and Board opt into, so the other layouts are untouched. Both dimensions' key/order/title logic is reused from buildGroupedIssues (via a shared subGroupKey) so a sub-grouping is always consistent with that dimension's normal grouping. Drag-and-drop is disabled in swimlane mode so a drop isn't ambiguously both a column and a lane change.

Test plan

  • npm run validate (typecheck + lint + prettier) green
  • Manual end-to-end (Playwright) on a project: Group by States + Sub-group by Priority
    • List: State sections each nest Priority sub-sections with correct counts (Backlog → High 1, Medium 1; No state → High 1, None 5)
    • Board: swimlanes per Priority, columns per State, items placed in the correct cells
    • Verified "Sub-group by" is hidden until a primary group is set and excludes the current primary
  • Tested at narrow viewport

Out of scope (follow-ups)

  • Swimlanes in the module work-items view
  • Drag-and-drop across swimlanes
  • Persisting sub-group to saved views (display_filters)

AI assistance

  • AI tools were used — tool(s): Claude Code (Claude Opus 4.8) — and AI-assisted commits include a Co-Authored-By: trailer

Checklist

  • PR title follows Conventional Commits and is ≤ 100 chars
  • Acceptance criteria from the linked issue are met (sub-group nested in list + swimlanes on board; can't equal primary)

Add an optional secondary grouping to the project work-item layouts. From the
Display panel, once a primary Group by is chosen, a new "Sub-group by" control
offers every other dimension (it can't equal the primary; "None" turns it off).

- List: primary groups become sections, each split into nested sub-group
  sections.
- Board: sub-groups become horizontal swimlanes, one band of primary-group
  columns per sub-group.

Implemented as a parallel buildSubGroupedIssues on top of the existing
buildGroupedIssues (reusing each dimension's ordering + titles), so the flat
GroupedIssuesResult that other layouts consume is unchanged. Drag-and-drop is
disabled in swimlane mode to keep the cross-dimension drop unambiguous. The
sub-group control is hidden in the module view, which doesn't render swimlanes.

Closes Devlaner#177

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cavidelizade
cavidelizade requested a review from a team as a code owner July 13, 2026 13:41
@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@cavidelizade, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 15 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a214ffc-2b57-4f03-aee2-dde88d9f51e2

📥 Commits

Reviewing files that changed from the base of the PR and between dc28bb0 and 2aade08.

📒 Files selected for processing (8)
  • apps/web/src/components/layout/ModuleDetailHeader.tsx
  • apps/web/src/components/project-issues/ProjectIssuesDisplayPanel.tsx
  • apps/web/src/components/work-item/layouts/IssueLayoutBoard.tsx
  • apps/web/src/components/work-item/layouts/IssueLayoutList.tsx
  • apps/web/src/lib/issueListGroupAndSort.ts
  • apps/web/src/lib/projectIssuesDisplay.ts
  • apps/web/src/lib/projectIssuesEvents.ts
  • apps/web/src/pages/IssueListPage.tsx
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cavidelizade

Copy link
Copy Markdown
Contributor Author

@martian56 this one's green with no CodeRabbit comments — sub-group-by / swimlanes for the work-item layouts. Good to merge when you get a chance.

@martian56
martian56 merged commit a080432 into Devlaner:main Jul 13, 2026
2 checks passed
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.

[FEAT] Add sub-group-by (swimlanes) to work-item layouts

2 participants