Skip to content

fix(vscode): open source files in different tab group from preview#2826

Merged
davydkov merged 3 commits into
mainfrom
fix/preview-source-navigation
Apr 2, 2026
Merged

fix(vscode): open source files in different tab group from preview#2826
davydkov merged 3 commits into
mainfrom
fix/preview-source-navigation

Conversation

@davydkov

@davydkov davydkov commented Apr 1, 2026

Copy link
Copy Markdown
Member

Summary

  • When clicking a node in the preview panel, source files now open in a different tab group from the preview panel instead of potentially opening in the same group (which could hide/resize the preview)
  • Focus is always preserved on the diagram preview (preserveFocus: true)
  • Added findSourceViewColumn() utility that prefers an existing visible editor in another group, or picks the opposite column if none exists

Test plan

  • Open a LikeC4 project with preview panel open beside the editor
  • Click a node in the preview — source should open in the editor group, not the preview group
  • Preview panel should retain focus after clicking
  • Test with single and multiple editor groups

🤖 Generated with Claude Code

When clicking a node in the preview panel, source files now open in a
tab group separate from the preview and preserve focus on the diagram.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Apr 1, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 1f8a5ea

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 20 packages
Name Type
likec4-vscode Patch
likec4 Patch
@likec4/docs-astro Patch
@likec4/playground Patch
@likec4/style-preset Patch
@likec4/styles Patch
@likec4/config Patch
@likec4/core Patch
@likec4/diagram Patch
@likec4/generators Patch
@likec4/language-server Patch
@likec4/language-services Patch
@likec4/layouts Patch
@likec4/leanix-bridge Patch
@likec4/log Patch
@likec4/mcp Patch
@likec4/react Patch
@likec4/tsconfig Patch
@likec4/vite-plugin Patch
@likec4/vscode-preview Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai

coderabbitai Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f1437bf9-9fb4-4f08-858d-da2332a368f1

📥 Commits

Reviewing files that changed from the base of the PR and between 9c5e3e6 and 1f8a5ea.

📒 Files selected for processing (1)
  • packages/vscode/src/utils.ts

📝 Walkthrough

Walkthrough

Derives editor placement from the diagram preview panel, adds utilities to open editors beside the preview, updates panel state and messenger/command flows to use the new utilities, and adjusts logging, RPC signatures, and a Projects screen data hook.

Changes

Cohort / File(s) Summary
Changeset Entry
.changeset/fix-preview-source-navigation.md
Adds a patch changeset documenting the preview→source navigation change for likec4-vscode.
Editor utilities
packages/vscode/src/utils.ts
Adds findViewColumnForEditor(previewColumn) and showEditorNextToPreview(...) to compute a non-preview view column and open a document with configurable preserveFocus, selection, and reveal behavior.
Panel state & lifecycle
packages/vscode/src/panel/useDiagramPanel.ts
Exports reactive panelViewColumn, sets panel viewColumn on create/change, changes teardown to resetState(), updates webview close handling, adjusts RPC subscription behaviors, and sets preserveFocus:false/retainContextWhenHidden:true on panel creation.
Command
packages/vscode/src/commands/locate.ts
Replaces active-editor-based viewColumn logic with showEditorNextToPreview(...); moves reveal handling into utility and sets caller preserveFocus:false.
Messenger / RPC handlers
packages/vscode/src/panel/activateMessenger.ts, packages/vscode/src/useRpc.ts
Calls showEditorNextToPreview for view-change opens; changes onDidChangeModel to receive params, adds onDidChangeProjects, and tweaks send/return/error handling and logging in messenger handlers.
Preview UI
packages/vscode-preview/src/screens/Projects.tsx
Replaces useSuspenseQuery with useQuery and conditionally renders LikeC4ProjectsOverview only when data is truthy.
Language server logging
packages/language-server/src/model-change/ModelChanges.ts
Reduces a catch log from logger.error to logger.warn while preserving error return payload.
Logger config
packages/vscode/src/useExtensionLogger.ts
Console sink switched to ANSI color formatter; likec4 logger minimum level lowered to trace.
Build config
packages/vscode/tsdown.config.ts
Resolves @likec4/config/schema.json via import.meta.resolve(import.meta.url, ...) and converts URL to file path with fileURLToPath during copy.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant P as DiagramPanel
    participant S as Utils (findViewColumnForEditor / showEditorNextToPreview)
    participant V as VSCode.Window/Editor

    rect rgba(200,200,255,0.5)
    U->>P: Trigger "open source" (locate / view-change)
    end
    rect rgba(200,255,200,0.5)
    P->>S: provide panelViewColumn + location + options
    S-->>P: computes target non-preview ViewColumn
    end
    rect rgba(255,200,200,0.5)
    S->>V: vscode.window.showTextDocument(uri, { viewColumn: target, preserveFocus, selection? })
    V-->>U: Source file opened (selection/reveal applied per options)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The PR description provides a clear summary, test plan, and implementation details about opening source files in different tab groups while preserving preview focus, but the template checklist is entirely unchecked with no responses provided. Complete the template checklist by checking off applicable items or providing explanations for any items that don't apply to this change.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: opening source files in a different tab group from the preview panel, which is the primary objective of this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/preview-source-navigation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 `@packages/vscode/src/panel/useDiagramPanel.ts`:
- Line 261: panelViewColumn currently reads from a non-reactive state.panel so
the computed caches null and won't update when the panel is created or moved;
change state to expose a reactive ref for the panel or its viewColumn and make
panelViewColumn compute from that ref (e.g., create a ref like panelRef =
ref<...>(null) or panelViewColumnRef = ref<number | null>(null) and update it
when you create the panel and on the panel's view-column change event), then
replace computed(() => state.panel?.viewColumn ?? null) with computed(() =>
panelRef.value?.viewColumn ?? panelViewColumnRef.value ?? null) (and ensure the
panel creation code sets panelRef.value and listens to
panel.onDidChangeViewColumn to update panelViewColumnRef.value) so locate.ts /
activateMessenger.ts get fresh values via toValue(preview.panelViewColumn).
🪄 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: 7271ce91-021e-4063-90e1-923cf28389f8

📥 Commits

Reviewing files that changed from the base of the PR and between a8c09b9 and 8c8e960.

📒 Files selected for processing (5)
  • .changeset/fix-preview-source-navigation.md
  • packages/vscode/src/commands/locate.ts
  • packages/vscode/src/panel/activateMessenger.ts
  • packages/vscode/src/panel/useDiagramPanel.ts
  • packages/vscode/src/utils.ts

Comment thread packages/vscode/src/panel/useDiagramPanel.ts Outdated
@a-scolan

a-scolan commented Apr 1, 2026

Copy link
Copy Markdown
Collaborator

Good one, got annoyed by this quite a few times

@davydkov davydkov force-pushed the fix/preview-source-navigation branch from 7229e52 to 9c5e3e6 Compare April 1, 2026 23:45

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
packages/vscode-preview/src/screens/Projects.tsx (1)

32-32: Use the ViewId() factory function instead of as ViewId cast.

Replace 'index' as ViewId with ViewId('index') to avoid direct type assertion and maintain type safety. The ViewId() factory is available from @likec4/core and is the proper typed helper for creating ViewId values.

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

In `@packages/vscode-preview/src/screens/Projects.tsx` at line 32, Replace the
unsafe type assertion in the call to ExtensionApi.navigateTo by using the ViewId
factory: change the argument currently passed as 'index' as ViewId to
ViewId('index') so the call becomes ExtensionApi.navigateTo(ViewId('index'),
projectId); update the import to ensure ViewId is imported from `@likec4/core` if
not already present.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/vscode-preview/src/screens/Projects.tsx`:
- Line 11: The Projects component currently relies on Suspense being removed and
therefore renders nothing when useQuery(queries.projectsOverview) returns both
data and error as undefined; restore an explicit loading state in the Projects
component by checking the query result (the variables data and error returned
from useQuery(queries.projectsOverview)) and render a loading placeholder
(spinner/text) while data === undefined && error === undefined; update the
render branch around the current conditional at the top of Projects.tsx (where
data, error, refetch are deconstructed) to return the loading UI, then continue
to handle error and data states as before so the screen is not blank during
initial load.

In `@packages/vscode/src/utils.ts`:
- Around line 79-82: The JSDoc for applySelection is incorrect: it says "Whether
to show the editor" but applySelection actually controls whether the selection
option is passed to showTextDocument (the editor is always shown). Update the
JSDoc for the applySelection property to clearly state that it toggles applying
the provided selection to the editor (i.e., whether to pass the selection to
showTextDocument), keep the `@default` true if intended, and ensure references to
selection and showTextDocument are mentioned so future readers understand the
semantics.

---

Nitpick comments:
In `@packages/vscode-preview/src/screens/Projects.tsx`:
- Line 32: Replace the unsafe type assertion in the call to
ExtensionApi.navigateTo by using the ViewId factory: change the argument
currently passed as 'index' as ViewId to ViewId('index') so the call becomes
ExtensionApi.navigateTo(ViewId('index'), projectId); update the import to ensure
ViewId is imported from `@likec4/core` if not already present.
🪄 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: f13f8407-2905-4344-b76b-86a401a3d26d

📥 Commits

Reviewing files that changed from the base of the PR and between 7229e52 and 9c5e3e6.

📒 Files selected for processing (10)
  • .changeset/fix-preview-source-navigation.md
  • packages/language-server/src/model-change/ModelChanges.ts
  • packages/vscode-preview/src/screens/Projects.tsx
  • packages/vscode/src/commands/locate.ts
  • packages/vscode/src/panel/activateMessenger.ts
  • packages/vscode/src/panel/useDiagramPanel.ts
  • packages/vscode/src/useExtensionLogger.ts
  • packages/vscode/src/useRpc.ts
  • packages/vscode/src/utils.ts
  • packages/vscode/tsdown.config.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/fix-preview-source-navigation.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/vscode/src/commands/locate.ts
  • packages/vscode/src/panel/useDiagramPanel.ts
  • packages/vscode/src/panel/activateMessenger.ts


export function ProjectsScreen() {
const { data, error, refetch } = useSuspenseQuery(queries.projectsOverview)
const { data, error, refetch } = useQuery(queries.projectsOverview)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Restore an explicit loading state after dropping Suspense.

At Line 11 and Lines 27-35, the component now renders nothing while the query is pending (data and error are both undefined). This creates a blank screen during initial load.

Suggested patch
-  const { data, error, refetch } = useQuery(queries.projectsOverview)
+  const { data, error, refetch, isPending } = useQuery(queries.projectsOverview)
@@
       {error && <ErrorMessage error={error} onReset={refetch} />}
+      {isPending && <div>Loading projects…</div>}
       {data &&
         (
           <LikeC4ProjectsOverview

Also applies to: 27-35

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

In `@packages/vscode-preview/src/screens/Projects.tsx` at line 11, The Projects
component currently relies on Suspense being removed and therefore renders
nothing when useQuery(queries.projectsOverview) returns both data and error as
undefined; restore an explicit loading state in the Projects component by
checking the query result (the variables data and error returned from
useQuery(queries.projectsOverview)) and render a loading placeholder
(spinner/text) while data === undefined && error === undefined; update the
render branch around the current conditional at the top of Projects.tsx (where
data, error, refetch are deconstructed) to return the loading UI, then continue
to handle error and data states as before so the screen is not blank during
initial load.

Comment thread packages/vscode/src/utils.ts Outdated
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Signed-off-by: Denis Davydkov <denis@davydkov.com>
@davydkov davydkov merged commit 0a4af22 into main Apr 2, 2026
8 of 9 checks passed
@davydkov davydkov deleted the fix/preview-source-navigation branch April 2, 2026 00:12
@likec4-ci likec4-ci Bot mentioned this pull request Apr 1, 2026
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.

2 participants