From a0946be8d08f21da56d3ca36c0ecf49ed4b29f13 Mon Sep 17 00:00:00 2001 From: Vasilii Iakliushin Date: Wed, 12 Nov 2025 18:19:19 +0100 Subject: [PATCH] Add pagination to mirrors list Contributes to https://gitlab.com/gitlab-org/gitlab/-/issues/580289 **Problem** Mirror configuration page is missing pagination for mirrors. **Solution** * Extract remote mirror page into a custom template * Add missing pagination logic Changelog: added --- .../settings/repository_controller.rb | 1 + .../mirrors/_mirror_repos_list.html.haml | 31 ++++--------------- .../projects/mirrors/_remote_mirror.html.haml | 24 ++++++++++++++ .../settings/repository_controller_spec.rb | 29 +++++++++++++++++ .../settings/mirroring_repositories.rb | 2 +- .../settings/repository_controller_spec.rb | 22 +++++++++++++ 6 files changed, 83 insertions(+), 26 deletions(-) create mode 100644 app/views/projects/mirrors/_remote_mirror.html.haml diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb index 5410b56b45770e..e8343b66868cbd 100644 --- a/app/controllers/projects/settings/repository_controller.rb +++ b/app/controllers/projects/settings/repository_controller.rb @@ -123,6 +123,7 @@ def fetch_protected_branches(project) def remote_mirror @remote_mirror = project.remote_mirrors.first_or_initialize + @remote_mirrors = project.remote_mirrors.page(pagination_params[:page]) end def deploy_token_params diff --git a/app/views/projects/mirrors/_mirror_repos_list.html.haml b/app/views/projects/mirrors/_mirror_repos_list.html.haml index b21f0d5e32697c..5891fe4c8a8892 100644 --- a/app/views/projects/mirrors/_mirror_repos_list.html.haml +++ b/app/views/projects/mirrors/_mirror_repos_list.html.haml @@ -1,4 +1,5 @@ - mirror_settings_enabled = can?(current_user, :admin_remote_mirror, @project) +- display_pull_mirrors = params.fetch(:page, '1').to_s == '1' .table-responsive.gl-mb-0 - if !@project.mirror? && @project.remote_mirrors.count == 0 @@ -14,28 +15,8 @@ %th %th %tbody.js-mirrors-table-body - = render_if_exists 'projects/mirrors/table_pull_row' - - @project.remote_mirrors.each_with_index do |mirror, index| - - next if mirror.new_record? - %tr.rspec-mirrored-repository-row{ class: ('bg-secondary' if mirror.disabled?), data: { testid: 'mirrored-repository-row-container' } } - %td{ data: { testid: 'mirror-repository-url-content' } } - = mirror.safe_url || _('Invalid URL') - = render_if_exists 'projects/mirrors/mirror_branches_setting_badge', record: mirror - %td= _('Push') - %td - = mirror.last_update_started_at.present? ? time_ago_with_tooltip(mirror.last_update_started_at) : _('Never') - %td{ data: { testid: 'mirror-last-update-at-content' } }= mirror.last_update_at.present? ? time_ago_with_tooltip(mirror.last_update_at) : _('Never') - %td - - if mirror.disabled? - = render 'projects/mirrors/disabled_mirror_badge' - - if mirror.last_error.present? - = gl_badge_tag _('Error'), { variant: :danger }, { data: { toggle: 'tooltip', html: 'true', testid: 'mirror-error-badge-content' }, title: html_escape(mirror.last_error.try(:strip)), tabindex: 0 } - %td - - if mirror_settings_enabled - .btn-group.mirror-actions-group{ role: 'group' } - - if mirror.ssh_key_auth? - = clipboard_button(text: mirror.ssh_public_key, variant: :default, category: :primary, size: :medium, title: _('Copy SSH public key'), testid: 'copy-public-key-button') - = render 'shared/remote_mirror_update_button', remote_mirror: mirror - = render Pajamas::ButtonComponent.new(variant: :danger, - icon: 'remove', - button_options: { class: 'js-delete-mirror rspec-delete-mirror', title: _('Remove'), data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' } }) + = render_if_exists 'projects/mirrors/table_pull_row' if display_pull_mirrors + - @remote_mirrors.each do |remote_mirror| + = render 'projects/mirrors/remote_mirror', remote_mirror: remote_mirror, mirror_settings_enabled: mirror_settings_enabled + + = paginate @remote_mirrors, theme: 'gitlab', params: { anchor: 'js-push-remote-settings' } diff --git a/app/views/projects/mirrors/_remote_mirror.html.haml b/app/views/projects/mirrors/_remote_mirror.html.haml new file mode 100644 index 00000000000000..6232971b9e2db5 --- /dev/null +++ b/app/views/projects/mirrors/_remote_mirror.html.haml @@ -0,0 +1,24 @@ +- return if remote_mirror.new_record? + +%tr.rspec-mirrored-repository-row{ class: ('bg-secondary' if remote_mirror.disabled?), data: { testid: 'mirrored-repository-row-container' } } + %td{ data: { testid: 'mirror-repository-url-content' } } + = remote_mirror.safe_url || _('Invalid URL') + = render_if_exists 'projects/mirrors/mirror_branches_setting_badge', record: remote_mirror + %td= _('Push') + %td + = remote_mirror.last_update_started_at.present? ? time_ago_with_tooltip(remote_mirror.last_update_started_at) : _('Never') + %td{ data: { testid: 'mirror-last-update-at-content' } }= remote_mirror.last_update_at.present? ? time_ago_with_tooltip(remote_mirror.last_update_at) : _('Never') + %td + - if remote_mirror.disabled? + = render 'projects/mirrors/disabled_mirror_badge' + - if remote_mirror.last_error.present? + = gl_badge_tag _('Error'), { variant: :danger }, { data: { toggle: 'tooltip', html: 'true', testid: 'mirror-error-badge-content' }, title: html_escape(remote_mirror.last_error.try(:strip)), tabindex: 0 } + %td + - if mirror_settings_enabled + .btn-group.mirror-actions-group{ role: 'group' } + - if remote_mirror.ssh_key_auth? + = clipboard_button(text: remote_mirror.ssh_public_key, variant: :default, category: :primary, size: :medium, title: _('Copy SSH public key'), testid: 'copy-public-key-button') + = render 'shared/remote_mirror_update_button', remote_mirror: remote_mirror + = render Pajamas::ButtonComponent.new(variant: :danger, + icon: 'remove', + button_options: { class: 'js-delete-mirror rspec-delete-mirror', title: _('Remove'), data: { mirror_id: remote_mirror.id, toggle: 'tooltip', container: 'body' } }) diff --git a/ee/spec/controllers/ee/projects/settings/repository_controller_spec.rb b/ee/spec/controllers/ee/projects/settings/repository_controller_spec.rb index 0cb53ff7fc972a..d824f3c0028215 100644 --- a/ee/spec/controllers/ee/projects/settings/repository_controller_spec.rb +++ b/ee/spec/controllers/ee/projects/settings/repository_controller_spec.rb @@ -40,6 +40,35 @@ end end + context 'mirrors pagination with pull and push mirrors' do + let!(:project) { create(:project_empty_repo, :mirror) } + let!(:remote_mirrors) { create_list(:remote_mirror, 3, project: project) } + + let(:base_params) { { namespace_id: project.namespace, project_id: project } } + + render_views + + before do + allow(Kaminari.config).to receive(:default_per_page).and_return(2) + end + + it 'displays pull mirror on first page only' do + get :show, params: base_params.merge(page: 1) + + expect(response.body).to include('js-delete-pull-mirror') + expect(assigns(:remote_mirrors).count).to eq(2) + expect(assigns(:remote_mirrors)).to be_a(ActiveRecord::Relation) + end + + it 'does not display pull mirror on subsequent pages' do + get :show, params: base_params.merge(page: 2) + + expect(response.body).not_to include('js-delete-pull-mirror') + expect(assigns(:remote_mirrors).count).to eq(1) + expect(assigns(:remote_mirrors).current_page).to eq(2) + end + end + describe 'group protected branches' do using RSpec::Parameterized::TableSyntax diff --git a/qa/qa/page/project/settings/mirroring_repositories.rb b/qa/qa/page/project/settings/mirroring_repositories.rb index 4ebdbc40fa955c..157551d1ea380b 100644 --- a/qa/qa/page/project/settings/mirroring_repositories.rb +++ b/qa/qa/page/project/settings/mirroring_repositories.rb @@ -17,7 +17,7 @@ class MirroringRepositories < Page::Base element 'add-new-mirror' end - view 'app/views/projects/mirrors/_mirror_repos_list.html.haml' do + view 'app/views/projects/mirrors/_remote_mirror.html.haml' do element 'mirror-repository-url-content' element 'mirror-last-update-at-content' element 'mirror-error-badge-content' diff --git a/spec/controllers/projects/settings/repository_controller_spec.rb b/spec/controllers/projects/settings/repository_controller_spec.rb index 781e4ff7b00446..4b098ba6d626e1 100644 --- a/spec/controllers/projects/settings/repository_controller_spec.rb +++ b/spec/controllers/projects/settings/repository_controller_spec.rb @@ -19,6 +19,28 @@ expect(response).to have_gitlab_http_status(:ok) expect(response).to render_template(:show) end + + context 'with remote mirrors pagination' do + let!(:remote_mirrors) { create_list(:remote_mirror, 3, project: project) } + + before do + allow(Kaminari.config).to receive(:default_per_page).and_return(2) + end + + it 'paginates remote mirrors' do + get :show, params: base_params + + expect(assigns(:remote_mirrors).count).to eq(2) + expect(assigns(:remote_mirrors)).to be_a(ActiveRecord::Relation) + end + + it 'returns second page of remote mirrors' do + get :show, params: base_params.merge(page: 2) + + expect(assigns(:remote_mirrors).count).to eq(1) + expect(assigns(:remote_mirrors).current_page).to eq(2) + end + end end describe 'PUT cleanup' do -- GitLab