user-search.vue 3.14 KB
Newer Older
1
<template lang="pug">
2 3 4 5
  v-dialog(
    v-model='dialogOpen'
    max-width='650'
    )
6
    v-card
7
      .dialog-header
8
        span {{$t('common:user.search')}}
9 10 11 12 13 14 15 16
        v-spacer
        v-progress-circular(
          indeterminate
          color='white'
          :size='20'
          :width='2'
          v-show='searchLoading'
          )
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 24
          color='primary'
          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 30 31
          two-line
          dense
          )
32
          template(v-for='(usr, idx) in items')
33
            v-list-item(:key='usr.id', @click='setUser(usr)')
34
              v-list-item-avatar(size='40', color='primary')
35
                span.body-1.white--text {{usr.name | initials}}
36 37
              v-list-item-content
                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 47
          @click='close'
          :disabled='loading'
48
          ) {{$t('common:actions.cancel')}}
49 50 51
</template>

<script>
52
import _ from 'lodash'
53
import gql from 'graphql-tag'
54 55

export default {
56 57
  filters: {
    initials(val) {
58
      return val.split(' ').map(v => v.substring(0, 1)).join('')
59 60
    }
  },
61
  props: {
62 63 64 65
    multiple: {
      type: Boolean,
      default: false
    },
66 67 68 69 70 71 72 73 74 75
    value: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      loading: false,
      searchLoading: false,
      search: '',
76
      items: []
77 78 79 80 81 82 83 84
    }
  },
  computed: {
    dialogOpen: {
      get() { return this.value },
      set(value) { this.$emit('input', value) }
    }
  },
85 86 87 88 89 90 91 92 93
  watch: {
    value(newValue, oldValue) {
      if (newValue && !oldValue) {
        this.search = ''
        this.selectedItems = null
        _.delay(() => { this.$refs.searchIpt.focus() }, 100)
      }
    }
  },
94 95 96 97
  methods: {
    close() {
      this.$emit('input', false)
    },
98 99
    setUser(usr) {
      this.$emit('select', usr)
100 101 102 103
      this.close()
    },
    searchFilter(item, queryText, itemText) {
      return _.includes(_.toLower(item.email), _.toLower(queryText)) || _.includes(_.toLower(item.name), _.toLower(queryText))
104 105 106 107
    }
  },
  apollo: {
    items: {
108 109 110 111 112 113 114 115 116 117 118 119
      query: gql`
        query ($query: String!) {
          users {
            search(query:$query) {
              id
              name
              email
              providerKey
            }
          }
        }
      `,
120 121
      variables() {
        return {
122
          query: this.search
123 124
        }
      },
125
      fetchPolicy: 'cache-and-network',
126 127 128
      skip() {
        return !this.search || this.search.length < 2
      },
129
      update: (data) => data.users.search,
130 131 132 133 134 135 136
      watchLoading (isLoading) {
        this.searchLoading = isLoading
      }
    }
  }
}
</script>