@@ -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