diff --git a/app/assets/javascripts/pages/users/user_tabs.js b/app/assets/javascripts/pages/users/user_tabs.js index 430022f9a9b3f5a4f3f0186544f20a82077abcfa..d368c76b6ccd6b0cfaf11564ab7db4c48d401f7f 100644 --- a/app/assets/javascripts/pages/users/user_tabs.js +++ b/app/assets/javascripts/pages/users/user_tabs.js @@ -194,7 +194,7 @@ export default class UserTabs { this.loadActivityCalendar(); UserTabs.renderMostRecentBlocks('#js-overview .activities-block', { - requestParams: { limit: 10 }, + requestParams: { limit: 15 }, }); UserTabs.renderMostRecentBlocks('#js-overview .projects-block', { requestParams: { limit: 10, skip_pagination: true, skip_namespace: true, compact_mode: true }, diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 2722893d04c32b9fbacaf1b209d5dffaf44e307f..8e0fab04ab29d5875087b87cc1d95193f2a4cb0e 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -10,16 +10,13 @@ $icon-size-diff: $avatar-icon-size - $system-note-icon-size; $system-note-icon-m-top: $avatar-m-top + $icon-size-diff - 1.3rem; $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio; -@mixin vertical-line($left) { - &::before { - content: ''; - border-left: 2px solid var(--gray-50, $gray-50); - position: absolute; - top: 16px; - bottom: 0; - left: calc(#{$left} - 1px); - height: calc(100% + 20px); - } +@mixin vertical-line($top, $left) { + content: ''; + position: absolute; + width: 2px; + left: $left; + top: $top; + height: calc(100% - #{$top}); } @mixin outline-comment() { @@ -32,12 +29,7 @@ $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio; .limited-width-notes { .main-notes-list::before, .timeline-entry:last-child::before { - content: ''; - position: absolute; - width: 2px; - left: 15px; - top: 15px; - height: calc(100% - 15px); + @include vertical-line(15px, 15px); } .main-notes-list::before { @@ -1143,6 +1135,24 @@ $system-note-icon-m-left: $avatar-m-left + $icon-size-diff / $avatar-m-ratio; } } +.user-activity-content { + &::before { + @include vertical-line(80px, 25px); + background: var(--gray-50, $gray-50); + } + + .system-note-image { + @include gl--flex-center; + top: 14px; + width: 22px; + height: 22px; + + svg { + fill: $gray-600 !important; + } + } +} + //This needs to be deleted when Snippet/Commit comments are convered to Vue // See https://gitlab.com/gitlab-org/gitlab-foss/issues/53918#note_117038785 .unstyled-comments { diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 795d35ec81fc15b295a3fb2beebd96b6013507e7..5fb36119fbfdf3391f0380ee162d4c30ae23147e 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -13,7 +13,10 @@ module EventsHelper 'deleted' => 'remove', 'destroyed' => 'remove', 'imported' => 'import', - 'joined' => 'users' + 'joined' => 'users', + 'approved' => 'check', + 'added' => 'upload', + 'removed' => 'remove' }.freeze def localized_action_name_map @@ -242,7 +245,7 @@ def event_note_target_url(event) def event_wiki_title_html(event) capture do - concat content_tag(:span, _('wiki page'), class: "event-target-type gl-mr-2") + concat content_tag(:span, _('wiki page'), class: "event-target-type gl-mr-2 #{user_profile_activity_classes}") concat link_to( event.target_title, event_wiki_page_target_url(event), @@ -254,7 +257,7 @@ def event_wiki_title_html(event) def event_design_title_html(event) capture do - concat content_tag(:span, _('design'), class: "event-target-type gl-mr-2") + concat content_tag(:span, _('design'), class: "event-target-type gl-mr-2 #{user_profile_activity_classes}") concat link_to( event.design.reference_link_text, design_url(event.design), @@ -271,7 +274,7 @@ def event_wiki_page_target_url(event) def event_note_title_html(event) if event.note_target capture do - concat content_tag(:span, event.note_target_type_name, class: "event-target-type gl-mr-2") + concat content_tag(:span, event.note_target_type_name, class: "event-target-type gl-mr-2 #{user_profile_activity_classes}") concat link_to(event.note_target_reference, event_note_target_url(event), title: event.target_title, class: 'has-tooltip event-target-link gl-mr-2') end else @@ -303,19 +306,16 @@ def design_event_icon(action, size: 24) end def icon_for_profile_event(event) - if current_path?('users#show') - content_tag :div, class: "system-note-image #{event.action_name.parameterize}-icon" do - icon_for_event(event.action_name) - end - else - content_tag :div, class: 'system-note-image user-avatar' do - author_avatar(event, size: 32) - end - end + base_class = 'system-note-image' + + classes = current_path?('users#activity') ? "#{event.action_name.parameterize}-icon gl-rounded-full gl-bg-gray-50 gl-line-height-0" : "user-avatar" + content = current_path?('users#activity') ? icon_for_event(event.action_name, size: 14) : author_avatar(event, size: 32) + + tag.div(class: "#{base_class} #{classes}") { content } end def inline_event_icon(event) - unless current_path?('users#show') + unless current_path?('users#activity') content_tag :span, class: "system-note-image-inline d-none d-sm-flex gl-mr-2 #{event.action_name.parameterize}-icon align-self-center" do next design_event_icon(event.action, size: 14) if event.design? @@ -325,13 +325,19 @@ def inline_event_icon(event) end def event_user_info(event) - content_tag(:div, class: "event-user-info") do - concat content_tag(:span, link_to_author(event), class: "author-name") - concat " ".html_safe - concat content_tag(:span, event.author.to_reference, class: "username") + return if current_path?('users#activity') + + tag.div(class: 'event-user-info') do + concat tag.span(link_to_author(event), class: 'author-name') + concat ' '.html_safe + concat tag.span(event.author.to_reference, class: 'username') end end + def user_profile_activity_classes + current_path?('users#activity') ? ' gl-font-weight-semibold gl-text-black-normal' : '' + end + private def design_url(design, opts = {}) diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml index a3be188854d4ff54b17a799772142152c12db548..c28fe7c8330152a1a27f55064febf5e5edf0af85 100644 --- a/app/views/events/_event.html.haml +++ b/app/views/events/_event.html.haml @@ -1,7 +1,7 @@ - event = event.present - if event.visible_to_user?(current_user) - .event-item + .event-item{ class: current_path?('users#activity') ? 'user-profile-activity gl-border-bottom-0 gl-pl-7! gl-pb-3' : '' } .event-item-timestamp.gl-font-sm #{time_ago_with_tooltip(event.created_at)} diff --git a/app/views/events/event/_common.html.haml b/app/views/events/event/_common.html.haml index 7ef3461a7fbf78528bb908ac446736da67d77731..78ce24c429a2cff05ec6c3817ad7ddea43b57bc3 100644 --- a/app/views/events/event/_common.html.haml +++ b/app/views/events/event/_common.html.haml @@ -5,9 +5,9 @@ .event-title.d-flex.flex-wrap = inline_event_icon(event) - if event.target - %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name } + %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes } = localized_action_name(event) - %span.event-target-type.gl-mr-2= event.target_type_name + %span.event-target-type.gl-mr-2{ class: user_profile_activity_classes }= event.target_type_name = link_to event_target_path(event), class: 'has-tooltip event-target-link gl-mr-2', title: event.target_title do = event.target.reference_link_text - unless event.milestone? diff --git a/app/views/events/event/_design.html.haml b/app/views/events/event/_design.html.haml index c1fa1aaca501bda1754712b1581806aa4347bc7a..945c7465ea8ef220f0ededf82e3c64e2cfde9abd 100644 --- a/app/views/events/event/_design.html.haml +++ b/app/views/events/event/_design.html.haml @@ -4,7 +4,7 @@ .event-title.d-flex.flex-wrap = inline_event_icon(event) - %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name } + %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes } = event.action_name = event_design_title_html(event) = render "events/event_scope", event: event diff --git a/app/views/events/event/_note.html.haml b/app/views/events/event/_note.html.haml index 53c59474d833c03cae6b7ac376d4467ef2d2426c..5bbece84e406b4b853a1081e2d78afef31ca736b 100644 --- a/app/views/events/event/_note.html.haml +++ b/app/views/events/event/_note.html.haml @@ -6,7 +6,7 @@ .event-title.d-flex.flex-wrap = inline_event_icon(event) - %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name } + %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes } = event.action_name = event_note_title_html(event) - title = note_target_title(event.target) diff --git a/app/views/events/event/_wiki.html.haml b/app/views/events/event/_wiki.html.haml index cbd5ebcae1224f0c1c9260d90d79dd67dd2a8297..a48c34f80d832f499ebe81d4b382bef75a812d4f 100644 --- a/app/views/events/event/_wiki.html.haml +++ b/app/views/events/event/_wiki.html.haml @@ -4,7 +4,7 @@ .event-title.d-flex.flex-wrap = inline_event_icon(event) - %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name } + %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes } = event.action_name = event_wiki_title_html(event) = render "events/event_scope", event: event diff --git a/app/views/users/_overview.html.haml b/app/views/users/_overview.html.haml index 3649f72c9566b0ffe81493d6a39fd392493163b8..597e7c37388590afe81ee7095d8f319724ea54eb 100644 --- a/app/views/users/_overview.html.haml +++ b/app/views/users/_overview.html.haml @@ -1,4 +1,4 @@ -- activity_pane_class = Feature.enabled?(:security_auto_fix) && @user.bot? ? "col-12" : "col-md-12 col-lg-6" +- activity_pane_class = Feature.enabled?(:security_auto_fix) && @user.bot? ? "col-12" : "col-md-12 col-lg-6 gl-align-self-start" .row.d-none.d-sm-flex .col-12.calendar-block.gl-my-3 @@ -33,7 +33,7 @@ %h4.gl-flex-grow-1 = Feature.enabled?(:security_auto_fix) && @user.bot? ? s_('UserProfile|Bot activity') : s_('UserProfile|Activity') = link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all" - .overview-content-list{ data: { href: user_activity_path, testid: 'user-activity-content' } } + .overview-content-list.user-activity-content{ data: { href: user_activity_path, testid: 'user-activity-content' } } = gl_loading_icon(size: 'md', css_class: 'loading') - unless Feature.enabled?(:security_auto_fix) && @user.bot? diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml index 16b69a4298b4154382af320e0b7fc1931902b3b2..c4a55a7d7ed92827517701cbc968147985438817 100644 --- a/app/views/users/show.html.haml +++ b/app/views/users/show.html.haml @@ -171,13 +171,15 @@ - if profile_tab?(:activity) #activity.tab-pane - .flash-container - - if can?(current_user, :read_cross_project) - %h4.prepend-top-20 - = s_('UserProfile|Most Recent Activity') - .content_list{ data: { href: user_activity_path } } - .loading - = gl_loading_icon(size: 'md') + .row + .col-12 + .flash-container + - if can?(current_user, :read_cross_project) + %h4.prepend-top-20 + = s_('UserProfile|Most Recent Activity') + .content_list.user-activity-content{ data: { href: user_activity_path } } + .loading + = gl_loading_icon(size: 'md') - unless @user.bot? - if profile_tab?(:groups) #groups.tab-pane diff --git a/spec/features/users/overview_spec.rb b/spec/features/users/overview_spec.rb index d1ff60b6069dd0ba905a1804ca217313fc15f642..528c50b8e548879bf23d0c728384d264b896d06e 100644 --- a/spec/features/users/overview_spec.rb +++ b/spec/features/users/overview_spec.rb @@ -61,15 +61,15 @@ def push_code_contribution end end - describe 'user has 11 activities' do + describe 'user has 15 activities' do before do - 11.times { push_code_contribution } + 16.times { push_code_contribution } end include_context 'visit overview tab' - it 'displays 10 entries in the list of activities' do - expect(find('#js-overview')).to have_selector('.event-item', count: 10) + it 'displays 15 entries in the list of activities' do + expect(find('#js-overview')).to have_selector('.event-item', count: 15) end it 'shows a link to the activity list' do diff --git a/spec/helpers/events_helper_spec.rb b/spec/helpers/events_helper_spec.rb index 6ffca87636120ca218d5212c31cd3a740cffb97b..2b677b0978184cec7b12b5391a306ddc2eb0186a 100644 --- a/spec/helpers/events_helper_spec.rb +++ b/spec/helpers/events_helper_spec.rb @@ -39,6 +39,69 @@ end end + describe '#icon_for_profile_event' do + let(:event) { build(:event, :joined) } + let(:users_activity_page?) { true } + + before do + allow(helper).to receive(:current_path?).and_call_original + allow(helper).to receive(:current_path?).with('users#activity').and_return(users_activity_page?) + end + + context 'when on users activity page' do + it 'gives an icon with specialized classes' do + result = helper.icon_for_profile_event(event) + + expect(result).to include('joined-icon') + expect(result).to include('wiki page", + "wiki page", + "", + title, + "" + ].join + + expect(helper.event_wiki_title_html(event)).to eq(html) + end + + it 'produces a suitable title chunk on the user profile' do + allow(helper).to receive(:user_profile_activity_classes).and_return( + 'gl-font-weight-semibold gl-text-black-normal') + + html = [ + "wiki page", "", title, "" @@ -441,5 +518,28 @@ def can_read_design_activity(object, ability) end end end + + describe '#user_profile_activity_classes' do + let(:users_activity_page?) { true } + + before do + allow(helper).to receive(:current_path?).and_call_original + allow(helper).to receive(:current_path?).with('users#activity').and_return(users_activity_page?) + end + + context 'when on the user activity page' do + it 'returns the expected class names' do + expect(helper.user_profile_activity_classes).to eq(' gl-font-weight-semibold gl-text-black-normal') + end + end + + context 'when not on the user activity page' do + let(:users_activity_page?) { false } + + it 'returns an empty string' do + expect(helper.user_profile_activity_classes).to eq('') + end + end + end end # rubocop:enable RSpec/FactoryBot/AvoidCreate