diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-14 15:09:44 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-14 15:09:44 +0300 |
commit | 95671fac6e66cd23da4669706a619c1139eb1f14 (patch) | |
tree | ff2259013a8143f9f6ee64b85f8d4d4d10bc3e58 /app/assets/javascripts/import_projects | |
parent | 181c5927ae0b7e7e18dbbe48b58915de922adcb9 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/import_projects')
13 files changed, 0 insertions, 1011 deletions
diff --git a/app/assets/javascripts/import_projects/components/bitbucket_status_table.vue b/app/assets/javascripts/import_projects/components/bitbucket_status_table.vue deleted file mode 100644 index bc8aa522596..00000000000 --- a/app/assets/javascripts/import_projects/components/bitbucket_status_table.vue +++ /dev/null @@ -1,75 +0,0 @@ -<script> -import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui'; -import ImportProjectsTable from './import_projects_table.vue'; - -export default { - components: { - ImportProjectsTable, - GlAlert, - GlSprintf, - GlLink, - }, - inheritAttrs: false, - props: { - providerTitle: { - type: String, - required: true, - }, - }, - data() { - return { - isWarningDismissed: false, - }; - }, - computed: { - currentPage() { - return window.location.href; - }, - }, -}; -</script> -<template> - <import-projects-table :provider-title="providerTitle" v-bind="$attrs"> - <template #actions> - <slot name="actions"></slot> - </template> - <template #incompatible-repos-warning> - <gl-alert - v-if="!isWarningDismissed" - variant="warning" - class="gl-my-2" - @dismiss="isWarningDismissed = true" - > - <gl-sprintf - :message=" - __( - 'One or more of your %{provider} projects cannot be imported into GitLab directly because they use Subversion or Mercurial for version control, rather than Git.', - ) - " - > - <template #provider> - {{ providerTitle }} - </template> - </gl-sprintf> - <gl-sprintf - :message=" - __( - 'Please convert %{linkStart}them to Git%{linkEnd}, and go through the %{linkToImportFlow} again.', - ) - " - > - <template #link="{ content }"> - <gl-link - href="https://www.atlassian.com/git/tutorials/migrating-overview" - target="_blank" - >{{ content }}</gl-link - > - </template> - <template #linkToImportFlow> - <gl-link :href="currentPage">{{ __('import flow') }}</gl-link> - </template> - </gl-sprintf> - </gl-alert> - </template> - </import-projects-table> -</template> diff --git a/app/assets/javascripts/import_projects/components/import_projects_table.vue b/app/assets/javascripts/import_projects/components/import_projects_table.vue deleted file mode 100644 index 2b6b8b765a2..00000000000 --- a/app/assets/javascripts/import_projects/components/import_projects_table.vue +++ /dev/null @@ -1,187 +0,0 @@ -<script> -import { mapActions, mapState, mapGetters } from 'vuex'; -import { GlButton, GlLoadingIcon, GlIntersectionObserver, GlModal } from '@gitlab/ui'; -import { n__, __, sprintf } from '~/locale'; -import ProviderRepoTableRow from './provider_repo_table_row.vue'; - -export default { - name: 'ImportProjectsTable', - components: { - ProviderRepoTableRow, - GlLoadingIcon, - GlButton, - GlModal, - GlIntersectionObserver, - }, - props: { - providerTitle: { - type: String, - required: true, - }, - filterable: { - type: Boolean, - required: false, - default: true, - }, - paginatable: { - type: Boolean, - required: false, - default: false, - }, - }, - - computed: { - ...mapState(['filter', 'repositories', 'namespaces', 'defaultTargetNamespace']), - ...mapGetters([ - 'isLoading', - 'isImportingAnyRepo', - 'hasImportableRepos', - 'hasIncompatibleRepos', - 'importAllCount', - ]), - - pagePaginationStateKey() { - return `${this.filter}-${this.repositories.length}`; - }, - - availableNamespaces() { - const serializedNamespaces = this.namespaces.map(({ fullPath }) => ({ - id: fullPath, - text: fullPath, - })); - - return [ - { text: __('Groups'), children: serializedNamespaces }, - { - text: __('Users'), - children: [{ id: this.defaultTargetNamespace, text: this.defaultTargetNamespace }], - }, - ]; - }, - - importAllButtonText() { - return this.hasIncompatibleRepos - ? n__( - 'Import %d compatible repository', - 'Import %d compatible repositories', - this.importAllCount, - ) - : n__('Import %d repository', 'Import %d repositories', this.importAllCount); - }, - - emptyStateText() { - return sprintf(__('No %{providerTitle} repositories found'), { - providerTitle: this.providerTitle, - }); - }, - - fromHeaderText() { - return sprintf(__('From %{providerTitle}'), { providerTitle: this.providerTitle }); - }, - }, - - mounted() { - this.fetchNamespaces(); - this.fetchJobs(); - - if (!this.paginatable) { - this.fetchRepos(); - } - }, - - beforeDestroy() { - this.stopJobsPolling(); - this.clearJobsEtagPoll(); - }, - - methods: { - ...mapActions([ - 'fetchRepos', - 'fetchJobs', - 'fetchNamespaces', - 'stopJobsPolling', - 'clearJobsEtagPoll', - 'setFilter', - 'importAll', - ]), - }, -}; -</script> - -<template> - <div> - <p class="light text-nowrap mt-2"> - {{ s__('ImportProjects|Select the repositories you want to import') }} - </p> - <template v-if="hasIncompatibleRepos"> - <slot name="incompatible-repos-warning"></slot> - </template> - <div class="d-flex justify-content-between align-items-end flex-wrap mb-3"> - <gl-button - variant="success" - :loading="isImportingAnyRepo" - :disabled="!hasImportableRepos" - type="button" - @click="$refs.importAllModal.show()" - >{{ importAllButtonText }}</gl-button - > - <gl-modal - ref="importAllModal" - modal-id="import-all-modal" - :title="s__('ImportProjects|Import repositories')" - :ok-title="__('Import')" - @ok="importAll" - > - {{ - n__( - 'Are you sure you want to import %d repository?', - 'Are you sure you want to import %d repositories?', - importAllCount, - ) - }} - </gl-modal> - - <slot name="actions"></slot> - <form v-if="filterable" class="gl-ml-auto" novalidate @submit.prevent> - <input - data-qa-selector="githubish_import_filter_field" - class="form-control" - name="filter" - :placeholder="__('Filter your repositories by name')" - autofocus - size="40" - @keyup.enter="setFilter($event.target.value)" - /> - </form> - </div> - <div v-if="repositories.length" class="table-responsive"> - <table class="table import-table"> - <thead> - <th class="import-jobs-from-col">{{ fromHeaderText }}</th> - <th class="import-jobs-to-col">{{ __('To GitLab') }}</th> - <th class="import-jobs-status-col">{{ __('Status') }}</th> - <th class="import-jobs-cta-col"></th> - </thead> - <tbody> - <template v-for="repo in repositories"> - <provider-repo-table-row - :key="repo.importSource.providerLink" - :repo="repo" - :available-namespaces="availableNamespaces" - /> - </template> - </tbody> - </table> - </div> - <gl-intersection-observer - v-if="paginatable" - :key="pagePaginationStateKey" - @appear="fetchRepos" - /> - <gl-loading-icon v-if="isLoading" class="import-projects-loading-icon" size="md" /> - - <div v-if="!isLoading && repositories.length === 0" class="text-center"> - <strong>{{ emptyStateText }}</strong> - </div> - </div> -</template> diff --git a/app/assets/javascripts/import_projects/components/import_status.vue b/app/assets/javascripts/import_projects/components/import_status.vue deleted file mode 100644 index 9e3347a657f..00000000000 --- a/app/assets/javascripts/import_projects/components/import_status.vue +++ /dev/null @@ -1,47 +0,0 @@ -<script> -import { GlLoadingIcon } from '@gitlab/ui'; -import CiIcon from '~/vue_shared/components/ci_icon.vue'; -import STATUS_MAP from '../constants'; - -export default { - name: 'ImportStatus', - components: { - CiIcon, - GlLoadingIcon, - }, - props: { - status: { - type: String, - required: true, - }, - }, - - computed: { - mappedStatus() { - return STATUS_MAP[this.status]; - }, - - ciIconStatus() { - const { icon } = this.mappedStatus; - - return { - icon: `status_${icon}`, - group: icon, - }; - }, - }, -}; -</script> - -<template> - <div> - <gl-loading-icon - v-if="mappedStatus.loadingIcon" - :inline="true" - :class="mappedStatus.textClass" - class="align-middle mr-2" - /> - <ci-icon v-else css-classes="align-middle mr-2" :status="ciIconStatus" /> - <span :class="mappedStatus.textClass">{{ mappedStatus.text }}</span> - </div> -</template> diff --git a/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue b/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue deleted file mode 100644 index 18971313dfe..00000000000 --- a/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue +++ /dev/null @@ -1,151 +0,0 @@ -<script> -import { mapState, mapGetters, mapActions } from 'vuex'; -import { GlIcon, GlBadge } from '@gitlab/ui'; -import Select2Select from '~/vue_shared/components/select2_select.vue'; -import { __ } from '~/locale'; -import ImportStatus from './import_status.vue'; -import { STATUSES } from '../constants'; -import { isProjectImportable, isIncompatible, getImportStatus } from '../utils'; - -export default { - name: 'ProviderRepoTableRow', - components: { - Select2Select, - ImportStatus, - GlIcon, - GlBadge, - }, - props: { - repo: { - type: Object, - required: true, - }, - availableNamespaces: { - type: Array, - required: true, - }, - }, - - computed: { - ...mapState(['ciCdOnly']), - ...mapGetters(['getImportTarget']), - - displayFullPath() { - return this.repo.importedProject.fullPath.replace(/^\//, ''); - }, - - isFinished() { - return this.repo.importedProject?.importStatus === STATUSES.FINISHED; - }, - - isImportNotStarted() { - return isProjectImportable(this.repo); - }, - - isIncompatible() { - return isIncompatible(this.repo); - }, - - importStatus() { - return getImportStatus(this.repo); - }, - - importTarget() { - return this.getImportTarget(this.repo.importSource.id); - }, - - importButtonText() { - return this.ciCdOnly ? __('Connect') : __('Import'); - }, - - select2Options() { - return { - data: this.availableNamespaces, - containerCssClass: 'import-namespace-select qa-project-namespace-select w-auto', - }; - }, - - targetNamespaceSelect: { - get() { - return this.importTarget.targetNamespace; - }, - set(value) { - this.updateImportTarget({ targetNamespace: value }); - }, - }, - - newNameInput: { - get() { - return this.importTarget.newName; - }, - set(value) { - this.updateImportTarget({ newName: value }); - }, - }, - }, - - methods: { - ...mapActions(['fetchImport', 'setImportTarget']), - updateImportTarget(changedValues) { - this.setImportTarget({ - repoId: this.repo.importSource.id, - importTarget: { ...this.importTarget, ...changedValues }, - }); - }, - }, -}; -</script> - -<template> - <tr class="qa-project-import-row import-row"> - <td> - <a - :href="repo.importSource.providerLink" - rel="noreferrer noopener" - target="_blank" - data-testid="providerLink" - >{{ repo.importSource.fullName }} - <gl-icon v-if="repo.importSource.providerLink" name="external-link" /> - </a> - </td> - <td class="d-flex flex-wrap flex-lg-nowrap" data-testid="fullPath"> - <template v-if="repo.importSource.target">{{ repo.importSource.target }}</template> - <template v-else-if="isImportNotStarted"> - <select2-select v-model="targetNamespaceSelect" :options="select2Options" /> - <span class="px-2 import-slash-divider d-flex justify-content-center align-items-center" - >/</span - > - <input - v-model="newNameInput" - type="text" - class="form-control import-project-name-input qa-project-path-field" - /> - </template> - <template v-else-if="repo.importedProject">{{ displayFullPath }}</template> - </td> - <td> - <import-status :status="importStatus" /> - </td> - <td data-testid="actions"> - <a - v-if="isFinished" - class="btn btn-default" - :href="repo.importedProject.fullPath" - rel="noreferrer noopener" - target="_blank" - >{{ __('Go to project') }} - </a> - <button - v-if="isImportNotStarted" - type="button" - class="qa-import-button btn btn-default" - @click="fetchImport(repo.importSource.id)" - > - {{ importButtonText }} - </button> - <gl-badge v-else-if="isIncompatible" variant="danger">{{ - __('Incompatible project') - }}</gl-badge> - </td> - </tr> -</template> diff --git a/app/assets/javascripts/import_projects/constants.js b/app/assets/javascripts/import_projects/constants.js deleted file mode 100644 index ad33ca158d2..00000000000 --- a/app/assets/javascripts/import_projects/constants.js +++ /dev/null @@ -1,48 +0,0 @@ -import { __ } from '../locale'; - -// The `scheduling` status is only present on the client-side, -// it is used as the status when we are requesting to start an import. - -export const STATUSES = { - FINISHED: 'finished', - FAILED: 'failed', - SCHEDULED: 'scheduled', - STARTED: 'started', - NONE: 'none', - SCHEDULING: 'scheduling', -}; - -const STATUS_MAP = { - [STATUSES.FINISHED]: { - icon: 'success', - text: __('Done'), - textClass: 'text-success', - }, - [STATUSES.FAILED]: { - icon: 'failed', - text: __('Failed'), - textClass: 'text-danger', - }, - [STATUSES.SCHEDULED]: { - icon: 'pending', - text: __('Scheduled'), - textClass: 'text-warning', - }, - [STATUSES.STARTED]: { - icon: 'running', - text: __('Running…'), - textClass: 'text-info', - }, - [STATUSES.NONE]: { - icon: 'created', - text: __('Not started'), - textClass: 'text-muted', - }, - [STATUSES.SCHEDULING]: { - loadingIcon: true, - text: __('Scheduling'), - textClass: 'text-warning', - }, -}; - -export default STATUS_MAP; diff --git a/app/assets/javascripts/import_projects/index.js b/app/assets/javascripts/import_projects/index.js deleted file mode 100644 index cbb98efa07e..00000000000 --- a/app/assets/javascripts/import_projects/index.js +++ /dev/null @@ -1,60 +0,0 @@ -import Vue from 'vue'; -import Translate from '../vue_shared/translate'; -import ImportProjectsTable from './components/import_projects_table.vue'; -import { parseBoolean } from '../lib/utils/common_utils'; -import createStore from './store'; - -Vue.use(Translate); - -export function initStoreFromElement(element) { - const { - ciCdOnly, - canSelectNamespace, - provider, - - reposPath, - jobsPath, - importPath, - namespacesPath, - paginatable, - } = element.dataset; - - return createStore({ - initialState: { - defaultTargetNamespace: gon.current_username, - ciCdOnly: parseBoolean(ciCdOnly), - canSelectNamespace: parseBoolean(canSelectNamespace), - provider, - }, - endpoints: { - reposPath, - jobsPath, - importPath, - namespacesPath, - }, - hasPagination: parseBoolean(paginatable), - }); -} - -export function initPropsFromElement(element) { - return { - providerTitle: element.dataset.providerTitle, - filterable: parseBoolean(element.dataset.filterable), - paginatable: parseBoolean(element.dataset.paginatable), - }; -} - -export default function mountImportProjectsTable(mountElement) { - if (!mountElement) return undefined; - - const store = initStoreFromElement(mountElement); - const props = initPropsFromElement(mountElement); - - return new Vue({ - el: mountElement, - store, - render(createElement) { - return createElement(ImportProjectsTable, { props }); - }, - }); -} 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, - }, -}); diff --git a/app/assets/javascripts/import_projects/utils.js b/app/assets/javascripts/import_projects/utils.js deleted file mode 100644 index 695b12cbcba..00000000000 --- a/app/assets/javascripts/import_projects/utils.js +++ /dev/null @@ -1,13 +0,0 @@ -import { STATUSES } from './constants'; - -export function isIncompatible(project) { - return project.importSource.incompatible; -} - -export function getImportStatus(project) { - return project.importedProject?.importStatus ?? STATUSES.NONE; -} - -export function isProjectImportable(project) { - return !isIncompatible(project) && getImportStatus(project) === STATUSES.NONE; -} |