Implemented search for users when adding a user to a list/namespace

This commit is contained in:
kolaente 2018-09-21 20:12:24 +02:00
parent df326618ce
commit 219995c341
No known key found for this signature in database
GPG key ID: F40E70337AB24C9B
3 changed files with 94 additions and 8 deletions

6
package-lock.json generated
View file

@ -15610,6 +15610,12 @@
"vue-style-loader": "^4.1.0" "vue-style-loader": "^4.1.0"
} }
}, },
"vue-multiselect": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-2.1.0.tgz",
"integrity": "sha512-mEhApxZ6MUISGLuGDy0RF5UlAKUgG/Qq0DWYE/C+CA1h6ZszM3cHfpNFfFm2AMWLclY2SAWpY1HlQLjsw8WnvQ==",
"dev": true
},
"vue-notification": { "vue-notification": {
"version": "1.3.13", "version": "1.3.13",
"resolved": "https://registry.npmjs.org/vue-notification/-/vue-notification-1.3.13.tgz", "resolved": "https://registry.npmjs.org/vue-notification/-/vue-notification-1.3.13.tgz",

View file

@ -25,6 +25,7 @@
"npm": "^6.4.1", "npm": "^6.4.1",
"sass-loader": "^7.1.0", "sass-loader": "^7.1.0",
"vue-flatpickr-component": "^7.0.6", "vue-flatpickr-component": "^7.0.6",
"vue-multiselect": "^2.1.0",
"vue-notification": "^1.3.13", "vue-notification": "^1.3.13",
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue-template-compiler": "^2.5.17" "vue-template-compiler": "^2.5.17"

View file

@ -9,14 +9,27 @@
<div class="card-content content users-list"> <div class="card-content content users-list">
<form @submit.prevent="addUser()" class="add-user-form" v-if="userIsAdmin"> <form @submit.prevent="addUser()" class="add-user-form" v-if="userIsAdmin">
<div class="field is-grouped"> <div class="field is-grouped">
<p class="control has-icons-left is-expanded" v-bind:class="{ 'is-loading': loading}"> <p class="control is-expanded" v-bind:class="{ 'is-loading': loading}">
<input class="input" v-bind:class="{ 'disabled': loading}" v-model.number="newUser.user_id" type="text" placeholder="Add a new user..."> <multiselect
<span class="icon is-small is-left"> v-model="newUser"
<icon icon="user"/> :options="foundUsers"
</span> :multiple="false"
:searchable="true"
:loading="loading"
:internal-search="true"
@search-change="findUsers"
placeholder="Type to search a user"
label="username"
track-by="user_id">
<template slot="clear" slot-scope="props">
<div class="multiselect__clear" v-if="newUser.id !== 0" @mousedown.prevent.stop="clearAll(props.search)"></div>
</template>
<span slot="noResult">Oops! No users found. Consider changing the search query.</span>
</multiselect>
</p> </p>
<p class="control"> <p class="control">
<button type="submit" class="button is-success"> <button type="submit" class="button is-success" style="margin-top: 3px;">
<span class="icon is-small"> <span class="icon is-small">
<icon icon="plus"/> <icon icon="plus"/>
</span> </span>
@ -90,6 +103,8 @@
import {HTTP} from '../../http-common' import {HTTP} from '../../http-common'
import auth from '../../auth' import auth from '../../auth'
import message from '../../message' import message from '../../message'
import multiselect from 'vue-multiselect'
import 'vue-multiselect/dist/vue-multiselect.min.css'
export default { export default {
name: 'user', name: 'user',
@ -105,10 +120,15 @@
typeString: '', typeString: '',
showUserDeleteModal: false, showUserDeleteModal: false,
users: [], users: [],
newUser: {user_id: 0}, newUser: {username: '', user_id: 0},
userToDelete: 0, userToDelete: 0,
newUserid: 0,
foundUsers: [],
} }
}, },
components: {
multiselect
},
created() { created() {
if (this.type === 'list') { if (this.type === 'list') {
this.typeString = `list` this.typeString = `list`
@ -152,9 +172,12 @@
this.newUser.right = 2 this.newUser.right = 2
} }
this.$set(this, 'foundUsers', [])
HTTP.put(this.typeString + `s/` + this.id + `/users`, this.newUser, {headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}}) HTTP.put(this.typeString + `s/` + this.id + `/users`, this.newUser, {headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}})
.then(() => { .then(() => {
this.loadUsers() this.loadUsers()
this.newUser = {}
this.handleSuccess({message: 'The user was successfully added.'}) this.handleSuccess({message: 'The user was successfully added.'})
}) })
.catch(e => { .catch(e => {
@ -176,6 +199,39 @@
this.handleError(e) this.handleError(e)
}) })
}, },
findUsers(query) {
this.loading = true;
if(query === '') {
this.$set(this, 'foundUsers', [])
this.loading = false
return
}
this.$set(this, 'newUser', {username: '', user_id: 0})
HTTP.get(`users?s=` + query, {headers: {'Authorization': 'Bearer ' + localStorage.getItem('token')}})
.then(response => {
this.$set(this, 'foundUsers', [])
for (const u in response.data) {
this.foundUsers.push({
username: response.data[u].username,
user_id: response.data[u].id,
})
}
this.loading = false
})
.catch(e => {
this.handleError(e)
})
},
clearAll () {
this.$set(this, 'foundUsers', [])
},
limitText (count) {
return `and ${count} others`
},
handleError(e) { handleError(e) {
this.loading = false this.loading = false
message.error(e, this) message.error(e, this)
@ -188,7 +244,7 @@
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss">
.card{ .card{
margin-bottom: 1rem; margin-bottom: 1rem;
@ -216,4 +272,27 @@
.users-list, .users-namespace{ .users-list, .users-namespace{
padding: 0 !important; padding: 0 !important;
} }
ul.multiselect__content{
margin: 0 !important;
}
.multiselect{
background-color: white;
border: 1px solid #dbdbdb;
color: #363636;
-webkit-box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1);
box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1);
border-radius: 4px;
font-size: 1rem;
height: 2.25em;
line-height: 1.5;
}
.multiselect--active{
-webkit-box-shadow: inset 0 0.125em 0 rgba(10, 10, 10, 0.075), 0 0 0 0.125em rgba(91, 183, 219, 0.25);
box-shadow: inset 0 0.125em 0 rgba(10, 10, 10, 0.075), 0 0 0 0.125em rgba(91, 183, 219, 0.25);
border: 1px solid #5bb7db;
}
</style> </style>