diff --git a/presetup-configurator/src/Configurator.css b/presetup-configurator/src/Configurator.css index 83d737cb..8bebd777 100644 --- a/presetup-configurator/src/Configurator.css +++ b/presetup-configurator/src/Configurator.css @@ -40,9 +40,12 @@ } .Configurator .result { + margin-top: 16px; + width: 100%; background-color: #eee; padding: 8px; border: 1px solid #444; border-radius: 4px; box-shadow: inset 0 0 4px rgba(0, 0, 0, 0.2); + cursor: copy; } diff --git a/presetup-configurator/src/Configurator.tsx b/presetup-configurator/src/Configurator.tsx index 437b4af7..8e2222de 100644 --- a/presetup-configurator/src/Configurator.tsx +++ b/presetup-configurator/src/Configurator.tsx @@ -85,9 +85,43 @@ export function Configurator() { const [formattedResult, setFormattedResult] = useState(""); useEffect(() => { - setFormattedResult(yaml.dump(result)); + let _formattedResult = yaml.dump(result); + + // Add line break before each unquoted top-level or second-level property + _formattedResult = _formattedResult.replace(/^ {0,2}[a-z_]+:/gm, "\n$&").trim(); + + // Add additional line break at the end + _formattedResult += "\n"; + + // Explain "exclude: []" + _formattedResult = _formattedResult.replace(/exclude: \[]/, "$& # Exclude nothing = include everything"); + + setFormattedResult(_formattedResult); }, [result]); + const resultRows = formattedResult.split("\n").length || 1; + + const [copied, setCopied] = useState(false); + function copyResultText(textarea: HTMLTextAreaElement) { + textarea.select(); + document.execCommand("copy"); + setCopied(true); + } + + const [copyResetTimeout, setCopyResetTimeout] = useState(null); + useEffect(() => { + if (!copied) { + return; + } + + if (copyResetTimeout != null) { + window.clearTimeout(copyResetTimeout); + } + + const timeout = window.setTimeout(() => setCopied(false), 3000); + setCopyResetTimeout(timeout); + }, [copied]); + return (
{/* Options */} @@ -146,7 +180,10 @@ export function Configurator() {
{/* Result */} -
{formattedResult}
+