diff --git a/app/views/profiles/gpg_keys/_form.html.haml b/app/views/profiles/gpg_keys/_form.html.haml index ffd8bc3de27e179fc3a05c010c0f8d1549c28cb2..2bc977feb24cae3bf123bf347e0f2ae25cf7e63b 100644 --- a/app/views/profiles/gpg_keys/_form.html.haml +++ b/app/views/profiles/gpg_keys/_form.html.haml @@ -8,3 +8,5 @@ .gl-mt-3 = f.submit s_('Profiles|Add key'), pajamas_button: true + = render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do + = _('Cancel') diff --git a/app/views/profiles/gpg_keys/_key.html.haml b/app/views/profiles/gpg_keys/_key.html.haml index d8b8dda29dce51673ca0e36fedb972314efbddae..f8520cb430dab983d056578d58c1231908248bdd 100644 --- a/app/views/profiles/gpg_keys/_key.html.haml +++ b/app/views/profiles/gpg_keys/_key.html.haml @@ -1,24 +1,29 @@ -%li.key-list-item - .float-left.gl-mr-3 - = sprite_icon('key', css_class: "settings-list-icon d-none d-sm-block gl-mt-4") - .key-list-item-info +%tr.key-list-item + %td{ data: { label: s_('Profiles|Key') } } + %div{ class: 'gl-display-flex! gl-pl-0!' } + = sprite_icon('key', css_class: "settings-list-icon d-none d-sm-inline gl-mr-2") + .gl-display-flex.gl-flex-direction-column.gl-text-truncate + %p.gl-text-truncate.gl-m-0 + %code= key.fingerprint + - if key.subkeys.present? + .subkeys.gl-mt-3{ class: 'gl-text-left!' } + %span.gl-font-sm + = _('Subkeys:') + %ul.subkeys-list + - key.subkeys.each do |subkey| + %li + %p.gl-text-truncate.gl-m-0 + %code= subkey.fingerprint + + %td{ data: { label: _('Status') } } - key.emails_with_verified_status.map do |email, verified| - = render partial: 'shared/email_with_badge', locals: { email: email, verified: verified } + %div{ class: 'gl-text-left!' } + = render partial: 'shared/email_with_badge', locals: { email: email, verified: verified } + + %td{ data: { label: _('Created') } } + = html_escape(s_('Created %{time_ago}')) % { time_ago: time_ago_with_tooltip(key.created_at) } - %span.text-truncate - %code= key.fingerprint - - if key.subkeys.present? - .subkeys - %span.bold - = _('Subkeys') - = ':' - %ul.subkeys-list - - key.subkeys.each do |subkey| - %li - %code= subkey.fingerprint - .float-right - %span.key-created-at - = html_escape(s_('Profiles|Created %{time_ago}')) % { time_ago: time_ago_with_tooltip(key.created_at) } - = link_button_to nil, profile_gpg_key_path(key), data: { confirm: _('Are you sure? Removing this GPG key does not affect already signed commits.') }, method: :delete, class: 'gl-ml-3', variant: :danger, icon: 'remove', 'aria-label': _('Remove') - = link_button_to revoke_profile_gpg_key_path(key), data: { confirm: _('Are you sure? All commits that were signed with this GPG key will be unverified.') }, method: :put, class: 'gl-ml-3', variant: :danger, 'aria-label': _('Revoke') do + %td{ class: 'gl-py-3!', data: { label: _('Actions') } } + = link_button_to nil, profile_gpg_key_path(key), data: { confirm: _('Are you sure? Removing this GPG key does not affect already signed commits.'), confirm_btn_variant: 'danger' }, method: :delete, class: 'has-tooltip', icon: 'remove', category: :secondary, 'title': _('Remove'), 'aria-label': _('Remove') + = link_button_to revoke_profile_gpg_key_path(key), data: { confirm: _('Are you sure? All commits that were signed with this GPG key will be unverified.'), confirm_btn_variant: 'danger' }, method: :put, class: 'gl-ml-3', category: :secondary, variant: :danger, 'aria-label': _('Revoke') do = _('Revoke') diff --git a/app/views/profiles/gpg_keys/_key_table.html.haml b/app/views/profiles/gpg_keys/_key_table.html.haml index ebbd1c8f67233298b1ac8a36bb9356e7a7446031..0a50ce55b5031464c39f2346808e3297dc944d59 100644 --- a/app/views/profiles/gpg_keys/_key_table.html.haml +++ b/app/views/profiles/gpg_keys/_key_table.html.haml @@ -1,10 +1,19 @@ - is_admin = local_assigns.fetch(:admin, false) +- hide_class = local_assigns.fetch(:hide_class, false) - if @gpg_keys.any? - %ul.content-list - = render partial: 'profiles/gpg_keys/key', collection: @gpg_keys, locals: { is_admin: is_admin } + .table-holder + %table.table.b-table.gl-table.b-table-stacked-md.gl-mt-n1.gl-mb-n2.ssh-keys-list{ data: { qa_selector: 'ssh_keys_list' } } + %thead.d-none.d-md-table-header-group + %tr + %th= s_('Profiles|Key') + %th= _('Status') + %th= _('Created') + %th= _('Actions') + = render partial: 'profiles/gpg_keys/key', collection: @gpg_keys, locals: { is_admin: is_admin } + - else - %p.settings-message.text-center + %p.gl-new-card-empty.gl-px-5.gl-py-4.js-toggle-content{ class: hide_class } - if is_admin = _('There are no GPG keys associated with this account.') - else diff --git a/app/views/profiles/gpg_keys/index.html.haml b/app/views/profiles/gpg_keys/index.html.haml index 2dfd6c7860f8255c40a7addf68b116ea8943a637..7e38771d81d794fc67e485ada30f9b8fe3c0ce27 100644 --- a/app/views/profiles/gpg_keys/index.html.haml +++ b/app/views/profiles/gpg_keys/index.html.haml @@ -1,6 +1,8 @@ - page_title _('GPG Keys') - add_page_specific_style 'page_bundles/profile' - @force_desktop_expanded_sidebar = true +- add_form_class = 'gl-display-none' if !form_errors(@gpg_key) +- hide_class = 'gl-display-none' if form_errors(@gpg_key) .settings-section.js-search-settings-section .settings-sticky-header @@ -10,17 +12,24 @@ %p.gl-text-secondary = _('GPG keys allow you to verify signed commits.') - %h5.gl-font-lg.gl-mt-0 - = _('Add a GPG key') - %p - - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') } - = _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more%{help_link_end}.').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe } - = render 'form' + = 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 + %h3.gl-new-card-title + = _('Your GPG keys') + .gl-new-card-count + = sprite_icon('key', css_class: 'gl-mr-2') + = @gpg_keys.count + .gl-new-card-actions + = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content #{hide_class}" }) do + = _('Add a GPG key') + - c.with_body do + .gl-new-card-add-form.gl-m-3.js-toggle-content{ class: add_form_class } + %h4.gl-mt-0 + = _('Add a GPG key') + %p + - help_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_path('user/project/repository/gpg_signed_commits/index.md') } + = _('Add a GPG key for secure access to GitLab. %{help_link_start}Learn more%{help_link_end}.').html_safe % {help_link_start: help_link_start, help_link_end: '</a>'.html_safe } + = render 'form' -.settings-section.js-search-settings-section - .settings-sticky-header - .settings-sticky-header-inner - %h4.gl-my-0 - = _('Your GPG keys (%{count})') % { count: @gpg_keys.count } - .gl-mb-3 - = render 'key_table' + = render 'key_table', hide_class: hide_class diff --git a/app/views/shared/_email_with_badge.html.haml b/app/views/shared/_email_with_badge.html.haml index a1398f85513d9db75232ea3b5dc507d291893d7c..14201c0d23a5f39101d69eb3969b7b0e1b1f273c 100644 --- a/app/views/shared/_email_with_badge.html.haml +++ b/app/views/shared/_email_with_badge.html.haml @@ -1,6 +1,7 @@ - variant = verified ? :success : :danger - text = verified ? _('Verified') : _('Unverified') -%span.gl-mr-3 - = email +- if email + %span.gl-mr-2 + = email = gl_badge_tag text, { variant: variant, size: :sm } diff --git a/locale/gitlab.pot b/locale/gitlab.pot index d74a9ee1a75189b1461050fb76e7926c071e9ea1..910c33da5b8d3401acc25b88ee81fca6afb09403 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -13519,6 +13519,9 @@ msgstr "" msgid "Created %{timeAgo} by %{author}" msgstr "" +msgid "Created %{time_ago}" +msgstr "" + msgid "Created %{timestamp}" msgstr "" @@ -35415,9 +35418,6 @@ msgstr "" msgid "Profiles|Control emails linked to your account" msgstr "" -msgid "Profiles|Created %{time_ago}" -msgstr "" - msgid "Profiles|Created%{time_ago}" msgstr "" @@ -44774,7 +44774,7 @@ msgstr "" msgid "Subject Key Identifier:" msgstr "" -msgid "Subkeys" +msgid "Subkeys:" msgstr "" msgid "Submit" @@ -53549,7 +53549,7 @@ msgstr "" msgid "Your Free top-level group, %{group_name}, has more than %{free_users_limit} users and uses more than %{free_storage_limit} of data. After usage limits are applied to Free top-level groups, projects in this group will be in a %{read_only_link_start}read-only state%{link_end}. You should reduce the number of users or upgrade to a paid tier %{strong_start}before%{strong_end} you manage your storage usage. Otherwise, your Free top-level group will become read-only immediately because the 5-user limit applies. For more information, see our %{faq_link_start}FAQ%{link_end}." msgstr "" -msgid "Your GPG keys (%{count})" +msgid "Your GPG keys" msgstr "" msgid "Your GitLab Ultimate free trial lasts for 30 days. After this period, you can maintain a GitLab Free account forever or upgrade to a paid plan." diff --git a/spec/features/profiles/gpg_keys_spec.rb b/spec/features/profiles/gpg_keys_spec.rb index f39d9ddaf5615448157cce3bc3754da544afb000..3adda251e40f6f977d0ecdbe5e9241510e8fbd65 100644 --- a/spec/features/profiles/gpg_keys_spec.rb +++ b/spec/features/profiles/gpg_keys_spec.rb @@ -15,6 +15,7 @@ end it 'saves the new key' do + click_button('Add a GPG key') fill_in('Key', with: GpgHelpers::User2.public_key) click_button('Add key') @@ -24,6 +25,7 @@ end it 'with multiple subkeys' do + click_button('Add a GPG key') fill_in('Key', with: GpgHelpers::User3.public_key) click_button('Add key') @@ -52,7 +54,10 @@ click_link('Remove') - expect(page).to have_content('Your GPG keys (0)') + expect(page).to have_content('Your GPG keys') + page.within('.gl-new-card-count') do + expect(page).to have_content('0') + end end it 'user revokes a key via the key index' do @@ -63,7 +68,10 @@ click_link('Revoke') - expect(page).to have_content('Your GPG keys (0)') + expect(page).to have_content('Your GPG keys') + page.within('.gl-new-card-count') do + expect(page).to have_content('0') + end expect(gpg_signature.reload).to have_attributes( verification_status: 'unknown_key',