Fix file tree clicks and redesign add-file UI on instructions tab
- Add onClick handler to file row div in PackageFileTree so clicks anywhere on the row select the file (not just the inner button) - Replace "Add" button with compact "+" icon that reveals an inline input with Create/Cancel actions - Hide file name input until "+" is clicked to reduce visual clutter - Validate new file paths: reject ".." path traversal segments - Change placeholder from "docs/TOOLS.md" to "TOOLS.md" Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
b0524412c4
commit
58d7f59477
2 changed files with 61 additions and 23 deletions
|
|
@ -286,6 +286,7 @@ export function PackageFileTree({
|
||||||
style={{
|
style={{
|
||||||
paddingInlineStart: `${TREE_BASE_INDENT + depth * TREE_STEP_INDENT - 8}px`,
|
paddingInlineStart: `${TREE_BASE_INDENT + depth * TREE_STEP_INDENT - 8}px`,
|
||||||
}}
|
}}
|
||||||
|
onClick={() => onSelectFile(node.path)}
|
||||||
>
|
>
|
||||||
{showCheckboxes && (
|
{showCheckboxes && (
|
||||||
<label className="flex items-center pl-2">
|
<label className="flex items-center pl-2">
|
||||||
|
|
|
||||||
|
|
@ -1514,6 +1514,7 @@ function PromptsTab({
|
||||||
entryFile: string;
|
entryFile: string;
|
||||||
} | null>(null);
|
} | null>(null);
|
||||||
const [newFilePath, setNewFilePath] = useState("");
|
const [newFilePath, setNewFilePath] = useState("");
|
||||||
|
const [showNewFileInput, setShowNewFileInput] = useState(false);
|
||||||
const [expandedDirs, setExpandedDirs] = useState<Set<string>>(new Set());
|
const [expandedDirs, setExpandedDirs] = useState<Set<string>>(new Set());
|
||||||
const [filePanelWidth, setFilePanelWidth] = useState(260);
|
const [filePanelWidth, setFilePanelWidth] = useState(260);
|
||||||
const containerRef = useRef<HTMLDivElement>(null);
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
@ -1960,30 +1961,66 @@ function PromptsTab({
|
||||||
<div className="border border-border rounded-lg p-3 space-y-3 shrink-0" style={{ width: filePanelWidth }}>
|
<div className="border border-border rounded-lg p-3 space-y-3 shrink-0" style={{ width: filePanelWidth }}>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<h4 className="text-sm font-medium">Files</h4>
|
<h4 className="text-sm font-medium">Files</h4>
|
||||||
<Button
|
{!showNewFileInput && (
|
||||||
type="button"
|
<Button
|
||||||
size="sm"
|
type="button"
|
||||||
variant="outline"
|
size="icon"
|
||||||
onClick={() => {
|
variant="outline"
|
||||||
const candidate = newFilePath.trim();
|
className="h-7 w-7"
|
||||||
if (!candidate) return;
|
onClick={() => setShowNewFileInput(true)}
|
||||||
setSelectedFile(candidate);
|
>
|
||||||
setDraft("");
|
+
|
||||||
setNewFilePath("");
|
</Button>
|
||||||
}}
|
)}
|
||||||
disabled={!newFilePath.trim()}
|
|
||||||
>
|
|
||||||
Add
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
<div className="flex gap-2">
|
|
||||||
<Input
|
|
||||||
value={newFilePath}
|
|
||||||
onChange={(event) => setNewFilePath(event.target.value)}
|
|
||||||
placeholder="docs/TOOLS.md"
|
|
||||||
className="font-mono text-sm"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
{showNewFileInput && (
|
||||||
|
<div className="space-y-2">
|
||||||
|
<Input
|
||||||
|
value={newFilePath}
|
||||||
|
onChange={(event) => setNewFilePath(event.target.value)}
|
||||||
|
placeholder="TOOLS.md"
|
||||||
|
className="font-mono text-sm"
|
||||||
|
autoFocus
|
||||||
|
onKeyDown={(event) => {
|
||||||
|
if (event.key === "Escape") {
|
||||||
|
setShowNewFileInput(false);
|
||||||
|
setNewFilePath("");
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<div className="flex gap-2">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
size="sm"
|
||||||
|
variant="default"
|
||||||
|
className="flex-1"
|
||||||
|
disabled={!newFilePath.trim() || newFilePath.includes("..")}
|
||||||
|
onClick={() => {
|
||||||
|
const candidate = newFilePath.trim();
|
||||||
|
if (!candidate || candidate.includes("..")) return;
|
||||||
|
setSelectedFile(candidate);
|
||||||
|
setDraft("");
|
||||||
|
setNewFilePath("");
|
||||||
|
setShowNewFileInput(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
size="sm"
|
||||||
|
variant="outline"
|
||||||
|
className="flex-1"
|
||||||
|
onClick={() => {
|
||||||
|
setShowNewFileInput(false);
|
||||||
|
setNewFilePath("");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<PackageFileTree
|
<PackageFileTree
|
||||||
nodes={fileTree}
|
nodes={fileTree}
|
||||||
selectedFile={selectedOrEntryFile}
|
selectedFile={selectedOrEntryFile}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue