diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-05 21:08:56 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-08-05 21:08:56 +0300 |
commit | 092e41f5660a356a6cebc26cd0274b531d8c70c6 (patch) | |
tree | e696f9ad230bc5d5a7222fb690e3699a1a8abe78 /app/assets/javascripts/projects | |
parent | 8ec882085e734458ffe0fff8e2e4b72bc3871419 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/projects')
3 files changed, 115 insertions, 25 deletions
diff --git a/app/assets/javascripts/projects/settings/components/transfer_project_form.vue b/app/assets/javascripts/projects/settings/components/transfer_project_form.vue index 5e1126fae09..c13753da00b 100644 --- a/app/assets/javascripts/projects/settings/components/transfer_project_form.vue +++ b/app/assets/javascripts/projects/settings/components/transfer_project_form.vue @@ -1,7 +1,13 @@ <script> import { GlFormGroup } from '@gitlab/ui'; -import NamespaceSelect from '~/vue_shared/components/namespace_select/namespace_select.vue'; +import produce from 'immer'; import ConfirmDanger from '~/vue_shared/components/confirm_danger/confirm_danger.vue'; +import NamespaceSelect from '~/vue_shared/components/namespace_select/namespace_select.vue'; +import { getIdFromGraphQLId } from '~/graphql_shared/utils'; +import { DEBOUNCE_DELAY } from '~/vue_shared/components/filtered_search_bar/constants'; +import searchNamespacesWhereUserCanTransferProjects from '../graphql/queries/search_namespaces_where_user_can_transfer_projects.query.graphql'; + +const GROUPS_PER_PAGE = 25; export default { name: 'TransferProjectForm', @@ -11,14 +17,6 @@ export default { ConfirmDanger, }, props: { - groupNamespaces: { - type: Array, - required: true, - }, - userNamespaces: { - type: Array, - required: true, - }, confirmationPhrase: { type: String, required: true, @@ -28,19 +26,88 @@ export default { required: true, }, }, + apollo: { + currentUser: { + query: searchNamespacesWhereUserCanTransferProjects, + debounce: DEBOUNCE_DELAY, + variables() { + return { + search: this.searchTerm, + after: null, + first: GROUPS_PER_PAGE, + }; + }, + result() { + this.isLoadingMoreGroups = false; + this.isSearchLoading = false; + }, + }, + }, data() { - return { selectedNamespace: null }; + return { + currentUser: {}, + selectedNamespace: null, + isLoadingMoreGroups: false, + isSearchLoading: false, + searchTerm: '', + }; }, computed: { hasSelectedNamespace() { return Boolean(this.selectedNamespace?.id); }, + groupNamespaces() { + return this.currentUser.groups?.nodes?.map(this.formatNamespace) || []; + }, + userNamespaces() { + const { namespace } = this.currentUser; + + return namespace ? [this.formatNamespace(namespace)] : []; + }, + hasNextPageOfGroups() { + return this.currentUser.groups?.pageInfo?.hasNextPage || false; + }, }, methods: { handleSelect(selectedNamespace) { this.selectedNamespace = selectedNamespace; this.$emit('selectNamespace', selectedNamespace.id); }, + handleLoadMoreGroups() { + this.isLoadingMoreGroups = true; + + this.$apollo.queries.currentUser.fetchMore({ + variables: { + after: this.currentUser.groups.pageInfo.endCursor, + first: GROUPS_PER_PAGE, + }, + updateQuery( + previousResult, + { + fetchMoreResult: { + currentUser: { groups: newGroups }, + }, + }, + ) { + const previousGroups = previousResult.currentUser.groups; + + return produce(previousResult, (draftData) => { + draftData.currentUser.groups.nodes = [...previousGroups.nodes, ...newGroups.nodes]; + draftData.currentUser.groups.pageInfo = newGroups.pageInfo; + }); + }, + }); + }, + handleSearch(searchTerm) { + this.isSearchLoading = true; + this.searchTerm = searchTerm; + }, + formatNamespace({ id, fullName }) { + return { + id: getIdFromGraphQLId(id), + humanName: fullName, + }; + }, }, }; </script> @@ -53,7 +120,13 @@ export default { :group-namespaces="groupNamespaces" :user-namespaces="userNamespaces" :selected-namespace="selectedNamespace" + :has-next-page-of-groups="hasNextPageOfGroups" + :is-loading-more-groups="isLoadingMoreGroups" + :is-search-loading="isSearchLoading" + :should-filter-namespaces="false" @select="handleSelect" + @load-more-groups="handleLoadMoreGroups" + @search="handleSearch" /> </gl-form-group> <confirm-danger diff --git a/app/assets/javascripts/projects/settings/graphql/queries/search_namespaces_where_user_can_transfer_projects.query.graphql b/app/assets/javascripts/projects/settings/graphql/queries/search_namespaces_where_user_can_transfer_projects.query.graphql new file mode 100644 index 00000000000..4e9d71d22c1 --- /dev/null +++ b/app/assets/javascripts/projects/settings/graphql/queries/search_namespaces_where_user_can_transfer_projects.query.graphql @@ -0,0 +1,25 @@ +#import "~/graphql_shared/fragments/page_info.fragment.graphql" + +query searchNamespacesWhereUserCanTransferProjects( + $search: String = "" + $after: String = "" + $first: Int = null +) { + currentUser { + id + groups(permissionScope: TRANSFER_PROJECTS, search: $search, after: $after, first: $first) { + nodes { + id + fullName + } + pageInfo { + __typename + ...PageInfo + } + } + namespace { + id + fullName + } + } +} diff --git a/app/assets/javascripts/projects/settings/init_transfer_project_form.js b/app/assets/javascripts/projects/settings/init_transfer_project_form.js index a5f720bffaa..bc1aff640d2 100644 --- a/app/assets/javascripts/projects/settings/init_transfer_project_form.js +++ b/app/assets/javascripts/projects/settings/init_transfer_project_form.js @@ -1,36 +1,29 @@ import Vue from 'vue'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import VueApollo from 'vue-apollo'; +import createDefaultClient from '~/lib/graphql'; import TransferProjectForm from './components/transfer_project_form.vue'; -const prepareNamespaces = (rawNamespaces = '') => { - if (!rawNamespaces) { - return { groupNamespaces: [], userNamespaces: [] }; - } - - const data = JSON.parse(rawNamespaces); - return { - groupNamespaces: data?.group?.map(convertObjectPropsToCamelCase) || [], - userNamespaces: data?.user?.map(convertObjectPropsToCamelCase) || [], - }; -}; - export default () => { const el = document.querySelector('.js-transfer-project-form'); if (!el) { return false; } + Vue.use(VueApollo); + const { targetFormId = null, targetHiddenInputId = null, buttonText: confirmButtonText = '', phrase: confirmationPhrase = '', confirmDangerMessage = '', - namespaces = '', } = el.dataset; return new Vue({ el, + apolloProvider: new VueApollo({ + defaultClient: createDefaultClient(), + }), provide: { confirmDangerMessage, }, @@ -39,7 +32,6 @@ export default () => { props: { confirmButtonText, confirmationPhrase, - ...prepareNamespaces(namespaces), }, on: { selectNamespace: (id) => { |