user-search.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <template lang="pug">
  2. v-dialog(
  3. v-model='dialogOpen'
  4. max-width='650'
  5. )
  6. v-card
  7. .dialog-header
  8. span Search User
  9. v-spacer
  10. v-progress-circular(
  11. indeterminate
  12. color='white'
  13. :size='20'
  14. :width='2'
  15. v-show='searchLoading'
  16. )
  17. v-card-text
  18. v-text-field(
  19. solo
  20. flat
  21. label='Search Users...'
  22. v-model='search'
  23. prepend-icon='search'
  24. :class='$vuetify.dark ? "grey darken-4" : "blue lighten-5"'
  25. color='primary'
  26. ref='searchIpt'
  27. )
  28. v-list(two-line)
  29. template(v-for='(usr, idx) in items')
  30. v-list-tile(:key='usr.id', @click='setUser(usr.id)')
  31. v-list-tile-avatar(size='40', color='primary')
  32. span.body-1.white--text {{usr.name | initials}}
  33. v-list-tile-content
  34. v-list-tile-title {{usr.name}}
  35. v-list-tile-sub-title {{usr.email}}
  36. v-list-tile-action
  37. v-icon(color='primary') arrow_forward
  38. v-divider.my-0(v-if='idx < items.length - 1')
  39. v-card-chin
  40. v-spacer
  41. v-btn(
  42. flat
  43. @click='close'
  44. :disabled='loading'
  45. ) Cancel
  46. </template>
  47. <script>
  48. import _ from 'lodash'
  49. import searchUsersQuery from 'gql/common/common-users-query-search.gql'
  50. export default {
  51. filters: {
  52. initials(val) {
  53. return val.split(' ').map(v => v.substring(0, 1)).join()
  54. }
  55. },
  56. props: {
  57. multiple: {
  58. type: Boolean,
  59. default: false
  60. },
  61. value: {
  62. type: Boolean,
  63. default: false
  64. }
  65. },
  66. data() {
  67. return {
  68. loading: false,
  69. searchLoading: false,
  70. search: '',
  71. items: []
  72. }
  73. },
  74. computed: {
  75. dialogOpen: {
  76. get() { return this.value },
  77. set(value) { this.$emit('input', value) }
  78. }
  79. },
  80. watch: {
  81. value(newValue, oldValue) {
  82. if (newValue && !oldValue) {
  83. this.search = ''
  84. this.selectedItems = null
  85. _.delay(() => { this.$refs.searchIpt.focus() }, 100)
  86. }
  87. }
  88. },
  89. methods: {
  90. close() {
  91. this.$emit('input', false)
  92. },
  93. setUser(id) {
  94. this.$emit('select', id)
  95. this.close()
  96. },
  97. searchFilter(item, queryText, itemText) {
  98. return _.includes(_.toLower(item.email), _.toLower(queryText)) || _.includes(_.toLower(item.name), _.toLower(queryText))
  99. }
  100. },
  101. apollo: {
  102. items: {
  103. query: searchUsersQuery,
  104. variables() {
  105. return {
  106. query: this.search
  107. }
  108. },
  109. skip() {
  110. return !this.search || this.search.length < 2
  111. },
  112. update: (data) => data.users.search,
  113. watchLoading (isLoading) {
  114. this.searchLoading = isLoading
  115. }
  116. }
  117. }
  118. }
  119. </script>