diff options
Diffstat (limited to 'app/assets/javascripts/import_projects/store/actions.js')
-rw-r--r-- | app/assets/javascripts/import_projects/store/actions.js | 142 |
1 files changed, 110 insertions, 32 deletions
diff --git a/app/assets/javascripts/import_projects/store/actions.js b/app/assets/javascripts/import_projects/store/actions.js index 8d8d33f5972..af410f411d8 100644 --- a/app/assets/javascripts/import_projects/store/actions.js +++ b/app/assets/javascripts/import_projects/store/actions.js @@ -1,41 +1,86 @@ import Visibility from 'visibilityjs'; import * as types from './mutation_types'; -import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import { isProjectImportable } from '../utils'; +import { + convertObjectPropsToCamelCase, + normalizeHeaders, + parseIntPagination, +} from '~/lib/utils/common_utils'; import Poll from '~/lib/utils/poll'; -import { visitUrl } from '~/lib/utils/url_utility'; -import createFlash from '~/flash'; +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 { jobsPathWithFilter, reposPathWithFilter } from './getters'; let eTagPoll; const hasRedirectInError = e => e?.response?.data?.error?.redirect; const redirectToUrlInError = e => visitUrl(e.response.data.error.redirect); +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'); +}; -export const clearJobsEtagPoll = () => { +const clearJobsEtagPoll = () => { eTagPoll = null; }; -export const stopJobsPolling = () => { + +const stopJobsPolling = () => { if (eTagPoll) eTagPoll.stop(); }; -export const restartJobsPolling = () => { + +const restartJobsPolling = () => { if (eTagPoll) eTagPoll.restart(); }; -export const setFilter = ({ commit }, filter) => commit(types.SET_FILTER, filter); +const setFilter = ({ commit }, filter) => commit(types.SET_FILTER, filter); + +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)), + ); +}; -export const fetchRepos = ({ state, dispatch, commit }) => { +const fetchReposFactory = ({ reposPath = isRequired(), hasPagination }) => ({ + state, + dispatch, + commit, +}) => { dispatch('stopJobsPolling'); commit(types.REQUEST_REPOS); - const { provider } = state; + const { provider, filter } = state; return axios - .get(reposPathWithFilter(state)) - .then(({ data }) => - commit(types.RECEIVE_REPOS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })), + .get( + pathWithParams({ + path: reposPath, + filter, + page: hasPagination ? state.pageInfo.page.toString() : '', + }), ) + .then(({ data, headers }) => { + const normalizedHeaders = normalizeHeaders(headers); + + if ('X-PAGE' in normalizedHeaders) { + commit(types.SET_PAGE_INFO, parseIntPagination(normalizedHeaders)); + } + + commit(types.RECEIVE_REPOS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })); + }) .then(() => dispatch('fetchJobs')) .catch(e => { if (hasRedirectInError(e)) { @@ -52,24 +97,26 @@ export const fetchRepos = ({ state, dispatch, commit }) => { }); }; -export const fetchImport = ({ state, commit }, { newName, targetNamespace, repo }) => { - if (!state.reposBeingImported.includes(repo.id)) { - commit(types.REQUEST_IMPORT, repo.id); - } +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(state.importPath, { - ci_cd_only: state.ciCdOnly, + .post(importPath, { + repo_id: repoId, + ci_cd_only: ciCdOnly, new_name: newName, - repo_id: repo.id, target_namespace: targetNamespace, }) - .then(({ data }) => + .then(({ data }) => { commit(types.RECEIVE_IMPORT_SUCCESS, { importedProject: convertObjectPropsToCamelCase(data, { deep: true }), - repoId: repo.id, - }), - ) + repoId, + }); + }) .catch(e => { const serverErrorMessage = e?.response?.data?.errors; const flashMessage = serverErrorMessage @@ -84,14 +131,11 @@ export const fetchImport = ({ state, commit }, { newName, targetNamespace, repo createFlash(flashMessage); - commit(types.RECEIVE_IMPORT_ERROR, repo.id); + commit(types.RECEIVE_IMPORT_ERROR, repoId); }); }; -export const receiveJobsSuccess = ({ commit }, updatedProjects) => - commit(types.RECEIVE_JOBS_SUCCESS, updatedProjects); - -export const fetchJobs = ({ state, commit, dispatch }) => { +export const fetchJobsFactory = (jobsPath = isRequired()) => ({ state, commit, dispatch }) => { const { filter } = state; if (eTagPoll) { @@ -101,7 +145,7 @@ export const fetchJobs = ({ state, commit, dispatch }) => { eTagPoll = new Poll({ resource: { - fetchJobs: () => axios.get(jobsPathWithFilter(state)), + fetchJobs: () => axios.get(pathWithParams({ path: jobsPath, filter })), }, method: 'fetchJobs', successCallback: ({ data }) => @@ -129,5 +173,39 @@ export const fetchJobs = ({ state, commit, dispatch }) => { }); }; -// prevent babel-plugin-rewire from generating an invalid default during karma tests -export default () => {}; +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 setPage = ({ state, commit, dispatch }, page) => { + if (page === state.pageInfo.page) { + return null; + } + + commit(types.SET_PAGE, page); + return dispatch('fetchRepos'); +}; + +export default ({ endpoints = isRequired(), hasPagination }) => ({ + clearJobsEtagPoll, + stopJobsPolling, + restartJobsPolling, + setFilter, + setImportTarget, + importAll, + setPage, + fetchRepos: fetchReposFactory({ reposPath: endpoints.reposPath, hasPagination }), + fetchImport: fetchImportFactory(endpoints.importPath), + fetchJobs: fetchJobsFactory(endpoints.jobsPath), + fetchNamespaces: fetchNamespacesFactory(endpoints.namespacesPath), +}); |