Skip to content

feat(tabs): 标签页分屏查看(左右并排对照两个脚本/数据表) - #7109

Open
encyc wants to merge 5 commits into
t8y2:mainfrom
encyc:feat/tab-split-view
Open

feat(tabs): 标签页分屏查看(左右并排对照两个脚本/数据表)#7109
encyc wants to merge 5 commits into
t8y2:mainfrom
encyc:feat/tab-split-view

Conversation

@encyc

@encyc encyc commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

改动

实现 #6910:标签页分屏,可并排同时查看两个脚本或两张表。

  • 参照窗格:右键任意非当前标签 →「在分屏中查看」(左右并排)或「在上下分屏中查看」(上下堆叠),打开一个并排窗格显示该标签页。支持脚本、数据表等全部标签类型
  • 两种布局方向:左右并排(垂直分隔)和上下堆叠(水平分隔);方向随 open_tabs 状态一起持久化,重启后恢复
  • 只读查看模式:参照窗格以查看为定位——支持滚动、文本选择、复制、查找;SQL 编辑器为只读,并屏蔽执行/保存/格式化快捷键(避免误触发到主窗格的标签)。窗格头部带「查看」徽标
  • 表格可浏览交互:参照窗格中表格/结果网格的分页、排序、刷新与执行操作按标签 id 路由(useDataGridActions 以参照标签实例化第二份),两张表可并排各自翻页对照;数据编辑仍保持只读
  • 设为主窗格:点击窗格头部的「设为主窗格」按钮,或直接点击标签栏中对应的标签,该标签回到主窗格继续编辑/执行,分屏自动关闭
  • 分隔条拖拽:窗格尺寸可拖拽调整(20%–80%),尺寸记忆在本地
  • 持久化:分屏标签随 open_tabs 状态一起保存,重启后恢复(标签不存在时自动丢弃);参照窗格的查询结果不会被结果缓存淘汰
  • 标签栏中处于分屏的标签显示「◫」指示器;文案覆盖全部 8 种语言
  • 快捷键Cmd+D(macOS)/ Ctrl+D(Win/Linux)打开或关闭左右分屏;Cmd+Shift+D / Ctrl+Shift+D 打开或关闭上下分屏。无已存在分屏时自动选择最近使用的其他标签页;分屏打开时再按同一快捷键切换方向,再次按下则关闭。快捷键可在设置里自定义
  • 标签栏右键菜单同步提供「在分屏中查看(左右并排)」和「在上下分屏中查看」两个入口

演示

split-view-demo

右键标签菜单(左右分屏 + 上下分屏两个入口):

context-menu

左右并排分屏(参照窗格在右侧):

split-vertical

上下堆叠分屏(Cmd+Shift+D 切换):

split-horizontal

拖拽分隔条调整宽度:

split-dragged

设计说明

主内容区的事件接线(执行、保存、重载等 30+ 事件)都绑定在唯一的 active tab 上。为避免大改接线层引入回归,v1 将参照窗格定位为只读参照面:浏览类操作(分页/排序/刷新)已按标签 id 路由可直接交互,数据编辑与 SQL 修改要切回主窗格。若后续需要双窗格同时可编辑,可在此基础上逐步把接线改为按标签 id 路由。

验证

  • pnpm typecheck
  • pnpm lint(0 错误)
  • pnpm exec vitest run apps/desktop/src/stores/__tests__/queryStore.splitPane.spec.ts apps/desktop/src/lib/__tests__/app/openTabsPersistence.spec.ts apps/desktop/src/composables/__tests__/usePaneResize.spec.ts(27 tests)
  • 全量 pnpm test:13 个失败文件均为本分支基线(upstream/main 最新)上已存在的环境性失败(DataGridSurfaces / Mqtt* / Meilisearch* / keyboardShortcuts / settingsStore / canvasDataGridRenderer 等,已用 stash 在干净基线上复现),与本 PR 无关

Closes #6910

Add a read-only reference pane next to the main content area so two
scripts or two tables can be viewed at the same time. Right-click a
non-active tab and choose "Open in split view"; the pane supports
scrolling, text selection and copy, and its SQL editor suppresses
execute/save/format shortcuts. A "Set as main pane" action promotes
the reference tab back to the main editing pane, and clicking the tab
in the tab bar does the same.

The split pane tab id is persisted with the open-tabs state (dropped
when its tab is missing), excluded from result-cache eviction, and
cleared whenever its tab is closed or activated. Pane width is
drag-resizable and remembered in localStorage.

Closes t8y2#6910
@github-actions github-actions Bot added area/desktop Desktop application or Tauri shell enhancement New feature or request ui-change Changes user-visible interface, text, or visual assets labels Aug 25, 2026
Pagination, sorting, refresh and grid execute actions in the split
pane now route through a second useDataGridActions instance bound to
the reference tab, so two tables can be browsed side by side. The bare
reload fallback stays tab-scoped for non-active tabs instead of
executing the main pane's active tab.
# Conflicts:
#	apps/desktop/src/components/editor/QueryEditor.vue
@eryajf

eryajf commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator
  1. 有没有一些截图实例,GIF就更好了。
  2. 分屏是否支持上下分屏
  3. 上下,左右分屏,最好支持常用快捷键(cmd+d竖向分屏,cmd+shift+d横向分屏)

- Split reference pane can now stack below the main pane (top/bottom) in
  addition to side-by-side; direction persists with the open-tabs state
- Divider drag maps to width or height depending on the layout
- Mod+D opens/toggles the side-by-side split, Shift+Mod+D the top/bottom
  split; both pick the most recently used other tab as the reference
- Tab context menu gains a top/bottom split entry; shortcut labels in
  settings and all 8 locales
@encyc

encyc commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

Hi eryajf,感谢 review!三个问题已全部处理:

1. 截图 & GIF

详见下方 GIF 演示,完整截图也在 PR 描述里。

split-view-demo

2. 上下分屏

已实现。右键标签有两个入口:「在分屏中查看(左右并排)」和「在上下分屏中查看(上下堆叠)」。上下布局下分隔条变成水平方向的行分隔条,可拖拽调整高度(20%–80%),方向随 open_tabs 状态一起持久化。

上下分屏

3. 快捷键

  • Cmd+D(macOS)/ Ctrl+D(Win/Linux):打开左右分屏,或在分屏已打开时切换方向,再按则关闭
  • Cmd+Shift+D / Ctrl+Shift+D:打开上下分屏,逻辑相同

两个快捷键都注册在全局 scope,可在「设置 → 键盘快捷键」里自定义修改。无已有分屏时自动选择最近使用的其他标签页作为参照页。

如果还需要其他功能或细节调整,随时告诉我。

@eryajf

eryajf commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

我突然想到,cmd+d当前在编辑区域默认应该是向下复制行,所以似乎有一些冲突(虽然都支持自定义,但是默认值好像也有点冲突?)
至于定义成什么更合适,这个建议可以再多调研几个常见编辑器的默认快捷键。

@encyc

encyc commented Aug 28, 2026

Copy link
Copy Markdown
Contributor Author

我比较喜欢的Ghostty上就是:
Cmd+D(macOS)/ Ctrl+D(Win/Linux):打开左右分屏
Cmd+Shift+D / Ctrl+Shift+D:打开上下分屏
Cmd+N:创建新窗口

@t8y2 t8y2 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Request changes —— pane 架构本身是对的(状态收敛在 queryStore、同标签双窗格互斥、持久化带失效校验、测试和 8 语言完整),但当前有三件事需要作者处理,其中 rebase 是语义性的,不适合代解:

  1. Rebase 冲突是语义性的:App.vue 里重排缩进的模板块,main 之后在块内新增了 @execute-pointer-down / 带参 @execute、Oracle 事务指示 props 和 zen mode 接线。手工解冲突若从 PR 的旧副本出发会静默回归执行快照与 Oracle 事务 UI。冲突共 4 个文件(App.vue、QueryEditor.vue、AppTabBar.vue、useDataGridActions.spec.ts)。另外请定义分屏在 zen mode 下的行为(当前参照窗格会在 zen 布局里照常渲染)。
  2. 只读保证有洞{ ...connection, read_only: true } 克隆保留了真实 connection id——该连接存在 write-unlock 会话时 connectionIsEffectivelyReadOnly 返回 false,参照窗格的控制台/网格会变回可编辑;且 ContentArea 的 activeResultConnection 在设置 activeResultExecutionTarget 时直接从 store 重读配置、绕过克隆。建议参照窗格的只读判定显式强制(独立 forcedReadOnly 传入路径),不依赖克隆对象。
  3. 参照窗格存在死控件:split ContentArea 只接了 reload/paginate/sort/execute-sql,@save-sql@structure-editor-saved@click-table 等未绑定——结构编辑器的保存按钮在参照窗格里点了没反应;format/compress request 信号与主窗格共享,主窗格格式化会同时打到参照编辑器。建议 view-only 模式下隐藏/禁用这些动作,或明确接线。

处理完(尤其冲突解决后请补一轮 typecheck + 针对 App.vue 接线的最小组件测试)我很乐意再 review。

@t8y2
t8y2 force-pushed the main branch 2 times, most recently from 920dc7c to c4cdcbc Compare September 1, 2026 10:08
Merge upstream/main (v0.6.0): tab bar position/grouping, Oracle manual
transaction indicators, zen mode, replace/SQL shortcut machinery — taking
main's semantic wiring (execute-pointer-down, parameterized execute,
preview-changes) and re-applying split-pane structure on top.

Review fixes:
- forcedReadOnly prop on ContentArea checked before every editing entry
  point (both grids, Nacos/MQ/Nacos-config consoles); split pane passes it
  explicitly so an active write-unlock session on the real connection can
  no longer make reference-pane grids editable through store re-reads
- TableStructureEditor gains readOnly presentation: footer save actions
  hidden, applyChanges rejected, Mod+S guarded — no more dead save button
  in the reference pane
- Wire the reference pane's remaining controls: cancel routes to the split
  tab's own execution, AI fix/selection routes to the global AI panel,
  object navigation (click-table/view-data/view-ddl/edit-structure/
  open-source/open-table/schema-change) routes to the main pane, structure
  editor close closes the reference view
- Pass null format/compress requests to the split pane so the shared
  signals can never reach the reference editor
- SQL shortcut keymap and DOM handler disabled under viewOnly
- Zen mode: split pane intentionally stays mounted (documented)
- Add ContentArea.splitPaneReadOnly.spec.ts guarding the wiring
@encyc

encyc commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

感谢详细的 review,三个问题都已处理(commit 2c603b5):

1. Rebase 冲突

已合并最新 main(v0.6.0)并按语义解决全部 5 个冲突文件。App.vue 的模板块以 main 为基准,保留了 @execute-pointer-down、带参 @execute@preview-changes-available、Oracle 事务指示 props(oracleTxnPossiblyDirty / isOracleManualTransaction)和新的 replace/SQL 快捷键机制,再把分屏结构重新套上;QueryEditor 的执行快捷键保留了 blockEditorActions 门控并与 main 的 createQueryEditorExecutionShortcutBindings 结合,SQL 快捷键 keymap/DOM handler 在 viewOnly 下显式禁用。zen mode 行为已在代码中定义:分屏参照窗格在 zen 布局下保持可用(并排对照本身即专注特性,窗格头部的「设为主窗格」按钮不依赖被隐藏的标签栏),见 App.vue 相关注释。

按建议补了接线守卫测试 ContentArea.splitPaneReadOnly.spec.ts(4 个用例:forcedReadOnly 全入口覆盖、分屏信号隔离、死控件接线、结构编辑器只读),另全量跑了 typecheck / lint / editor 套件(510 tests)与布局套件(51 tests)。

2. 只读保证

不再依赖克隆对象。ContentArea 新增 forcedReadOnly 独立 prop,在校验链最前侧强制:两张 DataGrid 的 :editable、NacosAccessControlConsole / MqAdminConsole / Nacos 配置三处 :read-only 判定均改为 forcedReadOnly || connectionIsEffectivelyReadOnly(...)。分屏实例显式传 forced-read-only,因此 write-unlock 会话激活时参照窗格的网格与控制台不再被 store 重读路径绕回可编辑。克隆的 read_only: true 保留作为第一层(供直接读 connection prop 的组件使用),但不再承担保证职责。

3. 死控件

  • 结构编辑器:新增 readOnly 呈现模式——隐藏底部保存动作栏、applyChanges() 直接拒绝、Mod+S 守卫,参照窗格中不再出现点了没反应的保存按钮
  • 明确接线@cancel 路由到分屏标签自身的执行取消;@fix-with-ai / @send-selection-to-ai 路由到全局 AI 面板;对象导航类(click-table / view-data / view-ddl / edit-structure / open-source / open-table / schema-change)显式路由到主窗格处理器(导航语义落在主窗格,与「设为主窗格」流程一致);@structure-editor-close 关闭参照视图
  • format/compress 信号:分屏实例改为显式传 null,彻底隔离主窗格的格式化/压缩信号

关于 Cmd+D 与复制行

补充调研:VS Code 的 Cmd+D 是多光标选中、分屏是 Cmd+\;JetBrains 系 Ctrl+D 默认复制行且分屏无默认键;iTerm2/Ghostty 用 Cmd+D / Cmd+Shift+D 分屏。当前实现的解析顺序与 VS Code 的上下文相关键位一致:编辑器聚焦时 Cmd+D 走 duplicateLine(编辑器 scope 的 keymap 先于全局 handler 且 preventDefault),焦点在表格/侧栏等非编辑器区域时走分屏。若认为默认值仍易混淆,duplicateLine 可在设置里改键,或我们可以把 splitTab 默认改为 Cmd+\(VS Code 语义)——倾向听维护者的定夺。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/desktop Desktop application or Tauri shell enhancement New feature or request ui-change Changes user-visible interface, text, or visual assets

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] 支持标签页分屏,可同时查看两个脚本或两张表

3 participants