import React, { useState, useMemo } from "react" import { Check, ChevronDown, Info, X } from "lucide-react" import { cn } from "../../lib/utils" import { useTranslation, Trans } from "react-i18next" import { VSCodeLink } from "@vscode/webview-ui-toolkit/react" import { StandardTooltip } from "../ui/standard-tooltip" interface CommandPattern { pattern: string description?: string } interface CommandPatternSelectorProps { patterns: CommandPattern[] allowedCommands: string[] deniedCommands: string[] onAllowPatternChange: (pattern: string) => void onDenyPatternChange: (pattern: string) => void } export const CommandPatternSelector: React.FC = ({ patterns, allowedCommands, deniedCommands, onAllowPatternChange, onDenyPatternChange, }) => { const { t } = useTranslation() const [isExpanded, setIsExpanded] = useState(false) const [editingStates, setEditingStates] = useState>({}) const handleOpenSettings = () => { window.postMessage({ type: "action", action: "settingsButtonClicked", values: { section: "autoApprove" } }) } // Create a combined list with full command first, then patterns const allPatterns = useMemo(() => { // Create a set to track unique patterns we've already seen const seenPatterns = new Set() // Filter out any patterns that are duplicates or are the same as the full command const uniquePatterns = patterns.filter((p) => { if (seenPatterns.has(p.pattern)) { return false } seenPatterns.add(p.pattern) return true }) return uniquePatterns }, [patterns]) const getPatternStatus = (pattern: string): "allowed" | "denied" | "none" => { if (allowedCommands.includes(pattern)) return "allowed" if (deniedCommands.includes(pattern)) return "denied" return "none" } const getEditState = (pattern: string) => { return editingStates[pattern] || { isEditing: false, value: pattern } } const setEditState = (pattern: string, isEditing: boolean, value?: string) => { setEditingStates((prev) => ({ ...prev, [pattern]: { isEditing, value: value ?? pattern }, })) } return (
{isExpanded && (
{allPatterns.map((item) => { const editState = getEditState(item.pattern) const status = getPatternStatus(editState.value) return (
{editState.isEditing ? ( setEditState(item.pattern, true, e.target.value)} onBlur={() => setEditState(item.pattern, false)} onKeyDown={(e) => { if (e.key === "Enter") { setEditState(item.pattern, false) } if (e.key === "Escape") { setEditState(item.pattern, false, item.pattern) } }} className="font-mono text-xs bg-vscode-input-background text-vscode-input-foreground border border-vscode-input-border rounded px-2 py-1.5 w-full focus:outline-0 focus:ring-1 focus:ring-vscode-focusBorder" placeholder={item.pattern} autoFocus /> ) : (
setEditState(item.pattern, true)} className="font-mono text-xs text-vscode-foreground cursor-pointer hover:bg-vscode-list-hoverBackground px-2 py-1.5 rounded transition-colors border border-transparent break-all" title="Click to edit pattern"> {editState.value} {item.description && ( - {item.description} )}
)}
) })}
)} ) }