User search bar

This commit is contained in:
Evert Prants 2017-12-07 21:57:42 +02:00
parent 61248119c5
commit 234744f5de
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
4 changed files with 89 additions and 2 deletions

View File

@ -154,6 +154,30 @@ const API = {
return {token}
},
// Search for users by terms and fields
searchUsers: async function (terms, fields = ['email']) {
let qb = Models.User.query()
terms = terms.replace(/_/g, '\\_').replace(/%/g, '\\%')
qb = qb.where(fields[0], 'like', '%' + terms + '%')
if (fields.length >= 1) {
for (let i = 1; i < fields.length; i++) {
qb = qb.orWhere(fields[i], 'like', '%' + terms + '%')
}
}
let rows = await qb.limit(8)
if (!rows.length) return { error: 'No results' }
let cleaned = []
for (let i in rows) {
let userRaw = rows[i]
cleaned.push(await cleanUserObject(userRaw, null))
}
return cleaned
},
// List all clients (paginated)
getAllClients: async function (page) {
let count = await Models.OAuth2Client.query().count('id as ids')

View File

@ -156,6 +156,31 @@ apiRouter.post('/user/reset_password', csrfVerify, wrap(async (req, res) => {
res.jsonp(await API.sendPasswordEmail(id))
}))
const availableScopes = ['uuid', 'email', 'username', 'display_name']
apiRouter.get('/search/users', wrap(async (req, res) => {
if (!req.query.terms) throw new Error('Please specify search terms!')
let scopes = []
if (req.query.scopes) {
let scq = req.query.scopes.split(',')
for (let i in scq) {
scq[i] = scq[i].trim()
if (availableScopes.indexOf(scq[i]) !== -1) {
scopes.push(scq[i])
}
}
}
if (!scopes.length) {
scopes.push('email')
}
let results = await API.searchUsers(req.query.terms, scopes)
res.jsonp(results)
}))
/* ===============
* OAuth2 Data
* ===============

View File

@ -3,7 +3,10 @@
h3 Registered Users ({{ pagination.total }})
pagination(:page="pagination.page" :pages="pagination.pages" v-on:page="getUsers")
.list.users
user(v-for='user in users' v-bind="user" :key="user.id")
.searchbox
input(v-model="search" placeholder="Begin typing a name or email address..")
.message.error(v-if="error") {{ error }}
user(v-else v-for='user in users' v-bind="user" :key="user.id")
ban-modal(:show='banning' @close='banning = 0' :id='banning')
user-modal(:show='editing' @close='editing = 0' :id='editing')
</template>
@ -13,6 +16,8 @@
import User from './User.vue'
import BanModal from './BanModal.vue'
import UserModal from './UserModal.vue'
import qs from 'querystring'
const csrfToken = document.querySelector('meta[name="csrf-token"]').content
export default {
@ -27,7 +32,9 @@
},
users: [],
banning: 0,
editing: 0
editing: 0,
search: '',
error: ''
}
},
components: {
@ -35,11 +42,35 @@
},
methods: {
getUsers: function (page) {
this.error = ''
this.$http.get('/admin/api/users?page=' + page).then(data => {
if (data.body && data.body.error) return
this.pagination = data.body.page
this.users = data.body.users
})
},
searchUsers: function () {
this.error = ''
this.$http.get('/admin/api/search/users?' + qs.stringify({
terms: this.search,
scopes: 'email,username,display_name'
})).then(data => {
if (data.body.error) {
this.error = data.body.error
return
}
this.users = data.body
})
}
},
watch: {
search: function () {
if (this.search === '') {
this.getUsers(1)
} else {
this.searchUsers(this.search)
}
}
},
mounted: function () {

View File

@ -133,6 +133,13 @@ nav
border-bottom: 1px solid #ddd
margin-bottom: 9px
.searchbox
margin: 10px 0
input
font-size: 140%
display: block
width: 100%
.modal-mask
position: fixed