feat(desktop): add Excel/spreadsheet viewer with diff support#1
feat(desktop): add Excel/spreadsheet viewer with diff support#1
Conversation
Add the ability to view .xlsx, .xls, .xlsm, .xlsb, and .ods files natively instead of showing "Binary file preview not supported". Features: - Full spreadsheet rendering with ExcelJS (formatting, borders, merged cells, fonts, colors, theme colors with tint, rich text, row heights, text wrapping, vertical text) - Print area aware column/row range detection - Auto fit-to-width column scaling - Multiple sheet tab navigation - Side-by-side diff viewer with cell-level change highlighting - Diff navigation (Prev/Next) with synchronized scrolling - Git binary file read via new readGitFileBinary tRPC procedure
|
Caution Review failedThe pull request is closed. ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (12)
📝 WalkthroughWalkthroughThis PR adds comprehensive spreadsheet file viewing and diffing support to the desktop application. It introduces a new tRPC endpoint for reading binary git blobs, Excel workbook parsing logic, dedicated UI components for viewing spreadsheets, and routing updates to display spreadsheets in specialized viewers instead of generic binary file messages. Changes
Sequence DiagramssequenceDiagram
participant User
participant UI as File Viewer
participant TRPC as tRPC Client
participant Server
participant Git as Git Repository
participant Parser as Workbook Parser
participant Renderer as Spreadsheet Renderer
User->>UI: View spreadsheet file
UI->>TRPC: readFile(filePath) query
TRPC->>Server: Fetch file data
Server->>Git: cat-file -p (read blob)
Git-->>Server: Binary blob
Server-->>TRPC: Base64-encoded content
TRPC-->>UI: File data received
UI->>Parser: parseWorkbook(base64Content)
Parser->>Parser: Decode & extract sheets, rows, cells
Parser->>Parser: Apply styling, merges, formulas
Parser-->>UI: ParsedSheet[]
UI->>Renderer: Render with sheets, column widths
Renderer->>Renderer: Calculate column widths
Renderer->>Renderer: Render rows with cells & styling
Renderer-->>User: Spreadsheet table display
sequenceDiagram
participant User
participant DiffUI as Spreadsheet Diff Viewer
participant Hook as useSpreadsheetDiff
participant TRPC as tRPC Client
participant Server
participant Parser as Workbook Parser
participant Differ as Diff Engine
participant Renderer as Diff Renderer
User->>DiffUI: View spreadsheet diff
DiffUI->>Hook: Load diff (workspaceId, filePath, diffCategory, commitHash)
Hook->>TRPC: Query original version (HEAD)
TRPC->>Server: Fetch blob at HEAD:path
Server-->>TRPC: Base64 content
Hook->>TRPC: Query modified version (working copy)
TRPC->>Server: Fetch file from worktree
Server-->>TRPC: Base64 content
Hook->>Parser: parseWorkbook(original base64)
Parser-->>Hook: ParsedSheet[] (original)
Hook->>Parser: parseWorkbook(modified base64)
Parser-->>Hook: ParsedSheet[] (modified)
Hook->>Differ: Align sheets, compute row/cell diffs
Differ->>Differ: Mark cells as added/removed/modified
Differ-->>Hook: DiffParsedSheet[]
Hook-->>DiffUI: Diff data ready
DiffUI->>Renderer: Render side-by-side tables with diff colors
Renderer->>Renderer: Color cells (red=removed, green=added, yellow=modified)
Renderer->>Renderer: Sync scroll positions between panes
Renderer-->>User: Synchronized diff display
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
#1 ダッシュボード戻り時のポーリング永続: activeWorkspaceId=null時に deactivateAll()を呼ぶ。setActiveWorkspace(null)対応追加 #2 deactivateされたWSのMapエントリ蓄積: 問題の根本はregisterが増え続ける ことではなく、全WSがisActive:trueで起動していたこと。#3で解消 #3 起動直後の全WSポーリング並走: registerWorkspaceをisActive:falseに変更。 タイマーはactivateWorkspace/setActiveWorkspaceでのみ起動 #4 WS切替時の初回表示5s遅延: activateWorkspace/setActiveWorkspace時に 即時sync(syncPRStatus+syncPRComments)を実行 追加改善: - startTimersに防衛的stopTimers追加(二重タイマー防止) - onWindowFocus()をデッドコードとして削除 - deactivateAll()メソッド追加
…sions #1 Target.closeTarget UI integrity v1/v2 secondary tab registry が webview "close" イベントを購読。 MCP の Target.closeTarget で Chromium が webContents を破棄すると guest 側が close を発火し、registry が closeTab → unregisterTab 経由で paneTabTargetIds を整理。tab バー UI と CDP allowedTargetIds が同期した状態を保つ。 #2 target="_blank" / window.open を MCP 可視に windowOpenHandler の非 new-window 分岐で new-window event を emit していた箇所を create-tab-requested:${paneId} に置換。同じペイン 内の secondary tab として生成されるので paneTabTargetIds に入り、 MCP が list_pages / select_page で扱える。Chrome の target="_blank" デフォルト (新タブ) 挙動に揃う。split-pane / workspace-tab が 欲しいケースは既存の "Open in Split" コンテキストメニューでカバー。 #3 非 media 権限の UI prompt 化 SITE_PERMISSION_KINDS に geolocation / notifications / clipboard-read を追加。browser-site-permission-manager が Electron の setPermissionRequestHandler で media 同様の consent flow に乗せる。 既存の permissionRequested イベント経路はそのまま再利用。 認識しない permission は従来通り permissive で許可。
Summary
readGitFileBinarytRPCプロシージャを追加Changes
New files (6)
SpreadsheetViewer/— Excel表示コンポーネント群parseWorkbook.ts— ExcelJSパースロジック(書式、罫線、テーマカラー、結合セル対応)SpreadsheetViewer.tsx— 通常表示コンポーネントSpreadsheetDiffViewer.tsx— サイドバイサイドdiff表示useSpreadsheetData.ts— ファイル読み込み+パースhookuseSpreadsheetDiff.ts— diff用データ取得+比較hookindex.ts— barrel exportModified files (7)
file-types.ts—isSpreadsheetFile()追加 (+10行)file-contents.ts—readGitFileBinarytRPCプロシージャ追加 (+49行)FileViewerContent.tsx— バイナリ/diff分岐にスプレッドシート判定追加 (+37行)FileViewerPane.tsx— 新props受け渡し (+4行)WorkspaceFilePreviewContent.tsx— V2プレビューにスプレッドシート分岐 (+10行)package.json— exceljs依存追加bun.lock— lockfile更新Test plan
Summary by CodeRabbit
Release Notes