Skip to content

Sidebar: Add dual-slot status icons for change detection and test results#34346

Merged
valentinpalkovic merged 18 commits into
nextfrom
valentin/dual-slot-filtering
Apr 7, 2026
Merged

Sidebar: Add dual-slot status icons for change detection and test results#34346
valentinpalkovic merged 18 commits into
nextfrom
valentin/dual-slot-filtering

Conversation

@valentinpalkovic
Copy link
Copy Markdown
Contributor

@valentinpalkovic valentinpalkovic commented Mar 26, 2026

Closes #34266

What I did

Separated change-detection statuses (new, modified, affected) from test statuses (error, warning, pending, success) into two independent icon slots in the sidebar tree. This allows both types of status information to be visible simultaneously on story leaf nodes.

  • Added a getChangeDetectionStatus helper that splits statuses by typeId into change-detection vs test categories
  • Rendered two independent StatusButton components per leaf node (change slot + test slot)
  • Added SVG icons for new, modified, and affected status values using UseSymbol
  • Updated statusOrder to include all status values
  • Added comprehensive unit tests for the dual-slot splitting logic
  • Added story variants covering all combinations (change-only, test-only, both, affected, branch priority)
image

Checklist for Contributors

Testing

The changes in this PR are covered in the following automated tests:

  • stories
  • unit tests
  • integration tests
  • end-to-end tests

Manual testing

  1. Run cd code && yarn storybook:ui
  2. Navigate to Sidebar/Tree stories
  3. Verify the new dual-slot stories (WithChangeDetectionOnly, WithChangeDetectionAndTestStatus, WithTestStatusOnly, WithAffectedStatus, BranchWithChangeDetectionPriority) render correctly with two separate status icon slots

Documentation

  • Add or update documentation reflecting your changes
  • If you are deprecating/removing a feature, make sure to update
    MIGRATION.MD

Checklist for Maintainers

  • When this PR is ready for testing, make sure to add ci:normal, ci:merged or ci:daily GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found in code/lib/cli-storybook/src/sandbox-templates.ts

  • Make sure this PR contains one of the labels below:

    Available labels
    • bug: Internal changes that fixes incorrect behavior.
    • maintenance: User-facing maintenance tasks.
    • dependencies: Upgrading (sometimes downgrading) dependencies.
    • build: Internal-facing build tooling & test updates. Will not show up in release changelog.
    • cleanup: Minor cleanup style change. Will not show up in release changelog.
    • documentation: Documentation only changes. Will not show up in release changelog.
    • feature request: Introducing a new feature.
    • BREAKING CHANGE: Changes that break compatibility in some way with current major version.
    • other: Changes that don't fit in the above categories.

🦋 Canary release

This PR does not have a canary release associated. You can request a canary release of this pull request by mentioning the @storybookjs/core team here.

core team members can create a canary release here or locally with gh workflow run --repo storybookjs/storybook publish.yml --field pr=<PR_NUMBER>

Summary by CodeRabbit

  • New Features

    • Sidebar now shows two separate status indicators per item: a "change" slot and a "test" slot, with selection/highlight behavior preserved.
  • Storybook

    • Added example scenarios demonstrating various dual-slot status combinations and selection initializations.
  • Bug Fixes

    • Unified status icon rendering and adjusted status priority so indicators reflect criticality more clearly.
  • Tests

    • Added coverage for splitting statuses into change vs. test and for priority rules.

…ults

Separate change-detection statuses (new/modified/affected) from test statuses
(error/warning/pending/success) into two independent icon slots in the sidebar
tree. This allows both types of information to be visible simultaneously on a
story leaf node.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Mar 26, 2026

View your CI Pipeline Execution ↗ for commit 9499622

Command Status Duration Result
nx run-many -t compile,check,knip,test,lint,fmt... ✅ Succeeded 9m 42s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-07 10:02:38 UTC

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Mar 26, 2026

View your CI Pipeline Execution ↗ for commit b8167af


☁️ Nx Cloud last updated this comment at 2026-03-26 13:50:23 UTC

@valentinpalkovic valentinpalkovic changed the base branch from next to valentin/status-based-filtering March 26, 2026 13:51
@valentinpalkovic valentinpalkovic marked this pull request as ready for review March 26, 2026 13:51
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 26, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Split sidebar statuses into separate "change-detection" and "test" slots: added getGroupDualStatus and getChangeDetectionStatus, updated Tree to compute/render dual-slot statuses (two status buttons/icons and adjusted ordering), plus stories and tests exercising dual-slot scenarios.

Changes

Cohort / File(s) Summary
Sidebar Tree component & helper
code/core/src/manager/components/sidebar/Tree.tsx
Render dual-slot statuses: compute separate change vs test statuses (via getChangeDetectionStatus/getGroupDualStatus), render up to two status buttons (distinct data-testid values), replace some icon mappings with UseSymbol, and change status ordering. Exports getChangeDetectionStatus.
Status utilities
code/core/src/manager/utils/status.tsx
Added getGroupDualStatus(collapsedData, allStatuses) which aggregates descendant statuses and returns { change, test } per node; imports CHANGE_DETECTION_STATUS_TYPE_ID. Existing single-slot helpers remain.
Stories (dual-slot scenarios)
code/core/src/manager/components/sidebar/Tree.stories.tsx
Added makeDualSlotStory(allStatuses), built dual-slot tree data, and exported five new story variants exercising different change/test status combinations; one variant overrides render to initialize selection differently.
Tests
code/core/src/manager/utils/status.test.ts
Added tests for dual-slot splitting and priority rules for getChangeDetectionStatus, including defaults when one slot is missing and cross-slot criticality checks.

Sequence Diagram(s)

(Skipped — changes are internal UI/status rendering and utilities; no multi-actor runtime flow requiring sequence visualization.)

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs


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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/core/src/manager/components/sidebar/Tree.tsx`:
- Around line 303-305: Branch/group rows currently flatten branch-local statuses
into a single StatusValue[] and use getMostCriticalStatusValue(), which loses
the split (change vs test) aggregation; instead, compute the two-part
aggregation for branches using getChangeDetectionStatus() (like for leaves) so
you obtain changeStatus and testStatus for branch/group rows, then call
getStatus(theme, changeStatus) and getStatus(theme, testStatus) to derive
changeIcon, testIcon and textColor; replace any flattening of statuses (the code
using statuses || {} and the getMostCriticalStatusValue merge) with calls to
getChangeDetectionStatus on the branch-local status map and merge
branch+descendant results per-channel (change/test) rather than as a single
flattened value.
- Around line 344-365: The two StatusButton elements must be rendered as a fixed
two-slot action cluster so LeafNodeStyleWrapper's adjacent-sibling selectors
continue to work; update the JSX around StatusButton to always render a
container (e.g., a "status-cluster" div) with two children (left/change slot and
right/test slot) and when changeIcon or testIcon is null render an empty
placeholder element with the same tag/attributes (data-testid, ariaLabel, status
prop) but no children so the DOM structure and selectors remain stable; ensure
you reuse the existing identifiers StatusButton, changeIcon, testIcon,
changeStatus, testStatus and preserve ariaLabel/data-testid values for each
slot.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9519f012-92c3-4c81-a503-42b6be8ac18c

📥 Commits

Reviewing files that changed from the base of the PR and between f546e38 and b8167af.

📒 Files selected for processing (3)
  • code/core/src/manager/components/sidebar/Tree.stories.tsx
  • code/core/src/manager/components/sidebar/Tree.tsx
  • code/core/src/manager/utils/status.test.ts

Comment thread code/core/src/manager/components/sidebar/Tree.tsx Outdated
Comment thread code/core/src/manager/components/sidebar/Tree.tsx Outdated
@storybook-app-bot
Copy link
Copy Markdown

storybook-app-bot Bot commented Mar 26, 2026

Package Benchmarks

Commit: 9499622, ran on 7 April 2026 at 10:04:03 UTC

No significant changes detected, all good. 👏

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/core/src/manager/components/sidebar/Tree.stories.tsx`:
- Around line 323-332: dualSlotData currently only seeds the immediate parent
and story entries (dualSlotParentId, dualSlotStoryId), which breaks when the
parent itself has a parent; update the construction of dualSlotData to include
the full ancestor chain from index by walking index[parent] repeatedly and
adding each ancestor entry (preserving their children arrays) so the tree
hierarchy remains intact; reference the symbols dualSlotStoryId,
dualSlotParentId, dualSlotData, index and ComponentEntry and ensure the
resulting map contains every ancestor id -> ComponentEntry needed for rendering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3920fa72-e16d-47e2-9296-cd89c2c9a204

📥 Commits

Reviewing files that changed from the base of the PR and between b8167af and ba0156f.

📒 Files selected for processing (1)
  • code/core/src/manager/components/sidebar/Tree.stories.tsx

Comment thread code/core/src/manager/components/sidebar/Tree.stories.tsx
Comment thread code/core/src/manager/components/sidebar/Tree.tsx Outdated
Comment thread code/core/src/manager/components/sidebar/Tree.tsx Outdated
Comment thread code/core/src/manager/components/sidebar/Tree.tsx Outdated
Comment thread code/core/src/manager/components/sidebar/Tree.tsx Outdated
Base automatically changed from valentin/status-based-filtering to next March 31, 2026 19:06
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@code/core/src/manager/components/sidebar/Tree.tsx`:
- Around line 441-456: The branch rows currently render two separate status
controls (branchChange and branchTest) and compute overallStatus from both;
instead derive a single branch status by choosing branchChange when it is not
'status-value:unknown' otherwise branchTest (e.g. const branchStatus =
branchChange !== 'status-value:unknown' ? branchChange : branchTest), then
compute a single branchIcon via getStatus(theme, branchStatus) or the small dot
SVG when branchStatus equals 'status-value:error' | 'status-value:warning', and
use that single branchStatus for overallStatus/color (replace
getMostCriticalStatusValue([branchChange, branchTest]) with branchStatus).
Update any places that expect branchChangeIcon/branchTestIcon to use this single
branchIcon so the left/right slot rendering no longer depends on both icons
existing and change-detection precedence is honored (refer to symbols:
branchChange, branchTest, branchStatus, branchIcon, overallStatus,
getMostCriticalStatusValue, getStatus, UseSymbol, theme).
- Around line 310-311: getChangeDetectionStatus is being partially destructured
(only testStatus) which drops the change-detection icon slot; instead capture
the full return value and derive the icon from it when rendering. Change the
code around getChangeDetectionStatus/getStatus so you keep the whole result
(e.g., const change = getChangeDetectionStatus(statuses || {})) and then call
getStatus(theme, change.testStatus || change.status) to obtain icon/textColor
(use those values where testIcon/textColor are used) and ensure the left-slot
rendering (the block around the current test button rendering at the 350-360
area) checks for change.* and renders the icon slot even when only
storybook/change-detection statuses exist.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: a68abb06-8856-430f-98d7-6c4007516b39

📥 Commits

Reviewing files that changed from the base of the PR and between 43f9222 and b51e94b.

📒 Files selected for processing (3)
  • code/core/src/manager/components/sidebar/Tree.stories.tsx
  • code/core/src/manager/components/sidebar/Tree.tsx
  • code/core/src/manager/utils/status.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • code/core/src/manager/components/sidebar/Tree.stories.tsx

Comment thread code/core/src/manager/components/sidebar/Tree.tsx Outdated
Comment thread code/core/src/manager/components/sidebar/Tree.tsx
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
code/core/src/manager/utils/status.tsx (1)

171-175: Consider extracting shared leaf-gathering logic.

Lines 171-175 duplicate the leaf-gathering logic from getGroupStatus (lines 142-146). A helper function could reduce duplication:

const getStoryLeaves = (collapsedData, itemId) =>
  getDescendantIds(collapsedData, itemId, false)
    .map((id) => collapsedData[id])
    .filter((i) => i.type === 'story');

This is a minor refactor that could be deferred.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@code/core/src/manager/utils/status.tsx` around lines 171 - 175, Duplicate
logic that gathers story leaf nodes (using getDescendantIds, mapping
collapsedData by id and filtering by type === 'story') appears in getGroupStatus
and the block handling item.type === 'group'|'component'|'story'; extract that
into a helper like getStoryLeaves(collapsedData, itemId) and replace both
occurrences by calling getStoryLeaves(collapsedData, item.id) to remove
duplication and centralize the leaf-gathering behavior; update imports/exports
or file scope accordingly and keep the helper typed to accept collapsedData and
an item id.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@code/core/src/manager/utils/status.tsx`:
- Around line 171-175: Duplicate logic that gathers story leaf nodes (using
getDescendantIds, mapping collapsedData by id and filtering by type === 'story')
appears in getGroupStatus and the block handling item.type ===
'group'|'component'|'story'; extract that into a helper like
getStoryLeaves(collapsedData, itemId) and replace both occurrences by calling
getStoryLeaves(collapsedData, item.id) to remove duplication and centralize the
leaf-gathering behavior; update imports/exports or file scope accordingly and
keep the helper typed to accept collapsedData and an item id.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2f1246ab-27b1-47af-90a0-921debb5c41c

📥 Commits

Reviewing files that changed from the base of the PR and between b51e94b and 158867a.

📒 Files selected for processing (1)
  • code/core/src/manager/utils/status.tsx

@valentinpalkovic valentinpalkovic added ci:daily Run the CI jobs that normally run in the daily job. and removed ci:normal labels Apr 1, 2026
@valentinpalkovic valentinpalkovic added ci:normal and removed ci:daily Run the CI jobs that normally run in the daily job. labels Apr 2, 2026
@valentinpalkovic valentinpalkovic merged commit 7cb708b into next Apr 7, 2026
124 checks passed
@valentinpalkovic valentinpalkovic deleted the valentin/dual-slot-filtering branch April 7, 2026 11:07
@github-actions github-actions Bot mentioned this pull request Apr 7, 2026
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Review Changes]: T5 - Sidebar dual slot

2 participants