import { Box, Button, IconButton, Stack, TextField, Tooltip, Typography, Autocomplete, InputAdornment } from "@mui/material"; import AddIcon from "@mui/icons-material/Add"; import RemoveCircleOutlineIcon from "@mui/icons-material/RemoveCircleOutline"; import { useState } from "react"; const PROTOCOL_OPTIONS = ["http://", "https://"]; type UpstreamEntry = { protocol: string; address: string; }; function parseUpstream(upstream: string): UpstreamEntry { if (upstream.startsWith("https://")) { return { protocol: "https://", address: upstream.slice(8) }; } if (upstream.startsWith("http://")) { return { protocol: "http://", address: upstream.slice(7) }; } return { protocol: "http://", address: upstream }; } export function UpstreamInput({ defaultUpstreams = [], name = "upstreams" }: { defaultUpstreams?: string[]; name?: string; }) { const initialEntries: UpstreamEntry[] = defaultUpstreams.length > 0 ? defaultUpstreams.map(parseUpstream) : [{ protocol: "http://", address: "" }]; const [entries, setEntries] = useState(initialEntries); const handleProtocolChange = (index: number, newProtocol: string | null) => { const updated = [...entries]; updated[index].protocol = newProtocol || "http://"; setEntries(updated); }; const handleAddressChange = (index: number, newAddress: string) => { const updated = [...entries]; // Strip protocol if user pasted a full URL if (newAddress.startsWith("https://")) { updated[index].protocol = "https://"; updated[index].address = newAddress.slice(8); } else if (newAddress.startsWith("http://")) { updated[index].protocol = "http://"; updated[index].address = newAddress.slice(7); } else { updated[index].address = newAddress; } setEntries(updated); }; const handleAdd = () => { setEntries([...entries, { protocol: "http://", address: "" }]); }; const handleRemove = (index: number) => { if (entries.length === 1) return; setEntries(entries.filter((_, i) => i !== index)); }; const serializedValue = entries .filter(e => e.address.trim() !== "") .map(e => `${e.protocol}${e.address.trim()}`) .join("\n"); return ( Upstreams {entries.map((entry, index) => ( handleProtocolChange(index, newValue)} onInputChange={(_, newInputValue) => { if (newInputValue) { handleProtocolChange(index, newInputValue); } }} disableClearable sx={{ width: 140 }} renderInput={(params) => ( )} /> handleAddressChange(index, e.target.value)} placeholder="10.0.0.5:8080" size="small" fullWidth required={index === 0} /> handleRemove(index)} disabled={entries.length === 1} color="error" sx={{ mt: 0.5 }} > ))} Backend servers to proxy requests to ); }