diff options
-rw-r--r-- | app/controllers/import/bitbucket_controller.rb | 8 | ||||
-rw-r--r-- | app/views/import/bitbucket/status.html.haml | 12 | ||||
-rw-r--r-- | app/views/import/bitbucket_server/status.html.haml | 2 | ||||
-rw-r--r-- | changelogs/unreleased/georgekoltsov-bitbucket-cloud-import-filtering.yml | 5 | ||||
-rw-r--r-- | doc/user/project/import/bitbucket.md | 6 | ||||
-rw-r--r-- | doc/user/project/import/img/bitbucket_import_select_project.png | bin | 8688 -> 0 bytes | |||
-rw-r--r-- | doc/user/project/import/img/bitbucket_import_select_project_v12_3.png | bin | 0 -> 47258 bytes | |||
-rw-r--r-- | lib/bitbucket/client.rb | 4 | ||||
-rw-r--r-- | spec/controllers/import/bitbucket_controller_spec.rb | 15 |
9 files changed, 44 insertions, 8 deletions
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb index 293d76ea765..c37e799de62 100644 --- a/app/controllers/import/bitbucket_controller.rb +++ b/app/controllers/import/bitbucket_controller.rb @@ -1,6 +1,8 @@ # frozen_string_literal: true class Import::BitbucketController < Import::BaseController + include ActionView::Helpers::SanitizeHelper + before_action :verify_bitbucket_import_enabled before_action :bitbucket_auth, except: :callback @@ -21,7 +23,7 @@ class Import::BitbucketController < Import::BaseController # rubocop: disable CodeReuse/ActiveRecord def status bitbucket_client = Bitbucket::Client.new(credentials) - repos = bitbucket_client.repos + repos = bitbucket_client.repos(filter: sanitized_filter_param) @repos, @incompatible_repos = repos.partition { |repo| repo.valid? } @@ -104,4 +106,8 @@ class Import::BitbucketController < Import::BaseController refresh_token: session[:bitbucket_refresh_token] } end + + def sanitized_filter_param + @filter ||= sanitize(params[:filter]) + end end diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml index 2336e1e83f9..5668b93e16a 100644 --- a/app/views/import/bitbucket/status.html.haml +++ b/app/views/import/bitbucket/status.html.haml @@ -8,7 +8,6 @@ - if @repos.any? %p.light = _('Select projects you want to import.') - %hr %p - if @incompatible_repos.any? = button_tag class: 'btn btn-import btn-success js-import-all' do @@ -19,6 +18,15 @@ = _('Import all projects') = icon('spinner spin', class: 'loading-icon') +.position-relative.ms-no-clear.d-flex.flex-fill.float-right + = form_tag status_import_bitbucket_path, method: 'get' do + = text_field_tag :filter, @filter, class: 'form-control append-bottom-10 pr-5', placeholder: _('Filter projects'), size: 40, autofocus: true + .position-absolute.position-top-0.d-flex.align-items-center.text-muted.position-right-0{ style: 'margin-top: 1px' } + %i{ class: 'fa fa-times fa-lg pl-2 pr-2 cursor-pointer d-none', 'aria-hidden': true } + .border-left + %button{ class: 'btn btn-transparent btn-secondary', type: 'submit' } + %i{ class: 'fa fa-search', 'aria-hidden': true } + .table-responsive %table.table.import-jobs %colgroup.import-jobs-from-col @@ -59,7 +67,7 @@ - if current_user.can_select_namespace? - selected = params[:namespace_id] || :current_user - opts = current_user.can_create_group? ? { extra_group: Group.new(name: repo.owner, path: repo.owner) } : {} - = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'input-group-text select2 js-select-namespace', tabindex: 1 } + = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 } - else = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true %span.input-group-prepend diff --git a/app/views/import/bitbucket_server/status.html.haml b/app/views/import/bitbucket_server/status.html.haml index aac09801d91..1aaf5883bf4 100644 --- a/app/views/import/bitbucket_server/status.html.haml +++ b/app/views/import/bitbucket_server/status.html.haml @@ -62,7 +62,7 @@ - if current_user.can_select_namespace? - selected = params[:namespace_id] || :extra_group - opts = current_user.can_create_group? ? { extra_group: Group.new(name: sanitize_project_name(repo.project_key), path: sanitize_project_name(repo.project_key)) } : {} - = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'input-group-text select2 js-select-namespace', tabindex: 1 } + = select_tag :namespace_id, namespaces_options(selected, opts.merge({ display_path: true })), { class: 'select2 js-select-namespace', tabindex: 1 } - else = text_field_tag :path, current_user.namespace_path, class: "input-group-text input-large form-control", tabindex: 1, disabled: true %span.input-group-prepend diff --git a/changelogs/unreleased/georgekoltsov-bitbucket-cloud-import-filtering.yml b/changelogs/unreleased/georgekoltsov-bitbucket-cloud-import-filtering.yml new file mode 100644 index 00000000000..3ba233c5bc8 --- /dev/null +++ b/changelogs/unreleased/georgekoltsov-bitbucket-cloud-import-filtering.yml @@ -0,0 +1,5 @@ +--- +title: Add project filtering to Bitbucket Cloud import +merge_request: 32398 +author: +type: added diff --git a/doc/user/project/import/bitbucket.md b/doc/user/project/import/bitbucket.md index e509e333313..77fc2761e07 100644 --- a/doc/user/project/import/bitbucket.md +++ b/doc/user/project/import/bitbucket.md @@ -56,10 +56,10 @@ namespace that started the import process. ![Grant access](img/bitbucket_import_grant_access.png) 1. Click on the projects that you'd like to import or **Import all projects**. - You can also select the namespace under which each project will be - imported. + You can also filter projects by name and select the namespace under which + each project will be imported. - ![Import projects](img/bitbucket_import_select_project.png) + ![Import projects](img/bitbucket_import_select_project_v12_3.png) [bb-import]: ../../../integration/bitbucket.md [social sign-in]: ../../profile/account/social_sign_in.md diff --git a/doc/user/project/import/img/bitbucket_import_select_project.png b/doc/user/project/import/img/bitbucket_import_select_project.png Binary files differdeleted file mode 100644 index 1bca6166ec8..00000000000 --- a/doc/user/project/import/img/bitbucket_import_select_project.png +++ /dev/null diff --git a/doc/user/project/import/img/bitbucket_import_select_project_v12_3.png b/doc/user/project/import/img/bitbucket_import_select_project_v12_3.png Binary files differnew file mode 100644 index 00000000000..db76736c369 --- /dev/null +++ b/doc/user/project/import/img/bitbucket_import_select_project_v12_3.png diff --git a/lib/bitbucket/client.rb b/lib/bitbucket/client.rb index 1343f424c51..92894575ec2 100644 --- a/lib/bitbucket/client.rb +++ b/lib/bitbucket/client.rb @@ -38,8 +38,10 @@ module Bitbucket Representation::Repo.new(parsed_response) end - def repos + def repos(filter: nil) path = "/repositories?role=member" + path += "&q=name~\"#{filter}\"" if filter + get_collection(path, :repo) end diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb index 38388c21749..d013bd6d427 100644 --- a/spec/controllers/import/bitbucket_controller_spec.rb +++ b/spec/controllers/import/bitbucket_controller_spec.rb @@ -80,6 +80,21 @@ describe Import::BitbucketController do expect(assigns(:already_added_projects)).to eq([@project]) expect(assigns(:repos)).to eq([]) end + + context 'when filtering' do + let(:filter) { '<html>test</html>' } + let(:expected_filter) { 'test' } + + subject { get :status, params: { filter: filter }, as: :json } + + it 'passes sanitized filter param to bitbucket client' do + expect_next_instance_of(Bitbucket::Client) do |client| + expect(client).to receive(:repos).with(filter: expected_filter).and_return([@repo]) + end + + subject + end + end end describe "POST create" do |