diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-08 15:08:26 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-08 15:08:26 +0300 |
commit | f149549c3432ffb179f6904e4ba0ea64027202d0 (patch) | |
tree | 9c6dca1e76c0de43e5e5f6b5d34c5616abbc7501 /app/assets/javascripts/import_projects | |
parent | b001207ce2033589373cd7558ca69c4e5732ce6b (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/import_projects')
10 files changed, 130 insertions, 71 deletions
diff --git a/app/assets/javascripts/import_projects/components/import_projects_table.vue b/app/assets/javascripts/import_projects/components/import_projects_table.vue index 849bda28d03..f2ed16ba59f 100644 --- a/app/assets/javascripts/import_projects/components/import_projects_table.vue +++ b/app/assets/javascripts/import_projects/components/import_projects_table.vue @@ -1,11 +1,11 @@ <script> import { throttle } from 'lodash'; import { mapActions, mapState, mapGetters } from 'vuex'; -import { GlLoadingIcon } from '@gitlab/ui'; -import LoadingButton from '~/vue_shared/components/loading_button.vue'; +import { GlButton, GlLoadingIcon } from '@gitlab/ui'; import { __, sprintf } from '~/locale'; import ImportedProjectTableRow from './imported_project_table_row.vue'; import ProviderRepoTableRow from './provider_repo_table_row.vue'; +import IncompatibleRepoTableRow from './incompatible_repo_table_row.vue'; import eventHub from '../event_hub'; const reposFetchThrottleDelay = 1000; @@ -15,8 +15,9 @@ export default { components: { ImportedProjectTableRow, ProviderRepoTableRow, - LoadingButton, + IncompatibleRepoTableRow, GlLoadingIcon, + GlButton, }, props: { providerTitle: { @@ -26,8 +27,25 @@ export default { }, computed: { - ...mapState(['importedProjects', 'providerRepos', 'isLoadingRepos', 'filter']), - ...mapGetters(['isImportingAnyRepo', 'hasProviderRepos', 'hasImportedProjects']), + ...mapState([ + 'importedProjects', + 'providerRepos', + 'incompatibleRepos', + 'isLoadingRepos', + 'filter', + ]), + ...mapGetters([ + 'isImportingAnyRepo', + 'hasProviderRepos', + 'hasImportedProjects', + 'hasIncompatibleRepos', + ]), + + importAllButtonText() { + return this.hasIncompatibleRepos + ? __('Import all compatible repositories') + : __('Import all repositories'); + }, emptyStateText() { return sprintf(__('No %{providerTitle} repositories found'), { @@ -68,7 +86,6 @@ export default { }, throttledFetchRepos: throttle(function fetch() { - eventHub.$off('importAll'); this.fetchRepos(); }, reposFetchThrottleDelay), }, @@ -80,17 +97,24 @@ export default { <p class="light text-nowrap mt-2"> {{ s__('ImportProjects|Select the projects you want to import') }} </p> - - <div class="d-flex justify-content-between align-items-end flex-wrap mb-3"> - <loading-button - container-class="btn btn-success js-import-all" + <template v-if="hasIncompatibleRepos"> + <slot name="incompatible-repos-warning"> </slot> + </template> + <div + v-if="!isLoadingRepos" + class="d-flex justify-content-between align-items-end flex-wrap mb-3" + > + <gl-button + variant="success" :loading="isImportingAnyRepo" - :label="__('Import all repositories')" :disabled="!hasProviderRepos" type="button" @click="importAll" - /> - <form novalidate @submit.prevent> + > + {{ importAllButtonText }} + </gl-button> + <slot name="actions"></slot> + <form class="gl-ml-auto" novalidate @submit.prevent> <input :value="filter" data-qa-selector="githubish_import_filter_field" @@ -109,7 +133,10 @@ export default { class="js-loading-button-icon import-projects-loading-icon" size="md" /> - <div v-else-if="hasProviderRepos || hasImportedProjects" class="table-responsive"> + <div + v-else-if="hasProviderRepos || hasImportedProjects || hasIncompatibleRepos" + class="table-responsive" + > <table class="table import-table"> <thead> <th class="import-jobs-from-col">{{ fromHeaderText }}</th> @@ -124,6 +151,11 @@ export default { :project="project" /> <provider-repo-table-row v-for="repo in providerRepos" :key="repo.id" :repo="repo" /> + <incompatible-repo-table-row + v-for="repo in incompatibleRepos" + :key="repo.id" + :repo="repo" + /> </tbody> </table> </div> diff --git a/app/assets/javascripts/import_projects/components/incompatible_repo_table_row.vue b/app/assets/javascripts/import_projects/components/incompatible_repo_table_row.vue new file mode 100644 index 00000000000..fa2fb439eac --- /dev/null +++ b/app/assets/javascripts/import_projects/components/incompatible_repo_table_row.vue @@ -0,0 +1,30 @@ +<script> +import { GlBadge } from '@gitlab/ui'; + +export default { + components: { + GlBadge, + }, + props: { + repo: { + type: Object, + required: true, + }, + }, +}; +</script> + +<template> + <tr class="import-row"> + <td> + <a :href="repo.providerLink" rel="noreferrer noopener" target="_blank"> + {{ repo.fullName }} + </a> + </td> + <td></td> + <td></td> + <td> + <gl-badge variant="danger">{{ __('Incompatible project') }}</gl-badge> + </td> + </tr> +</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 index 6e227ab3d82..63524d61146 100644 --- a/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue +++ b/app/assets/javascripts/import_projects/components/provider_repo_table_row.vue @@ -53,7 +53,11 @@ export default { }, created() { - eventHub.$on('importAll', () => this.importRepo()); + eventHub.$on('importAll', this.importRepo); + }, + + beforeDestroy() { + eventHub.$off('importAll', this.importRepo); }, methods: { diff --git a/app/assets/javascripts/import_projects/index.js b/app/assets/javascripts/import_projects/index.js index b069dcb7766..49d38b56e40 100644 --- a/app/assets/javascripts/import_projects/index.js +++ b/app/assets/javascripts/import_projects/index.js @@ -1,5 +1,4 @@ import Vue from 'vue'; -import { mapActions } from 'vuex'; import Translate from '../vue_shared/translate'; import ImportProjectsTable from './components/import_projects_table.vue'; import { parseBoolean } from '../lib/utils/common_utils'; @@ -7,42 +6,44 @@ import createStore from './store'; Vue.use(Translate); -export default function mountImportProjectsTable(mountElement) { - if (!mountElement) return undefined; - +export function initStoreFromElement(element) { const { reposPath, provider, - providerTitle, canSelectNamespace, jobsPath, importPath, ciCdOnly, - } = mountElement.dataset; + } = element.dataset; - const store = createStore(); - return new Vue({ - el: mountElement, - store, + return createStore({ + reposPath, + provider, + jobsPath, + importPath, + defaultTargetNamespace: gon.current_username, + ciCdOnly: parseBoolean(ciCdOnly), + canSelectNamespace: parseBoolean(canSelectNamespace), + }); +} - created() { - this.setInitialData({ - reposPath, - provider, - jobsPath, - importPath, - defaultTargetNamespace: gon.current_username, - ciCdOnly: parseBoolean(ciCdOnly), - canSelectNamespace: parseBoolean(canSelectNamespace), - }); - }, +export function initPropsFromElement(element) { + return { + providerTitle: element.dataset.providerTitle, + }; +} - methods: { - ...mapActions(['setInitialData', 'setFilter']), - }, +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: { providerTitle } }); + return createElement(ImportProjectsTable, { props }); }, }); } diff --git a/app/assets/javascripts/import_projects/store/actions.js b/app/assets/javascripts/import_projects/store/actions.js index 0fb9a4cdfd4..6cf71126882 100644 --- a/app/assets/javascripts/import_projects/store/actions.js +++ b/app/assets/javascripts/import_projects/store/actions.js @@ -19,23 +19,18 @@ export const restartJobsPolling = () => { if (eTagPoll) eTagPoll.restart(); }; -export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data); export const setFilter = ({ commit }, filter) => commit(types.SET_FILTER, filter); -export const requestRepos = ({ commit }, repos) => commit(types.REQUEST_REPOS, repos); -export const receiveReposSuccess = ({ commit }, repos) => - commit(types.RECEIVE_REPOS_SUCCESS, repos); -export const receiveReposError = ({ commit }) => commit(types.RECEIVE_REPOS_ERROR); -export const fetchRepos = ({ state, dispatch }) => { +export const fetchRepos = ({ state, dispatch, commit }) => { dispatch('stopJobsPolling'); - dispatch('requestRepos'); + commit(types.REQUEST_REPOS); const { provider } = state; return axios .get(reposPathWithFilter(state)) .then(({ data }) => - dispatch('receiveReposSuccess', convertObjectPropsToCamelCase(data, { deep: true })), + commit(types.RECEIVE_REPOS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })), ) .then(() => dispatch('fetchJobs')) .catch(() => { @@ -45,19 +40,14 @@ export const fetchRepos = ({ state, dispatch }) => { }), ); - dispatch('receiveReposError'); + commit(types.RECEIVE_REPOS_ERROR); }); }; -export const requestImport = ({ commit, state }, repoId) => { - if (!state.reposBeingImported.includes(repoId)) commit(types.REQUEST_IMPORT, repoId); -}; -export const receiveImportSuccess = ({ commit }, { importedProject, repoId }) => - commit(types.RECEIVE_IMPORT_SUCCESS, { importedProject, repoId }); -export const receiveImportError = ({ commit }, repoId) => - commit(types.RECEIVE_IMPORT_ERROR, repoId); -export const fetchImport = ({ state, dispatch }, { newName, targetNamespace, repo }) => { - dispatch('requestImport', repo.id); +export const fetchImport = ({ state, commit }, { newName, targetNamespace, repo }) => { + if (!state.reposBeingImported.includes(repo.id)) { + commit(types.REQUEST_IMPORT, repo.id); + } return axios .post(state.importPath, { @@ -67,7 +57,7 @@ export const fetchImport = ({ state, dispatch }, { newName, targetNamespace, rep target_namespace: targetNamespace, }) .then(({ data }) => - dispatch('receiveImportSuccess', { + commit(types.RECEIVE_IMPORT_SUCCESS, { importedProject: convertObjectPropsToCamelCase(data, { deep: true }), repoId: repo.id, }), @@ -75,13 +65,14 @@ export const fetchImport = ({ state, dispatch }, { newName, targetNamespace, rep .catch(() => { createFlash(s__('ImportProjects|Importing the project failed')); - dispatch('receiveImportError', { repoId: repo.id }); + commit(types.RECEIVE_IMPORT_ERROR, repo.id); }); }; export const receiveJobsSuccess = ({ commit }, updatedProjects) => commit(types.RECEIVE_JOBS_SUCCESS, updatedProjects); -export const fetchJobs = ({ state, dispatch }) => { + +export const fetchJobs = ({ state, commit, dispatch }) => { const { filter } = state; if (eTagPoll) { @@ -95,7 +86,7 @@ export const fetchJobs = ({ state, dispatch }) => { }, method: 'fetchJobs', successCallback: ({ data }) => - dispatch('receiveJobsSuccess', convertObjectPropsToCamelCase(data, { deep: true })), + commit(types.RECEIVE_JOBS_SUCCESS, convertObjectPropsToCamelCase(data, { deep: true })), errorCallback: () => createFlash(s__('ImportProjects|Update of imported projects with realtime changes failed')), data: { filter }, diff --git a/app/assets/javascripts/import_projects/store/getters.js b/app/assets/javascripts/import_projects/store/getters.js index b107c293181..e6eb8f523de 100644 --- a/app/assets/javascripts/import_projects/store/getters.js +++ b/app/assets/javascripts/import_projects/store/getters.js @@ -21,6 +21,8 @@ export const hasProviderRepos = state => state.providerRepos.length > 0; export const hasImportedProjects = state => state.importedProjects.length > 0; +export const hasIncompatibleRepos = state => state.incompatibleRepos.length > 0; + export const reposPathWithFilter = ({ reposPath, filter = '' }) => filter ? `${reposPath}?filter=${filter}` : reposPath; export const jobsPathWithFilter = ({ jobsPath, filter = '' }) => diff --git a/app/assets/javascripts/import_projects/store/index.js b/app/assets/javascripts/import_projects/store/index.js index ff1fd1e598e..29deb7868ba 100644 --- a/app/assets/javascripts/import_projects/store/index.js +++ b/app/assets/javascripts/import_projects/store/index.js @@ -9,9 +9,9 @@ Vue.use(Vuex); export { state, actions, getters, mutations }; -export default () => +export default initialState => new Vuex.Store({ - state: state(), + state: { ...state(), ...initialState }, actions, mutations, getters, diff --git a/app/assets/javascripts/import_projects/store/mutation_types.js b/app/assets/javascripts/import_projects/store/mutation_types.js index 16574f4450f..a23b7eef986 100644 --- a/app/assets/javascripts/import_projects/store/mutation_types.js +++ b/app/assets/javascripts/import_projects/store/mutation_types.js @@ -1,5 +1,3 @@ -export const SET_INITIAL_DATA = 'SET_INITIAL_DATA'; - export const REQUEST_REPOS = 'REQUEST_REPOS'; export const RECEIVE_REPOS_SUCCESS = 'RECEIVE_REPOS_SUCCESS'; export const RECEIVE_REPOS_ERROR = 'RECEIVE_REPOS_ERROR'; diff --git a/app/assets/javascripts/import_projects/store/mutations.js b/app/assets/javascripts/import_projects/store/mutations.js index 6c56cfa8298..ec62d0640ef 100644 --- a/app/assets/javascripts/import_projects/store/mutations.js +++ b/app/assets/javascripts/import_projects/store/mutations.js @@ -2,10 +2,6 @@ import Vue from 'vue'; import * as types from './mutation_types'; export default { - [types.SET_INITIAL_DATA](state, data) { - Object.assign(state, data); - }, - [types.SET_FILTER](state, filter) { state.filter = filter; }, @@ -14,11 +10,15 @@ export default { state.isLoadingRepos = true; }, - [types.RECEIVE_REPOS_SUCCESS](state, { importedProjects, providerRepos, namespaces }) { + [types.RECEIVE_REPOS_SUCCESS]( + state, + { importedProjects, providerRepos, incompatibleRepos, namespaces }, + ) { state.isLoadingRepos = false; state.importedProjects = importedProjects; state.providerRepos = providerRepos; + state.incompatibleRepos = incompatibleRepos ?? []; state.namespaces = namespaces; }, diff --git a/app/assets/javascripts/import_projects/store/state.js b/app/assets/javascripts/import_projects/store/state.js index 829f3aa4fbb..0418d735b1d 100644 --- a/app/assets/javascripts/import_projects/store/state.js +++ b/app/assets/javascripts/import_projects/store/state.js @@ -7,6 +7,7 @@ export default () => ({ currentUsername: '', importedProjects: [], providerRepos: [], + incompatibleRepos: [], namespaces: [], reposBeingImported: [], isLoadingRepos: false, |