diff options
Diffstat (limited to 'app/assets/javascripts/import_projects/store')
6 files changed, 0 insertions, 430 deletions
diff --git a/app/assets/javascripts/import_projects/store/actions.js b/app/assets/javascripts/import_projects/store/actions.js deleted file mode 100644 index 7b7afd13c55..00000000000 --- a/app/assets/javascripts/import_projects/store/actions.js +++ /dev/null @@ -1,201 +0,0 @@ -import Visibility from 'visibilityjs'; -import * as types from './mutation_types'; -import { isProjectImportable } from '../utils'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; -import Poll from '~/lib/utils/poll'; -import { visitUrl, objectToQuery } from '~/lib/utils/url_utility'; -import { deprecatedCreateFlash as createFlash } from '~/flash'; -import { s__, sprintf } from '~/locale'; -import axios from '~/lib/utils/axios_utils'; -import httpStatusCodes from '~/lib/utils/http_status'; -import { capitalizeFirstCharacter } from '~/lib/utils/text_utility'; - -let eTagPoll; - -const hasRedirectInError = e => e?.response?.data?.error?.redirect; -const redirectToUrlInError = e => visitUrl(e.response.data.error.redirect); -const tooManyRequests = e => e.response.status === httpStatusCodes.TOO_MANY_REQUESTS; -const pathWithParams = ({ path, ...params }) => { - const filteredParams = Object.fromEntries( - Object.entries(params).filter(([, value]) => value !== ''), - ); - const queryString = objectToQuery(filteredParams); - return queryString ? `${path}?${queryString}` : path; -}; - -const isRequired = () => { - // eslint-disable-next-line @gitlab/require-i18n-strings - throw new Error('param is required'); -}; - -const clearJobsEtagPoll = () => { - eTagPoll = null; -}; - -const stopJobsPolling = () => { - if (eTagPoll) eTagPoll.stop(); -}; - -const restartJobsPolling = () => { - if (eTagPoll) eTagPoll.restart(); -}; - -const setImportTarget = ({ commit }, { repoId, importTarget }) => - commit(types.SET_IMPORT_TARGET, { repoId, importTarget }); - -const importAll = ({ state, dispatch }) => { - return Promise.all( - state.repositories - .filter(isProjectImportable) - .map(r => dispatch('fetchImport', r.importSource.id)), - ); -}; - -const fetchReposFactory = ({ reposPath = isRequired() }) => ({ state, commit }) => { - const nextPage = state.pageInfo.page + 1; - commit(types.SET_PAGE, nextPage); - commit(types.REQUEST_REPOS); - - const { provider, filter } = state; - - return axios - .get( - pathWithParams({ - path: reposPath, - filter: filter ?? '', - page: nextPage === 1 ? '' : nextPage.toString(), - }), - ) - .then(({ data }) => { - commit(types.RECEIVE_REPOS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })); - }) - .catch(e => { - commit(types.SET_PAGE, nextPage - 1); - - if (hasRedirectInError(e)) { - redirectToUrlInError(e); - } else if (tooManyRequests(e)) { - createFlash( - sprintf(s__('ImportProjects|%{provider} rate limit exceeded. Try again later'), { - provider: capitalizeFirstCharacter(provider), - }), - ); - - commit(types.RECEIVE_REPOS_ERROR); - } else { - createFlash( - sprintf(s__('ImportProjects|Requesting your %{provider} repositories failed'), { - provider, - }), - ); - - commit(types.RECEIVE_REPOS_ERROR); - } - }); -}; - -const fetchImportFactory = (importPath = isRequired()) => ({ state, commit, getters }, repoId) => { - const { ciCdOnly } = state; - const importTarget = getters.getImportTarget(repoId); - - commit(types.REQUEST_IMPORT, { repoId, importTarget }); - - const { newName, targetNamespace } = importTarget; - return axios - .post(importPath, { - repo_id: repoId, - ci_cd_only: ciCdOnly, - new_name: newName, - target_namespace: targetNamespace, - }) - .then(({ data }) => { - commit(types.RECEIVE_IMPORT_SUCCESS, { - importedProject: convertObjectPropsToCamelCase(data, { deep: true }), - repoId, - }); - }) - .catch(e => { - const serverErrorMessage = e?.response?.data?.errors; - const flashMessage = serverErrorMessage - ? sprintf( - s__('ImportProjects|Importing the project failed: %{reason}'), - { - reason: serverErrorMessage, - }, - false, - ) - : s__('ImportProjects|Importing the project failed'); - - createFlash(flashMessage); - - commit(types.RECEIVE_IMPORT_ERROR, repoId); - }); -}; - -export const fetchJobsFactory = (jobsPath = isRequired()) => ({ state, commit, dispatch }) => { - if (eTagPoll) { - stopJobsPolling(); - clearJobsEtagPoll(); - } - - eTagPoll = new Poll({ - resource: { - fetchJobs: () => axios.get(pathWithParams({ path: jobsPath, filter: state.filter })), - }, - method: 'fetchJobs', - successCallback: ({ data }) => - commit(types.RECEIVE_JOBS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })), - errorCallback: e => { - if (hasRedirectInError(e)) { - redirectToUrlInError(e); - } else { - createFlash(s__('ImportProjects|Update of imported projects with realtime changes failed')); - } - }, - }); - - if (!Visibility.hidden()) { - eTagPoll.makeRequest(); - } - - Visibility.change(() => { - if (!Visibility.hidden()) { - dispatch('restartJobsPolling'); - } else { - dispatch('stopJobsPolling'); - } - }); -}; - -const fetchNamespacesFactory = (namespacesPath = isRequired()) => ({ commit }) => { - commit(types.REQUEST_NAMESPACES); - axios - .get(namespacesPath) - .then(({ data }) => - commit(types.RECEIVE_NAMESPACES_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })), - ) - .catch(() => { - createFlash(s__('ImportProjects|Requesting namespaces failed')); - - commit(types.RECEIVE_NAMESPACES_ERROR); - }); -}; - -const setFilter = ({ commit, dispatch }, filter) => { - commit(types.SET_FILTER, filter); - - return dispatch('fetchRepos'); -}; - -export default ({ endpoints = isRequired() }) => ({ - clearJobsEtagPoll, - stopJobsPolling, - restartJobsPolling, - setFilter, - setImportTarget, - importAll, - fetchRepos: fetchReposFactory({ reposPath: endpoints.reposPath }), - fetchImport: fetchImportFactory(endpoints.importPath), - fetchJobs: fetchJobsFactory(endpoints.jobsPath), - fetchNamespaces: fetchNamespacesFactory(endpoints.namespacesPath), -}); diff --git a/app/assets/javascripts/import_projects/store/getters.js b/app/assets/javascripts/import_projects/store/getters.js deleted file mode 100644 index b76c52beea2..00000000000 --- a/app/assets/javascripts/import_projects/store/getters.js +++ /dev/null @@ -1,30 +0,0 @@ -import { STATUSES } from '../constants'; -import { isProjectImportable, isIncompatible } from '../utils'; - -export const isLoading = state => state.isLoadingRepos || state.isLoadingNamespaces; - -export const isImportingAnyRepo = state => - state.repositories.some(repo => - [STATUSES.SCHEDULING, STATUSES.SCHEDULED, STATUSES.STARTED].includes( - repo.importedProject?.importStatus, - ), - ); - -export const hasIncompatibleRepos = state => state.repositories.some(isIncompatible); - -export const hasImportableRepos = state => state.repositories.some(isProjectImportable); - -export const importAllCount = state => state.repositories.filter(isProjectImportable).length; - -export const getImportTarget = state => repoId => { - if (state.customImportTargets[repoId]) { - return state.customImportTargets[repoId]; - } - - const repo = state.repositories.find(r => r.importSource.id === repoId); - - return { - newName: repo.importSource.sanitizedName, - targetNamespace: state.defaultTargetNamespace, - }; -}; diff --git a/app/assets/javascripts/import_projects/store/index.js b/app/assets/javascripts/import_projects/store/index.js deleted file mode 100644 index 7ba12f81eb9..00000000000 --- a/app/assets/javascripts/import_projects/store/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import Vue from 'vue'; -import Vuex from 'vuex'; -import state from './state'; -import actionsFactory from './actions'; -import * as getters from './getters'; -import mutations from './mutations'; - -Vue.use(Vuex); - -export default ({ initialState, endpoints, hasPagination }) => - new Vuex.Store({ - state: { ...state(), ...initialState }, - actions: actionsFactory({ endpoints, hasPagination }), - mutations, - getters, - }); diff --git a/app/assets/javascripts/import_projects/store/mutation_types.js b/app/assets/javascripts/import_projects/store/mutation_types.js deleted file mode 100644 index 6adf5e59cff..00000000000 --- a/app/assets/javascripts/import_projects/store/mutation_types.js +++ /dev/null @@ -1,21 +0,0 @@ -export const REQUEST_REPOS = 'REQUEST_REPOS'; -export const RECEIVE_REPOS_SUCCESS = 'RECEIVE_REPOS_SUCCESS'; -export const RECEIVE_REPOS_ERROR = 'RECEIVE_REPOS_ERROR'; - -export const REQUEST_NAMESPACES = 'REQUEST_NAMESPACES'; -export const RECEIVE_NAMESPACES_SUCCESS = 'RECEIVE_NAMESPACES_SUCCESS'; -export const RECEIVE_NAMESPACES_ERROR = 'RECEIVE_NAMESPACES_ERROR'; - -export const REQUEST_IMPORT = 'REQUEST_IMPORT'; -export const RECEIVE_IMPORT_SUCCESS = 'RECEIVE_IMPORT_SUCCESS'; -export const RECEIVE_IMPORT_ERROR = 'RECEIVE_IMPORT_ERROR'; - -export const RECEIVE_JOBS_SUCCESS = 'RECEIVE_JOBS_SUCCESS'; - -export const SET_FILTER = 'SET_FILTER'; - -export const SET_IMPORT_TARGET = 'SET_IMPORT_TARGET'; - -export const SET_PAGE = 'SET_PAGE'; - -export const SET_PAGE_INFO = 'SET_PAGE_INFO'; diff --git a/app/assets/javascripts/import_projects/store/mutations.js b/app/assets/javascripts/import_projects/store/mutations.js deleted file mode 100644 index 6999253d4b2..00000000000 --- a/app/assets/javascripts/import_projects/store/mutations.js +++ /dev/null @@ -1,149 +0,0 @@ -import Vue from 'vue'; -import * as types from './mutation_types'; -import { STATUSES } from '../constants'; - -const makeNewImportedProject = importedProject => ({ - importSource: { - id: importedProject.id, - fullName: importedProject.importSource, - sanitizedName: importedProject.name, - providerLink: importedProject.providerLink, - }, - importedProject, -}); - -const makeNewIncompatibleProject = project => ({ - importSource: { ...project, incompatible: true }, - importedProject: null, -}); - -const processLegacyEntries = ({ newRepositories, existingRepositories, factory }) => { - const newEntries = []; - newRepositories.forEach(project => { - const existingProject = existingRepositories.find(p => p.importSource.id === project.id); - const importedProjectShape = factory(project); - - if (existingProject) { - Object.assign(existingProject, importedProjectShape); - } else { - newEntries.push(importedProjectShape); - } - }); - return newEntries; -}; - -export default { - [types.SET_FILTER](state, filter) { - state.filter = filter; - state.repositories = []; - state.pageInfo.page = 0; - }, - - [types.REQUEST_REPOS](state) { - state.isLoadingRepos = true; - }, - - [types.RECEIVE_REPOS_SUCCESS](state, repositories) { - state.isLoadingRepos = false; - - if (!Array.isArray(repositories)) { - // Legacy code path, will be removed when all importers will be switched to new pagination format - // https://gitlab.com/gitlab-org/gitlab/-/issues/27370#note_379034091 - - const newImportedProjects = processLegacyEntries({ - newRepositories: repositories.importedProjects, - existingRepositories: state.repositories, - factory: makeNewImportedProject, - }); - - const incompatibleRepos = repositories.incompatibleRepos ?? []; - const newIncompatibleProjects = processLegacyEntries({ - newRepositories: incompatibleRepos, - existingRepositories: state.repositories, - factory: makeNewIncompatibleProject, - }); - - state.repositories = [ - ...newImportedProjects, - ...state.repositories, - ...repositories.providerRepos.map(project => ({ - importSource: project, - importedProject: null, - })), - ...newIncompatibleProjects, - ]; - - if (incompatibleRepos.length === 0 && repositories.providerRepos.length === 0) { - state.pageInfo.page -= 1; - } - - return; - } - - state.repositories = [...state.repositories, ...repositories]; - if (repositories.length === 0) { - state.pageInfo.page -= 1; - } - }, - - [types.RECEIVE_REPOS_ERROR](state) { - state.isLoadingRepos = false; - }, - - [types.REQUEST_IMPORT](state, { repoId, importTarget }) { - const existingRepo = state.repositories.find(r => r.importSource.id === repoId); - existingRepo.importedProject = { - importStatus: STATUSES.SCHEDULING, - fullPath: `/${importTarget.targetNamespace}/${importTarget.newName}`, - }; - }, - - [types.RECEIVE_IMPORT_SUCCESS](state, { importedProject, repoId }) { - const existingRepo = state.repositories.find(r => r.importSource.id === repoId); - existingRepo.importedProject = importedProject; - }, - - [types.RECEIVE_IMPORT_ERROR](state, repoId) { - const existingRepo = state.repositories.find(r => r.importSource.id === repoId); - existingRepo.importedProject = null; - }, - - [types.RECEIVE_JOBS_SUCCESS](state, updatedProjects) { - updatedProjects.forEach(updatedProject => { - const repo = state.repositories.find(p => p.importedProject?.id === updatedProject.id); - if (repo?.importedProject) { - repo.importedProject.importStatus = updatedProject.importStatus; - } - }); - }, - - [types.REQUEST_NAMESPACES](state) { - state.isLoadingNamespaces = true; - }, - - [types.RECEIVE_NAMESPACES_SUCCESS](state, namespaces) { - state.isLoadingNamespaces = false; - state.namespaces = namespaces; - }, - - [types.RECEIVE_NAMESPACES_ERROR](state) { - state.isLoadingNamespaces = false; - }, - - [types.SET_IMPORT_TARGET](state, { repoId, importTarget }) { - const existingRepo = state.repositories.find(r => r.importSource.id === repoId); - - if ( - importTarget.targetNamespace === state.defaultTargetNamespace && - importTarget.newName === existingRepo.importSource.sanitizedName - ) { - Vue.delete(state.customImportTargets, repoId); - } else { - Vue.set(state.customImportTargets, repoId, importTarget); - } - }, - - [types.SET_PAGE](state, page) { - state.pageInfo.page = page; - }, -}; diff --git a/app/assets/javascripts/import_projects/store/state.js b/app/assets/javascripts/import_projects/store/state.js deleted file mode 100644 index ecd93561d52..00000000000 --- a/app/assets/javascripts/import_projects/store/state.js +++ /dev/null @@ -1,13 +0,0 @@ -export default () => ({ - provider: '', - repositories: [], - namespaces: [], - customImportTargets: {}, - isLoadingRepos: false, - isLoadingNamespaces: false, - ciCdOnly: false, - filter: '', - pageInfo: { - page: 0, - }, -}); |