summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue')
-rw-r--r--app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue162
1 files changed, 108 insertions, 54 deletions
diff --git a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue
index 1acf3a03e73..05b87abecd5 100644
--- a/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue
+++ b/app/assets/javascripts/pipeline_editor/components/file_nav/branch_switcher.vue
@@ -6,7 +6,10 @@ import {
GlInfiniteScroll,
GlLoadingIcon,
GlSearchBoxByType,
+ GlTooltipDirective,
} from '@gitlab/ui';
+import { produce } from 'immer';
+import { fetchPolicies } from '~/lib/graphql';
import { historyPushState } from '~/lib/utils/common_utils';
import { setUrlParams } from '~/lib/utils/url_utility';
import { s__ } from '~/locale';
@@ -15,12 +18,14 @@ import {
BRANCH_SEARCH_DEBOUNCE,
DEFAULT_FAILURE,
} from '~/pipeline_editor/constants';
-import getAvailableBranches from '~/pipeline_editor/graphql/queries/available_branches.graphql';
-import getCurrentBranch from '~/pipeline_editor/graphql/queries/client/current_branch.graphql';
+import updateCurrentBranchMutation from '~/pipeline_editor/graphql/mutations/update_current_branch.mutation.graphql';
+import getAvailableBranchesQuery from '~/pipeline_editor/graphql/queries/available_branches.graphql';
+import getCurrentBranchQuery from '~/pipeline_editor/graphql/queries/client/current_branch.graphql';
+import getLastCommitBranchQuery from '~/pipeline_editor/graphql/queries/client/last_commit_branch.query.graphql';
export default {
i18n: {
- dropdownHeader: s__('Switch Branch'),
+ dropdownHeader: s__('Switch branch'),
title: s__('Branches'),
fetchError: s__('Unable to fetch branch list for this project.'),
},
@@ -33,6 +38,9 @@ export default {
GlLoadingIcon,
GlSearchBoxByType,
},
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
inject: ['projectFullPath', 'totalBranches'],
props: {
paginationLimit: {
@@ -43,101 +51,147 @@ export default {
},
data() {
return {
- branches: [],
- page: {
- limit: this.paginationLimit,
- offset: 0,
- searchTerm: '',
- },
+ availableBranches: [],
+ filteredBranches: [],
+ isSearchingBranches: false,
+ pageLimit: this.paginationLimit,
+ pageCounter: 0,
+ searchTerm: '',
+ lastCommitBranch: '',
};
},
apollo: {
availableBranches: {
- query: getAvailableBranches,
+ query: getAvailableBranchesQuery,
variables() {
return {
- limit: this.page.limit,
- offset: this.page.offset,
+ limit: this.paginationLimit,
+ offset: 0,
projectFullPath: this.projectFullPath,
- searchPattern: this.searchPattern,
+ searchPattern: '*',
};
},
update(data) {
return data.project?.repository?.branchNames || [];
},
- result({ data }) {
- const newBranches = data.project?.repository?.branchNames || [];
-
- // check that we're not re-concatenating existing fetch results
- if (!this.branches.includes(newBranches[0])) {
- this.branches = this.branches.concat(newBranches);
- }
+ result() {
+ this.pageCounter += 1;
},
error() {
- this.$emit('showError', {
- type: DEFAULT_FAILURE,
- reasons: [this.$options.i18n.fetchError],
- });
+ this.showFetchError();
},
},
currentBranch: {
- query: getCurrentBranch,
+ query: getCurrentBranchQuery,
+ },
+ lastCommitBranch: {
+ query: getLastCommitBranchQuery,
+ result({ data: { lastCommitBranch } }) {
+ if (lastCommitBranch === '' || this.availableBranches.includes(lastCommitBranch)) {
+ return;
+ }
+ this.availableBranches.unshift(lastCommitBranch);
+ },
},
},
computed: {
+ branches() {
+ return this.searchTerm.length > 0 ? this.filteredBranches : this.availableBranches;
+ },
isBranchesLoading() {
- return this.$apollo.queries.availableBranches.loading;
+ return this.$apollo.queries.availableBranches.loading || this.isSearchingBranches;
},
showBranchSwitcher() {
- return this.branches.length > 0 || this.page.searchTerm.length > 0;
+ return this.branches.length > 0 || this.searchTerm.length > 0;
},
- searchPattern() {
- if (this.page.searchTerm === '') {
- return '*';
+ },
+ methods: {
+ availableBranchesQueryVars(varsOverride = {}) {
+ if (this.searchTerm.length > 0) {
+ return {
+ limit: this.totalBranches,
+ offset: 0,
+ projectFullPath: this.projectFullPath,
+ searchPattern: `*${this.searchTerm}*`,
+ ...varsOverride,
+ };
}
- return `*${this.page.searchTerm}*`;
+ return {
+ limit: this.paginationLimit,
+ offset: this.pageCounter * this.paginationLimit,
+ projectFullPath: this.projectFullPath,
+ searchPattern: '*',
+ ...varsOverride,
+ };
},
- },
- methods: {
// if there is no searchPattern, paginate by {paginationLimit} branches
fetchNextBranches() {
if (
this.isBranchesLoading ||
- this.page.searchTerm.length > 0 ||
- this.branches.length === this.totalBranches
+ this.searchTerm.length > 0 ||
+ this.branches.length >= this.totalBranches
) {
return;
}
- this.page = {
- ...this.page,
- limit: this.paginationLimit,
- offset: this.page.offset + this.paginationLimit,
- };
+ this.$apollo.queries.availableBranches
+ .fetchMore({
+ variables: this.availableBranchesQueryVars(),
+ updateQuery(previousResult, { fetchMoreResult }) {
+ const previousBranches = previousResult.project.repository.branchNames;
+ const newBranches = fetchMoreResult.project.repository.branchNames;
+
+ return produce(fetchMoreResult, (draftData) => {
+ draftData.project.repository.branchNames = previousBranches.concat(newBranches);
+ });
+ },
+ })
+ .catch(this.showFetchError);
},
async selectBranch(newBranch) {
if (newBranch === this.currentBranch) {
return;
}
- await this.$apollo.getClient().writeQuery({
- query: getCurrentBranch,
- data: { currentBranch: newBranch },
- });
-
+ this.updateCurrentBranch(newBranch);
const updatedPath = setUrlParams({ branch_name: newBranch });
historyPushState(updatedPath);
this.$emit('refetchContent');
},
- setSearchTerm(newSearchTerm) {
- this.branches = [];
- this.page = {
- limit: newSearchTerm.trim() === '' ? this.paginationLimit : this.totalBranches,
- offset: 0,
- searchTerm: newSearchTerm.trim(),
- };
+ async setSearchTerm(newSearchTerm) {
+ this.pageCounter = 0;
+ this.searchTerm = newSearchTerm.trim();
+
+ if (this.searchTerm === '') {
+ this.pageLimit = this.paginationLimit;
+ return;
+ }
+
+ this.isSearchingBranches = true;
+ const fetchResults = await this.$apollo
+ .query({
+ query: getAvailableBranchesQuery,
+ fetchPolicy: fetchPolicies.NETWORK_ONLY,
+ variables: this.availableBranchesQueryVars(),
+ })
+ .catch(this.showFetchError);
+
+ this.isSearchingBranches = false;
+ this.filteredBranches = fetchResults?.data?.project?.repository?.branchNames || [];
+ },
+ showFetchError() {
+ this.$emit('showError', {
+ type: DEFAULT_FAILURE,
+ reasons: [this.$options.i18n.fetchError],
+ });
+ },
+ updateCurrentBranch(currentBranch) {
+ this.$apollo.mutate({
+ mutation: updateCurrentBranchMutation,
+ variables: { currentBranch },
+ });
},
},
};
@@ -146,7 +200,8 @@ export default {
<template>
<gl-dropdown
v-if="showBranchSwitcher"
- class="gl-ml-2"
+ v-gl-tooltip.hover
+ :title="$options.i18n.dropdownHeader"
:header-text="$options.i18n.dropdownHeader"
:text="currentBranch"
icon="branch"
@@ -158,7 +213,6 @@ export default {
<gl-infinite-scroll
:fetched-items="branches.length"
- :total-items="totalBranches"
:max-list-height="250"
@bottomReached="fetchNextBranches"
>