@@ -638,6 +638,8 @@ export function AssistantEditor({
638
638
values,
639
639
setFieldValue,
640
640
errors,
641
+ submitForm,
642
+ validateForm,
641
643
...formikProps
642
644
} : FormikProps < any > ) => {
643
645
function toggleToolInValues ( toolId : number ) {
@@ -648,6 +650,55 @@ export function AssistantEditor({
648
650
setFieldValue ( "enabled_tools_map" , updatedEnabledToolsMap ) ;
649
651
}
650
652
653
+ // Helper function to scroll to the first error field
654
+ const scrollToFirstError = ( errors : Record < string , any > ) => {
655
+ const errorFields = Object . keys ( errors ) ;
656
+ if ( errorFields . length === 0 ) return ;
657
+
658
+ const firstErrorField = errorFields [ 0 ] ;
659
+ // Try to find the field element by name attribute or aria-label
660
+ const fieldElement =
661
+ document . querySelector ( `[name="${ firstErrorField } "]` ) ||
662
+ document . querySelector ( `[aria-label*="${ firstErrorField } "]` ) ||
663
+ document . querySelector ( `input[name="${ firstErrorField } "]` ) ||
664
+ document . querySelector ( `textarea[name="${ firstErrorField } "]` ) ||
665
+ document . querySelector ( `select[name="${ firstErrorField } "]` ) ||
666
+ // Fallback to finding by field wrapper with error message
667
+ document . querySelector ( `.field-${ firstErrorField } ` ) ||
668
+ // Look for error message elements that might be near the field
669
+ document . querySelector ( `[class*="error"][class*="${ firstErrorField } "]` ) ;
670
+
671
+ if ( fieldElement ) {
672
+ fieldElement . scrollIntoView ( {
673
+ behavior : 'smooth' ,
674
+ block : 'center' ,
675
+ inline : 'nearest'
676
+ } ) ;
677
+
678
+ // Focus the field if it's focusable
679
+ if ( fieldElement instanceof HTMLElement &&
680
+ ( fieldElement . tagName === 'INPUT' ||
681
+ fieldElement . tagName === 'TEXTAREA' ||
682
+ fieldElement . tagName === 'SELECT' ) ) {
683
+ setTimeout ( ( ) => fieldElement . focus ( ) , 300 ) ;
684
+ }
685
+ }
686
+ } ;
687
+
688
+ // Custom submit handler that scrolls to errors
689
+ const handleFormSubmit = async ( ) => {
690
+ const validationErrors = await validateForm ( values ) ;
691
+
692
+ if ( Object . keys ( validationErrors ) . length > 0 ) {
693
+ // There are validation errors, scroll to the first one
694
+ scrollToFirstError ( validationErrors ) ;
695
+ return ;
696
+ }
697
+
698
+ // No validation errors, proceed with normal submission
699
+ submitForm ( ) ;
700
+ } ;
701
+
651
702
// model must support image input for image generation
652
703
// to work
653
704
const currentLLMSupportsImageOutput = modelSupportsImageInput (
@@ -1620,7 +1671,8 @@ export function AssistantEditor({
1620
1671
</ div >
1621
1672
< div className = "flex gap-x-2" >
1622
1673
< Button
1623
- type = "submit"
1674
+ type = "button"
1675
+ onClick = { handleFormSubmit }
1624
1676
disabled = { isSubmitting || isRequestSuccessful }
1625
1677
>
1626
1678
{ isUpdate ? "Update" : "Create" }
0 commit comments