Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/jira_connect')
-rw-r--r--app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue76
1 files changed, 61 insertions, 15 deletions
diff --git a/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue b/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue
index 52a12cc7771..e3fa0ce8073 100644
--- a/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue
+++ b/app/assets/javascripts/jira_connect/branches/components/project_dropdown.vue
@@ -1,20 +1,20 @@
<script>
import { GlAvatarLabeled, GlCollapsibleListbox } from '@gitlab/ui';
import { debounce } from 'lodash';
+import produce from 'immer';
import { __ } from '~/locale';
import { AVATAR_SHAPE_OPTION_RECT } from '~/vue_shared/constants';
import { PROJECTS_PER_PAGE } from '../constants';
import getProjectsQuery from '../graphql/queries/get_projects.query.graphql';
export default {
- PROJECTS_PER_PAGE,
- projectQueryPageInfo: {
- endCursor: '',
- },
+ name: 'ProjectDropdown',
+
components: {
GlAvatarLabeled,
GlCollapsibleListbox,
},
+
props: {
selectedProject: {
type: Object,
@@ -22,27 +22,29 @@ export default {
default: null,
},
},
+
data() {
return {
initialProjectsLoading: true,
+ isLoadingMore: false,
projectSearchQuery: '',
selectedProjectId: this.selectedProject?.id,
};
},
+
apollo: {
projects: {
query: getProjectsQuery,
variables() {
return {
- search: this.projectSearchQuery,
- first: this.$options.PROJECTS_PER_PAGE,
- after: this.$options.projectQueryPageInfo.endCursor,
- searchNamespaces: true,
- sort: 'similarity',
+ ...this.queryVariables,
};
},
update(data) {
- return data?.projects?.nodes.filter((project) => !project.repository?.empty) ?? [];
+ return {
+ nodes: data?.projects?.nodes.filter((project) => !project.repository?.empty) ?? [],
+ pageInfo: data?.projects?.pageInfo,
+ };
},
result() {
this.initialProjectsLoading = false;
@@ -52,24 +54,37 @@ export default {
},
},
},
+
computed: {
- projectsLoading() {
- return Boolean(this.$apollo.queries.projects.loading);
+ queryVariables() {
+ return {
+ search: this.projectSearchQuery,
+ first: PROJECTS_PER_PAGE,
+ searchNamespaces: true,
+ sort: 'similarity',
+ };
+ },
+ isLoading() {
+ return this.$apollo.queries.projects.loading && !this.isLoadingMore;
},
projectDropdownText() {
return this.selectedProject?.nameWithNamespace || this.$options.i18n.selectProjectText;
},
projectList() {
- return (this.projects || []).map((project) => ({
+ return (this.projects?.nodes || []).map((project) => ({
...project,
text: project.nameWithNamespace,
value: String(project.id),
}));
},
+ hasNextPage() {
+ return this.projects?.pageInfo?.hasNextPage;
+ },
},
+
methods: {
findProjectById(id) {
- return this.projects.find((project) => id === project.id);
+ return this.projects?.nodes?.find((project) => id === project.id);
},
onProjectSelect(projectId) {
this.$emit('change', this.findProjectById(projectId));
@@ -77,13 +92,41 @@ export default {
onError({ message } = {}) {
this.$emit('error', { message });
},
+ async onBottomReached() {
+ if (!this.hasNextPage) return;
+
+ this.isLoadingMore = true;
+
+ try {
+ await this.$apollo.queries.projects.fetchMore({
+ variables: {
+ ...this.queryVariables,
+ after: this.projects.pageInfo?.endCursor,
+ },
+ updateQuery: (previousResult, { fetchMoreResult }) => {
+ return produce(fetchMoreResult, (draftData) => {
+ draftData.projects.nodes = [
+ ...previousResult.projects.nodes,
+ ...draftData.projects.nodes,
+ ];
+ });
+ },
+ });
+ } catch (error) {
+ this.onError({ message: __('Failed to load projects') });
+ } finally {
+ this.isLoadingMore = false;
+ }
+ },
onSearch: debounce(function debouncedSearch(query) {
this.projectSearchQuery = query;
}, 250),
},
+
i18n: {
selectProjectText: __('Select a project'),
},
+
AVATAR_SHAPE_OPTION_RECT,
};
</script>
@@ -97,8 +140,11 @@ export default {
:header-text="$options.i18n.selectProjectText"
:loading="initialProjectsLoading"
:searchable="true"
- :searching="projectsLoading"
+ :searching="isLoading"
fluid-width
+ infinite-scroll
+ :infinite-scroll-loading="isLoadingMore"
+ @bottom-reached="onBottomReached"
@search="onSearch"
@select="onProjectSelect"
>