Skip to content

Commit bc0a0be

Browse files
committed
EnvVarGrid fixes
- Do not repeatedly call setEnvironmentVariables inside useEffect that depends on it - Do not call setError from inside setEnvironmentVariables - Do not disable name fields when they contain duplicates of sensitive names
1 parent 9c00187 commit bc0a0be

5 files changed

Lines changed: 128 additions & 145 deletions

File tree

frontend/src/components/config/workload/CommonWorkloadConfigFields.tsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,16 @@ export const CommonWorkloadConfigFields = ({
125125
}
126126
}, [state.git.repositoryId, state.image.imageTag]);
127127

128-
const fixedSensitiveNames =
128+
const fixedSensitiveVars =
129129
originalConfig?.appType === "workload"
130-
? new Set(
131-
originalConfig.env
132-
.filter((env) => env.isSensitive)
133-
.map((env) => env.name),
134-
)
135-
: new Set<string>();
130+
? originalConfig.env
131+
.map((env, idx) => ({ env, idx }))
132+
.filter(({ env }) => env.isSensitive)
133+
.reduce(
134+
(obj, cur) => Object.assign(obj, { [cur.env.name]: cur.idx }),
135+
{},
136+
)
137+
: {};
136138

137139
return (
138140
<>
@@ -323,7 +325,7 @@ export const CommonWorkloadConfigFields = ({
323325
setValue={(updater) => {
324326
setState((prev) => ({ ...prev, env: updater(prev.env) }));
325327
}}
326-
fixedSensitiveNames={fixedSensitiveNames}
328+
fixedSensitiveVars={fixedSensitiveVars}
327329
disabled={disabled ?? false}
328330
/>
329331
</AccordionContent>

frontend/src/components/config/workload/EnvVarGrid.tsx

Lines changed: 63 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,38 @@ import { Fragment, useEffect, useState } from "react";
77

88
type EnvVars = { name: string; value: string | null; isSensitive: boolean }[];
99

10-
// TODO: show error message on duplicate env names
1110
export const EnvVarGrid = ({
1211
value: envVars,
1312
setValue: setEnvironmentVariables,
14-
fixedSensitiveNames,
13+
fixedSensitiveVars,
1514
disabled = false,
1615
}: {
1716
value: EnvVars;
1817
setValue: (updater: (envVars: EnvVars) => EnvVars) => void;
19-
fixedSensitiveNames: Set<string>;
18+
fixedSensitiveVars: Record<string, number>;
2019
disabled: boolean;
2120
}) => {
2221
const [error, setError] = useState("");
2322
useEffect(() => {
24-
for (const i of envVars.keys()) {
25-
if (
26-
envVars[i].name === "" &&
27-
envVars[i].value === "" &&
28-
!envVars[i].isSensitive &&
29-
i < envVars.length - 1
30-
) {
31-
setEnvironmentVariables((prev) => prev.toSpliced(i, 1));
32-
return;
23+
const names = new Set<string>();
24+
const duplicates = new Set<string>();
25+
26+
envVars.forEach((env) => {
27+
if (env.name === "") return;
28+
29+
if (names.has(env.name)) {
30+
duplicates.add(env.name);
31+
} else {
32+
names.add(env.name);
3333
}
34-
}
35-
if (
36-
envVars[envVars.length - 1]?.name !== "" ||
37-
envVars[envVars.length - 1]?.value !== "" ||
38-
envVars[envVars.length - 1]?.isSensitive
39-
) {
40-
setEnvironmentVariables((prev) => [
41-
...prev,
42-
{ name: "", value: "", isSensitive: false },
43-
]);
34+
});
35+
36+
if (duplicates.size !== 0) {
37+
setError(
38+
`Duplicate environment variable(s): ${[...duplicates.values()].join(", ")}`,
39+
);
40+
} else {
41+
setError("");
4442
}
4543
}, [envVars, setEnvironmentVariables]);
4644

@@ -57,7 +55,7 @@ export const EnvVarGrid = ({
5755
</span>
5856
<span></span>
5957
{envVars.map(({ name, value, isSensitive }, index) => {
60-
const isFixedSensitive = fixedSensitiveNames.has(name);
58+
const isFixedSensitive = fixedSensitiveVars[name] === index;
6159
return (
6260
<Fragment key={index}>
6361
<Input
@@ -76,21 +74,14 @@ export const EnvVarGrid = ({
7674
value={name}
7775
onChange={(e) => {
7876
const value = e.currentTarget.value;
79-
setEnvironmentVariables((prev) => {
80-
const newList = prev.toSpliced(index, 1, {
81-
...prev[index],
82-
name: value,
83-
});
84-
const duplicates = getDuplicates(newList);
85-
if (duplicates.length != 0) {
86-
setError(
87-
`Duplicate environment variable(s): ${duplicates.join(", ")}`,
88-
);
89-
} else {
90-
setError("");
91-
}
92-
return newList;
93-
});
77+
setEnvironmentVariables((prev) =>
78+
getCorrectEnvBlanks(
79+
prev.toSpliced(index, 1, {
80+
...prev[index],
81+
name: value,
82+
}),
83+
),
84+
);
9485
}}
9586
/>
9687
<span className="w-fit align-middle text-xl">=</span>
@@ -103,13 +94,14 @@ export const EnvVarGrid = ({
10394
value={value ?? ""}
10495
onChange={(e) => {
10596
const value = e.currentTarget.value;
106-
setEnvironmentVariables((prev) => {
107-
const newList = prev.toSpliced(index, 1, {
108-
...prev[index],
109-
value: value,
110-
});
111-
return newList;
112-
});
97+
setEnvironmentVariables((prev) =>
98+
getCorrectEnvBlanks(
99+
prev.toSpliced(index, 1, {
100+
...prev[index],
101+
value: value,
102+
}),
103+
),
104+
);
113105
}}
114106
autoComplete="off"
115107
autoCorrect="off"
@@ -123,10 +115,12 @@ export const EnvVarGrid = ({
123115
checked={isSensitive}
124116
onCheckedChange={(checked) => {
125117
setEnvironmentVariables((prev) =>
126-
prev.toSpliced(index, 1, {
127-
...prev[index],
128-
isSensitive: checked === true,
129-
}),
118+
getCorrectEnvBlanks(
119+
prev.toSpliced(index, 1, {
120+
...prev[index],
121+
isSensitive: checked === true,
122+
}),
123+
),
130124
);
131125
}}
132126
/>
@@ -136,7 +130,9 @@ export const EnvVarGrid = ({
136130
variant="secondary"
137131
type="button"
138132
onClick={() =>
139-
setEnvironmentVariables((prev) => prev.toSpliced(index, 1))
133+
setEnvironmentVariables((prev) =>
134+
index != prev.length - 1 ? prev.toSpliced(index, 1) : prev,
135+
)
140136
}
141137
>
142138
<Trash2 />
@@ -149,17 +145,23 @@ export const EnvVarGrid = ({
149145
);
150146
};
151147

152-
const getDuplicates = (values: EnvVars): string[] => {
153-
const names = new Set();
154-
const result = [];
155-
for (const env of values) {
156-
if (env.name === "") {
157-
continue;
158-
}
159-
if (names.has(env.name)) {
160-
result.push(env.name);
148+
export const getCorrectEnvBlanks = (envVars: EnvVars): EnvVars => {
149+
const indicesToDelete = new Set<number>();
150+
envVars.forEach((env, idx) => {
151+
if (
152+
env.name === "" &&
153+
env.value === "" &&
154+
!env.isSensitive &&
155+
idx < envVars.length - 1
156+
) {
157+
indicesToDelete.add(idx);
161158
}
162-
names.add(env.name);
159+
});
160+
const cleanedVars = envVars.filter((_, idx) => !indicesToDelete.has(idx));
161+
162+
const last = cleanedVars[cleanedVars.length - 1];
163+
if (last.name !== "" || last.value !== "" || last.isSensitive) {
164+
cleanedVars.push({ name: "", value: "", isSensitive: false });
163165
}
164-
return result;
166+
return cleanedVars;
165167
};

frontend/src/components/diff/workload/CommonWorkloadConfigDiff.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ export const CommonWorkloadConfigDiff = ({
4040
const appConfig = useAppConfig();
4141
const baseWorkloadState = base.appType === "workload" ? base.workload : null;
4242

43-
const fixedSensitiveNames = new Set(
43+
const fixedSensitiveVars =
4444
baseWorkloadState?.env
45-
.filter((env) => env.isSensitive)
46-
.map((env) => env.name) ?? [],
47-
);
48-
45+
.map((env, idx) => ({ env, idx }))
46+
.filter(({ env }) => env.isSensitive)
47+
.reduce((obj, cur) => Object.assign(obj, { [cur.env.name]: cur.idx })) ??
48+
{};
4949
return (
5050
<>
5151
<h3 className="mt-4 border-b pb-1 font-bold">Deployment Options</h3>
@@ -189,7 +189,7 @@ export const CommonWorkloadConfigDiff = ({
189189
env: updater(prev.env),
190190
}))
191191
}
192-
fixedSensitiveNames={fixedSensitiveNames}
192+
fixedSensitiveVars={fixedSensitiveVars}
193193
/>
194194
</AccordionContent>
195195
</AccordionItem>

0 commit comments

Comments
 (0)