You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
3.0 KiB

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