Skip to content

feat(DockView): support switching layouts - #1126

Open
ArgoZhang wants to merge 23 commits into
masterfrom
feat/dockview-layout-switching
Open

feat(DockView): support switching layouts#1126
ArgoZhang wants to merge 23 commits into
masterfrom
feat/dockview-layout-switching

Conversation

@ArgoZhang

@ArgoZhang ArgoZhang commented Aug 31, 2026

Copy link
Copy Markdown
Member

Link issues

fixes #1125

Summary By Copilot

  • add LayoutName to DockViewV2 and its child layout definitions for runtime layout selection
  • switch layouts explicitly when the selected name changes and filter serialized content on the server
  • use layout-specific local-storage keys while preserving the existing key format for unnamed layouts
  • harden layout reset for empty configuration, rapid switches, floating groups, and measured container sizing
  • clear and rebuild drawer controls without accumulating stale buttons or detached handlers
  • avoid rendering duplicate empty panel shells across declarative layouts
  • bump BootstrapBlazor.DockView to version 10.0.24

Regression?

  • Yes
  • No

Existing unnamed single-layout usage and its local-storage key format remain unchanged.

Risk

  • High
  • Medium
  • Low

The change updates layout reconstruction, drawer lifecycle, panel selection, and persisted-layout behavior. Guards preserve existing single-layout behavior and handle empty or superseded layouts.

Verification

  • Manual (required)

  • Automated

  • built BootstrapBlazor.DockView for all target frameworks with no warnings or errors

  • checked all six changed JavaScript modules with Node.js syntax validation

  • checked the branch diff for whitespace errors

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Enable DockView applications to select and switch between named layouts while preserving existing single-layout behavior.

New Features:

  • Add named layout support to DockView, including runtime switching between declarative layouts and separate persistence for each named layout.

Bug Fixes:

  • Prevent empty or duplicate panel shells, stale drawer controls, detached event handlers, and invalid layout state during resets and rapid layout changes.
  • Preserve existing local-storage key compatibility for unnamed layouts.

Enhancements:

  • Improve layout reconstruction, container sizing synchronization, floating-group restoration, and panel visibility notifications across initialization and resets.

Build:

  • Bump the DockView and Region package versions.

ArgoZhang and others added 15 commits August 4, 2026 14:07
- reset 前整体清空抽屉按钮容器(:scope > 限定直接子元素),避免 onDidLayoutFromJSON 重建后累积
- 浮动组位置恢复与抽屉重建解耦:位置缺失跳过防解构抛错,抽屉重建无条件执行
- 布局切换判定收敛到 C# 侧显式调用 switchLayout,update 仅做增量更新
- removeDrawerBtn 空值保护;纯 LayoutConfig 用法的空集合守卫(C#/JS 各处)
- GetLayoutContents 空集合守卫,防 _components[0] 越界
@bb-auto bb-auto Bot added the enhancement New feature or request label Aug 31, 2026
@bb-auto bb-auto Bot added this to the v10.0.0 milestone Aug 31, 2026
@sourcery-ai

sourcery-ai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds named declarative layouts with server/client selection, explicit runtime switching, layout-specific persistence, and defensive reconstruction of panels, floating groups, sizing, and drawer controls while preserving existing unnamed single-layout behavior.

Sequence diagram for runtime DockView layout switching

sequenceDiagram
    participant Blazor as DockViewV2
    participant JS as DockViewV2.js
    participant Dock as DockView
    participant Config as LayoutConfig

    Blazor->>Blazor: GetLayoutContents()
    Blazor->>JS: switchLayout(id, options)
    JS->>Dock: switchLayout(options)
    Dock->>Dock: reset(options)
    Dock->>Config: getRootContent(options)
    Config-->>Dock: selected layout content
    Dock->>Dock: fromJSON(layout)
    Dock->>Dock: syncLayoutToContainer()
    Dock-->>Blazor: render selected layout
Loading

Flow diagram for defensive DockView layout reconstruction

flowchart TD
    Reset["reset(options)"] --> Clear["Remove drawer buttons"]
    Clear --> Init["Initialize selected layout"]
    Init --> Empty{"Root content exists?"}
    Empty -->|No| Fallback["Create empty grid"]
    Empty -->|Yes| Build["Build panels from selected root"]
    Fallback --> Measure["syncLayoutToContainer()"]
    Build --> Measure
    Measure --> Token["Validate layout sequence"]
    Token -->|Current| Rebuild["Restore floating groups and drawer controls"]
    Token -->|Superseded| Stop["Discard stale callback"]
Loading

File-Level Changes

Change Details Files
Add named-layout selection across declarative components and server/client configuration generation.
  • Expose LayoutName on DockViewV2, component bases, and layout config models.
  • Select the matching layout server-side before serializing contents, while retaining unnamed-layout behavior.
  • Select the same layout root when extracting client panels and building the grid.
  • Avoid rendering duplicate empty panel shells for components declared in inactive layouts.
src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor
src/components/BootstrapBlazor.DockView/Components/DockViewComponentBase.cs
src/components/BootstrapBlazor.DockView/Components/DockViewConfig.cs
src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-config.js
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-content.js
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-panel.js
Implement explicit runtime layout switching with isolated persistence and safer reset/reconstruction behavior.
  • Invoke the JavaScript switch operation when LayoutName changes.
  • Use layout-specific local-storage keys while preserving the legacy key for unnamed layouts.
  • Reset from normalized options, clear stale drawer controls, and guard asynchronous callbacks against superseded switches.
  • Handle empty content, floating groups without saved positions, and measured container dimensions during reconstruction.
  • Reset invisible-panel state and avoid accumulating detached drawer handlers.
src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.cs
src/components/BootstrapBlazor.DockView/Components/DockViewV2.razor.js
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-config.js
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-group.js
src/components/BootstrapBlazor.DockView/wwwroot/js/dockview-utils.js
Update the DockView package version for the feature release.
  • Bump BootstrapBlazor.DockView to version 10.0.24.
src/components/BootstrapBlazor.DockView/BootstrapBlazor.DockView.csproj

Assessment against linked issues

Issue Objective Addressed Explanation
#1125 Add a LayoutName parameter to DockViewV2 and declarative child layouts, select the matching layout at runtime when LayoutName changes, and preserve compatibility when LayoutName is unset.
#1125 Filter layout content server-side and maintain independent local-storage state for named layouts while retaining the existing storage key format for unnamed layouts.
#1125 Make layout switching and reset robust for empty or floating layouts, rapid switches, drawer reconstruction, duplicate panel shells, and measured container sizing, and bump BootstrapBlazor.DockView to version 10.0.24.

Possibly linked issues


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[bot]
bb-auto Bot previously approved these changes Aug 31, 2026

@bb-auto bb-auto 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.

Auto approved by bb-auto

@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 found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/components/BootstrapBlazor.DockView/Components/DockViewComponent.razor" line_range="4-22" />
<code_context>
-    }
-</div>
+@* 多布局下同一组件会在各布局重复声明(仅一处有内容);无条件渲染外壳会产生同 key 空 div,导致 querySelector 命中空壳 *@
+@if (ChildContent != null)
+{
+    <div id="@Id" class="bb-dockview-panel" data-bb-key="@Key" data-bb-title="@Title">
+        @if (TitleTemplate != null)
+        {
+            <div class="bb-dockview-item-title">
+                @TitleTemplate
+            </div>
+        }
+        else if (ShowTitleBar)
+        {
</code_context>
<issue_to_address>
**issue (broader_impact):** When a `DockViewComponent` has no child content, the entire panel shell and its title bar are omitted. This changes the previous behavior, where the shell and title bar were still rendered, so valid title-only or otherwise content-less panels are no longer discoverable or renderable by DockView.

**Triggers:** When an unnamed single-layout configuration contains a component with `ChildContent == null`.

**Suggested fix:** Only suppress duplicate shells when the component is a known inactive layout declaration; preserve shell rendering for the existing single-layout case.
</issue_to_address>

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[bot]
bb-auto Bot previously approved these changes Aug 31, 2026

@bb-auto bb-auto 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.

Auto approved by bb-auto

bb-auto[bot]
bb-auto Bot previously approved these changes Aug 31, 2026

@bb-auto bb-auto 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.

Auto approved by bb-auto

bb-auto[bot]
bb-auto Bot previously approved these changes Aug 31, 2026

@bb-auto bb-auto 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.

Auto approved by bb-auto

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bb-auto[bot]
bb-auto Bot previously approved these changes Aug 31, 2026

@bb-auto bb-auto 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.

Auto approved by bb-auto

@bb-auto bb-auto 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.

Auto approved by bb-auto

bb-auto[bot]
bb-auto Bot previously approved these changes Aug 31, 2026

@bb-auto bb-auto 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.

Auto approved by bb-auto

- postLayoutInit:浮窗位置恢复/观察器挂载/inited 门控从 setTimeout(0) 提前到 initDockviewFromConfig 返回后同步执行
- 可见性通知/loadTabs/initialized 改为微任务发出(早于绘制,消除队列空等约50ms)
- 抽屉外点关闭改为实例级单次绑定,修复重复绑定
- onDidLayoutFromJSON 仅保留 markFirstVisibleElement,重建后处理收敛到 postLayoutInit 单处维护
bb-auto[bot]
bb-auto Bot previously approved these changes Sep 1, 2026

@bb-auto bb-auto 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.

Auto approved by bb-auto

@bb-auto bb-auto 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.

Auto approved by bb-auto

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.

feat(DockView): support switching layouts

2 participants