From aefc4fd5c91705d7375eda05363547e63b502a09 Mon Sep 17 00:00:00 2001 From: Justin Ho Tuan Duong Date: Wed, 23 Aug 2023 15:51:41 +0700 Subject: [PATCH 1/7] Add infinite scroll to source branch dropdown - Allow loading more branch names by using offset pagination with GraphQL. This fixes an issue with not being able to display all branches. - Add specs and refactor mocking of Apollo to follow newest guidelines. Changelog: fixed --- .../components/source_branch_dropdown.vue | 47 +++++-- .../components/source_branch_dropdown_spec.js | 118 +++++++++++------- .../jira_connect/branches/mock_data.js | 15 +++ 3 files changed, 126 insertions(+), 54 deletions(-) diff --git a/app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue b/app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue index e443df35ad2360..53973a8928b3a3 100644 --- a/app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue +++ b/app/assets/javascripts/jira_connect/branches/components/source_branch_dropdown.vue @@ -26,7 +26,9 @@ export default { return { initialSourceBranchNamesLoading: false, sourceBranchNamesLoading: false, + sourceBranchNamesLoadingMore: false, sourceBranchNames: [], + sourceBranchNamesOffset: 0, }; }, computed: { @@ -59,45 +61,64 @@ export default { onSearch: debounce(function debouncedSearch(branchSearchQuery) { this.onSourceBranchSearchQuery(branchSearchQuery); }, 250), - onSourceBranchSearchQuery(branchSearchQuery) { + async onSourceBranchSearchQuery(branchSearchQuery) { this.branchSearchQuery = branchSearchQuery; - this.fetchSourceBranchNames({ + this.sourceBranchNamesOffset = 0; + this.sourceBranchNamesLoading = true; + + await this.fetchSourceBranchNames({ + projectPath: this.selectedProject.fullPath, + searchPattern: this.branchSearchQuery, + }); + this.sourceBranchNamesLoading = false; + }, + async onBottomReached() { + this.sourceBranchNamesOffset = this.sourceBranchNames.length; + this.sourceBranchNamesLoadingMore = true; + + await this.fetchSourceBranchNames({ projectPath: this.selectedProject.fullPath, searchPattern: this.branchSearchQuery, + append: true, }); + + this.sourceBranchNamesLoadingMore = false; }, onError({ message } = {}) { this.$emit('error', { message }); }, - async fetchSourceBranchNames({ projectPath, searchPattern } = {}) { - this.sourceBranchNamesLoading = true; + async fetchSourceBranchNames({ projectPath, searchPattern, append = false } = {}) { try { const { data } = await this.$apollo.query({ query: getProjectQuery, variables: { projectPath, branchNamesLimit: this.$options.BRANCHES_PER_PAGE, - branchNamesOffset: 0, + branchNamesOffset: this.sourceBranchNamesOffset, branchNamesSearchPattern: searchPattern ? `*${searchPattern}*` : '*', }, }); const { branchNames, rootRef } = data?.project.repository || {}; - this.sourceBranchNames = + const branchNameItems = branchNames.map((value) => { return { text: value, value }; }) || []; - // Use root ref as the default selection - if (rootRef && !this.hasSelectedSourceBranch) { - this.onSourceBranchSelect(rootRef); + if (append) { + this.sourceBranchNames.push(...branchNameItems); + } else { + this.sourceBranchNames = branchNameItems; + + // Use root ref as the default selection + if (rootRef && !this.hasSelectedSourceBranch) { + this.onSourceBranchSelect(rootRef); + } } } catch (err) { this.onError({ message: __('Something went wrong while fetching source branches.'), }); - } finally { - this.sourceBranchNamesLoading = false; } }, }, @@ -107,6 +128,7 @@ export default {