172 lines
4.5 KiB
Vue
172 lines
4.5 KiB
Vue
<script>
|
|
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlDropdownSectionHeader } from '@gitlab/ui';
|
|
import { debounce } from 'lodash';
|
|
import { createAlert } from '~/alert';
|
|
import axios from '~/lib/utils/axios_utils';
|
|
import { s__ } from '~/locale';
|
|
|
|
const EMPTY_DROPDOWN_TEXT = s__('CompareRevisions|Select branch/tag');
|
|
const SEARCH_DEBOUNCE_MS = 300;
|
|
|
|
export default {
|
|
components: {
|
|
GlDropdown,
|
|
GlDropdownItem,
|
|
GlDropdownSectionHeader,
|
|
GlSearchBoxByType,
|
|
},
|
|
props: {
|
|
refsProjectPath: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
paramsName: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
paramsBranch: {
|
|
type: String,
|
|
required: false,
|
|
default: null,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
branches: [],
|
|
tags: [],
|
|
loading: true,
|
|
searchTerm: '',
|
|
selectedRevision: this.getDefaultBranch(),
|
|
};
|
|
},
|
|
computed: {
|
|
hasBranches() {
|
|
return Boolean(this.branches?.length);
|
|
},
|
|
hasTags() {
|
|
return Boolean(this.tags?.length);
|
|
},
|
|
},
|
|
watch: {
|
|
refsProjectPath(newRefsProjectPath, oldRefsProjectPath) {
|
|
if (newRefsProjectPath !== oldRefsProjectPath) {
|
|
this.fetchBranchesAndTags(true);
|
|
}
|
|
},
|
|
searchTerm: debounce(function debounceSearch() {
|
|
this.searchBranchesAndTags();
|
|
}, SEARCH_DEBOUNCE_MS),
|
|
paramsBranch(newBranch) {
|
|
this.setSelectedRevision(newBranch);
|
|
},
|
|
},
|
|
mounted() {
|
|
this.fetchBranchesAndTags();
|
|
},
|
|
methods: {
|
|
searchBranchesAndTags() {
|
|
return axios
|
|
.get(this.refsProjectPath, {
|
|
params: {
|
|
search: this.searchTerm,
|
|
},
|
|
})
|
|
.then(({ data }) => {
|
|
this.branches = data.Branches || [];
|
|
this.tags = data.Tags || [];
|
|
})
|
|
.catch(() => {
|
|
createAlert({
|
|
message: s__(
|
|
'CompareRevisions|There was an error while searching the branch/tag list. Please try again.',
|
|
),
|
|
});
|
|
});
|
|
},
|
|
fetchBranchesAndTags(reset = false) {
|
|
this.loading = true;
|
|
|
|
if (reset) {
|
|
this.setSelectedRevision(this.paramsBranch);
|
|
}
|
|
|
|
return axios
|
|
.get(this.refsProjectPath)
|
|
.then(({ data }) => {
|
|
this.branches = data.Branches || [];
|
|
this.tags = data.Tags || [];
|
|
})
|
|
.catch(() => {
|
|
createAlert({
|
|
message: s__(
|
|
'CompareRevisions|There was an error while loading the branch/tag list. Please try again.',
|
|
),
|
|
});
|
|
})
|
|
.finally(() => {
|
|
this.loading = false;
|
|
});
|
|
},
|
|
getDefaultBranch() {
|
|
return this.paramsBranch || EMPTY_DROPDOWN_TEXT;
|
|
},
|
|
onClick(revision) {
|
|
this.setSelectedRevision(revision);
|
|
this.$emit('selectRevision', { direction: this.paramsName, revision });
|
|
},
|
|
onSearchEnter() {
|
|
this.setSelectedRevision(this.searchTerm);
|
|
},
|
|
setSelectedRevision(revision) {
|
|
this.selectedRevision = revision || EMPTY_DROPDOWN_TEXT;
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div :class="`js-compare-${paramsName}-dropdown`">
|
|
<input type="hidden" :name="paramsName" :value="selectedRevision" />
|
|
<gl-dropdown
|
|
class="gl-w-full gl-font-monospace"
|
|
toggle-class="form-control compare-dropdown-toggle gl-min-w-0"
|
|
:text="selectedRevision"
|
|
:header-text="s__('CompareRevisions|Select Git revision')"
|
|
:loading="loading"
|
|
>
|
|
<template #header>
|
|
<gl-search-box-by-type
|
|
v-model.trim="searchTerm"
|
|
:placeholder="s__('CompareRevisions|Filter by Git revision')"
|
|
@keyup.enter="onSearchEnter"
|
|
/>
|
|
</template>
|
|
<gl-dropdown-section-header v-if="hasBranches">
|
|
{{ s__('CompareRevisions|Branches') }}
|
|
</gl-dropdown-section-header>
|
|
<gl-dropdown-item
|
|
v-for="branch in branches"
|
|
:key="branch"
|
|
is-check-item
|
|
:is-checked="selectedRevision === branch"
|
|
data-testid="branches-dropdown-item"
|
|
@click="onClick(branch)"
|
|
>
|
|
{{ branch }}
|
|
</gl-dropdown-item>
|
|
<gl-dropdown-section-header v-if="hasTags">
|
|
{{ s__('CompareRevisions|Tags') }}
|
|
</gl-dropdown-section-header>
|
|
<gl-dropdown-item
|
|
v-for="tag in tags"
|
|
:key="tag"
|
|
is-check-item
|
|
:is-checked="selectedRevision === tag"
|
|
data-testid="tags-dropdown-item"
|
|
@click="onClick(tag)"
|
|
>
|
|
{{ tag }}
|
|
</gl-dropdown-item>
|
|
</gl-dropdown>
|
|
</div>
|
|
</template>
|