Improve usability of users view (#5176)
* Improve usability of users view Resolve #5173 * Fix query * Follow review and fix * Follow review
This commit is contained in:
		
							parent
							
								
									9a09ed6290
								
							
						
					
					
						commit
						8e4ad4b919
					
				
					 4 changed files with 50 additions and 7 deletions
				
			
		|  | @ -1502,6 +1502,8 @@ admin/views/users.vue: | |||
|   remote-user-updated: "リモートユーザー情報を更新しました" | ||||
|   delete-all-files: "すべてのファイルを削除" | ||||
|   delete-all-files-confirm: "すべてのファイルを削除しますか?" | ||||
|   username: "ユーザー名" | ||||
|   host: "ホスト" | ||||
|   users: | ||||
|     title: "ユーザー" | ||||
|     sort: | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <div class="kofvwchc"> | ||||
| <div class="kofvwchc" @click="click(user.id)"> | ||||
| 	<div> | ||||
| 		<a :href="user | userPage(null, true)"> | ||||
| 			<mk-avatar class="avatar" :user="user" :disable-link="true"/> | ||||
|  | @ -32,7 +32,7 @@ import { faSnowflake } from '@fortawesome/free-regular-svg-icons'; | |||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	i18n: i18n('admin/views/users.vue'), | ||||
| 	props: ['user'], | ||||
| 	props: ['user', 'click'], | ||||
| 	data() { | ||||
| 		return { | ||||
| 			faSnowflake, faMicrophoneSlash | ||||
|  |  | |||
|  | @ -8,7 +8,7 @@ | |||
| 			</ui-input> | ||||
| 			<ui-button @click="showUser"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button> | ||||
| 
 | ||||
| 			<div class="user" v-if="user"> | ||||
| 			<div ref="user" class="user" v-if="user" :key="user.id"> | ||||
| 				<x-user :user="user"/> | ||||
| 				<div class="actions"> | ||||
| 					<ui-button v-if="user.host != null" @click="updateRemoteUser"><fa :icon="faSync"/> {{ $t('update-remote-user') }}</ui-button> | ||||
|  | @ -54,8 +54,16 @@ | |||
| 					<option value="remote">{{ $t('users.origin.remote') }}</option> | ||||
| 				</ui-select> | ||||
| 			</ui-horizon-group> | ||||
| 			<ui-horizon-group searchboxes> | ||||
| 				<ui-input v-model="searchUsername" type="text" spellcheck="false" @input="fetchUsers(true)"> | ||||
| 					<span>{{ $t('username') }}</span> | ||||
| 				</ui-input> | ||||
| 				<ui-input v-model="searchHost" type="text" spellcheck="false" @input="fetchUsers(true)" :readonly="origin === 'local'"> | ||||
| 					<span>{{ $t('host') }}</span> | ||||
| 				</ui-input> | ||||
| 			</ui-horizon-group> | ||||
| 			<sequential-entrance animation="entranceFromTop" delay="25"> | ||||
| 				<x-user v-for="user in users" :user='user' :key="user.id"/> | ||||
| 				<x-user v-for="user in users" :key="user.id" :user='user' :click="showUserOnClick"/> | ||||
| 			</sequential-entrance> | ||||
| 			<ui-button v-if="existMore" @click="fetchUsers">{{ $t('@.load-more') }}</ui-button> | ||||
| 		</section> | ||||
|  | @ -85,6 +93,8 @@ export default Vue.extend({ | |||
| 			sort: '+createdAt', | ||||
| 			state: 'all', | ||||
| 			origin: 'local', | ||||
| 			searchUsername: '', | ||||
| 			searchHost: '', | ||||
| 			limit: 10, | ||||
| 			offset: 0, | ||||
| 			users: [], | ||||
|  | @ -107,6 +117,7 @@ export default Vue.extend({ | |||
| 		}, | ||||
| 
 | ||||
| 		origin() { | ||||
| 			if (this.origin === 'local') this.searchHost = ''; | ||||
| 			this.users = []; | ||||
| 			this.offset = 0; | ||||
| 			this.fetchUsers(); | ||||
|  | @ -157,6 +168,15 @@ export default Vue.extend({ | |||
| 			this.target = ''; | ||||
| 		}, | ||||
| 
 | ||||
| 		async showUserOnClick(userId: string) { | ||||
| 			this.$root.api('admin/show-user', { userId: userId }).then(info => { | ||||
| 				this.user = info; | ||||
| 				this.$nextTick(() => { | ||||
| 					this.$refs.user.scrollIntoView(); | ||||
| 				}); | ||||
| 			}); | ||||
| 		}, | ||||
| 
 | ||||
| 		/** 処理対象ユーザーの情報を更新する */ | ||||
| 		async refreshUser() { | ||||
| 			this.$root.api('admin/show-user', { userId: this.user.id }).then(info => { | ||||
|  | @ -308,13 +328,16 @@ export default Vue.extend({ | |||
| 			return !confirm.canceled; | ||||
| 		}, | ||||
| 
 | ||||
| 		fetchUsers() { | ||||
| 		fetchUsers(truncate?: boolean) { | ||||
| 			if (truncate) this.offset = 0; | ||||
| 			this.$root.api('admin/show-users', { | ||||
| 				state: this.state, | ||||
| 				origin: this.origin, | ||||
| 				sort: this.sort, | ||||
| 				offset: this.offset, | ||||
| 				limit: this.limit + 1 | ||||
| 				limit: this.limit + 1, | ||||
| 				username: this.searchUsername, | ||||
| 				hostname: this.searchHost | ||||
| 			}).then(users => { | ||||
| 				if (users.length == this.limit + 1) { | ||||
| 					users.pop(); | ||||
|  | @ -322,7 +345,7 @@ export default Vue.extend({ | |||
| 				} else { | ||||
| 					this.existMore = false; | ||||
| 				} | ||||
| 				this.users = this.users.concat(users); | ||||
| 				this.users = truncate ? users : this.users.concat(users); | ||||
| 				this.offset += this.limit; | ||||
| 			}); | ||||
| 		} | ||||
|  |  | |||
|  | @ -49,6 +49,16 @@ export const meta = { | |||
| 				'remote', | ||||
| 			]), | ||||
| 			default: 'local' | ||||
| 		}, | ||||
| 
 | ||||
| 		username: { | ||||
| 			validator: $.optional.str, | ||||
| 			default: null | ||||
| 		}, | ||||
| 
 | ||||
| 		hostname: { | ||||
| 			validator: $.optional.str, | ||||
| 			default: null | ||||
| 		} | ||||
| 	} | ||||
| }; | ||||
|  | @ -70,6 +80,14 @@ export default define(meta, async (ps, me) => { | |||
| 		case 'remote': query.andWhere('user.host IS NOT NULL'); break; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ps.username) { | ||||
| 		query.andWhere('user.usernameLower like :username', { username: ps.username.toLowerCase() + '%' }); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ps.hostname) { | ||||
| 		query.andWhere('user.host like :hostname', { hostname: '%' + ps.hostname.toLowerCase() + '%' }); | ||||
| 	} | ||||
| 
 | ||||
| 	switch (ps.sort) { | ||||
| 		case '+follower': query.orderBy('user.followersCount', 'DESC'); break; | ||||
| 		case '-follower': query.orderBy('user.followersCount', 'ASC'); break; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue