Skip to content

fix(ConnectionState): unify connection selection with block selection pattern#300

Open
lilylilps wants to merge 2 commits into
mainfrom
fix_connection_selection_reset
Open

fix(ConnectionState): unify connection selection with block selection pattern#300
lilylilps wants to merge 2 commits into
mainfrom
fix_connection_selection_reset

Conversation

@lilylilps

@lilylilps lilylilps commented Jun 15, 2026

Copy link
Copy Markdown

Problem
Connection selection state was inconsistent with the block selection pattern. ConnectionState stored selected directly in $state signal, while BlockState derives it from the selection bucket via a computed signal. This caused a bug where omitting the selected field from connection data (e.g. when calling setEntities) would not reset selection — Object.assign in updateConnection preserved the stale selected: true value since undefined keys don't overwrite existing ones.

Solution
Aligned ConnectionState architecture with BlockState:

  • Before: $state was a writable signal<T> holding all connection data including selected
  • After: $rawState (protected signal) holds raw data; $state is a computed signal that derives selected from the selection bucket

This makes the selection bucket the single source of truth for connection selection, exactly as it is for blocks.

Changes
ConnectionState.ts:

  • $state signal → $rawState (protected) + computed $state that overrides selected from $selected
  • Moved $selected declaration before $state to avoid circular dependency (reads id from $rawState)
  • updateConnection() now writes to $rawState
  • isSelected() reads from $selected (bucket-derived)
  • toJSON() / asTConnection() construct output from $rawState + $selected

ConnectionList.ts:

  • Removed dead setSelection method (was never called, wrote directly to $state.selected)
  • deleteSelectedConnections now checks $selected.value instead of $state.value.selected

Summary by Sourcery

Unify connection selection handling with the existing block selection pattern so that selection state is always derived from the selection bucket rather than stored directly on connection entities.

Bug Fixes:

  • Ensure connection selection is correctly reset when connection data is updated without an explicit selected flag, preventing stale selected states from persisting.

Enhancements:

  • Refactor ConnectionState to maintain raw connection data separately from derived selection state, aligning it with BlockState and simplifying selection checks.
  • Remove unused selection mutation logic from ConnectionsStore in favor of relying on the centralized selection bucket API.

Tests:

  • Add Storybook stories that demonstrate and validate connection selection behavior via both the selection bucket API and React state + setEntities flows.

@sourcery-ai

sourcery-ai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Reviewer's Guide

Refactors connection selection so that ConnectionState derives selected from the shared selection bucket (like BlockState), ensuring selection is single-sourced and correctly reset, removes legacy direct-selection APIs, and adds Storybook stories demonstrating the new connection selection behavior.

File-Level Changes

Change Details Files
Refactor ConnectionState to separate raw connection data from derived selection state and make the selection bucket the single source of truth.
  • Introduce protected $rawState signal to store the raw connection data and change constructor and update logic to write into it instead of $state.
  • Define $selected as a computed signal that checks membership of the connection id in connectionSelectionBucket.$selected using $rawState.value.id.
  • Redefine $state as a computed signal that spreads $rawState and overrides selected with $selected.value, mirroring the BlockState pattern.
  • Update isSelected() to return $selected.value instead of reading selected from $state.
  • Change asTConnection() and toJSON() to build output objects from $rawState.toJSON() plus selected from $selected.value.
  • Update updateConnection() to merge props and styles into $rawState, avoiding direct writes to $state and preventing stale selected values from being preserved.
src/store/connection/ConnectionState.ts
Align connection list behavior with the new selection model and remove dead selection code.
  • Remove the unused setSelection helper that wrote selected directly into connection state and was never called.
  • Change deleteSelectedConnections() to check c.$selected.value instead of c.$state.value.selected, relying on the bucket-derived selection.
src/store/connection/ConnectionList.ts
Add Storybook stories illustrating connection selection driven by the selection bucket and React state rather than direct selected flags on connections.
  • Create ConnectionSelectionDemo story that wires block selection events to connection selection via connectionSelectionBucket.updateSelection, showing correct deselection when no blocks are selected.
  • Create ConnectionSelectionViaSetEntitiesDemo story that uses React state for selected blocks and updates the connection selection bucket accordingly, validating that omitting selected in connection data no longer leaves stale selection.
  • Configure Storybook metadata and exports for the new stories, using shared graph settings and block rendering via BlockStory.
src/stories/api/connectionSelection/connectionSelection.stories.tsx

Possibly linked issues

  • #(none provided): PR refactors ConnectionState to derive selection from bucket, fixing connections staying selected when selected is omitted.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've left some high level feedback:

  • In ConnectionState.$selected you access this.$rawState.value.id while $rawState is initialized with undefined; depending on the signal implementation this may run before the constructor assigns a value and cause a runtime error, so consider guarding for !this.$rawState.value or providing a non-undefined initial value.
  • asTConnection and toJSON now duplicate the same merge logic of $rawState with $selected; consider extracting a small helper to avoid divergence if this shape changes again.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `ConnectionState.$selected` you access `this.$rawState.value.id` while `$rawState` is initialized with `undefined`; depending on the signal implementation this may run before the constructor assigns a value and cause a runtime error, so consider guarding for `!this.$rawState.value` or providing a non-undefined initial value.
- `asTConnection` and `toJSON` now duplicate the same merge logic of `$rawState` with `$selected`; consider extracting a small helper to avoid divergence if this shape changes again.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@gravity-ui-bot

Copy link
Copy Markdown
Contributor

Preview is ready.

@lilylilps lilylilps linked an issue Jun 15, 2026 that may be closed by this pull request
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.

Selection of connections cannot be cleared

2 participants