chore: remove comments

This commit is contained in:
Austin Pickett 2026-04-28 12:28:08 -04:00
parent 0348a69c51
commit e1027134cd
12 changed files with 721 additions and 378 deletions

View file

@ -22,7 +22,13 @@ import { useConfirmDelete } from "@/hooks/useConfirmDelete";
import { useToast } from "@/hooks/useToast";
import { OAuthProvidersCard } from "@/components/OAuthProvidersCard";
import { Button } from "@nous-research/ui";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Badge } from "@nous-research/ui";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
@ -36,25 +42,25 @@ import { PluginSlot } from "@/plugins";
/** Map env-var key prefixes to a human-friendly provider name + ordering. */
const PROVIDER_GROUPS: { prefix: string; name: string; priority: number }[] = [
// Nous Portal first
{ prefix: "NOUS_", name: "Nous Portal", priority: 0 },
{ prefix: "NOUS_", name: "Nous Portal", priority: 0 },
// Then alphabetical by display name
{ prefix: "ANTHROPIC_", name: "Anthropic", priority: 1 },
{ prefix: "DASHSCOPE_", name: "DashScope (Qwen)", priority: 2 },
{ prefix: "HERMES_QWEN_", name: "DashScope (Qwen)", priority: 2 },
{ prefix: "DEEPSEEK_", name: "DeepSeek", priority: 3 },
{ prefix: "GOOGLE_", name: "Gemini", priority: 4 },
{ prefix: "GEMINI_", name: "Gemini", priority: 4 },
{ prefix: "GLM_", name: "GLM / Z.AI", priority: 5 },
{ prefix: "ZAI_", name: "GLM / Z.AI", priority: 5 },
{ prefix: "Z_AI_", name: "GLM / Z.AI", priority: 5 },
{ prefix: "HF_", name: "Hugging Face", priority: 6 },
{ prefix: "KIMI_", name: "Kimi / Moonshot", priority: 7 },
{ prefix: "MINIMAX_CN_", name: "MiniMax (China)", priority: 9 },
{ prefix: "MINIMAX_", name: "MiniMax", priority: 8 },
{ prefix: "OPENCODE_GO_", name: "OpenCode Go", priority: 10 },
{ prefix: "OPENCODE_ZEN_", name: "OpenCode Zen", priority: 11 },
{ prefix: "OPENROUTER_", name: "OpenRouter", priority: 12 },
{ prefix: "XIAOMI_", name: "Xiaomi MiMo", priority: 13 },
{ prefix: "ANTHROPIC_", name: "Anthropic", priority: 1 },
{ prefix: "DASHSCOPE_", name: "DashScope (Qwen)", priority: 2 },
{ prefix: "HERMES_QWEN_", name: "DashScope (Qwen)", priority: 2 },
{ prefix: "DEEPSEEK_", name: "DeepSeek", priority: 3 },
{ prefix: "GOOGLE_", name: "Gemini", priority: 4 },
{ prefix: "GEMINI_", name: "Gemini", priority: 4 },
{ prefix: "GLM_", name: "GLM / Z.AI", priority: 5 },
{ prefix: "ZAI_", name: "GLM / Z.AI", priority: 5 },
{ prefix: "Z_AI_", name: "GLM / Z.AI", priority: 5 },
{ prefix: "HF_", name: "Hugging Face", priority: 6 },
{ prefix: "KIMI_", name: "Kimi / Moonshot", priority: 7 },
{ prefix: "MINIMAX_CN_", name: "MiniMax (China)", priority: 9 },
{ prefix: "MINIMAX_", name: "MiniMax", priority: 8 },
{ prefix: "OPENCODE_GO_", name: "OpenCode Go", priority: 10 },
{ prefix: "OPENCODE_ZEN_", name: "OpenCode Zen", priority: 11 },
{ prefix: "OPENROUTER_", name: "OpenRouter", priority: 12 },
{ prefix: "XIAOMI_", name: "Xiaomi MiMo", priority: 13 },
];
function getProviderGroup(key: string): string {
@ -117,25 +123,38 @@ function EnvVarRow({
const { t } = useI18n();
const isEditing = edits[varKey] !== undefined;
const isRevealed = !!revealed[varKey];
const displayValue = isRevealed ? revealed[varKey] : (info.redacted_value ?? "---");
const displayValue = isRevealed
? revealed[varKey]
: (info.redacted_value ?? "---");
// Compact inline row for unset, non-editing keys (used inside provider groups)
if (compact && !info.is_set && !isEditing) {
return (
<div className="flex items-center justify-between gap-3 py-1.5 opacity-50 hover:opacity-100 transition-opacity">
<div className="flex items-center gap-2 min-w-0">
<span className="font-mono-ui text-[0.7rem] text-muted-foreground">{varKey}</span>
<span className="text-[0.65rem] text-muted-foreground/60 truncate hidden sm:block">{info.description}</span>
<span className="font-mono-ui text-[0.7rem] text-muted-foreground">
{varKey}
</span>
<span className="text-[0.65rem] text-muted-foreground/60 truncate hidden sm:block">
{info.description}
</span>
</div>
<div className="flex items-center gap-2 shrink-0">
{info.url && (
<a href={info.url} target="_blank" rel="noreferrer"
className="inline-flex items-center gap-1 text-[0.65rem] text-primary hover:underline">
<a
href={info.url}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1 text-[0.65rem] text-primary hover:underline"
>
{t.env.getKey} <ExternalLink className="h-2.5 w-2.5" />
</a>
)}
<Button outlined prefix={<Pencil />}
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}>
<Button
outlined
prefix={<Pencil />}
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}
>
{t.common.set}
</Button>
</div>
@ -148,18 +167,29 @@ function EnvVarRow({
return (
<div className="flex items-center justify-between gap-3 border border-border/50 px-4 py-2.5 opacity-60 hover:opacity-100 transition-opacity">
<div className="flex items-center gap-3 min-w-0">
<Label className="font-mono-ui text-[0.7rem] text-muted-foreground">{varKey}</Label>
<span className="text-[0.65rem] text-muted-foreground/60 truncate hidden sm:block">{info.description}</span>
<Label className="font-mono-ui text-[0.7rem] text-muted-foreground">
{varKey}
</Label>
<span className="text-[0.65rem] text-muted-foreground/60 truncate hidden sm:block">
{info.description}
</span>
</div>
<div className="flex items-center gap-2 shrink-0">
{info.url && (
<a href={info.url} target="_blank" rel="noreferrer"
className="inline-flex items-center gap-1 text-[0.65rem] text-primary hover:underline">
<a
href={info.url}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1 text-[0.65rem] text-primary hover:underline"
>
{t.env.getKey} <ExternalLink className="h-2.5 w-2.5" />
</a>
)}
<Button outlined prefix={<Pencil />}
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}>
<Button
outlined
prefix={<Pencil />}
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}
>
{t.common.set}
</Button>
</div>
@ -178,8 +208,12 @@ function EnvVarRow({
</Badge>
</div>
{info.url && (
<a href={info.url} target="_blank" rel="noreferrer"
className="inline-flex items-center gap-1 text-[0.65rem] text-primary hover:underline">
<a
href={info.url}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1 text-[0.65rem] text-primary hover:underline"
>
{t.env.getKey} <ExternalLink className="h-2.5 w-2.5" />
</a>
)}
@ -190,35 +224,57 @@ function EnvVarRow({
{info.tools.length > 0 && (
<div className="flex flex-wrap gap-1">
{info.tools.map((tool) => (
<Badge key={tool} tone="secondary" className="text-[0.6rem] py-0 px-1.5">{tool}</Badge>
<Badge
key={tool}
tone="secondary"
className="text-[0.6rem] py-0 px-1.5"
>
{tool}
</Badge>
))}
</div>
)}
{!isEditing && (
<div className="flex items-center gap-2">
<div className={`flex-1 border border-border px-3 py-2 font-mono-ui text-xs ${
isRevealed ? "bg-background text-foreground select-all" : "bg-muted/30 text-muted-foreground"
}`}>
<div
className={`flex-1 border border-border px-3 py-2 font-mono-ui text-xs ${
isRevealed
? "bg-background text-foreground select-all"
: "bg-muted/30 text-muted-foreground"
}`}
>
{info.is_set ? displayValue : "---"}
</div>
{info.is_set && (
<Button ghost size="icon" onClick={() => onReveal(varKey)}
<Button
ghost
size="icon"
onClick={() => onReveal(varKey)}
title={isRevealed ? t.env.hideValue : t.env.showValue}
aria-label={isRevealed ? `Hide ${varKey}` : `Reveal ${varKey}`}>
aria-label={isRevealed ? `Hide ${varKey}` : `Reveal ${varKey}`}
>
{isRevealed ? <EyeOff /> : <Eye />}
</Button>
)}
<Button outlined prefix={<Pencil />}
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}>
<Button
outlined
prefix={<Pencil />}
onClick={() => setEdits((prev) => ({ ...prev, [varKey]: "" }))}
>
{info.is_set ? t.common.replace : t.common.set}
</Button>
{info.is_set && (
<Button outlined destructive prefix={<Trash2 />}
onClick={() => onClear(varKey)} disabled={saving === varKey || clearDialogOpen}>
<Button
outlined
destructive
prefix={<Trash2 />}
onClick={() => onClear(varKey)}
disabled={saving === varKey || clearDialogOpen}
>
{saving === varKey ? "..." : t.common.clear}
</Button>
)}
@ -227,12 +283,28 @@ function EnvVarRow({
{isEditing && (
<div className="flex items-center gap-2">
<Input autoFocus type="text" value={edits[varKey]}
onChange={(e) => setEdits((prev) => ({ ...prev, [varKey]: e.target.value }))}
placeholder={info.is_set ? t.env.replaceCurrentValue.replace("{preview}", info.redacted_value ?? "---") : t.env.enterValue}
className="flex-1 font-mono-ui text-xs" />
<Button onClick={() => onSave(varKey)} prefix={<Save />}
disabled={saving === varKey || !edits[varKey]}>
<Input
autoFocus
type="text"
value={edits[varKey]}
onChange={(e) =>
setEdits((prev) => ({ ...prev, [varKey]: e.target.value }))
}
placeholder={
info.is_set
? t.env.replaceCurrentValue.replace(
"{preview}",
info.redacted_value ?? "---",
)
: t.env.enterValue
}
className="flex-1 font-mono-ui text-xs"
/>
<Button
onClick={() => onSave(varKey)}
prefix={<Save />}
disabled={saving === varKey || !edits[varKey]}
>
{saving === varKey ? "..." : t.common.save}
</Button>
<Button outlined prefix={<X />} onClick={() => onCancelEdit(varKey)}>
@ -275,11 +347,20 @@ function ProviderGroupCard({
const { t } = useI18n();
// Separate API keys from base URLs and other settings
const apiKeys = group.entries.filter(([k]) => k.endsWith("_API_KEY") || k.endsWith("_TOKEN"));
const apiKeys = group.entries.filter(
([k]) => k.endsWith("_API_KEY") || k.endsWith("_TOKEN"),
);
const baseUrls = group.entries.filter(([k]) => k.endsWith("_BASE_URL"));
const other = group.entries.filter(([k]) => !k.endsWith("_API_KEY") && !k.endsWith("_TOKEN") && !k.endsWith("_BASE_URL"));
const other = group.entries.filter(
([k]) =>
!k.endsWith("_API_KEY") &&
!k.endsWith("_TOKEN") &&
!k.endsWith("_BASE_URL"),
);
const hasAnyConfigured = group.entries.some(([, info]) => info.is_set);
const configuredCount = group.entries.filter(([, info]) => info.is_set).length;
const configuredCount = group.entries.filter(
([, info]) => info.is_set,
).length;
// Get a representative URL for "Get key" link
const keyUrl = apiKeys.find(([, info]) => info.url)?.[1]?.url ?? null;
@ -293,8 +374,14 @@ function ProviderGroupCard({
className="flex w-full items-center justify-between gap-3 px-4 py-3 cursor-pointer hover:bg-primary/5 transition-colors"
>
<div className="flex items-center gap-3 min-w-0">
{expanded ? <ChevronDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" /> : <ChevronRight className="h-3.5 w-3.5 text-muted-foreground shrink-0" />}
<span className="font-semibold text-sm tracking-wide">{group.name === "Other" ? t.common.other : group.name}</span>
{expanded ? (
<ChevronDown className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
) : (
<ChevronRight className="h-3.5 w-3.5 text-muted-foreground shrink-0" />
)}
<span className="font-semibold text-sm tracking-wide">
{group.name === "Other" ? t.common.other : group.name}
</span>
{hasAnyConfigured && (
<Badge tone="success" className="text-[0.6rem]">
{configuredCount} {t.common.set.toLowerCase()}
@ -303,45 +390,76 @@ function ProviderGroupCard({
</div>
<div className="flex items-center gap-2 shrink-0">
{keyUrl && (
<a href={keyUrl} target="_blank" rel="noreferrer"
<a
href={keyUrl}
target="_blank"
rel="noreferrer"
className="inline-flex items-center gap-1 text-[0.65rem] text-primary hover:underline"
onClick={(e) => e.stopPropagation()}>
onClick={(e) => e.stopPropagation()}
>
{t.env.getKey} <ExternalLink className="h-2.5 w-2.5" />
</a>
)}
<span className="text-[0.65rem] text-muted-foreground/60">
{t.env.keysCount.replace("{count}", String(group.entries.length)).replace("{s}", group.entries.length !== 1 ? "s" : "")}
{t.env.keysCount
.replace("{count}", String(group.entries.length))
.replace("{s}", group.entries.length !== 1 ? "s" : "")}
</span>
</div>
</button>
{/* Expanded content */}
{expanded && (
<div className="border-t border-border px-4 py-3 grid gap-2">
{/* API keys first (most important) */}
{apiKeys.map(([key, info]) => (
<EnvVarRow
key={key} varKey={key} info={info} compact
edits={edits} setEdits={setEdits} revealed={revealed} saving={saving}
onSave={onSave} onClear={onClear} onReveal={onReveal} onCancelEdit={onCancelEdit}
key={key}
varKey={key}
info={info}
compact
edits={edits}
setEdits={setEdits}
revealed={revealed}
saving={saving}
onSave={onSave}
onClear={onClear}
onReveal={onReveal}
onCancelEdit={onCancelEdit}
clearDialogOpen={clearDialogOpen}
/>
))}
{/* Base URLs (secondary) */}
{baseUrls.map(([key, info]) => (
<EnvVarRow
key={key} varKey={key} info={info} compact
edits={edits} setEdits={setEdits} revealed={revealed} saving={saving}
onSave={onSave} onClear={onClear} onReveal={onReveal} onCancelEdit={onCancelEdit}
key={key}
varKey={key}
info={info}
compact
edits={edits}
setEdits={setEdits}
revealed={revealed}
saving={saving}
onSave={onSave}
onClear={onClear}
onReveal={onReveal}
onCancelEdit={onCancelEdit}
clearDialogOpen={clearDialogOpen}
/>
))}
{/* Anything else */}
{other.map(([key, info]) => (
<EnvVarRow
key={key} varKey={key} info={info} compact
edits={edits} setEdits={setEdits} revealed={revealed} saving={saving}
onSave={onSave} onClear={onClear} onReveal={onReveal} onCancelEdit={onCancelEdit}
key={key}
varKey={key}
info={info}
compact
edits={edits}
setEdits={setEdits}
revealed={revealed}
saving={saving}
onSave={onSave}
onClear={onClear}
onReveal={onReveal}
onCancelEdit={onCancelEdit}
clearDialogOpen={clearDialogOpen}
/>
))}
@ -365,7 +483,10 @@ export default function EnvPage() {
const { t } = useI18n();
useEffect(() => {
api.getEnvVars().then(setVars).catch(() => {});
api
.getEnvVars()
.then(setVars)
.catch(() => {});
}, []);
const handleSave = async (key: string) => {
@ -378,12 +499,24 @@ export default function EnvPage() {
prev
? {
...prev,
[key]: { ...prev[key], is_set: true, redacted_value: value.slice(0, 4) + "..." + value.slice(-4) },
[key]: {
...prev[key],
is_set: true,
redacted_value: value.slice(0, 4) + "..." + value.slice(-4),
},
}
: prev,
);
setEdits((prev) => { const n = { ...prev }; delete n[key]; return n; });
setRevealed((prev) => { const n = { ...prev }; delete n[key]; return n; });
setEdits((prev) => {
const n = { ...prev };
delete n[key];
return n;
});
setRevealed((prev) => {
const n = { ...prev };
delete n[key];
return n;
});
showToast(`${key} ${t.common.save.toLowerCase()}d`, "success");
} catch (e) {
showToast(`${t.config.failedToSave} ${key}: ${e}`, "error");
@ -400,11 +533,22 @@ export default function EnvPage() {
await api.deleteEnvVar(key);
setVars((prev) =>
prev
? { ...prev, [key]: { ...prev[key], is_set: false, redacted_value: null } }
? {
...prev,
[key]: { ...prev[key], is_set: false, redacted_value: null },
}
: prev,
);
setEdits((prev) => { const n = { ...prev }; delete n[key]; return n; });
setRevealed((prev) => { const n = { ...prev }; delete n[key]; return n; });
setEdits((prev) => {
const n = { ...prev };
delete n[key];
return n;
});
setRevealed((prev) => {
const n = { ...prev };
delete n[key];
return n;
});
showToast(`${key} ${t.common.removed}`, "success");
} catch (e) {
showToast(`${t.common.failedToRemove} ${key}: ${e}`, "error");
@ -419,7 +563,11 @@ export default function EnvPage() {
const handleReveal = async (key: string) => {
if (revealed[key]) {
setRevealed((prev) => { const n = { ...prev }; delete n[key]; return n; });
setRevealed((prev) => {
const n = { ...prev };
delete n[key];
return n;
});
return;
}
try {
@ -431,7 +579,11 @@ export default function EnvPage() {
};
const cancelEdit = (key: string) => {
setEdits((prev) => { const n = { ...prev }; delete n[key]; return n; });
setEdits((prev) => {
const n = { ...prev };
delete n[key];
return n;
});
};
/* ---- Build provider groups ---- */
@ -439,7 +591,8 @@ export default function EnvPage() {
if (!vars) return { providerGroups: [], nonProviderGrouped: [] };
const providerEntries = Object.entries(vars).filter(
([, info]) => info.category === "provider" && (showAdvanced || !info.advanced),
([, info]) =>
info.category === "provider" && (showAdvanced || !info.advanced),
);
// Group by provider
@ -498,9 +651,7 @@ export default function EnvPage() {
const pendingClearKey = keyClear.pendingId;
const pendingKeyDescription =
pendingClearKey && vars
? vars[pendingClearKey]?.description
: undefined;
pendingClearKey && vars ? vars[pendingClearKey]?.description : undefined;
return (
<div className="flex flex-col gap-6">
@ -534,13 +685,11 @@ export default function EnvPage() {
</Button>
</div>
{/* ═══════════════ OAuth Logins ══ */}
<OAuthProvidersCard
onError={(msg) => showToast(msg, "error")}
onSuccess={(msg) => showToast(msg, "success")}
/>
{/* ═══════════════ LLM Providers (grouped) ═══════════════ */}
<Card>
<CardHeader className="border-b border-border bg-card">
<div className="flex items-center gap-2">
@ -548,7 +697,9 @@ export default function EnvPage() {
<CardTitle className="text-base">{t.env.llmProviders}</CardTitle>
</div>
<CardDescription>
{t.env.providersConfigured.replace("{configured}", String(configuredProviders)).replace("{total}", String(totalProviders))}
{t.env.providersConfigured
.replace("{configured}", String(configuredProviders))
.replace("{total}", String(totalProviders))}
</CardDescription>
</CardHeader>
@ -557,53 +708,82 @@ export default function EnvPage() {
<ProviderGroupCard
key={group.name}
group={group}
edits={edits} setEdits={setEdits} revealed={revealed} saving={saving}
onSave={handleSave} onClear={keyClear.requestDelete} onReveal={handleReveal} onCancelEdit={cancelEdit}
edits={edits}
setEdits={setEdits}
revealed={revealed}
saving={saving}
onSave={handleSave}
onClear={keyClear.requestDelete}
onReveal={handleReveal}
onCancelEdit={cancelEdit}
clearDialogOpen={keyClear.isOpen}
/>
))}
</CardContent>
</Card>
{/* ═══════════════ Other categories (flat) ═══════════════ */}
{nonProviderGrouped.map(({ label, icon: Icon, setEntries, unsetEntries, totalEntries, category }) => {
if (totalEntries === 0) return null;
{nonProviderGrouped.map(
({
label,
icon: Icon,
setEntries,
unsetEntries,
totalEntries,
category,
}) => {
if (totalEntries === 0) return null;
return (
<Card key={category}>
<CardHeader className="border-b border-border bg-card">
<div className="flex items-center gap-2">
<Icon className="h-5 w-5 text-muted-foreground" />
<CardTitle className="text-base">{label}</CardTitle>
</div>
<CardDescription>
{setEntries.length} {t.common.of} {totalEntries} {t.common.configured}
</CardDescription>
</CardHeader>
return (
<Card key={category}>
<CardHeader className="border-b border-border bg-card">
<div className="flex items-center gap-2">
<Icon className="h-5 w-5 text-muted-foreground" />
<CardTitle className="text-base">{label}</CardTitle>
</div>
<CardDescription>
{setEntries.length} {t.common.of} {totalEntries}{" "}
{t.common.configured}
</CardDescription>
</CardHeader>
<CardContent className="grid gap-3 pt-4">
{setEntries.map(([key, info]) => (
<EnvVarRow
key={key} varKey={key} info={info}
edits={edits} setEdits={setEdits} revealed={revealed} saving={saving}
onSave={handleSave} onClear={keyClear.requestDelete} onReveal={handleReveal} onCancelEdit={cancelEdit}
clearDialogOpen={keyClear.isOpen}
/>
))}
<CardContent className="grid gap-3 pt-4">
{setEntries.map(([key, info]) => (
<EnvVarRow
key={key}
varKey={key}
info={info}
edits={edits}
setEdits={setEdits}
revealed={revealed}
saving={saving}
onSave={handleSave}
onClear={keyClear.requestDelete}
onReveal={handleReveal}
onCancelEdit={cancelEdit}
clearDialogOpen={keyClear.isOpen}
/>
))}
{unsetEntries.length > 0 && (
<CollapsibleUnset
category={category}
unsetEntries={unsetEntries}
edits={edits} setEdits={setEdits} revealed={revealed} saving={saving}
onSave={handleSave} onClear={keyClear.requestDelete} onReveal={handleReveal} onCancelEdit={cancelEdit}
clearDialogOpen={keyClear.isOpen}
/>
)}
</CardContent>
</Card>
);
})}
{unsetEntries.length > 0 && (
<CollapsibleUnset
category={category}
unsetEntries={unsetEntries}
edits={edits}
setEdits={setEdits}
revealed={revealed}
saving={saving}
onSave={handleSave}
onClear={keyClear.requestDelete}
onReveal={handleReveal}
onCancelEdit={cancelEdit}
clearDialogOpen={keyClear.isOpen}
/>
)}
</CardContent>
</Card>
);
},
)}
<PluginSlot name="env:bottom" />
</div>
);
@ -648,20 +828,33 @@ function CollapsibleUnset({
className="flex items-center gap-2 text-xs text-muted-foreground hover:text-foreground transition-colors cursor-pointer pt-1"
onClick={() => setCollapsed(!collapsed)}
>
{collapsed
? <ChevronRight className="h-3 w-3" />
: <ChevronDown className="h-3 w-3" />}
<span>{t.env.notConfigured.replace("{count}", String(unsetEntries.length))}</span>
{collapsed ? (
<ChevronRight className="h-3 w-3" />
) : (
<ChevronDown className="h-3 w-3" />
)}
<span>
{t.env.notConfigured.replace("{count}", String(unsetEntries.length))}
</span>
</button>
{!collapsed && unsetEntries.map(([key, info]) => (
<EnvVarRow
key={key} varKey={key} info={info}
edits={edits} setEdits={setEdits} revealed={revealed} saving={saving}
onSave={onSave} onClear={onClear} onReveal={onReveal} onCancelEdit={onCancelEdit}
clearDialogOpen={clearDialogOpen}
/>
))}
{!collapsed &&
unsetEntries.map(([key, info]) => (
<EnvVarRow
key={key}
varKey={key}
info={info}
edits={edits}
setEdits={setEdits}
revealed={revealed}
saving={saving}
onSave={onSave}
onClear={onClear}
onReveal={onReveal}
onCancelEdit={onCancelEdit}
clearDialogOpen={clearDialogOpen}
/>
))}
</>
);
}