summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipeline_new/components/refs_dropdown.vue
blob: d35d20101509441f75dd4cd41c67bb8a7514b523 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
<script>
import { GlDropdown, GlDropdownItem, GlDropdownSectionHeader, GlSearchBoxByType } from '@gitlab/ui';
import { debounce } from 'lodash';
import axios from '~/lib/utils/axios_utils';
import { BRANCH_REF_TYPE, TAG_REF_TYPE, DEBOUNCE_REFS_SEARCH_MS } from '../constants';
import formatRefs from '../utils/format_refs';

export default {
  components: {
    GlDropdown,
    GlDropdownItem,
    GlDropdownSectionHeader,
    GlSearchBoxByType,
  },
  inject: ['projectRefsEndpoint'],
  props: {
    value: {
      type: Object,
      required: false,
      default: () => ({}),
    },
  },
  data() {
    return {
      isLoading: false,
      searchTerm: '',
      branches: [],
      tags: [],
    };
  },
  computed: {
    lowerCasedSearchTerm() {
      return this.searchTerm.toLowerCase();
    },
    refShortName() {
      return this.value.shortName;
    },
    hasTags() {
      return this.tags.length > 0;
    },
  },
  watch: {
    searchTerm() {
      this.debouncedLoadRefs();
    },
  },
  methods: {
    loadRefs() {
      this.isLoading = true;

      axios
        .get(this.projectRefsEndpoint, {
          params: {
            search: this.lowerCasedSearchTerm,
          },
        })
        .then(({ data }) => {
          // Note: These keys are uppercase in API
          const { Branches = [], Tags = [] } = data;

          this.branches = formatRefs(Branches, BRANCH_REF_TYPE);
          this.tags = formatRefs(Tags, TAG_REF_TYPE);
        })
        .catch((e) => {
          this.$emit('loadingError', e);
        })
        .finally(() => {
          this.isLoading = false;
        });
    },
    debouncedLoadRefs: debounce(function debouncedLoadRefs() {
      this.loadRefs();
    }, DEBOUNCE_REFS_SEARCH_MS),
    setRefSelected(ref) {
      this.$emit('input', ref);
    },
    isSelected(ref) {
      return ref.fullName === this.value.fullName;
    },
  },
};
</script>
<template>
  <gl-dropdown :text="refShortName" block data-testid="ref-select" @show.once="loadRefs">
    <gl-search-box-by-type
      v-model.trim="searchTerm"
      :is-loading="isLoading"
      :placeholder="__('Search refs')"
      data-testid="search-refs"
    />
    <gl-dropdown-section-header>{{ __('Branches') }}</gl-dropdown-section-header>
    <gl-dropdown-item
      v-for="branch in branches"
      :key="branch.fullName"
      class="gl-font-monospace"
      is-check-item
      :is-checked="isSelected(branch)"
      @click="setRefSelected(branch)"
    >
      {{ branch.shortName }}
    </gl-dropdown-item>
    <gl-dropdown-section-header v-if="hasTags">{{ __('Tags') }}</gl-dropdown-section-header>
    <gl-dropdown-item
      v-for="tag in tags"
      :key="tag.fullName"
      class="gl-font-monospace"
      is-check-item
      :is-checked="isSelected(tag)"
      @click="setRefSelected(tag)"
    >
      {{ tag.shortName }}
    </gl-dropdown-item>
  </gl-dropdown>
</template>