import { useTranslation } from "react-i18next"; import { useEffect, useState, useCallback, useMemo } from "react"; import { FullScreenPanel } from "@/components/common/FullScreenPanel"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { Save, Download, Loader2, Package } from "lucide-react"; import JsonEditor from "@/components/JsonEditor"; interface CommonConfigEditorProps { value: string; onChange: (value: string) => void; useCommonConfig: boolean; onCommonConfigToggle: (checked: boolean) => void; commonConfigSnippet: string; onCommonConfigSnippetChange: (value: string) => void; commonConfigError: string; onEditClick: () => void; isModalOpen: boolean; onModalClose: () => void; onExtract?: () => void; isExtracting?: boolean; } export function CommonConfigEditor({ value, onChange, useCommonConfig, onCommonConfigToggle, commonConfigSnippet, onCommonConfigSnippetChange, commonConfigError, onEditClick, isModalOpen, onModalClose, onExtract, isExtracting, }: CommonConfigEditorProps) { const { t } = useTranslation(); const [isDarkMode, setIsDarkMode] = useState(false); useEffect(() => { setIsDarkMode(document.documentElement.classList.contains("dark")); const observer = new MutationObserver(() => { setIsDarkMode(document.documentElement.classList.contains("dark")); }); observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"], }); return () => observer.disconnect(); }, []); // Mirror value prop to local state so checkbox toggles and JsonEditor stay in sync // (parent uses form.getValues which doesn't trigger re-renders) const [localValue, setLocalValue] = useState(value); useEffect(() => { setLocalValue(value); }, [value]); const handleLocalChange = useCallback( (newValue: string) => { setLocalValue(newValue); onChange(newValue); }, [onChange], ); const toggleStates = useMemo(() => { try { const config = JSON.parse(localValue); return { hideAttribution: config?.attribution?.commit === "" && config?.attribution?.pr === "", teammates: config?.env?.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === "1" || config?.env?.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS === 1, enableToolSearch: config?.env?.ENABLE_TOOL_SEARCH === "true" || config?.env?.ENABLE_TOOL_SEARCH === "1", effortHigh: config?.effortLevel === "high", disableAutoUpgrade: config?.env?.DISABLE_AUTOUPDATER === "1" || config?.env?.DISABLE_AUTOUPDATER === 1, }; } catch { return { hideAttribution: false, teammates: false, enableToolSearch: false, effortHigh: false, disableAutoUpgrade: false, }; } }, [localValue]); const handleToggle = useCallback( (toggleKey: string, checked: boolean) => { try { const config = JSON.parse(localValue || "{}"); switch (toggleKey) { case "hideAttribution": if (checked) { config.attribution = { commit: "", pr: "" }; } else { delete config.attribution; } break; case "teammates": if (!config.env) config.env = {}; if (checked) { config.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = "1"; } else { delete config.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS; if (Object.keys(config.env).length === 0) delete config.env; } break; case "enableToolSearch": if (!config.env) config.env = {}; if (checked) { config.env.ENABLE_TOOL_SEARCH = "true"; } else { delete config.env.ENABLE_TOOL_SEARCH; if (Object.keys(config.env).length === 0) delete config.env; } break; case "effortHigh": if (checked) { config.effortLevel = "high"; } else { delete config.effortLevel; } break; case "disableAutoUpgrade": if (!config.env) config.env = {}; if (checked) { config.env.DISABLE_AUTOUPDATER = "1"; } else { delete config.env.DISABLE_AUTOUPDATER; if (Object.keys(config.env).length === 0) delete config.env; } break; } handleLocalChange(JSON.stringify(config, null, 2)); } catch { // Don't modify if JSON is invalid } }, [localValue, handleLocalChange], ); return ( <>
{commonConfigError && !isModalOpen && (

{commonConfigError}

)}
{onExtract && ( )} } >

{t("commonConfig.guideTitle")}

{t("commonConfig.guidePurpose")}

{t("commonConfig.guideUsage")}

{t("commonConfig.guideReExtract")}

{t("commonConfig.guideReassurance")}

{(!commonConfigSnippet || commonConfigSnippet.trim() === "" || commonConfigSnippet.trim() === "{}") && (

{t("commonConfig.emptyTitle")}

{t("commonConfig.emptyHint")}

)} {commonConfigError && (

{commonConfigError}

)}
); }