/** * GraphQL Environment Variables (IDEA's dialog): the `${NAME}` variables a graphql-config * uses, one row each with its value; Copy / Paste exchange them as `NAME=value` lines. */ import { useState } from "react"; import { readClipboardText } from "@/platform/clipboard"; import { useTx } from "@/platform/i18n"; import { Dialog, IconButton, T } from "@/ui"; import { copyText } from "@/ui/selectableText"; import { closeEnvironmentDialog, environmentOf, saveEnvironment, useGraphQL } from "./store"; import styles from "./GraphQL.module.css"; /** `NAME=value` lines (a `.env` file's shape). */ export function formatEnvironment(names: readonly string[], values: Readonly>): string { return names.map((n) => `${n}=${values[n] ?? ""}`).join("\n"); } /** Values of `names` found in `NAME=value` lines; other lines are ignored. */ export function parseEnvironment(text: string, names: readonly string[]): Record { const out: Record = {}; for (const line of text.split(/\r?\n/)) { const at = line.indexOf("="); if (at <= 0) continue; const name = line.slice(0, at).trim(); if (names.includes(name)) out[name] = line.slice(at + 1).trim(); } return out; } export function EnvironmentDialogOverlay() { const dialog = useGraphQL((s) => s.envDialog); return dialog ? : null; } function EnvironmentDialog({ configPath, variables }: { configPath: string; variables: string[] }) { const tx = useTx(); const [values, setValues] = useState(() => ({ ...environmentOf(configPath) })); const ok = () => { saveEnvironment(configPath, values); closeEnvironmentDialog(true); }; return ( closeEnvironmentDialog(false)} width={480} buttons={[ { label: "OK", role: "default", onClick: ok }, { label: "Cancel", role: "cancel" }, ]} >
void copyText(formatEnvironment(variables, values))} /> void readClipboardText().then((text) => setValues((v) => ({ ...v, ...parseEnvironment(text, variables) })), ) } />
{variables.map((name) => ( ))}
Name Value
{name} setValues((v) => ({ ...v, [name]: e.target.value }))} onKeyDown={(e) => { if (e.key === "Enter") ok(); }} />
); }