From b0c317b0c0c3d3e4150c1a272b796eca07ff3eaf Mon Sep 17 00:00:00 2001 From: Annabel Dunstone Gray Date: Tue, 1 Aug 2023 15:19:49 -0600 Subject: [PATCH] Move mirrored repositories to card Changelog: changed --- app/helpers/mirror_helper.rb | 5 ++ .../projects/mirrors/_mirror_repos.html.haml | 65 ++++++++------ .../mirrors/_mirror_repos_list.html.haml | 86 +++++++++---------- .../repository/show/ee_mirror_repos.js | 2 +- ee/app/helpers/ee/mirror_helper.rb | 5 -- .../_mirrored_repositories_count.html.haml | 1 - .../mirrors/_table_pull_row.html.haml | 1 + ee/spec/features/projects/mirror_spec.rb | 10 +++ .../ee/repository_mirrors_settings_spec.rb | 5 ++ locale/gitlab.pot | 3 + .../settings/repository_settings_spec.rb | 1 + 11 files changed, 106 insertions(+), 78 deletions(-) delete mode 100644 ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml diff --git a/app/helpers/mirror_helper.rb b/app/helpers/mirror_helper.rb index 06deaeb5e9e753..158aa5e0944e67 100644 --- a/app/helpers/mirror_helper.rb +++ b/app/helpers/mirror_helper.rb @@ -15,6 +15,11 @@ def mirror_lfs_sync_message html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) % { docs_link_start: docs_link_start, docs_link_end: ''.html_safe, strong_open: ''.html_safe, strong_close: ''.html_safe } end + + def mirrored_repositories_count + count = @project.mirror == true ? 1 : 0 + count + @project.remote_mirrors.to_a.count(&:enabled) + end end MirrorHelper.prepend_mod_with('MirrorHelper') diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index 110bc8d82f85ab..a9a2ca6a494970 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -12,28 +12,45 @@ = _('Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically.') = link_to _('How do I mirror repositories?'), help_page_path('user/project/repository/mirror/index.md'), target: '_blank', rel: 'noopener noreferrer' - .settings-content - - if mirror_settings_enabled - = gitlab_ui_form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'new-password', data: mirrors_form_data_attributes } do |f| - .panel.panel-default - .panel-body - %div= form_errors(@project) - - .form-group.has-feedback - = label_tag :url, _('Git repository URL'), class: 'label-light' - = text_field_tag :url, nil, class: 'form-control gl-form-input js-mirror-url js-repo-url', placeholder: _('Input the remote repository URL'), required: true, pattern: "(#{protocols}):\/\/.+", autocomplete: 'new-password', data: { qa_selector: 'mirror_repository_url_field' } - - = render 'projects/mirrors/instructions' - - = render 'projects/mirrors/mirror_repos_form', f: f - = render 'projects/mirrors/branch_filter' - - .panel-footer - = f.submit _('Mirror repository'), class: 'js-mirror-submit', name: :update_remote_mirror, pajamas_button: true, data: { qa_selector: 'mirror_repository_button' } - - else - = render Pajamas::AlertComponent.new(dismissible: false) do |c| - - c.with_body do - = _('Mirror settings are only available to GitLab administrators.') - - = render 'projects/mirrors/mirror_repos_list' + .settings-content + = render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card js-toggle-container' }, header_options: { class: 'gl-new-card-header' }, body_options: { class: 'gl-new-card-body gl-px-0' }) do |c| + - c.with_header do + .gl-new-card-title-wrapper + %h5.gl-new-card-title + = _('Mirrored repositories') + .gl-new-card-count + = sprite_icon('earth', css_class: 'gl-mr-2') + %span.js-mirrored-repo-count + = mirrored_repositories_count + .gl-new-card-actions + = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content" }) do + = _('Add new') + - c.with_body do + - if mirror_settings_enabled + .gl-new-card-add-form.gl-m-3.gl-mb-4.gl-display-none.js-toggle-content + %h4.gl-mt-0 + = s_('Profiles|Add new mirror repository') + = gitlab_ui_form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'new-password', data: mirrors_form_data_attributes } do |f| + %div= form_errors(@project) + .form-group.has-feedback + = label_tag :url, _('Git repository URL'), class: 'label-light' + = text_field_tag :url, nil, class: 'form-control gl-form-input js-mirror-url js-repo-url', placeholder: _('Input the remote repository URL'), required: true, pattern: "(#{protocols}):\/\/.+", autocomplete: 'new-password', data: { qa_selector: 'mirror_repository_url_field' } + + = render 'projects/mirrors/instructions' + + = render 'projects/mirrors/mirror_repos_form', f: f + + = render 'projects/mirrors/branch_filter' + + = f.submit _('Mirror repository'), class: 'js-mirror-submit', name: :update_remote_mirror, pajamas_button: true, data: { qa_selector: 'mirror_repository_button' } + + = render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do + = _('Cancel') + + - else + = render Pajamas::AlertComponent.new(dismissible: false) do |c| + - c.with_body do + = _('Mirror settings are only available to GitLab administrators.') + + = render 'projects/mirrors/mirror_repos_list' diff --git a/app/views/projects/mirrors/_mirror_repos_list.html.haml b/app/views/projects/mirrors/_mirror_repos_list.html.haml index 185d86245c53cd..0debd13709dbd9 100644 --- a/app/views/projects/mirrors/_mirror_repos_list.html.haml +++ b/app/views/projects/mirrors/_mirror_repos_list.html.haml @@ -1,49 +1,41 @@ - mirror_settings_enabled = can?(current_user, :admin_remote_mirror, @project) -.panel.panel-default - .table-responsive - - if !@project.mirror? && @project.remote_mirrors.count == 0 - = render Pajamas::CardComponent.new(card_options: { class: 'gl-mt-5' }) do |c| - - c.with_header do - %strong - = _('Mirrored repositories') + ' (0)' - - c.with_body do - = _('There are currently no mirrored repositories.') - - else - %table.table.gl-table.gl-mt-5 - %thead - %tr - %th - = _('Mirrored repositories') - = render_if_exists 'projects/mirrors/mirrored_repositories_count' - %th= _('Direction') - %th= _('Last update attempt') - %th= _('Last successful update') - %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: { qa_selector: 'mirrored_repository_row_container' } } - %td{ data: { qa_selector: '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: { qa_selector: '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', qa_selector: 'mirror_error_badge_content' }, title: html_escape(mirror.last_error.try(:strip)) } - %td.gl-display-flex - - if mirror_settings_enabled - .btn-group.mirror-actions-group{ role: 'group' } - - if mirror.ssh_key_auth? - = clipboard_button(text: mirror.ssh_public_key, class: 'gl-button btn btn-default btn-icon', title: _('Copy SSH public key'), qa_selector: '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' } }) +.table-responsive.gl-mb-0 + - if !@project.mirror? && @project.remote_mirrors.count == 0 + .gl-new-card-empty.gl-px-5.gl-py-4= _('There are currently no mirrored repositories.') + - else + %table.table.b-table.gl-table.b-table-stacked-md + %thead.d-none.d-md-table-header-group + %tr + %th= _('Repository') + %th= _('Direction') + %th= _('Last update attempt') + %th= _('Last successful update') + %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: { qa_selector: 'mirrored_repository_row_container' } } + %td{ data: { qa_selector: '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: { qa_selector: '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', qa_selector: 'mirror_error_badge_content' }, title: html_escape(mirror.last_error.try(:strip)) } + %td + - if mirror_settings_enabled + .btn-group.mirror-actions-group{ role: 'group' } + - if mirror.ssh_key_auth? + = clipboard_button(text: mirror.ssh_public_key, class: 'gl-button btn btn-default btn-icon', title: _('Copy SSH public key'), qa_selector: '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' } }) diff --git a/ee/app/assets/javascripts/pages/projects/settings/repository/show/ee_mirror_repos.js b/ee/app/assets/javascripts/pages/projects/settings/repository/show/ee_mirror_repos.js index b02246d81e139e..9cd088bab99c74 100644 --- a/ee/app/assets/javascripts/pages/projects/settings/repository/show/ee_mirror_repos.js +++ b/ee/app/assets/javascripts/pages/projects/settings/repository/show/ee_mirror_repos.js @@ -141,6 +141,6 @@ export default class EEMirrorRepos extends MirrorRepos { super.removeRow($target); const currentCount = parseInt(this.$repoCount.text().replace(/(\(|\))/, ''), 10); - this.$repoCount.text(`(${currentCount - 1})`); + this.$repoCount.text(`${currentCount - 1}`); } } diff --git a/ee/app/helpers/ee/mirror_helper.rb b/ee/app/helpers/ee/mirror_helper.rb index 7ab3ec074504cb..de87b39feba35b 100644 --- a/ee/app/helpers/ee/mirror_helper.rb +++ b/ee/app/helpers/ee/mirror_helper.rb @@ -35,11 +35,6 @@ def branch_diverged_tooltip_message message.join end - def mirrored_repositories_count(project = @project) - count = project.mirror == true ? 1 : 0 - count + @project.remote_mirrors.to_a.count { |mirror| mirror.enabled } - end - def mirror_branches_text(record) case record.mirror_branches_setting when 'all' diff --git a/ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml b/ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml deleted file mode 100644 index 38831c07d89b3b..00000000000000 --- a/ee/app/views/projects/mirrors/_mirrored_repositories_count.html.haml +++ /dev/null @@ -1 +0,0 @@ -%span.js-mirrored-repo-count (#{mirrored_repositories_count}) diff --git a/ee/app/views/projects/mirrors/_table_pull_row.html.haml b/ee/app/views/projects/mirrors/_table_pull_row.html.haml index f6a3f0e8da5ce3..fc9928294ed9d5 100644 --- a/ee/app/views/projects/mirrors/_table_pull_row.html.haml +++ b/ee/app/views/projects/mirrors/_table_pull_row.html.haml @@ -33,5 +33,6 @@ - else = link_button_to nil, update_now_project_mirror_path(@project), method: :post, class: 'js-force-update-mirror', data: { container: 'body', toggle: 'tooltip', qa_selector: 'update_now_button', testid: 'update-now-button' }, title: _('Update now'), icon: 'retry' = render Pajamas::ButtonComponent.new(variant: :danger, + category: :secondary, icon: 'remove', button_options: { class: 'js-delete-mirror js-delete-pull-mirror', title: _('Remove'), data: { toggle: 'tooltip', container: 'body' } }) diff --git a/ee/spec/features/projects/mirror_spec.rb b/ee/spec/features/projects/mirror_spec.rb index 7161ed4ed0b886..53f7b3a2cf8dff 100644 --- a/ee/spec/features/projects/mirror_spec.rb +++ b/ee/spec/features/projects/mirror_spec.rb @@ -110,6 +110,7 @@ describe 'password authentication' do it 'can be set up' do visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', 'http://user@example.com') @@ -149,6 +150,7 @@ it 'can be recreated after an SSH mirror is set' do visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', 'ssh://user@example.com') @@ -165,6 +167,7 @@ expect(page).to have_content('Mirroring settings were successfully updated') find('.js-delete-pull-mirror').click + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', 'http://git@example.com') @@ -188,6 +191,7 @@ it 'can be set up' do visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', ssh_url) @@ -218,6 +222,7 @@ stub_reactive_cache(cache, known_hosts: key.key_text) visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', ssh_url) @@ -239,6 +244,7 @@ stub_reactive_cache(cache, error: 'Some error text here') visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', ssh_url) @@ -255,6 +261,7 @@ it 'allows manual host keys entry' do visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', ssh_url) @@ -265,6 +272,7 @@ click_without_sidekiq 'Mirror repository' find('.js-delete-mirror').click + click_button('Add new') fill_and_wait_for_mirror_url_javascript('Git repository URL', 'ssh://example.com') select('Pull', from: 'Mirror direction') @@ -278,6 +286,7 @@ describe 'authentication methods' do it 'shows SSH related fields for an SSH URL' do visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', 'ssh://example.com') @@ -303,6 +312,7 @@ it 'hides SSH-related fields for a HTTP URL' do visit project_settings_repository_path(project) + click_button('Add new') page.within('.project-mirror-settings') do fill_and_wait_for_mirror_url_javascript('Git repository URL', 'https://example.com') diff --git a/ee/spec/features/projects/settings/ee/repository_mirrors_settings_spec.rb b/ee/spec/features/projects/settings/ee/repository_mirrors_settings_spec.rb index 7eb3b7c62b4329..9a4bd5699d078b 100644 --- a/ee/spec/features/projects/settings/ee/repository_mirrors_settings_spec.rb +++ b/ee/spec/features/projects/settings/ee/repository_mirrors_settings_spec.rb @@ -18,6 +18,7 @@ stub_licensed_features(repository_mirrors: false) visit project_settings_repository_path(project) + click_button 'Add new' page.within('.project-mirror-settings') do expect(page).to have_selector('#url') @@ -37,6 +38,7 @@ it 'shows pull mirror settings', :js do visit project_settings_repository_path(project) + click_button 'Add new' page.within('.project-mirror-settings') do expect(page).to have_selector('#url') @@ -108,6 +110,7 @@ it 'does not show a pull mirror' do visit project_settings_repository_path(external_project) + click_button 'Add new' expect(page).to have_selector('.js-delete-mirror', count: 0) expect(page).to have_select('Mirror direction', options: %w[Pull Push]) @@ -119,6 +122,7 @@ before do visit project_settings_repository_path(project) + click_button 'Add new' end it 'that mirrors all branches', :js do @@ -184,6 +188,7 @@ before do visit project_settings_repository_path(project) + click_button 'Add new' end it 'that mirrors all branches', :js do diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 869e246f591f24..47f2c892745a20 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -35848,6 +35848,9 @@ msgstr "" msgid "Profiles|Add new email" msgstr "" +msgid "Profiles|Add new mirror repository" +msgstr "" + msgid "Profiles|An error occurred while updating your username, please try again." msgstr "" diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index d53aefe5a4eeef..838ac67ee3dd54 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -156,6 +156,7 @@ before do visit project_settings_repository_path(project) + click_button 'Add new' end it 'shows push mirror settings', :js do -- GitLab