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
|
<script>
import { GlCollapsibleListbox } from '@gitlab/ui';
import { debounce } from 'lodash';
import axios from '~/lib/utils/axios_utils';
import { DEBOUNCE_REFS_SEARCH_MS } from '../constants';
import { formatListBoxItems, searchByFullNameInListboxOptions } from '../utils/format_refs';
export default {
components: {
GlCollapsibleListbox,
},
inject: ['projectRefsEndpoint'],
props: {
value: {
type: Object,
required: false,
default: () => ({}),
},
},
data() {
return {
isLoading: false,
searchTerm: '',
listBoxItems: [],
};
},
computed: {
lowerCasedSearchTerm() {
return this.searchTerm.toLowerCase();
},
refShortName() {
return this.value.shortName;
},
},
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.listBoxItems = formatListBoxItems(Branches, Tags);
})
.catch((e) => {
this.$emit('loadingError', e);
})
.finally(() => {
this.isLoading = false;
});
},
debouncedLoadRefs: debounce(function debouncedLoadRefs() {
this.loadRefs();
}, DEBOUNCE_REFS_SEARCH_MS),
setRefSelected(refFullName) {
const ref = searchByFullNameInListboxOptions(refFullName, this.listBoxItems);
this.$emit('input', ref);
},
setSearchTerm(searchQuery) {
this.searchTerm = searchQuery?.trim();
this.debouncedLoadRefs();
},
},
};
</script>
<template>
<gl-collapsible-listbox
class="gl-w-full gl-font-monospace"
:items="listBoxItems"
:searchable="true"
:searching="isLoading"
:search-placeholder="__('Search refs')"
:selected="value.fullName"
toggle-class="gl-flex-direction-column gl-align-items-stretch!"
:toggle-text="refShortName"
@search="setSearchTerm"
@select="setRefSelected"
@shown.once="loadRefs"
/>
</template>
|