Преглед изворни кода

feat: add debounced enter key submission to install form (#15445) (#15542)

Lam пре 1 месец
родитељ
комит
0bc4da38fc
1 измењених фајлова са 20 додато и 6 уклоњено
  1. 20 6
      web/app/install/installForm.tsx

+ 20 - 6
web/app/install/installForm.tsx

@@ -1,6 +1,7 @@
 'use client'
-import React, { useEffect } from 'react'
+import React, { useCallback, useEffect } from 'react'
 import { useTranslation } from 'react-i18next'
+import { useDebounceFn } from 'ahooks'
 
 import Link from 'next/link'
 import { useRouter } from 'next/navigation'
@@ -39,7 +40,7 @@ const InstallForm = () => {
   const {
     register,
     handleSubmit,
-    formState: { errors },
+    formState: { errors, isSubmitting },
   } = useForm<AccountFormValues>({
     resolver: zodResolver(accountFormSchema),
     defaultValues: {
@@ -59,9 +60,22 @@ const InstallForm = () => {
   }
 
   const handleSetting = async () => {
+    if (isSubmitting) return
     handleSubmit(onSubmit)()
   }
 
+  const { run: debouncedHandleKeyDown } = useDebounceFn(
+    (e: React.KeyboardEvent) => {
+      if (e.key === 'Enter') {
+        e.preventDefault()
+        handleSetting()
+      }
+    },
+    { wait: 200 },
+  )
+
+  const handleKeyDown = useCallback(debouncedHandleKeyDown, [debouncedHandleKeyDown])
+
   useEffect(() => {
     fetchSetupStatus().then((res: SetupStatusResponse) => {
       if (res.step === 'finished') {
@@ -90,7 +104,7 @@ const InstallForm = () => {
         </div>
         <div className="grow mt-8 sm:mx-auto sm:w-full sm:max-w-md">
           <div className="bg-white ">
-            <form onSubmit={handleSubmit(onSubmit)}>
+            <form onSubmit={handleSubmit(onSubmit)} onKeyDown={handleKeyDown}>
               <div className='mb-5'>
                 <label htmlFor="email" className="my-2 flex items-center justify-between text-sm font-medium text-gray-900">
                   {t('login.email')}
@@ -99,7 +113,7 @@ const InstallForm = () => {
                   <input
                     {...register('email')}
                     placeholder={t('login.emailPlaceholder') || ''}
-                    className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm'}
+                    className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder:text-gray-400 caret-primary-600 sm:text-sm'}
                   />
                   {errors.email && <span className='text-red-400 text-sm'>{t(`${errors.email?.message}`)}</span>}
                 </div>
@@ -114,7 +128,7 @@ const InstallForm = () => {
                   <input
                     {...register('name')}
                     placeholder={t('login.namePlaceholder') || ''}
-                    className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'}
+                    className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder:text-gray-400 caret-primary-600 sm:text-sm pr-10'}
                   />
                 </div>
                 {errors.name && <span className='text-red-400 text-sm'>{t(`${errors.name.message}`)}</span>}
@@ -129,7 +143,7 @@ const InstallForm = () => {
                     {...register('password')}
                     type={showPassword ? 'text' : 'password'}
                     placeholder={t('login.passwordPlaceholder') || ''}
-                    className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder-gray-400 caret-primary-600 sm:text-sm pr-10'}
+                    className={'appearance-none block w-full rounded-lg pl-[14px] px-3 py-2 border border-gray-200 hover:border-gray-300 hover:shadow-sm focus:outline-none focus:ring-primary-500 focus:border-primary-500 placeholder:text-gray-400 caret-primary-600 sm:text-sm pr-10'}
                   />
 
                   <div className="absolute inset-y-0 right-0 flex items-center pr-3">