Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,22 @@ const { t } = useI18n();
const {
status: reviewStatus,
gitRevertFile, gitRevertAll,
refresh: refreshReview,
} = useReview();
const { switching, pickWorkspace } = useWorkspace();
const { loadCurrentWorkspace, currentWorkspace, activeRoot } = useStore();

// The changes panel is scoped to a single active folder (backend workspace_root):
// activeRoot when set, otherwise the workspace's first folder.
const activeFolderPath = activeRoot || currentWorkspace?.folders?.[0] || '';
const activeFolderName = activeFolderPath.split('/').pop() || activeFolderPath.split('\\').pop() || '';

// Re-fetch the diff whenever the folder or workspace changes. The backend
// updates its workspace_root before either value settles, so by now
// get_review_status reads the newly-selected folder. Without this the panel
// keeps showing the previous folder's (or workspace's) changes.
useEffect(() => {
refreshReview();
}, [refreshReview, activeFolderPath, currentWorkspace?.id]);

const handleDeleteSessionConfirm = async () => {
const id = confirmDeleteSession;
Expand Down Expand Up @@ -264,8 +272,6 @@ const { t } = useI18n();
{panelContent === 'review' ? (
<ReviewPanel
gitFiles={reviewStatus.changes.git_files}
folderName={activeFolderName}
folderPath={activeFolderPath}
onClose={() => setRightPanel(null)}
onRevert={gitRevertFile}
onRevertAll={gitRevertAll}
Expand Down
15 changes: 2 additions & 13 deletions frontend/src/components/ReviewChip.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo, useState } from 'react';
import { reviewPanelStyles } from '@/utils/theme-styles';
import { CheckCircle, X, GitFork, CaretDown, FolderOpen } from '@phosphor-icons/react';
import { CheckCircle, X, GitFork, CaretDown } from '@phosphor-icons/react';
import { theme } from '@/theme';
import type { ReviewFileInfo } from '@/hooks/useReview';
import { computeDiff } from '@/utils/diff';
Expand Down Expand Up @@ -160,33 +160,22 @@ function FileCard({ file, onRevert }: FileCardProps) {

interface ReviewPanelProps {
gitFiles: ReviewFileInfo[];
/** Active folder the diff is scoped to — shown so the source is unambiguous. */
folderName?: string;
folderPath?: string;
onClose: () => void;
onRevert: (path: string) => void;
onRevertAll: () => void;
}

export function ReviewPanel({
gitFiles,
folderName,
folderPath,
onClose,
onRevert,
onRevertAll,
}: ReviewPanelProps) {
return (
<div style={reviewPanelStyles.panel}>
{/* Header — title + which folder these changes come from */}
{/* Header */}
<div style={reviewPanelStyles.head}>
<span style={{ ...reviewPanelStyles.headTitle, flex: '0 0 auto' }}>Changes</span>
{folderName && (
<span style={reviewPanelStyles.headFolder} title={folderPath || folderName}>
<FolderOpen size={11} style={{ flexShrink: 0 }} />
<span style={reviewPanelStyles.headFolderName}>{folderName}</span>
</span>
)}
<span style={{ flex: 1 }} />
<button className="close-btn" onClick={onClose} title="Close"><X size={15} /></button>
</div>
Expand Down
5 changes: 0 additions & 5 deletions frontend/src/utils/theme-styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,6 @@ export const reviewPanelStyles: Record<string, CSSProperties> = {
flexShrink: 0,
},
headTitle: { flex: 1, color: theme.text, fontSize: 13, fontWeight: 600 },
headFolder: {
display: 'flex', alignItems: 'center', gap: 4, minWidth: 0,
color: theme.dim, fontSize: 11.5,
},
headFolderName: { overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' },
closeBtn: {
// Uses .close-btn from primitives.css — same as BgTasks
},
Expand Down
12 changes: 9 additions & 3 deletions src/backend/review.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,14 @@ pub fn git_diff_files(workspace_root: &Path) -> Result<Vec<ReviewFileInfo>, Stri
use crate::backend::cmd::no_window_cmd;

// 1. Get list of changed files vs HEAD (staged + unstaged, no untracked).
// `--relative` scopes the diff to `workspace_root` — the selected folder —
// excluding changes elsewhere in the repo and emitting folder-relative
// paths. Without it, `git diff` reports the whole repository even when run
// from a subfolder, so the panel would show changes outside the folder.
// On failure (not a git repo, or no commits yet) treat the tracked set
// as empty and still surface untracked files in step 3.
let name_output = no_window_cmd("git")
.args(["diff", "HEAD", "--name-only"])
.args(["diff", "HEAD", "--name-only", "--relative"])
.current_dir(workspace_root)
.output()
.map_err(|e| format!("git failed: {e}"))?;
Expand All @@ -148,9 +152,11 @@ pub fn git_diff_files(workspace_root: &Path) -> Result<Vec<ReviewFileInfo>, Stri
// 2. For each file, get unified diff and also the original/current content
let mut files = Vec::new();
for name in &names {
// Original content (from HEAD)
// Original content (from HEAD). `name` is folder-relative (see
// `--relative` above), so prefix `./` to resolve it against the cwd
// rather than the repo root.
let original = no_window_cmd("git")
.args(["show", &format!("HEAD:{}", name)])
.args(["show", &format!("HEAD:./{}", name)])
.current_dir(workspace_root)
.output()
.ok()
Expand Down
4 changes: 3 additions & 1 deletion src/commands/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,8 +523,10 @@ pub async fn get_git_context(state: State<'_, AppState>) -> Result<GitContext, S
.unwrap_or_else(|| "no git".to_string());

// Diff stats vs HEAD so both staged and unstaged changes are counted.
// `--relative` scopes the stats to the selected folder (`root`), matching
// the changes panel; without it git reports the whole repo from a subfolder.
let diff_output = no_window_cmd("git")
.args(["diff", "HEAD", "--numstat"])
.args(["diff", "HEAD", "--numstat", "--relative"])
.current_dir(&*root)
.output()
.ok()
Expand Down
Loading