Skip to content

Commit 6e4ea8f

Browse files
committed
idea 1
1 parent 1bda2c6 commit 6e4ea8f

File tree

4 files changed

+67
-31
lines changed

4 files changed

+67
-31
lines changed

src/core/tools/readFileTool.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -338,16 +338,12 @@ export async function readFileTool(
338338
if (approved) {
339339
updateFileResult(fileResult.path, {
340340
status: "approved",
341-
feedbackText: text,
342-
feedbackImages: images,
343341
})
344342
} else {
345343
hasAnyDenial = true
346344
updateFileResult(fileResult.path, {
347345
status: "denied",
348346
xmlContent: `<file><path>${fileResult.path}</path><status>Denied by user</status></file>`,
349-
feedbackText: text,
350-
feedbackImages: images,
351347
})
352348
}
353349
})
@@ -363,8 +359,6 @@ export async function readFileTool(
363359
updateFileResult(fileResult.path, {
364360
status: "denied",
365361
xmlContent: `<file><path>${fileResult.path}</path><status>Denied by user</status></file>`,
366-
feedbackText: text,
367-
feedbackImages: images,
368362
})
369363
})
370364
}

webview-ui/src/components/chat/BatchFilePermission.tsx

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import { memo } from "react"
2-
import { FileCode } from "lucide-react"
1+
import { memo, useState, useEffect, useCallback } from "react"
2+
import { CheckCircle } from "lucide-react"
33

44
import { useAppTranslation } from "@src/i18n/TranslationContext"
55
import { ToolUseBlock, ToolUseBlockHeader } from "../common/ToolUseBlock"
6+
import { Checkbox } from "../ui/checkbox"
7+
import { Button } from "../ui/button"
68
import { vscode } from "@src/utils/vscode"
79
import { removeLeadingNonAlphanumeric } from "@src/utils/removeLeadingNonAlphanumeric"
810

@@ -22,40 +24,59 @@ interface BatchFilePermissionProps {
2224

2325
export const BatchFilePermission = memo(({ files = [], onPermissionResponse, ts }: BatchFilePermissionProps) => {
2426
const { t } = useAppTranslation()
27+
const [individualPermissions, setIndividualPermissions] = useState<{ [key: string]: boolean }>({})
28+
const [isSubmitting, setIsSubmitting] = useState(false)
29+
30+
// Initialize permissions as true when files change
31+
useEffect(() => {
32+
const initialPermissions: { [key: string]: boolean } = {}
33+
files.forEach((file) => {
34+
initialPermissions[file.path] = true
35+
})
36+
setIndividualPermissions(initialPermissions)
37+
setIsSubmitting(false)
38+
}, [files, ts])
39+
40+
const handleIndividualPermission = useCallback((filePath: string, checked: boolean) => {
41+
setIndividualPermissions((prev) => ({
42+
...prev,
43+
[filePath]: checked,
44+
}))
45+
}, [])
46+
47+
const handleSubmitIndividual = useCallback(() => {
48+
setIsSubmitting(true)
49+
const response: { [key: string]: boolean } = {}
50+
files.forEach((file) => {
51+
response[file.key] = individualPermissions[file.path] ?? true
52+
})
53+
onPermissionResponse?.(response)
54+
}, [files, individualPermissions, onPermissionResponse])
2555

2656
// Don't render if there are no files or no response handler
2757
if (!files?.length || !onPermissionResponse) {
2858
return null
2959
}
3060

31-
const headerStyle = {
32-
display: "flex",
33-
alignItems: "center",
34-
fontSize: "13px",
35-
marginBottom: 5,
36-
gap: 8,
37-
opacity: 0.8,
38-
}
39-
40-
const toolIcon = (type: string) => {
41-
const size = 15
42-
const color = "var(--vscode-foreground)"
43-
switch (type) {
44-
case "file-code":
45-
return <FileCode size={size} color={color} />
46-
default:
47-
return null
48-
}
49-
}
61+
// Check if all files are checked or all are unchecked
62+
const checkedCount = Object.values(individualPermissions).filter((v) => v === true).length
63+
const allChecked = checkedCount === files.length
64+
const allUnchecked = checkedCount === 0
65+
const showSubmitButton = !allChecked && !allUnchecked
5066

5167
return (
5268
<div style={{ paddingTop: 5 }}>
5369
{/* Individual files */}
54-
<div style={{ display: "flex", flexDirection: "column", gap: 20 }}>
55-
{files.map((file, index) => {
70+
<div style={{ display: "flex", flexDirection: "column", gap: 0 }}>
71+
{files.map((file) => {
5672
return (
57-
<div key={`${file.path}-${ts}`}>
58-
<ToolUseBlock>
73+
<div key={`${file.path}-${ts}`} style={{ display: "flex", alignItems: "center", gap: 8 }}>
74+
<Checkbox
75+
checked={individualPermissions[file.path] !== false}
76+
onCheckedChange={(checked) => handleIndividualPermission(file.path, checked as boolean)}
77+
variant="description"
78+
/>
79+
<ToolUseBlock style={{ flex: 1 }}>
5980
<ToolUseBlockHeader
6081
onClick={() => vscode.postMessage({ type: "openFile", text: file.content })}>
6182
{file.path?.startsWith(".") && <span>.</span>}
@@ -75,6 +96,20 @@ export const BatchFilePermission = memo(({ files = [], onPermissionResponse, ts
7596
})}
7697
</div>
7798

99+
{/* Submit button - only show when there's a mix of checked/unchecked */}
100+
{showSubmitButton && (
101+
<div style={{ marginTop: 12 }}>
102+
<Button
103+
variant="default"
104+
size="default"
105+
style={{ width: "100%" }}
106+
onClick={handleSubmitIndividual}
107+
disabled={isSubmitting}>
108+
<CheckCircle className="w-4 h-4" />
109+
{t("chat:batchFilePermission.approveSelected")}
110+
</Button>
111+
</div>
112+
)}
78113
</div>
79114
)
80115
})

webview-ui/src/components/chat/ChatView.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1164,6 +1164,11 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
11641164
[handleSendMessage, setInputValue], // setInputValue is stable, handleSendMessage depends on clineAsk
11651165
)
11661166

1167+
const handleBatchFileResponse = useCallback((response: { [key: string]: boolean }) => {
1168+
// Handle batch file response, e.g., for file uploads
1169+
vscode.postMessage({ type: "askResponse", askResponse: "objectResponse", text: JSON.stringify(response) })
1170+
}, [])
1171+
11671172
const itemContent = useCallback(
11681173
(index: number, messageOrGroup: ClineMessage | ClineMessage[]) => {
11691174
// browser session group
@@ -1198,6 +1203,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
11981203
onHeightChange={handleRowHeightChange}
11991204
isStreaming={isStreaming}
12001205
onSuggestionClick={handleSuggestionClickInRow} // This was already stabilized
1206+
onBatchFileResponse={handleBatchFileResponse}
12011207
/>
12021208
)
12031209
},

webview-ui/src/i18n/locales/en/chat.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@
243243
"deny": "Deny",
244244
"outsideWorkspace": "Outside workspace",
245245
"submitDecisions": "Submit Decisions",
246+
"approveSelected": "Approve Selected",
246247
"makeAllDecisions": "Make decisions for all files ({{remaining}} remaining)",
247248
"reviewFiles": "Review {{count}} file{{count, plural, one {} other {s}}}",
248249
"submitting": "Submitting..."

0 commit comments

Comments
 (0)