Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

improvement: add Preview button to AI apply confirmation dialog#756

Merged
breaking-brake merged 2 commits intomainbreaking-brake/cc-wf-studio:mainfrom
improvement/ai-apply-dialog-overview-previewbreaking-brake/cc-wf-studio:improvement/ai-apply-dialog-overview-previewCopy head branch name to clipboard
May 4, 2026
Merged

improvement: add Preview button to AI apply confirmation dialog#756
breaking-brake merged 2 commits intomainbreaking-brake/cc-wf-studio:mainfrom
improvement/ai-apply-dialog-overview-previewbreaking-brake/cc-wf-studio:improvement/ai-apply-dialog-overview-previewCopy head branch name to clipboard

Conversation

@breaking-brake
Copy link
Copy Markdown
Owner

@breaking-brake breaking-brake commented May 4, 2026

Summary

Add a Preview button to the AI edit confirmation dialog (DiffPreviewDialog) so users can inspect the proposed workflow in Overview format before accepting. As a prerequisite refactor, the Overview view is split into a reusable WorkflowOverview component so it can be hosted in multiple containers (full-screen mode, dialog overlay, and future call sites).

What Changed

Lets users review AI-proposed workflows visually (Mermaid + per-node instructions) without leaving the confirmation flow.

Before

  • The confirmation dialog only listed textual diff (added/removed/modified nodes, connections, files).
  • To see the proposed workflow visually, the user had to accept first or open Overview manually after applying.
  • OverviewMode was tightly coupled to the canvas page (Git diff context, edit-mode switching), making it hard to reuse elsewhere.

After

  • A "Preview" button appears in the dialog footer.
  • Clicking it opens a near-fullscreen overlay (z-index 10002) rendering the proposed workflow with WorkflowOverview.
  • Closing the overlay (X / ESC / background click) returns to the confirmation dialog without affecting Accept/Reject state.
  • OverviewMode is now a thin wrapper around the reusable WorkflowOverview, which accepts splitRatioStorageKey so each host keeps independent layout preferences (the preview uses its own key to avoid leaking into the main Overview).

Changes

  • src/webview/src/components/overview/WorkflowOverview.tsx - New presentational component (extracted from OverviewMode); renders header + Mermaid + instructions split pane; accepts splitRatioStorageKey and hideHeader.
  • src/webview/src/components/overview/OverviewMode.tsx - Reduced to a thin wrapper delegating to WorkflowOverview; preserves the existing public API.
  • src/webview/src/components/dialogs/DiffPreviewDialog.tsx - Add workflow prop, footer Preview button, nested Radix Dialog overlay (z-index 10002) hosting WorkflowOverview; visible close button at top-right with ESC / X / background-click behavior; resets showOverview when the parent dialog closes.
  • src/webview/src/App.tsx - Pass pendingMcpApply.workflow into DiffPreviewDialog.
  • src/webview/src/i18n/translation-keys.ts - Add dialog.diffPreview.previewOverview and dialog.diffPreview.closeOverview keys.
  • src/webview/src/i18n/translations/{en,ja,ko,zh-CN,zh-TW}.ts - Localize the new keys (label kept short: "Preview" / "プレビュー" / "미리보기" / "预览" / "預覽").
  • CLAUDE.md - Extend dialog z-index hierarchy from 3 tiers to 4 tiers; document new DIALOG_PREVIEW_OVERLAY = 10002 tier and update the dialog inventory table.

Testing

  • Manual E2E: trigger AI apply_workflow; Preview button appears; click opens full-size overlay with proposed workflow; ESC / X / background-click each return to the dialog without closing it; Accept/Reject continue to work.
  • Verified existing canvas Overview mode unchanged (split ratio not leaked between contexts).
  • npm run check (Biome) passes.
  • npm run build (extension + webview) passes.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a "Preview Overview" button that opens a full-size overlay for workflow visualization
    • Overview shows diagram and instructions in a resizable two-pane layout with persisted split ratio
    • Keyboard resizing (Arrow keys, Home/End) and node-click navigation that scrolls instructions
    • Focus-based navigation to highlight and scroll to specific nodes
  • Internationalization

    • Added preview overview labels in English, Japanese, Korean, Simplified Chinese, and Traditional Chinese
  • Documentation

    • Updated dialog layering guidelines to include the full-size preview overlay layer

- Extract WorkflowOverview from OverviewMode for reuse
- Add Preview button to DiffPreviewDialog footer
- Show proposed workflow in z-index 10002 overlay
- Document new DIALOG_PREVIEW_OVERLAY tier in CLAUDE.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 4, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c09a4fd8-dcfb-44a7-ae22-038a50690208

📥 Commits

Reviewing files that changed from the base of the PR and between 43fe11c and c750f40.

📒 Files selected for processing (2)
  • CLAUDE.md
  • src/webview/src/components/overview/WorkflowOverview.tsx
✅ Files skipped from review due to trivial changes (1)
  • CLAUDE.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/webview/src/components/overview/WorkflowOverview.tsx

📝 Walkthrough

Walkthrough

Adds a full‑size WorkflowOverview overlay accessible from DiffPreviewDialog, passes workflow data into the dialog, refactors OverviewMode into a thin wrapper, introduces WorkflowOverview as a reusable two‑pane viewer with splitter/focus behavior, adds i18n keys, and updates dialog z-index documentation to include a new preview overlay layer.

Changes

Workflow Overview in Diff Preview

Layer / File(s) Summary
Type Definitions / i18n keys
src/webview/src/i18n/translation-keys.ts
Added dialog.diffPreview.previewOverview and dialog.diffPreview.closeOverview.
App Wiring
src/webview/src/App.tsx
Passes workflow={pendingMcpApply?.workflow ?? null} into DiffPreviewDialog.
Dialog Integration
src/webview/src/components/dialogs/DiffPreviewDialog.tsx
Added optional `workflow?: Workflow
Core UI Component
src/webview/src/components/overview/WorkflowOverview.tsx
New/updated component exposing WorkflowOverviewProps with focusRequest, parseError, splitRatioStorageKey, hideHeader. Implements two-pane layout with MermaidDiagram, InstructionsPanel/empty state, draggable keyboard-accessible splitter, persisted ratio via localStorage, node-click navigation, focusRequest scrolling, parse-error and loading states, and cleanup of drag listeners.
OverviewMode Refactor
src/webview/src/components/overview/OverviewMode.tsx
Replaced prior in-file implementation with a thin wrapper that forwards props into WorkflowOverview.
Localized Labels
src/webview/src/i18n/translations/{en,ja,ko,zh-CN,zh-TW}.ts
Added dialog.diffPreview.previewOverview and dialog.diffPreview.closeOverview translations for supported locales.
Design Guidelines
CLAUDE.md
Expanded Radix UI dialog z-index model from three tiers to four by adding DIALOG_PREVIEW_OVERLAY: 10002 and updating examples, checklist, and current-dialogs table to reflect DiffPreviewDialog confirmation at 10001 and overview/full-size preview at 10002.

Sequence Diagram

sequenceDiagram
    actor User
    participant DiffPreviewDialog as DiffPreviewDialog
    participant WorkflowOverview as WorkflowOverview Overlay
    participant MermaidDiagram as MermaidDiagram
    participant InstructionsPanel as InstructionsPanel

    User->>DiffPreviewDialog: Click "Preview Overview" button
    DiffPreviewDialog->>DiffPreviewDialog: set showOverview = true
    DiffPreviewDialog->>WorkflowOverview: render with workflow prop
    WorkflowOverview->>MermaidDiagram: initialize diagram
    WorkflowOverview->>InstructionsPanel: load instructions pane
    User->>MermaidDiagram: click node
    MermaidDiagram->>WorkflowOverview: handleNodeClick(nodeId)
    WorkflowOverview->>InstructionsPanel: scroll to node
    User->>WorkflowOverview: drag splitter / press arrow keys
    WorkflowOverview->>WorkflowOverview: update ratio, persist to localStorage
    User->>WorkflowOverview: Click "Close Preview"
    WorkflowOverview->>DiffPreviewDialog: set showOverview = false
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

released

Poem

🐰
I nibbled code beneath the moonlit view,
Split panes and nodes in tidy two,
A preview blooms at z‑one‑zero‑zero‑oh‑two,
Ratios saved, the workflow hops anew,
Close the preview — the rabbit applauds you.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding a Preview button to the AI apply confirmation dialog, which is the primary feature across the modified DiffPreviewDialog and supporting components.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for 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 improvement/ai-apply-dialog-overview-preview

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
Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@CLAUDE.md`:
- Around line 407-414: The fenced z-index table block is untagged and triggers
markdownlint MD040; update the opening triple-backtick for that z-index block
(the fenced block showing "レイヤー  z-index  用途" and the subsequent rows including
Base, Nested, Confirm, PreviewOverlay) to include a language tag (preferably
"text") so it becomes ```text and resolves the lint warning.

In `@src/webview/src/components/overview/WorkflowOverview.tsx`:
- Around line 255-257: In WorkflowOverview.tsx update the splitter's ARIA
semantics: change the element currently rendered with role="slider" and
aria-orientation="vertical" to use aria-orientation="horizontal" so
screen-reader semantics match the left/right (ArrowLeft/ArrowRight) keyboard
handling; verify the splitter element in the component that renders the slider
(the DOM node with role="slider") also exposes appropriate
aria-valuemin/aria-valuemax/aria-valuenow if present and that existing key
handlers remain aligned with horizontal orientation.
- Around line 83-95: The component can persist the old context's ratio into a
newly changed splitRatioStorageKey; to fix, add an effect that listens for
changes to splitRatioStorageKey and calls
setRatio(loadStoredRatio(splitRatioStorageKey)) so the component hydrates the
correct ratio before any write, and update the persisting effect (the useEffect
that writes localStorage.setItem using ratio and splitRatioStorageKey) to avoid
writing immediately on a key switch — e.g., track the previous key with a ref
(prevKeyRef) and skip the first persist when splitRatioStorageKey !==
prevKeyRef.current, then update prevKeyRef.current after hydration; reference:
ratio, splitRatioStorageKey, loadStoredRatio, setRatio, the persisting useEffect
and a new useEffect watching splitRatioStorageKey.
- Around line 106-126: The mousemove/mouseup listeners added in
handleSplitterMouseDown (which registers handleMove and handleUp and flips
isResizingRef) are not removed if the component unmounts mid-drag; add a cleanup
to remove those listeners on unmount and reset isResizingRef. Implement this by
returning a cleanup from a useEffect that references the same handler functions
(or stores the active handlers on refs) so
document.removeEventListener('mousemove', handleMove) and
document.removeEventListener('mouseup', handleUp) are called on unmount and set
isResizingRef.current = false; ensure references match the ones added in
handleSplitterMouseDown (handleMove, handleUp, isResizingRef, splitContainerRef,
setRatio).
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a45db0e-9e0d-409c-9678-27d29454e013

📥 Commits

Reviewing files that changed from the base of the PR and between fdd0617 and 43fe11c.

📒 Files selected for processing (11)
  • CLAUDE.md
  • src/webview/src/App.tsx
  • src/webview/src/components/dialogs/DiffPreviewDialog.tsx
  • src/webview/src/components/overview/OverviewMode.tsx
  • src/webview/src/components/overview/WorkflowOverview.tsx
  • src/webview/src/i18n/translation-keys.ts
  • src/webview/src/i18n/translations/en.ts
  • src/webview/src/i18n/translations/ja.ts
  • src/webview/src/i18n/translations/ko.ts
  • src/webview/src/i18n/translations/zh-CN.ts
  • src/webview/src/i18n/translations/zh-TW.ts

Comment thread CLAUDE.md Outdated
Comment on lines +83 to +95
const [ratio, setRatio] = useState<number>(() => loadStoredRatio(splitRatioStorageKey));
const splitContainerRef = useRef<HTMLDivElement>(null);
const isResizingRef = useRef(false);
const instructionsRef = useRef<InstructionsPanelHandle>(null);
const [activeSanitizedNodeId, setActiveSanitizedNodeId] = useState<string | null>(null);

useEffect(() => {
try {
localStorage.setItem(splitRatioStorageKey, ratio.toString());
} catch {
// ignore quota errors
}
}, [ratio, splitRatioStorageKey]);
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 4, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Reload ratio on splitRatioStorageKey changes before persisting

When splitRatioStorageKey changes, Line 91 can write the previous context’s ratio into the new key before this component hydrates from that key. That can break the intended per-context isolation.

Suggested patch
 const [ratio, setRatio] = useState<number>(() => loadStoredRatio(splitRatioStorageKey));
+const skipNextPersistRef = useRef(false);

+useEffect(() => {
+  skipNextPersistRef.current = true;
+  setRatio(loadStoredRatio(splitRatioStorageKey));
+}, [splitRatioStorageKey]);
+
 useEffect(() => {
+  if (skipNextPersistRef.current) {
+    skipNextPersistRef.current = false;
+    return;
+  }
   try {
     localStorage.setItem(splitRatioStorageKey, ratio.toString());
   } catch {
     // ignore quota errors
   }
 }, [ratio, splitRatioStorageKey]);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [ratio, setRatio] = useState<number>(() => loadStoredRatio(splitRatioStorageKey));
const splitContainerRef = useRef<HTMLDivElement>(null);
const isResizingRef = useRef(false);
const instructionsRef = useRef<InstructionsPanelHandle>(null);
const [activeSanitizedNodeId, setActiveSanitizedNodeId] = useState<string | null>(null);
useEffect(() => {
try {
localStorage.setItem(splitRatioStorageKey, ratio.toString());
} catch {
// ignore quota errors
}
}, [ratio, splitRatioStorageKey]);
const [ratio, setRatio] = useState<number>(() => loadStoredRatio(splitRatioStorageKey));
const skipNextPersistRef = useRef(false);
const splitContainerRef = useRef<HTMLDivElement>(null);
const isResizingRef = useRef(false);
const instructionsRef = useRef<InstructionsPanelHandle>(null);
const [activeSanitizedNodeId, setActiveSanitizedNodeId] = useState<string | null>(null);
useEffect(() => {
skipNextPersistRef.current = true;
setRatio(loadStoredRatio(splitRatioStorageKey));
}, [splitRatioStorageKey]);
useEffect(() => {
if (skipNextPersistRef.current) {
skipNextPersistRef.current = false;
return;
}
try {
localStorage.setItem(splitRatioStorageKey, ratio.toString());
} catch {
// ignore quota errors
}
}, [ratio, splitRatioStorageKey]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/webview/src/components/overview/WorkflowOverview.tsx` around lines 83 -
95, The component can persist the old context's ratio into a newly changed
splitRatioStorageKey; to fix, add an effect that listens for changes to
splitRatioStorageKey and calls setRatio(loadStoredRatio(splitRatioStorageKey))
so the component hydrates the correct ratio before any write, and update the
persisting effect (the useEffect that writes localStorage.setItem using ratio
and splitRatioStorageKey) to avoid writing immediately on a key switch — e.g.,
track the previous key with a ref (prevKeyRef) and skip the first persist when
splitRatioStorageKey !== prevKeyRef.current, then update prevKeyRef.current
after hydration; reference: ratio, splitRatioStorageKey, loadStoredRatio,
setRatio, the persisting useEffect and a new useEffect watching
splitRatioStorageKey.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Skipping for now: in current usage each call site mounts WorkflowOverview with a fixed splitRatioStorageKey (no in-place key swap), so the race cannot trigger. Worth revisiting if a future caller needs to swap keys on the same instance.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@breaking-brake, that's a fair call — since all current mount sites use a stable key, the stale-write path is unreachable today. Acknowledged, no action needed now.

Would you like me to open a small follow-up GitHub issue to track the defensive guard (key-swap hydration) for if/when a dynamic splitRatioStorageKey caller is introduced?


🧠 Learnings used
Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 695
File: src/webview/src/components/toolbar/CommentaryOptionsDropdown.tsx:8-39
Timestamp: 2026-03-31T09:22:07.702Z
Learning: In this repo’s webview code (src/webview/src/**/*.tsx), it’s acceptable to reference React types such as `React.CSSProperties` without importing `React`. `types/react` provides the global `React` namespace, so `React.CSSProperties` should resolve correctly even with the `react-jsx` JSX transform. Do not flag missing `import React` for this specific type-usage pattern as an error during future code reviews.

Learnt from: breaking-brake
Repo: breaking-brake/cc-wf-studio PR: 699
File: src/webview/src/components/UndoRedoControls.tsx:55-89
Timestamp: 2026-04-02T12:27:24.241Z
Learning: For toolbar-related components under src/webview/src/components/ that intentionally implement a hover-only popover using the shared usePopoverHover hook (e.g., Popover.Root with open={isHovered}), do not raise code review findings about missing keyboard/focus support for that popover implementation while the unified accessibility fix is still pending. This exemption applies specifically when the hover-only pattern is clearly wired through usePopoverHover and the popover’s open state is controlled by hover (isHovered).

Comment thread src/webview/src/components/overview/WorkflowOverview.tsx
Comment thread src/webview/src/components/overview/WorkflowOverview.tsx
- Tag z-index fenced block as text in CLAUDE.md (MD040)
- Clean up document drag listeners on unmount
- Fix splitter aria-orientation to horizontal

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@breaking-brake breaking-brake merged commit c73f88a into main May 4, 2026
2 checks passed
@breaking-brake breaking-brake deleted the improvement/ai-apply-dialog-overview-preview branch May 4, 2026 13:25
@breaking-brake breaking-brake mentioned this pull request May 4, 2026
braking-brake-semantic-release Bot pushed a commit that referenced this pull request May 4, 2026
## [3.34.0](v3.33.1...v3.34.0) (2026-05-04)

### Features

* workflow Overview (View) mode with bidirectional canvas sync ([#755](#755)) ([fdd0617](fdd0617))

### Improvements

* add Preview button to AI apply confirmation dialog ([#756](#756)) ([c73f88a](c73f88a))
@braking-brake-semantic-release
Copy link
Copy Markdown

🎉 This PR is included in version 3.34.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

Morty Proxy This is a proxified and sanitized view of the page, visit original site.