mirror of
				https://github.com/MHSanaei/3x-ui.git
				synced 2025-10-31 04:12:51 +00:00 
			
		
		
		
	chore: login improvements (#3408)
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Release 3X-UI / build (386) (push) Has been cancelled
				
			
		
			
				
	
				Release 3X-UI / build (amd64) (push) Has been cancelled
				
			
		
			
				
	
				Release 3X-UI / build (arm64) (push) Has been cancelled
				
			
		
			
				
	
				Release 3X-UI / build (armv5) (push) Has been cancelled
				
			
		
			
				
	
				Release 3X-UI / build (armv6) (push) Has been cancelled
				
			
		
			
				
	
				Release 3X-UI / build (armv7) (push) Has been cancelled
				
			
		
			
				
	
				Release 3X-UI / build (s390x) (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Release 3X-UI / build (386) (push) Has been cancelled
				
			Release 3X-UI / build (amd64) (push) Has been cancelled
				
			Release 3X-UI / build (arm64) (push) Has been cancelled
				
			Release 3X-UI / build (armv5) (push) Has been cancelled
				
			Release 3X-UI / build (armv6) (push) Has been cancelled
				
			Release 3X-UI / build (armv7) (push) Has been cancelled
				
			Release 3X-UI / build (s390x) (push) Has been cancelled
				
			- added client-side form validation - now with slow internet otp input does not appear later than all input
This commit is contained in:
		
							parent
							
								
									d7882c25d1
								
							
						
					
					
						commit
						da6b89fdcd
					
				
					 1 changed files with 89 additions and 70 deletions
				
			
		|  | @ -466,15 +466,24 @@ | ||||||
|           </g> |           </g> | ||||||
|         </svg> |         </svg> | ||||||
|       </div> |       </div> | ||||||
|       <a-row type="flex" justify="center" align="middle" :style="{ height: '100%', overflow: 'auto', overflowX: 'hidden' }"> |       <a-row type="flex" justify="center" align="middle" | ||||||
|  |         :style="{ height: '100%', overflow: 'auto', overflowX: 'hidden' }"> | ||||||
|         <a-col :xs="22" :sm="12" :md="10" :lg="8" :xl="6" :xxl="5" id="login" :style="{ margin: '3rem 0' }"> |         <a-col :xs="22" :sm="12" :md="10" :lg="8" :xl="6" :xxl="5" id="login" :style="{ margin: '3rem 0' }"> | ||||||
|  |           <template v-if="!loadingStates.fetched"> | ||||||
|  |             <div :style="{ textAlign: 'center' }"> | ||||||
|  |               <a-spin size="large" /> | ||||||
|  |             </div> | ||||||
|  |           </template> | ||||||
|  |           <template v-else> | ||||||
|             <div class="setting-section"> |             <div class="setting-section"> | ||||||
|             <a-popover :overlay-class-name="themeSwitcher.currentTheme" title='{{ i18n "menu.settings" }}' placement="bottomRight" trigger="click"> |               <a-popover :overlay-class-name="themeSwitcher.currentTheme" title='{{ i18n "menu.settings" }}' | ||||||
|  |                 placement="bottomRight" trigger="click"> | ||||||
|                 <template slot="content"> |                 <template slot="content"> | ||||||
|                   <a-space direction="vertical" :size="10"> |                   <a-space direction="vertical" :size="10"> | ||||||
|                     <a-theme-switch-login></a-theme-switch-login> |                     <a-theme-switch-login></a-theme-switch-login> | ||||||
|                     <span>{{ i18n "pages.settings.language" }}</span> |                     <span>{{ i18n "pages.settings.language" }}</span> | ||||||
|                   <a-select ref="selectLang" :style="{ width: '100%' }" v-model="lang" @change="LanguageManager.setLanguage(lang)" :dropdown-class-name="themeSwitcher.currentTheme"> |                     <a-select ref="selectLang" :style="{ width: '100%' }" v-model="lang" | ||||||
|  |                       @change="LanguageManager.setLanguage(lang)" :dropdown-class-name="themeSwitcher.currentTheme"> | ||||||
|                       <a-select-option :value="l.value" label="English" v-for="l in LanguageManager.supportedLanguages"> |                       <a-select-option :value="l.value" label="English" v-for="l in LanguageManager.supportedLanguages"> | ||||||
|                         <span role="img" aria-label="l.name" v-text="l.icon"></span> |                         <span role="img" aria-label="l.name" v-text="l.icon"></span> | ||||||
|                           <span v-text="l.name"></span> |                           <span v-text="l.name"></span> | ||||||
|  | @ -497,32 +506,34 @@ | ||||||
|             </a-row> |             </a-row> | ||||||
|             <a-row type="flex" justify="center"> |             <a-row type="flex" justify="center"> | ||||||
|               <a-col span="24"> |               <a-col span="24"> | ||||||
|               <a-form> |                 <a-form @submit.prevent="login"> | ||||||
|                   <a-space direction="vertical" size="middle"> |                   <a-space direction="vertical" size="middle"> | ||||||
|                     <a-form-item> |                     <a-form-item> | ||||||
|                       <a-input autocomplete="username" name="username" v-model.trim="user.username" |                       <a-input autocomplete="username" name="username" v-model.trim="user.username" | ||||||
|                       placeholder='{{ i18n "username" }}' @keydown.enter.native="login" autofocus> |                         placeholder='{{ i18n "username" }}' autofocus required> | ||||||
|                         <a-icon slot="prefix" type="user" :style="{ fontSize: '1rem' }"></a-icon> |                         <a-icon slot="prefix" type="user" :style="{ fontSize: '1rem' }"></a-icon> | ||||||
|                       </a-input> |                       </a-input> | ||||||
|                     </a-form-item> |                     </a-form-item> | ||||||
|                     <a-form-item> |                     <a-form-item> | ||||||
|                       <a-input-password autocomplete="password" name="password" v-model.trim="user.password" |                       <a-input-password autocomplete="password" name="password" v-model.trim="user.password" | ||||||
|                       placeholder='{{ i18n "password" }}' @keydown.enter.native="login"> |                         placeholder='{{ i18n "password" }}' required> | ||||||
|                         <a-icon slot="prefix" type="lock" :style="{ fontSize: '1rem' }"></a-icon> |                         <a-icon slot="prefix" type="lock" :style="{ fontSize: '1rem' }"></a-icon> | ||||||
|                       </a-input-password> |                       </a-input-password> | ||||||
|                     </a-form-item> |                     </a-form-item> | ||||||
|                     <a-form-item v-if="twoFactorEnable"> |                     <a-form-item v-if="twoFactorEnable"> | ||||||
|                       <a-input autocomplete="one-time-code" name="twoFactorCode" v-model.trim="user.twoFactorCode" |                       <a-input autocomplete="one-time-code" name="twoFactorCode" v-model.trim="user.twoFactorCode" | ||||||
|                       placeholder='{{ i18n "twoFactorCode" }}' @keydown.enter.native="login"> |                         placeholder='{{ i18n "twoFactorCode" }}' required> | ||||||
|                         <a-icon slot="prefix" type="key" :style="{ fontSize: '1rem' }"></a-icon> |                         <a-icon slot="prefix" type="key" :style="{ fontSize: '1rem' }"></a-icon> | ||||||
|                       </a-input> |                       </a-input> | ||||||
|                     </a-form-item> |                     </a-form-item> | ||||||
|                     <a-form-item> |                     <a-form-item> | ||||||
|                       <a-row justify="center" class="centered"> |                       <a-row justify="center" class="centered"> | ||||||
|                       <div :style="{ height: '50px', marginTop: '1rem', ...loading ? { width: '52px' } : { display: 'inline-block' } }" class="wave-btn-bg wave-btn-bg-cl"> |                         <div | ||||||
|                         <a-button class="ant-btn-primary-login" type="primary" :loading="loading" @click="login" |                           :style="{ height: '50px', marginTop: '1rem', ...loadingStates.spinning ? { width: '52px' } : { display: 'inline-block' } }" | ||||||
|                           :icon="loading ? 'poweroff' : undefined"> |                           class="wave-btn-bg wave-btn-bg-cl"> | ||||||
|                           [[ loading ? '' : '{{ i18n "login" }}' ]] |                           <a-button class="ant-btn-primary-login" type="primary" :loading="loadingStates.spinning" | ||||||
|  |                             :icon="loadingStates.spinning ? 'poweroff' : undefined" html-type="submit"> | ||||||
|  |                             [[ loadingStates.spinning ? '' : '{{ i18n "login" }}' ]] | ||||||
|                           </a-button> |                           </a-button> | ||||||
|                         </div> |                         </div> | ||||||
|                       </a-row> |                       </a-row> | ||||||
|  | @ -531,6 +542,7 @@ | ||||||
|                 </a-form> |                 </a-form> | ||||||
|               </a-col> |               </a-col> | ||||||
|             </a-row> |             </a-row> | ||||||
|  |           </template> | ||||||
|         </a-col> |         </a-col> | ||||||
|       </a-row> |       </a-row> | ||||||
|     </a-layout-content> |     </a-layout-content> | ||||||
|  | @ -544,7 +556,10 @@ | ||||||
|     el: '#app', |     el: '#app', | ||||||
|     data: { |     data: { | ||||||
|       themeSwitcher, |       themeSwitcher, | ||||||
|       loading: false, |       loadingStates: { | ||||||
|  |         fetched: false, | ||||||
|  |         spinning: false | ||||||
|  |       }, | ||||||
|       user: { |       user: { | ||||||
|         username: "", |         username: "", | ||||||
|         password: "", |         password: "", | ||||||
|  | @ -559,19 +574,23 @@ | ||||||
|     }, |     }, | ||||||
|     methods: { |     methods: { | ||||||
|       async login() { |       async login() { | ||||||
|         this.loading = true; |         this.loadingStates.spinning = true; | ||||||
|  | 
 | ||||||
|         const msg = await HttpUtil.post('/login', this.user); |         const msg = await HttpUtil.post('/login', this.user); | ||||||
|         this.loading = false; | 
 | ||||||
|         if (msg.success) { |         if (msg.success) { | ||||||
|           location.href = basePath + 'panel/'; |           location.href = basePath + 'panel/'; | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         this.loadingStates.spinning = false; | ||||||
|       }, |       }, | ||||||
|       async getTwoFactorEnable() { |       async getTwoFactorEnable() { | ||||||
|         this.loading = true; |  | ||||||
|         const msg = await HttpUtil.post('/getTwoFactorEnable'); |         const msg = await HttpUtil.post('/getTwoFactorEnable'); | ||||||
|         this.loading = false; | 
 | ||||||
|         if (msg.success) { |         if (msg.success) { | ||||||
|           this.twoFactorEnable = msg.obj; |           this.twoFactorEnable = msg.obj; | ||||||
|  |           this.loadingStates.fetched = true; | ||||||
|  | 
 | ||||||
|           return msg.obj; |           return msg.obj; | ||||||
|         } |         } | ||||||
|       }, |       }, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Danil S.
						Danil S.