diff --git a/src/main/frontend/app/components/git/git-changes.tsx b/src/main/frontend/app/components/git/git-changes.tsx index 994a16fe..8fd523aa 100644 --- a/src/main/frontend/app/components/git/git-changes.tsx +++ b/src/main/frontend/app/components/git/git-changes.tsx @@ -60,17 +60,14 @@ function FileSection({ const dirPath = file.includes('/') ? file.slice(0, file.lastIndexOf('/')) : '' const hunkState = fileHunkStates[file] - let checkboxChecked = false - let checkboxIndeterminate = false + const totalHunks = hunkState?.totalHunks ?? 0 + const selectedCount = hunkState?.selectedHunks.size ?? 0 + const allHunksSelected = totalHunks > 0 && selectedCount === totalHunks + const someHunksSelected = totalHunks > 0 && selectedCount > 0 + const fileSelectedWithNoHunks = totalHunks === 0 && (hunkState?.selected ?? false) - if (hunkState && hunkState.totalHunks > 0) { - const selectedCount = hunkState.selectedHunks.size - if (selectedCount === hunkState.totalHunks) { - checkboxChecked = true - } else if (selectedCount > 0) { - checkboxIndeterminate = true - } - } + const checkboxChecked = allHunksSelected || fileSelectedWithNoHunks + const checkboxIndeterminate = someHunksSelected && !allHunksSelected return (
{ const hunkState = useGitStore.getState().fileHunkStates[filePath] - if (!hunkState || hunkState.totalHunks === 0) { + if (!hunkState) { await handleSelectFile(filePath) } const updatedState = useGitStore.getState().fileHunkStates[filePath] + + if (!updatedState) { + initFileHunks(filePath, 0) + selectAllFileHunks(filePath) + return + } + + if (updatedState.totalHunks === 0) { + if (updatedState.selected) { + clearFileHunks(filePath) + } else { + selectAllFileHunks(filePath) + } + return + } + if (updatedState.selectedHunks.size === updatedState.totalHunks) { clearFileHunks(filePath) } else { selectAllFileHunks(filePath) } }, - [handleSelectFile, clearFileHunks, selectAllFileHunks], + [handleSelectFile, initFileHunks, clearFileHunks, selectAllFileHunks], ) const handleCommit = useCallback(async () => { @@ -113,8 +129,11 @@ export default function GitPanel({ projectName, hasStoredToken }: GitPanelProps) const allHunkStates = useGitStore.getState().fileHunkStates for (const [filePath, hunkState] of Object.entries(allHunkStates)) { - if (hunkState.selectedHunks.size === 0) continue - await (hunkState.selectedHunks.size === hunkState.totalHunks + const isZeroHunkSelected = hunkState.totalHunks === 0 && hunkState.selected + + if (hunkState.selectedHunks.size === 0 && !isZeroHunkSelected) continue + + await (isZeroHunkSelected || hunkState.selectedHunks.size === hunkState.totalHunks ? stageFile(projectName, filePath) : stageHunks(projectName, filePath, [...hunkState.selectedHunks])) } @@ -175,7 +194,9 @@ export default function GitPanel({ projectName, hasStoredToken }: GitPanelProps) } }, [projectName, token, refreshStatus]) - const hasSelectedChunks = Object.values(fileHunkStates).some((s) => s.selectedHunks.size > 0) + const hasSelectedChunks = Object.values(fileHunkStates).some( + (state) => state.selectedHunks.size > 0 || (state.totalHunks === 0 && state.selected), + ) return (
diff --git a/src/main/frontend/app/stores/git-store.ts b/src/main/frontend/app/stores/git-store.ts index 2f454a10..246442c7 100644 --- a/src/main/frontend/app/stores/git-store.ts +++ b/src/main/frontend/app/stores/git-store.ts @@ -43,7 +43,7 @@ export const useGitStore = create((set, get) => ({ set((state) => ({ fileHunkStates: { ...state.fileHunkStates, - [file]: { selectedHunks: new Set(), totalHunks }, + [file]: { selectedHunks: new Set(), totalHunks, selected: false }, }, })) }, @@ -73,7 +73,7 @@ export const useGitStore = create((set, get) => ({ set((s) => ({ fileHunkStates: { ...s.fileHunkStates, - [file]: { ...state, selectedHunks: all }, + [file]: { ...state, selectedHunks: all, selected: true }, }, })) }, @@ -84,7 +84,7 @@ export const useGitStore = create((set, get) => ({ set((s) => ({ fileHunkStates: { ...s.fileHunkStates, - [file]: { ...state, selectedHunks: new Set() }, + [file]: { ...state, selectedHunks: new Set(), selected: false }, }, })) }, diff --git a/src/main/frontend/app/types/git.types.ts b/src/main/frontend/app/types/git.types.ts index e61b7ec3..daccb64a 100644 --- a/src/main/frontend/app/types/git.types.ts +++ b/src/main/frontend/app/types/git.types.ts @@ -52,4 +52,5 @@ export interface GitPullResult { export interface FileHunkState { selectedHunks: Set totalHunks: number + selected: boolean }