Skip to content

Commit 7b15616

Browse files
committed
fix: include name validation in canSaveProfile and validateAndSave
- Add validateName() function that validates and updates state - Add isNameValid() pure function for checking without side effects - Update canSaveProfile() to check name, targets, and rules - Update validateAndSave() to gate saving on name validity - Update auto-save status indicator to show name validation errors - Prevents autosave of empty or duplicate profile names
1 parent 7448d4e commit 7b15616

File tree

1 file changed

+31
-10
lines changed

1 file changed

+31
-10
lines changed

webview-ui/src/components/ProfileManager/ProfileEditorForm.tsx

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -138,28 +138,43 @@ export const ProfileEditorForm: React.FC<{
138138
setLocalProfile(updated);
139139
};
140140

141-
const handleBlur = () => {
142-
const trimmedName = localProfile.name.trim();
143-
141+
// Validates profile name and updates validation state
142+
const validateName = (profileToCheck: AnalysisProfile): boolean => {
143+
const trimmedName = profileToCheck.name.trim();
144144
const isDuplicate =
145145
trimmedName !== profile.name && allProfiles.some((p) => p.name === trimmedName);
146146
const isEmpty = trimmedName === "";
147147

148148
if (isEmpty) {
149149
setNameValidation("error");
150150
setNameErrorMsg("Profile name is required.");
151-
return;
151+
return false;
152152
}
153153

154154
if (isDuplicate) {
155155
setNameValidation("error");
156156
setNameErrorMsg("A profile with this name already exists.");
157-
return;
157+
return false;
158158
}
159159

160160
setNameValidation("default");
161161
setNameErrorMsg(null);
162-
debouncedChange({ ...localProfile, name: trimmedName });
162+
return true;
163+
};
164+
165+
// Checks name validity without updating state (for canSaveProfile)
166+
const isNameValid = (profileToCheck: AnalysisProfile): boolean => {
167+
const trimmedName = profileToCheck.name.trim();
168+
const isDuplicate =
169+
trimmedName !== profile.name && allProfiles.some((p) => p.name === trimmedName);
170+
const isEmpty = trimmedName === "";
171+
return !isEmpty && !isDuplicate;
172+
};
173+
174+
const handleBlur = () => {
175+
if (validateName(localProfile)) {
176+
debouncedChange({ ...localProfile, name: localProfile.name.trim() });
177+
}
163178
};
164179

165180
const validateTargets = (targets: string[]) => {
@@ -189,18 +204,20 @@ export const ProfileEditorForm: React.FC<{
189204

190205
// Helper to check if a profile can be saved (all validation passes)
191206
const canSaveProfile = (profileToCheck: AnalysisProfile, targets: string[]): boolean => {
207+
const hasValidName = isNameValid(profileToCheck);
192208
const hasTargets = targets.length > 0;
193209
const hasRules =
194210
profileToCheck.useDefaultRules || (profileToCheck.customRules?.length ?? 0) > 0;
195-
return hasTargets && hasRules;
211+
return hasValidName && hasTargets && hasRules;
196212
};
197213

198214
// Validates and optionally saves if valid
199215
const validateAndSave = (updatedProfile: AnalysisProfile, targets: string[]) => {
216+
const isProfileNameValid = isNameValid(updatedProfile);
200217
const isTargetsValid = validateTargets(targets);
201218
const isRulesValid = validateRules(updatedProfile);
202219

203-
if (isTargetsValid && isRulesValid) {
220+
if (isProfileNameValid && isTargetsValid && isRulesValid) {
204221
debouncedChange(updatedProfile);
205222
}
206223
};
@@ -283,7 +300,9 @@ export const ProfileEditorForm: React.FC<{
283300
<Flex alignItems={{ default: "alignItemsCenter" }}>
284301
<FlexItem>
285302
<Icon>
286-
{targetsValidation === "error" || rulesValidation === "error" ? (
303+
{nameValidation === "error" ||
304+
targetsValidation === "error" ||
305+
rulesValidation === "error" ? (
287306
<ExclamationTriangleIcon color="var(--pf-v5-global--warning-color--100)" />
288307
) : (
289308
<CheckCircleIcon color="var(--pf-v5-global--success-color--100)" />
@@ -292,7 +311,9 @@ export const ProfileEditorForm: React.FC<{
292311
</FlexItem>
293312
<FlexItem>
294313
<span style={{ fontSize: "0.875rem", color: "var(--pf-v5-global--Color--200)" }}>
295-
{targetsValidation === "error" || rulesValidation === "error"
314+
{nameValidation === "error" ||
315+
targetsValidation === "error" ||
316+
rulesValidation === "error"
296317
? "Fix errors to save"
297318
: isSaving
298319
? "Saving..."

0 commit comments

Comments
 (0)