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/boards/components/project_select.vue')
-rw-r--r--app/assets/javascripts/boards/components/project_select.vue119
1 files changed, 78 insertions, 41 deletions
diff --git a/app/assets/javascripts/boards/components/project_select.vue b/app/assets/javascripts/boards/components/project_select.vue
index 960c8e472b8..7bbc444701a 100644
--- a/app/assets/javascripts/boards/components/project_select.vue
+++ b/app/assets/javascripts/boards/components/project_select.vue
@@ -1,11 +1,8 @@
<script>
import { GlCollapsibleListbox } from '@gitlab/ui';
-import { mapActions, mapGetters, mapState } from 'vuex';
-import { debounce } from 'lodash';
import { s__ } from '~/locale';
-import { featureAccessLevel } from '~/pages/projects/shared/permissions/constants';
-import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
-import { ListType } from '../constants';
+import groupProjectsQuery from '../graphql/group_projects.query.graphql';
+import { setError } from '../graphql/cache_updates';
export default {
name: 'ProjectSelect',
@@ -14,6 +11,9 @@ export default {
dropdownText: s__(`BoardNewIssue|Select a project`),
searchPlaceholder: s__(`BoardNewIssue|Search projects`),
emptySearchResult: s__(`BoardNewIssue|No matching results`),
+ errorFetchingProjects: s__(
+ 'Boards|An error occurred while fetching group projects. Please try again.',
+ ),
},
defaultFetchOptions: {
with_issues_enabled: true,
@@ -24,70 +24,107 @@ export default {
components: {
GlCollapsibleListbox,
},
- inject: ['groupId'],
+ inject: ['groupId', 'fullPath'],
+ model: {
+ prop: 'selectedProject',
+ event: 'selectProject',
+ },
props: {
list: {
type: Object,
required: true,
},
+ selectedProject: {
+ type: Object,
+ required: true,
+ },
},
data() {
return {
initialLoading: true,
selectedProjectId: '',
- selectedProject: {},
searchTerm: '',
+ projects: {},
+ isLoadingMore: false,
};
},
+ apollo: {
+ projects: {
+ query: groupProjectsQuery,
+ variables() {
+ return {
+ fullPath: this.fullPath,
+ search: this.searchTerm,
+ };
+ },
+ update(data) {
+ return data.group.projects;
+ },
+ error(error) {
+ setError({
+ error,
+ message: this.$options.i18n.errorFetchingProjects,
+ });
+ },
+ result() {
+ this.initialLoading = false;
+ },
+ },
+ },
computed: {
- ...mapState(['groupProjectsFlags']),
- ...mapGetters(['activeGroupProjects']),
- projects() {
- return this.activeGroupProjects.map((project) => ({
- value: project.id,
- text: project.nameWithNamespace,
- }));
+ isLoading() {
+ return this.$apollo.queries.projects.loading && !this.isLoadingMore;
+ },
+ activeGroupProjects() {
+ return (
+ this.projects?.nodes?.map((project) => ({
+ value: project.id,
+ text: project.nameWithNamespace,
+ })) || []
+ );
},
selectedProjectName() {
return this.selectedProject.name || this.$options.i18n.dropdownText;
},
- fetchOptions() {
- const additionalAttrs = {};
- if (this.list.type && this.list.type !== ListType.backlog) {
- additionalAttrs.min_access_level = featureAccessLevel.EVERYONE;
- }
-
- return {
- ...this.$options.defaultFetchOptions,
- ...additionalAttrs,
- };
- },
isFetchResultEmpty() {
return this.activeGroupProjects.length === 0;
},
hasNextPage() {
- return this.groupProjectsFlags.pageInfo?.hasNextPage;
+ return this.projects.pageInfo?.hasNextPage;
},
},
watch: {
- searchTerm: debounce(function debouncedSearch() {
- this.fetchGroupProjects({ search: this.searchTerm });
- }, DEFAULT_DEBOUNCE_AND_THROTTLE_MS),
- },
- mounted() {
- this.fetchGroupProjects({});
- this.initialLoading = false;
+ endCursor() {
+ return this.projects.pageInfo?.endCursor;
+ },
},
methods: {
- ...mapActions(['fetchGroupProjects', 'setSelectedProject']),
selectProject(projectId) {
this.selectedProjectId = projectId;
- this.selectedProject = this.activeGroupProjects.find((project) => project.id === projectId);
- this.setSelectedProject(this.selectedProject);
+ this.$emit(
+ 'selectProject',
+ this.projects.nodes.find((project) => project.id === projectId),
+ );
},
- loadMoreProjects() {
+ async loadMoreProjects() {
if (!this.hasNextPage) return;
- this.fetchGroupProjects({ search: this.searchTerm, fetchNext: true });
+ this.isLoadingMore = true;
+ try {
+ await this.$apollo.queries.projects.fetchMore({
+ variables: {
+ fullPath: this.fullPath,
+ search: this.searchTerm,
+ after: this.endCursor,
+ },
+ });
+ } catch (error) {
+ setError({
+ error,
+ message: this.$options.i18n.errorFetchingProjects,
+ });
+ } finally {
+ this.isLoadingMore = false;
+ }
},
onSearch(query) {
this.searchTerm = query;
@@ -107,14 +144,14 @@ export default {
searchable
infinite-scroll
data-testid="project-select-dropdown"
- :items="projects"
+ :items="activeGroupProjects"
:toggle-text="selectedProjectName"
:header-text="$options.i18n.headerTitle"
:loading="initialLoading"
- :searching="groupProjectsFlags.isLoading"
+ :searching="isLoading"
:search-placeholder="$options.i18n.searchPlaceholder"
:no-results-text="$options.i18n.emptySearchResult"
- :infinite-scroll-loading="groupProjectsFlags.isLoadingMore"
+ :infinite-scroll-loading="isLoadingMore"
@select="selectProject"
@search="onSearch"
@bottom-reached="loadMoreProjects"