Skip to content

fix(DockView): correctness fixes for group delete/re-insert, float and dock-back#1047

Merged
ArgoZhang merged 7 commits into
masterfrom
fix-dockview-group
Jun 25, 2026
Merged

fix(DockView): correctness fixes for group delete/re-insert, float and dock-back#1047
ArgoZhang merged 7 commits into
masterfrom
fix-dockview-group

Conversation

@zhaijunlei955

@zhaijunlei955 zhaijunlei955 commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

A set of related fixes for the group lifecycle (delete → re-insert → float → dock).

Fixes

close #1048

  • Re-insert into an emptied group: defer action-button state while a placeholder
    group is empty (avoids [].every() showing wrong buttons that stick), and restore
    the pre-delete width instead of collapsing to the ~100px minimum.
  • Dock a floating group back to grid: re-render the origin group's action buttons,
    which were deferred while it sat empty as a placeholder.
  • Floating group close / re-insert: closing a floating group now closes its panels
    individually, so external panel buttons stay highlight-synced; a re-added floating
    group gets its active panel set (no blank); a hidden→re-inserted floating group keeps
    its last size & position (offset-based capture, immune to style:auto).
  • Width after re-open + float/dock-back: clear the stale _pendingSize left by the
    width restore, so a group resized after re-opening no longer snaps back to its old
    width on dock-back.
  • Re-open a panel while its group is floated: route it into the floating group
    instead of resurrecting the hidden grid placeholder. This avoids forking one group
    into two (a grid copy + the float) — which collided on the float id and left the
    second floating group unable to dock back.

Scope

DockView only, 3 JS files (dockview-group.js, dockview-extensions.js,
dockview-panel.js). Only the delete/re-insert/float/dock paths are touched; adding a
tab to an existing group and all non-floating paths are unchanged.

Summary by Sourcery

Improve DockView group lifecycle behavior when deleting, re-inserting, floating, and docking groups to avoid placeholder glitches and stale layout state.

Bug Fixes:

  • Route panels re-opened from a hidden grid placeholder into the corresponding floating group to prevent duplicate groups and docking failures.
  • Restore pre-delete grid group width when re-inserting into an empty placeholder instead of collapsing to the minimum width, and clear any stale pending size so later dock operations do not snap back.
  • Ensure action buttons for empty placeholder groups are deferred and correctly re-rendered once a panel is added or a floating group is docked back.
  • Initialize newly created floating groups with an active panel so they are not shown blank on creation.
  • When closing a floating group, close its panels individually so panel visibility events fire consistently and the group is removed via the standard empty-group path.
  • Preserve floating group position and size across hide/re-insert operations by saving offsets via currentPosition instead of unreliable style-based values.

Enhancements:

  • Add utilities to re-render group action button states when an empty placeholder becomes populated, keeping lock/minimize/maximize visibility in sync with options.

@bb-auto

bb-auto Bot commented Jun 24, 2026

Copy link
Copy Markdown

Thanks for your PR, @zhaijunlei955. Someone from the team will get assigned to your PR shortly and we'll get it reviewed.

@sourcery-ai

sourcery-ai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adjusts DockView group lifecycle behavior (delete → re-insert → float → dock) to correctly reuse placeholder groups, preserve floating position/size and grid width, keep action buttons in sync, and ensure floating panels close and re-open without desynchronizing state.

Sequence diagram for panel re-open into floating group and placeholder reuse

sequenceDiagram
    actor User
    participant DockviewComponent
    participant addPanelWidthGroupId
    participant GridGroup as Grid_group_placeholder
    participant FloatingGroup as Floating_group

    User->>DockviewComponent: reopenPanel(panel)
    DockviewComponent->>addPanelWidthGroupId: addPanelWidthGroupId(dockview, panel, index)
    addPanelWidthGroupId->>DockviewComponent: dockview.api.getGroup(panel.groupId)
    addPanelWidthGroupId->>GridGroup: [group.panels.length === 0 && location.type === grid]
    addPanelWidthGroupId->>DockviewComponent: dockview.api.getGroup(getFloatingId(group.id))
    addPanelWidthGroupId->>FloatingGroup: [floated.api.location.type === floating]

    addPanelWidthGroupId->>DockviewComponent: dockview.addPanel({ id, title, component, position, initialWidth })
    addPanelWidthGroupId->>FloatingGroup: group.panels.find(...).api.setActive()

    addPanelWidthGroupId->>GridGroup: [reusedEmptyGroup && location.type === grid]
    addPanelWidthGroupId->>DockviewComponent: reRenderActionStates(group)
    addPanelWidthGroupId->>GridGroup: group.api._pendingSize = undefined
Loading

Sequence diagram for closing a floating group via panel closes

sequenceDiagram
    actor User
    participant DockviewComponent
    participant removeGroupFn as removeGroup
    participant Group as Floating_group
    participant Panel

    User->>DockviewComponent: removeGroup(group)
    DockviewComponent->>Group: group.api.location.type
    alt type == floating
        DockviewComponent->>Group: removeDrawerBtn(group)
        DockviewComponent->>Group: [...group.panels]
        loop each panel
            DockviewComponent->>Panel: panel.api.close()
        end
        Note over Group: last close re-enters removeGroup as empty
        DockviewComponent->>removeGroupFn: removeGroup(group)
    else type != floating
        DockviewComponent->>removeGroupFn: removeGroup(group)
    end
Loading

File-Level Changes

Change Details Files
Route re-opened panels into existing floating groups, reuse empty placeholder groups safely, and restore group widths when re-inserting.
  • Detect when a grid group entry is an empty placeholder for a floated group and route re-opened panels to the corresponding floating group instead of resurrecting the placeholder.
  • Track whether a reused empty group is a placeholder and whether a new floating group is being created to drive subsequent behavior.
  • When creating a floating group, prefer the saved currentPosition (from hide) over rect to restore the last size and position of the floating window.
  • On re-insert into an empty grid group, restore the pre-delete width via initialWidth so the group does not reopen at the minimum width.
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js
Keep action button state (lock/float/packup/close/etc.) correct for empty placeholders and after float/dock transitions.
  • Guard resetActionStates so it no-ops for empty groups, avoiding vacuous [].every() checks that would incorrectly show action buttons.
  • Ensure lock state is still applied even when the lock button is hidden, so groups remain logically locked when showLock is false.
  • Introduce reRenderActionStates helper to recompute header action buttons once an empty placeholder group gains a panel or after docking a floating group back.
  • Invoke reRenderActionStates when re-inserting into a placeholder grid group and when docking a floating group back to its origin group.
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js
Ensure floating groups are immediately usable and avoid stale pending sizes causing width snaps after dock-back.
  • After addPanel creates a new floating group, explicitly activate the newly added panel so the floating group is not initially blank.
  • When restoring width via initialWidth for a reused empty grid group, clear the internal _pendingSize afterward to prevent later visibility changes (float/dock) from reapplying a stale width.
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js
Align floating-group removal with grid behavior by closing panels individually before removing the group.
  • In DockviewComponent.removeGroup, when removing a floating group, first remove the drawer button and then close all panels via panel.api.close(), allowing each panel to fire visibility change hooks.
  • Fallback to the original removeGroup behavior only when the floating group is already empty, preserving the existing removal path.
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-extensions.js
Capture and reuse robust floating group geometry when hiding/removing panels to avoid losing position due to style:auto.
  • When computing currentPosition on panel removal, switch from reading style.top/left (which may be 'auto') to offsetTop/offsetLeft, ensuring numeric coordinates are always captured.
  • Continue to store the current group container width and height so later re-open/float operations can restore the floating window dimensions accurately.
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js

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

@bb-auto bb-auto Bot requested a review from ArgoZhang June 24, 2026 09:55

@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 addPanelWidthGroupId, clearing group.api._pendingSize reaches into a private/underscored field; if possible, prefer using or adding a public API hook for resetting pending size so this logic doesn’t silently break on upstream changes.
  • reRenderActionStates assumes group.header is always present; adding a null guard around group.header before querying .dv-right-actions-container would make this more robust against groups without headers or lifecycle edge cases.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `addPanelWidthGroupId`, clearing `group.api._pendingSize` reaches into a private/underscored field; if possible, prefer using or adding a public API hook for resetting pending size so this logic doesn’t silently break on upstream changes.
- `reRenderActionStates` assumes `group.header` is always present; adding a null guard around `group.header` before querying `.dv-right-actions-container` would make this more robust against groups without headers or lifecycle edge cases.

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.

@bb-auto bb-auto Bot added the enhancement New feature or request label Jun 25, 2026
@bb-auto bb-auto Bot added this to the v10.0.0 milestone Jun 25, 2026
ArgoZhang
ArgoZhang previously approved these changes Jun 25, 2026
@ArgoZhang ArgoZhang merged commit dc38e84 into master Jun 25, 2026
3 checks passed
@ArgoZhang ArgoZhang deleted the fix-dockview-group branch June 25, 2026 04:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(DockView): correctness fixes for group delete/re-insert, float and dock-back

2 participants