From 254e375a19cbb82f90613dec5cc6ae7a8dff293e Mon Sep 17 00:00:00 2001 From: Peter Hegman <phegman@gitlab.com> Date: Wed, 4 Sep 2024 22:52:49 +0000 Subject: [PATCH] Revert "Merge branch 'refactor-avatars' into 'master'" This reverts merge request !163899 --- .../boards/components/board_list_header.vue | 13 +- .../diffs/components/commit_item.vue | 2 +- app/assets/javascripts/gfm_auto_complete.js | 6 +- .../components/assignees/assignee_avatar.vue | 14 +- .../components/reviewers/reviewer_avatar.vue | 13 +- app/assets/javascripts/users_select/index.js | 6 +- .../components/mr_widget_author.vue | 7 +- .../components/sidebar/sidebar_assignees.vue | 4 +- app/assets/stylesheets/components/avatar.scss | 168 +++++++++++++++++- .../stylesheets/framework/dropdowns.scss | 4 - app/assets/stylesheets/framework/lists.scss | 12 ++ .../page_bundles/_ide_theme_overrides.scss | 10 ++ app/assets/stylesheets/page_bundles/ide.scss | 5 + .../stylesheets/page_bundles/projects.scss | 10 ++ app/assets/stylesheets/pages/groups.scss | 9 + .../themes/dark_mode_overrides.scss | 1 + app/assets/stylesheets/vendors/atwho.scss | 4 + app/helpers/avatars_helper.rb | 2 +- app/helpers/projects_helper.rb | 2 +- app/helpers/sidebars_helper.rb | 2 +- app/helpers/wiki_page_version_helper.rb | 4 + app/views/projects/commits/_commit.html.haml | 6 +- .../issuable/_user_dropdown_item.html.haml | 2 +- .../shared/milestones/_issuable.html.haml | 2 +- .../billings/_billing_plan_header.html.haml | 2 +- .../billings/_billing_plans_layout.html.haml | 2 +- .../users/_user_detail.html.haml | 6 +- lib/banzai/filter/commit_trailers_filter.rb | 2 +- spec/frontend/gfm_auto_complete_spec.js | 9 +- .../groups/components/group_item_spec.js | 5 +- .../assignees/assignee_avatar_spec.js | 3 +- .../components/assignees/assignees_spec.js | 20 +-- .../components/mr_widget_author_spec.js | 5 +- .../sidebar/alert_sidebar_assignees_spec.js | 4 +- spec/helpers/avatars_helper_spec.rb | 24 +-- spec/helpers/projects_helper_spec.rb | 4 +- spec/helpers/wiki_page_version_helper_spec.rb | 14 ++ 37 files changed, 316 insertions(+), 92 deletions(-) diff --git a/app/assets/javascripts/boards/components/board_list_header.vue b/app/assets/javascripts/boards/components/board_list_header.vue index e79013324f233..20457f60adf4b 100644 --- a/app/assets/javascripts/boards/components/board_list_header.vue +++ b/app/assets/javascripts/boards/components/board_list_header.vue @@ -1,6 +1,5 @@ <script> import { - GlAvatar, GlButton, GlButtonGroup, GlLabel, @@ -40,7 +39,6 @@ export default { ), }, components: { - GlAvatar, GlButton, GlButtonGroup, GlLabel, @@ -361,18 +359,17 @@ export default { 'gl-mt-3 gl-rotate-90': list.collapsed, }" > - <gl-avatar + <img v-gl-tooltip.hover.bottom :title="listAssignee" - :label="list.assignee.name" + :alt="list.assignee.name" :src="list.assignee.avatarUrl" - :entity-name="list.assignee.name" - :size="24" - class="gl-mr-3" + class="avatar s20" + height="20" + width="20" /> </a> <!-- EE end --> - <div class="board-title-text" :class="{ diff --git a/app/assets/javascripts/diffs/components/commit_item.vue b/app/assets/javascripts/diffs/components/commit_item.vue index 01bdd67046ce9..181a76be1beea 100644 --- a/app/assets/javascripts/diffs/components/commit_item.vue +++ b/app/assets/javascripts/diffs/components/commit_item.vue @@ -125,7 +125,7 @@ export default { :img-src="authorAvatar" :img-alt="authorName" :img-size="32" - class="gl-my-2 gl-mr-4 gl-hidden gl-self-start sm:gl-block" + class="avatar-cell gl-my-2 gl-mr-4 gl-hidden sm:gl-block" /> </div> <div diff --git a/app/assets/javascripts/gfm_auto_complete.js b/app/assets/javascripts/gfm_auto_complete.js index 0d4b182b2a21f..d67fa85fe81d8 100644 --- a/app/assets/javascripts/gfm_auto_complete.js +++ b/app/assets/javascripts/gfm_auto_complete.js @@ -110,9 +110,9 @@ export function membersBeforeSave(members) { const autoCompleteAvatar = member.avatar_url || member.username.charAt(0).toUpperCase(); - const avatarShapeClass = member.type === GROUP_TYPE ? '' : 'gl-avatar-circle'; - const imgAvatar = `<img src="${member.avatar_url}" alt="${member.username}" class="gl-avatar gl-avatar-s24 gl-mr-2 ${avatarShapeClass}"/>`; - const txtAvatar = `<div class="gl-avatar gl-avatar-s24 gl-mr-2 gl-justify-center gl-items-center ${avatarShapeClass}">${autoCompleteAvatar}</div>`; + const rectAvatarClass = member.type === GROUP_TYPE ? 'rect-avatar' : ''; + const imgAvatar = `<img src="${member.avatar_url}" alt="${member.username}" class="avatar ${rectAvatarClass} avatar-inline s24 gl-mr-2"/>`; + const txtAvatar = `<div class="avatar ${rectAvatarClass} avatar-inline s24 gl-mr-2">${autoCompleteAvatar}</div>`; const avatarIcon = member.mentionsDisabled ? spriteIcon('notifications-off', 's16 vertical-align-middle gl-ml-2') : ''; diff --git a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue index 69d19b54e7bea..81fc226762263 100644 --- a/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue +++ b/app/assets/javascripts/sidebar/components/assignees/assignee_avatar.vue @@ -1,11 +1,10 @@ <script> -import { GlAvatar, GlIcon } from '@gitlab/ui'; +import { GlIcon } from '@gitlab/ui'; import { TYPE_ISSUE, TYPE_MERGE_REQUEST } from '~/issues/constants'; import { __, sprintf } from '~/locale'; export default { components: { - GlAvatar, GlIcon, }, props: { @@ -44,12 +43,13 @@ export default { </script> <template> - <span class="gl-relative"> - <gl-avatar - :label="user.name" - :src="avatarUrl" - :size="imgSize" + <span class="position-relative"> + <img :alt="assigneeAlt" + :src="avatarUrl" + :width="imgSize" + :class="`s${imgSize}`" + class="avatar avatar-inline m-0" data-testid="avatar-image" /> <gl-icon v-if="hasMergeIcon" name="warning-solid" aria-hidden="true" class="merge-icon" /> diff --git a/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue b/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue index 39e37591a79ac..f93d22b411e46 100644 --- a/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue +++ b/app/assets/javascripts/sidebar/components/reviewers/reviewer_avatar.vue @@ -1,12 +1,11 @@ <script> // NOTE! For the first iteration, we are simply copying the implementation of Assignees // It will soon be overhauled in Issue https://gitlab.com/gitlab-org/gitlab/-/issues/233736 -import { GlAvatar, GlIcon } from '@gitlab/ui'; +import { GlIcon } from '@gitlab/ui'; import { __, sprintf } from '~/locale'; export default { components: { - GlAvatar, GlIcon, }, props: { @@ -34,8 +33,14 @@ export default { </script> <template> - <span class="gl-relative"> - <gl-avatar :label="user.name" :src="avatarUrl" :size="imgSize" :alt="reviewerAlt" /> + <span class="position-relative"> + <img + :alt="reviewerAlt" + :src="avatarUrl" + :width="imgSize" + :class="`s${imgSize}`" + class="avatar avatar-inline m-0" + /> <gl-icon v-if="hasMergeIcon" name="warning-solid" diff --git a/app/assets/javascripts/users_select/index.js b/app/assets/javascripts/users_select/index.js index 9ad89bdecf829..acf9bec8c8f7e 100644 --- a/app/assets/javascripts/users_select/index.js +++ b/app/assets/javascripts/users_select/index.js @@ -252,12 +252,12 @@ function UsersSelect(currentUser, els, options = {}) { }); }; collapsedAssigneeTemplate = template( - `<% if( avatar ) { %> <a class="author-link" href="/<%- username %>"> <img width="24" class="gl-avatar gl-avatar-circle gl-avatar-s24" alt="" src="<%- avatar %>"> </a> <% } else { %> ${spriteIcon( + `<% if( avatar ) { %> <a class="author-link" href="/<%- username %>"> <img width="24" class="avatar avatar-inline s24" alt="" src="<%- avatar %>"> </a> <% } else { %> ${spriteIcon( 'user', )} <% } %>`, ); assigneeTemplate = template( - `<% if (username) { %> <a class="author-link gl-font-bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="gl-avatar gl-avatar-circle gl-avatar-s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> + `<% if (username) { %> <a class="author-link gl-font-bold" href="/<%- username %>"> <% if( avatar ) { %> <img width="32" class="avatar avatar-inline s32" alt="" src="<%- avatar %>"> <% } %> <span class="author"><%- name %></span> <span class="username"> @<%- username %> </span> </a> <% } else { %> <span class="no-value assign-yourself"> ${sprintf(s__('UsersSelect|No assignee - %{openingTag} assign yourself %{closingTag}'), { openingTag: '<a href="#" class="js-assign-yourself">', closingTag: '</a>', @@ -637,7 +637,7 @@ function UsersSelect(currentUser, els, options = {}) { )}</a></li>`; } else { // 0 margin, because it's now handled by a wrapper - img = `<img src='${avatar}' class='gl-avatar gl-avatar-circle gl-avatar-s32 !gl-m-0' width='32' />`; + img = `<img src='${avatar}' class='avatar avatar-inline !gl-m-0' width='32' />`; } return userSelect.renderRow( diff --git a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.vue b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.vue index e3b85e8acb4bc..79ea2624ec510 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/mr_widget_author.vue @@ -1,10 +1,9 @@ <script> -import { GlAvatar, GlTooltipDirective, GlLink } from '@gitlab/ui'; +import { GlTooltipDirective, GlLink } from '@gitlab/ui'; export default { name: 'MrWidgetAuthor', components: { - GlAvatar, GlLink, }, directives: { @@ -38,9 +37,9 @@ export default { :title="showAuthorName ? null : author.name" class="mr-widget-author" > - <gl-avatar :src="avatarUrl" :size="16" :alt="author.name" /><span + <img :src="avatarUrl" :alt="author.name" class="avatar avatar-inline s16" /><span v-if="showAuthorName" - class="author gl-ml-2" + class="author" >{{ author.name }}</span > </gl-link> diff --git a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue index 237b09bc8a16a..0bf84661b10ec 100644 --- a/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue +++ b/app/assets/javascripts/vue_shared/alert_details/components/sidebar/sidebar_assignees.vue @@ -10,7 +10,6 @@ import { GlTooltip, GlButton, GlSprintf, - GlAvatar, } from '@gitlab/ui'; import { debounce } from 'lodash'; import axios from '~/lib/utils/axios_utils'; @@ -44,7 +43,6 @@ export default { GlTooltip, GlButton, GlSprintf, - GlAvatar, SidebarAssignee, }, props: { @@ -284,7 +282,7 @@ export default { > <div v-if="userName" class="gl-mt-2 gl-inline-flex" data-testid="assigned-users"> <span class="gl-relative gl-mr-4"> - <gl-avatar :src="userImg" :size="32" :alt="userName" /> + <img :alt="userName" :src="userImg" :width="32" class="avatar avatar-inline s32 gl-m-0" /> </span> <span class="gl-flex gl-flex-col gl-overflow-hidden"> <strong class="dropdown-menu-user-full-name"> diff --git a/app/assets/stylesheets/components/avatar.scss b/app/assets/stylesheets/components/avatar.scss index 7de9bffca8b70..561097edbe670 100644 --- a/app/assets/stylesheets/components/avatar.scss +++ b/app/assets/stylesheets/components/avatar.scss @@ -1,8 +1,86 @@ -// Left over of avatar. Still used in email templates. -.avatar { +$avatar-sizes: ( + 16: ( + font-size: 10px, + line-height: 16px, + border-radius: $border-radius-small + ), + 18: ( + border-radius: $border-radius-small + ), + 20: ( + border-radius: $border-radius-small + ), + 24: ( + font-size: 12px, + line-height: 24px, + border-radius: $gl-border-radius-base + ), + 26: ( + font-size: 20px, + line-height: 1.33, + border-radius: $gl-border-radius-base + ), + 32: ( + font-size: 14px, + line-height: 32px, + border-radius: $gl-border-radius-base + ), + 40: ( + font-size: 16px, + line-height: 38px, + border-radius: $gl-border-radius-base + ), + 48: ( + font-size: 20px, + line-height: 48px, + border-radius: $border-radius-large + ), + 60: ( + font-size: 32px, + line-height: 60px, + border-radius: $border-radius-large + ), + 64: ( + font-size: 28px, + line-height: 64px, + border-radius: $border-radius-large + ), + 90: ( + font-size: 36px, + line-height: 90px, + border-radius: $border-radius-large + ), + 96: ( + font-size: 36px, + line-height: 94px, + border-radius: $border-radius-large + ), + 100: ( + font-size: 36px, + line-height: 98px, + border-radius: $border-radius-large + ), + 160: ( + font-size: 96px, + line-height: 158px, + border-radius: $border-radius-large + ) +); + +.avatar, +.avatar-container { float: left; margin-right: $gl-padding; border-radius: $avatar-radius; + + @each $size, $size-config in $avatar-sizes { + &.s#{$size} { + @include avatar-size(#{$size}px, if($size < 48, 8px, 16px)); + } + } +} + +.avatar { transition-property: none; width: 40px; height: 40px; @@ -11,6 +89,18 @@ overflow: hidden; box-shadow: inset 0 0 0 1px var(--gl-avatar-border-color-default); + &.avatar-inline { + float: none; + display: inline-block; + margin-left: 2px; + flex-shrink: 0; + + &.s16, + &.s24 { + margin-right: 4px; + } + } + &.center { font-size: 14px; line-height: 1.8em; @@ -23,6 +113,80 @@ } } +.identicon { + text-align: center; + vertical-align: top; + color: var(--gl-text-color-strong); + background-color: var(--gl-avatar-fallback-background-color-neutral); + + // Sizes + @each $size, $size-config in $avatar-sizes { + $keys: map-keys($size-config); + + &.s#{$size} { + @each $key in $keys { + // We don't want `border-radius` to be included here. + @if ($key != 'border-radius') { + #{$key}: map-get($size-config, #{$key}); + } + } + } + } + + // Background colors + @for $i from 1 through length($gl-avatar-identicon-bgs) { + &.bg#{$i} { + color: nth($gl-avatar-identicon-texts, $i); + background-color: nth($gl-avatar-identicon-bgs, $i); + } + } +} + +.avatar-container { + overflow: hidden; + display: flex; + + a { + width: 100%; + height: 100%; + display: flex; + text-decoration: none; + } + + .avatar { + border-radius: 0; + border: 0; + height: auto; + width: 100%; + margin: 0; + align-self: center; + } + + &.s40 { + min-width: 40px; + min-height: 40px; + } + + &.s64 { + min-width: 64px; + min-height: 64px; + } +} + +.rect-avatar { + border-radius: $border-radius-small; + + @each $size, $size-config in $avatar-sizes { + &.s#{$size} { + border-radius: map-get($size-config, 'border-radius'); + + .avatar { + border-radius: map-get($size-config, 'border-radius'); + } + } + } +} + .avatar-counter { @include avatar-counter(); } diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss index 2a0f1ad2ac65b..128755d59e884 100644 --- a/app/assets/stylesheets/framework/dropdowns.scss +++ b/app/assets/stylesheets/framework/dropdowns.scss @@ -505,10 +505,6 @@ top: calc(50% + 5px); left: 3rem; } - - .gl-avatar { - margin-right: 0; - } } } diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss index f81f47a7ecd06..c53e376e53e90 100644 --- a/app/assets/stylesheets/framework/lists.scss +++ b/app/assets/stylesheets/framework/lists.scss @@ -164,6 +164,10 @@ ul.content-list { .badge-secondary { color: $gl-text-color-secondary; } + + .avatar-cell { + align-self: flex-start; + } } ul.content-list.content-list-items-padding > li, @@ -190,6 +194,14 @@ ul.controls { &:last-child { margin-right: 0; } + + .author-link { + .avatar-inline { + margin-left: 0; + margin-right: 0; + margin-bottom: 0; + } + } } .issuable-pipeline-broken a, diff --git a/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss b/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss index d915e22773c15..7bf86242cad93 100644 --- a/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss +++ b/app/assets/stylesheets/page_bundles/_ide_theme_overrides.scss @@ -172,6 +172,16 @@ .gl-tabs-nav li a.gl-tab-nav-item-active { box-shadow: inset 0 -2px 0 0 var(--ide-highlight-accent, $gl-text-color); } + + // for other themes, suppress different avatar default colors for simplicity + .avatar-container { + &, + .avatar { + color: var(--ide-text-color, $gl-text-color); + background-color: var(--ide-highlight-background, $white); + border-color: var(--ide-highlight-background, rgba($black, $gl-avatar-border-opacity)); + } + } } input[type='text'], diff --git a/app/assets/stylesheets/page_bundles/ide.scss b/app/assets/stylesheets/page_bundles/ide.scss index c0bafd314a917..382fb0db134ee 100644 --- a/app/assets/stylesheets/page_bundles/ide.scss +++ b/app/assets/stylesheets/page_bundles/ide.scss @@ -863,6 +863,11 @@ $ide-commit-header-height: 48px; } .ide-context-header { + .avatar-container { + flex: 0 0 auto; + margin-right: 0; + } + .ide-sidebar-project-title { margin-left: $ide-tree-text-start - $ide-project-avatar-end; } diff --git a/app/assets/stylesheets/page_bundles/projects.scss b/app/assets/stylesheets/page_bundles/projects.scss index 2d5a08712898c..483a3e427bc61 100644 --- a/app/assets/stylesheets/page_bundles/projects.scss +++ b/app/assets/stylesheets/page_bundles/projects.scss @@ -372,6 +372,16 @@ table-layout: fixed; } + .avatar-container { + @include avatar-size(40px, 10px); + min-height: 40px; + min-width: 40px; + + .identicon.s48 { + font-size: 16px; + } + } + .updated-note { @include media-breakpoint-up(sm) { margin-top: $gl-spacing-scale-2; diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss index 6ebe8f86162e9..c873d1bac030c 100644 --- a/app/assets/stylesheets/pages/groups.scss +++ b/app/assets/stylesheets/pages/groups.scss @@ -140,6 +140,15 @@ table.pipeline-project-metrics tr td { flex-basis: 100%; } + .avatar-container { + flex-shrink: 0; + + > a { + width: 100%; + text-decoration: none; + } + } + .title { font-size: $gl-font-size; } diff --git a/app/assets/stylesheets/themes/dark_mode_overrides.scss b/app/assets/stylesheets/themes/dark_mode_overrides.scss index 60c96d09260dc..55c47ddb5847d 100644 --- a/app/assets/stylesheets/themes/dark_mode_overrides.scss +++ b/app/assets/stylesheets/themes/dark_mode_overrides.scss @@ -65,6 +65,7 @@ } .gl-avatar:not(.gl-avatar-identicon), +.avatar-container, .avatar { background: rgba($gray-950, 0.04); } diff --git a/app/assets/stylesheets/vendors/atwho.scss b/app/assets/stylesheets/vendors/atwho.scss index e3684dc3d324d..ef4eddbcba588 100644 --- a/app/assets/stylesheets/vendors/atwho.scss +++ b/app/assets/stylesheets/vendors/atwho.scss @@ -21,6 +21,10 @@ margin-top: $gl-spacing-scale-2; } + .avatar-inline { + margin-bottom: 0; + } + .has-warning { .description { color: $gray-900; diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb index e3c60a7a12d89..599978af0a928 100644 --- a/app/helpers/avatars_helper.rb +++ b/app/helpers/avatars_helper.rb @@ -94,7 +94,7 @@ def user_avatar_without_link(options = {}) has_tooltip = options[:has_tooltip].nil? ? true : options[:has_tooltip] data_attributes = options[:data] || {} - css_class = %W[gl-avatar gl-avatar-circle gl-avatar-s#{avatar_size}].push(*options[:css_class]) + css_class = %W[avatar s#{avatar_size}].push(*options[:css_class]) alt_text = user_name ? "#{user_name}'s avatar" : "default avatar" if has_tooltip diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index 4b5b5131567b8..ba29d0e8977fa 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -29,7 +29,7 @@ def link_to_member_avatar(author, opts = {}) default_opts = { size: 16 } opts = default_opts.merge(opts) - classes = %W[gl-avatar gl-avatar-circle gl-avatar-s#{opts[:size]}] + classes = %W[avatar avatar-inline s#{opts[:size]}] classes << opts[:avatar_class] if opts[:avatar_class] avatar = avatar_icon_for_user(author, opts[:size]) diff --git a/app/helpers/sidebars_helper.rb b/app/helpers/sidebars_helper.rb index 492c22fde0890..929da0b2cf58a 100644 --- a/app/helpers/sidebars_helper.rb +++ b/app/helpers/sidebars_helper.rb @@ -9,7 +9,7 @@ def sidebar_tracking_attributes_by_object(object) end def scope_avatar_classes(object) - %w[gl-avatar gl-avatar-s32].tap do |klasses| + %w[avatar-container rect-avatar s32].tap do |klasses| klass = sidebar_attributes_for_object(object).fetch(:scope_avatar_class, nil) klasses << klass if klass end diff --git a/app/helpers/wiki_page_version_helper.rb b/app/helpers/wiki_page_version_helper.rb index 577b6252b0fbb..34864fddc9250 100644 --- a/app/helpers/wiki_page_version_helper.rb +++ b/app/helpers/wiki_page_version_helper.rb @@ -7,4 +7,8 @@ def wiki_page_version_author_url(wiki_page_version) user = wiki_page_version.author user.nil? ? "mailto:#{wiki_page_version.author_email}" : Gitlab::UrlBuilder.build(user) end + + def wiki_page_version_author_avatar(wiki_page_version) + image_tag(avatar_icon_for_email(wiki_page_version.author_email, 24), class: "avatar s24 float-none !gl-mr-0") + end end diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index a07d147b76c5c..24444743575d9 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -24,8 +24,8 @@ - add_page_specific_style 'page_bundles/commit_description' %li{ class: ["commit flex-row", ("js-toggle-container" if collapsible)], id: "commit-#{commit.short_id}" } - .gl-self-start.gl-hidden.sm:gl-block.gl-mr-3 - = author_avatar(commit, size: 32, has_tooltip: false) + .avatar-cell.gl-hidden.sm:gl-block + = author_avatar(commit, size: 40, has_tooltip: false) .commit-detail.flex-list.gl-flex.gl-justify-between.gl-items-center.gl-grow.gl-min-w-0 .commit-content{ data: { testid: 'commit-content' } } @@ -46,7 +46,7 @@ - if commit.different_committer? && commit.committer - commit_committer_link = commit_committer_link(commit) - commit_committer_timeago = time_ago_with_tooltip(commit.committed_date, placement: 'bottom') - - commit_committer_avatar = commit_committer_avatar(commit.committer, size: 16, has_tooltip: false) + - commit_committer_avatar = commit_committer_avatar(commit.committer, size: 18, has_tooltip: false) - commit_text = _('%{commit_author_link} authored %{commit_authored_timeago} and %{commit_committer_avatar} %{commit_committer_link} committed %{commit_committer_timeago}') % { commit_author_link: commit_author_link, commit_authored_timeago: commit_authored_timeago, commit_committer_avatar: commit_committer_avatar, commit_committer_link: commit_committer_link, commit_committer_timeago: commit_committer_timeago } - else - commit_text = _('%{commit_author_link} authored %{commit_authored_timeago}') % { commit_author_link: commit_author_link, commit_authored_timeago: commit_authored_timeago } diff --git a/app/views/shared/issuable/_user_dropdown_item.html.haml b/app/views/shared/issuable/_user_dropdown_item.html.haml index 51147bc2ae921..0bd211a2cc56b 100644 --- a/app/views/shared/issuable/_user_dropdown_item.html.haml +++ b/app/views/shared/issuable/_user_dropdown_item.html.haml @@ -4,7 +4,7 @@ %li.filter-dropdown-item{ class: ('js-current-user' if user == current_user) } = render Pajamas::ButtonComponent.new(variant: :link, button_text_classes: 'gl-flex gl-items-center') do .gl-shrink-0 - = user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 32, has_tooltip: false) + = user_avatar_without_link(user: user, lazy: avatar[:lazy], url: avatar[:url], size: 40, has_tooltip: false) .gl-flex.gl-flex-col %span.gl-font-bold.gl-whitespace-normal.gl-break-words = user.name diff --git a/app/views/shared/milestones/_issuable.html.haml b/app/views/shared/milestones/_issuable.html.haml index 5f05403b53b1b..9a3df35d4bf32 100644 --- a/app/views/shared/milestones/_issuable.html.haml +++ b/app/views/shared/milestones/_issuable.html.haml @@ -24,6 +24,6 @@ - assignees.each do |assignee| = link_to polymorphic_path(issuable_type_args, { milestone_title: @milestone.title, assignee_id: assignee.id, state: 'all' }), class: 'has-tooltip', title: _("Assigned to %{assignee_name}") % { assignee_name: assignee.name }, data: { container: 'body' } do - - image_tag(avatar_icon_for_user(assignee, 16), class: "gl-avatar gl-avatar-circle gl-avatar-s16", alt: '') + - image_tag(avatar_icon_for_user(assignee, 16), class: "avatar s16", alt: '') = render_if_exists "shared/milestones/issuable_weight", issuable: issuable diff --git a/ee/app/views/profiles/billings/_billing_plan_header.html.haml b/ee/app/views/profiles/billings/_billing_plan_header.html.haml index 8dc72be9d2347..ae1a6bfe0dbb6 100644 --- a/ee/app/views/profiles/billings/_billing_plan_header.html.haml +++ b/ee/app/views/profiles/billings/_billing_plan_header.html.haml @@ -2,7 +2,7 @@ .billing-plan-header.content-block.gl-text-center .billing-plan-logo - .gl-flex.gl-justify-center.home-panel-avatar.gl-mb-6.gl-mt-2{ class: '!gl-mx-auto' } + .avatar-container.s96.home-panel-avatar.gl-mr-3.float-none.gl-mb-6.gl-mt-2{ class: '!gl-mx-auto' } = user_avatar_without_link(user: current_user, class: 'mb-3', size: 96) %h4 diff --git a/ee/app/views/shared/billings/_billing_plans_layout.html.haml b/ee/app/views/shared/billings/_billing_plans_layout.html.haml index 3ef4b670538d2..15d7e9955d72c 100644 --- a/ee/app/views/shared/billings/_billing_plans_layout.html.haml +++ b/ee/app/views/shared/billings/_billing_plans_layout.html.haml @@ -3,7 +3,7 @@ - if namespace.avatar_url.present? = render Pajamas::AvatarComponent.new(namespace, alt: namespace.name, class: 'border rounded gl-mb-5 gl-mt-2', size: 96) - else - .gl-flex.gl-justify-center.home-panel-avatar.gl-mb-6.gl-mt-2{ class: '!gl-mx-auto' } + .avatar-container.rect-avatar.s96.home-panel-avatar.gl-mr-3.float-none.gl-mb-6.gl-mt-2{ class: '!gl-mx-auto' } = render Pajamas::AvatarComponent.new(namespace, alt: namespace.name, size: 96) %h4{ data: { testid: 'billing-plan-header-content' } } diff --git a/ee/app/views/shared/credentials_inventory/users/_user_detail.html.haml b/ee/app/views/shared/credentials_inventory/users/_user_detail.html.haml index 54c5c31a692d4..962bc10b445dd 100644 --- a/ee/app/views/shared/credentials_inventory/users/_user_detail.html.haml +++ b/ee/app/views/shared/credentials_inventory/users/_user_detail.html.haml @@ -1,10 +1,10 @@ .flex-list .flex-row - = user_avatar_without_link(user: user, size: 32, css_class: 'gl-hidden md:gl-flex gl-mr-3') + = user_avatar_without_link(user: user, size: 32, css_class: 'avatar s32 gl-hidden md:gl-flex') .row-main-content .row-title.str-truncated-100 - = user_avatar_without_link(user: user, size: 16, css_class: 'md:gl-hidden gl-mr-2') + = user_avatar_without_link(user: user, size: 16, css_class: 'avatar s16 gl-flex md:gl-hidden mr-1 gl-mt-2') = link_to user.name, user_detail_path(user), class: 'gl-text-default hover:gl-text-default js-user-link', data: { user_id: user.id } .row-second-line.str-truncated-100 - = mail_to user.email, user.email, class: '!gl-text-subtle' + = mail_to user.email, user.email, class: '!gl-text-secondary' diff --git a/lib/banzai/filter/commit_trailers_filter.rb b/lib/banzai/filter/commit_trailers_filter.rb index c4d131daa7dcb..058faccf92447 100644 --- a/lib/banzai/filter/commit_trailers_filter.rb +++ b/lib/banzai/filter/commit_trailers_filter.rb @@ -90,7 +90,7 @@ def link_to_user(user, name:, email:, trailer:) avatar = user_avatar_without_link( user: user, user_email: email, - css_class: 'gl-mr-2', + css_class: 'avatar-inline', has_tooltip: false, only_path: false ) diff --git a/spec/frontend/gfm_auto_complete_spec.js b/spec/frontend/gfm_auto_complete_spec.js index 5f08566ee070e..f490424081e78 100644 --- a/spec/frontend/gfm_auto_complete_spec.js +++ b/spec/frontend/gfm_auto_complete_spec.js @@ -557,8 +557,7 @@ describe('GfmAutoComplete', () => { expect(membersBeforeSave([{ ...mockGroup, avatar_url: null }])).toEqual([ { username: 'my-group', - avatarTag: - '<div class="gl-avatar gl-avatar-s24 gl-mr-2 gl-justify-center gl-items-center ">M</div>', + avatarTag: '<div class="avatar rect-avatar avatar-inline s24 gl-mr-2">M</div>', title: 'My Group (2)', search: 'MyGroup my-group', icon: '', @@ -571,7 +570,7 @@ describe('GfmAutoComplete', () => { { username: 'my-group', avatarTag: - '<img src="./group.jpg" alt="my-group" class="gl-avatar gl-avatar-s24 gl-mr-2 "/>', + '<img src="./group.jpg" alt="my-group" class="avatar rect-avatar avatar-inline s24 gl-mr-2"/>', title: 'My Group (2)', search: 'MyGroup my-group', icon: '', @@ -584,7 +583,7 @@ describe('GfmAutoComplete', () => { { username: 'my-group', avatarTag: - '<img src="./group.jpg" alt="my-group" class="gl-avatar gl-avatar-s24 gl-mr-2 "/>', + '<img src="./group.jpg" alt="my-group" class="avatar rect-avatar avatar-inline s24 gl-mr-2"/>', title: 'My Group', search: 'MyGroup my-group', icon: '<svg class="s16 vertical-align-middle gl-ml-2"><use xlink:href="/icons.svg#notifications-off" /></svg>', @@ -601,7 +600,7 @@ describe('GfmAutoComplete', () => { { username: 'my-user', avatarTag: - '<img src="./users.jpg" alt="my-user" class="gl-avatar gl-avatar-s24 gl-mr-2 gl-avatar-circle"/>', + '<img src="./users.jpg" alt="my-user" class="avatar avatar-inline s24 gl-mr-2"/>', title: 'My User', search: 'MyUser my-user', icon: '', diff --git a/spec/frontend/groups/components/group_item_spec.js b/spec/frontend/groups/components/group_item_spec.js index b33832fb4f843..e89acbadedec7 100644 --- a/spec/frontend/groups/components/group_item_spec.js +++ b/spec/frontend/groups/components/group_item_spec.js @@ -260,8 +260,9 @@ describe('GroupItemComponent', () => { expect(vm.$el.querySelector('.folder-toggle-wrap')).toBeDefined(); expect(vm.$el.querySelector('.folder-toggle-wrap .item-type-icon')).toBeDefined(); - expect(vm.$el.querySelector('.gl-avatar')).toBeDefined(); - expect(vm.$el.querySelector('.gl-avatar a.no-expand')).toBeDefined(); + expect(vm.$el.querySelector('.avatar-container')).toBeDefined(); + expect(vm.$el.querySelector('.avatar-container a.no-expand')).toBeDefined(); + expect(vm.$el.querySelector('.avatar-container .avatar')).toBeDefined(); expect(vm.$el.querySelector('.title')).toBeDefined(); expect(vm.$el.querySelector('.title a.no-expand')).toBeDefined(); diff --git a/spec/frontend/sidebar/components/assignees/assignee_avatar_spec.js b/spec/frontend/sidebar/components/assignees/assignee_avatar_spec.js index 36090f15305ac..b6b3dbd5b6b65 100644 --- a/spec/frontend/sidebar/components/assignees/assignee_avatar_spec.js +++ b/spec/frontend/sidebar/components/assignees/assignee_avatar_spec.js @@ -1,5 +1,4 @@ import { shallowMount } from '@vue/test-utils'; -import { GlAvatar } from '@gitlab/ui'; import { TEST_HOST } from 'helpers/test_constants'; import AssigneeAvatar from '~/sidebar/components/assignees/assignee_avatar.vue'; import userDataMock from '../../user_data_mock'; @@ -27,7 +26,7 @@ describe('AssigneeAvatar', () => { window.gon = { default_avatar_url: TEST_DEFAULT_AVATAR_URL }; }); - const findImg = () => wrapper.findComponent(GlAvatar); + const findImg = () => wrapper.find('img'); it('does not show warning icon if assignee can merge', () => { createComponent(); diff --git a/spec/frontend/sidebar/components/assignees/assignees_spec.js b/spec/frontend/sidebar/components/assignees/assignees_spec.js index 878a0ec007c2b..2767d36ac3d96 100644 --- a/spec/frontend/sidebar/components/assignees/assignees_spec.js +++ b/spec/frontend/sidebar/components/assignees/assignees_spec.js @@ -1,4 +1,4 @@ -import { GlAvatar, GlIcon } from '@gitlab/ui'; +import { GlIcon } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import { trimText } from 'helpers/text_helper'; import UsersMockHelper from 'helpers/user_mock_data_helper'; @@ -79,10 +79,8 @@ describe('Assignee component', () => { const assignee = collapsedChildren.at(0); expect(collapsedChildren.length).toBe(1); - expect(assignee.findComponent(GlAvatar).attributes('src')).toBe(UsersMock.user.avatar); - expect(assignee.findComponent(GlAvatar).attributes('alt')).toBe( - `${UsersMock.user.name}'s avatar`, - ); + expect(assignee.find('.avatar').attributes('src')).toBe(UsersMock.user.avatar); + expect(assignee.find('.avatar').attributes('alt')).toBe(`${UsersMock.user.name}'s avatar`); expect(trimText(assignee.find('.author').text())).toBe(UsersMock.user.name); }); @@ -102,15 +100,15 @@ describe('Assignee component', () => { const first = collapsedChildren.at(0); - expect(first.findComponent(GlAvatar).attributes('src')).toBe(users[0].avatar_url); - expect(first.findComponent(GlAvatar).attributes('alt')).toBe(`${users[0].name}'s avatar`); + expect(first.find('.avatar').attributes('src')).toBe(users[0].avatar_url); + expect(first.find('.avatar').attributes('alt')).toBe(`${users[0].name}'s avatar`); expect(trimText(first.find('.author').text())).toBe(users[0].name); const second = collapsedChildren.at(1); - expect(second.findComponent(GlAvatar).attributes('src')).toBe(users[1].avatar_url); - expect(second.findComponent(GlAvatar).attributes('alt')).toBe(`${users[1].name}'s avatar`); + expect(second.find('.avatar').attributes('src')).toBe(users[1].avatar_url); + expect(second.find('.avatar').attributes('alt')).toBe(`${users[1].name}'s avatar`); expect(trimText(second.find('.author').text())).toBe(users[1].name); }); @@ -128,8 +126,8 @@ describe('Assignee component', () => { const first = collapsedChildren.at(0); - expect(first.findComponent(GlAvatar).attributes('src')).toBe(users[0].avatar_url); - expect(first.findComponent(GlAvatar).attributes('alt')).toBe(`${users[0].name}'s avatar`); + expect(first.find('.avatar').attributes('src')).toBe(users[0].avatar_url); + expect(first.find('.avatar').attributes('alt')).toBe(`${users[0].name}'s avatar`); expect(trimText(first.find('.author').text())).toBe(users[0].name); diff --git a/spec/frontend/vue_merge_request_widget/components/mr_widget_author_spec.js b/spec/frontend/vue_merge_request_widget/components/mr_widget_author_spec.js index b935e7c47ab94..7eafccae08312 100644 --- a/spec/frontend/vue_merge_request_widget/components/mr_widget_author_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/mr_widget_author_spec.js @@ -1,5 +1,4 @@ import { shallowMount } from '@vue/test-utils'; -import { GlAvatar } from '@gitlab/ui'; import { nextTick } from 'vue'; import MrWidgetAuthor from '~/vue_merge_request_widget/components/mr_widget_author.vue'; @@ -38,7 +37,7 @@ describe('MrWidgetAuthor', () => { }); it('renders image with avatar url', () => { - expect(wrapper.findComponent(GlAvatar).attributes('src')).toBe( + expect(wrapper.find('img').attributes('src')).toBe( 'http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon', ); }); @@ -53,7 +52,7 @@ describe('MrWidgetAuthor', () => { await nextTick(); - expect(wrapper.findComponent(GlAvatar).props('src')).toBe('no_avatar.png'); + expect(wrapper.find('img').attributes('src')).toBe('no_avatar.png'); }); it('renders author name', () => { diff --git a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js index 75384e7a11549..bf4435fae4570 100644 --- a/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js +++ b/spec/frontend/vue_shared/alert_details/sidebar/alert_sidebar_assignees_spec.js @@ -1,6 +1,6 @@ import Vue from 'vue'; import VueApollo from 'vue-apollo'; -import { GlAvatar, GlDropdownItem } from '@gitlab/ui'; +import { GlDropdownItem } from '@gitlab/ui'; import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; @@ -146,7 +146,7 @@ describe('Alert Details Sidebar Assignees', () => { props: { alert: mockAlerts[1] }, }); - expect(findAssigned().findComponent(GlAvatar).props('src')).toBe('/url'); + expect(findAssigned().find('img').attributes('src')).toBe('/url'); expect(findAssigned().find('.dropdown-menu-user-full-name').text()).toBe('root'); expect(findAssigned().find('.dropdown-menu-user-username').text()).toBe('@root'); }); diff --git a/spec/helpers/avatars_helper_spec.rb b/spec/helpers/avatars_helper_spec.rb index 33a2c0007058e..d988bded4ea57 100644 --- a/spec/helpers/avatars_helper_spec.rb +++ b/spec/helpers/avatars_helper_spec.rb @@ -290,7 +290,7 @@ alt: "#{user.name}'s avatar", src: avatar_icon_for_user(user, 16), data: { container: 'body' }, - class: 'gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip', + class: 'avatar s16 has-tooltip', title: user.name ) end @@ -303,7 +303,7 @@ alt: "#{user.name}'s avatar", src: avatar_icon_for_user(user, 16), data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 #{options[:css_class]} has-tooltip", + class: "avatar s16 #{options[:css_class]} has-tooltip", title: user.name ) end @@ -317,7 +317,7 @@ alt: "#{user.name}'s avatar", src: avatar_icon_for_user(user, options[:size]), data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s#{options[:size]} has-tooltip", + class: "avatar s#{options[:size]} has-tooltip", title: user.name ) end @@ -331,7 +331,7 @@ alt: "#{user.name}'s avatar", src: options[:url], data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip", + class: "avatar s16 has-tooltip", title: user.name ) end @@ -345,7 +345,7 @@ alt: "#{user.name}'s avatar", src: LazyImageTagHelper.placeholder_image, data: { container: 'body', src: avatar_icon_for_user(user, 16) }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip lazy", + class: "avatar s16 has-tooltip lazy", title: user.name ) end @@ -360,7 +360,7 @@ alt: "#{user.name}'s avatar", src: avatar_icon_for_user(user, 16), data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip", + class: "avatar s16 has-tooltip", title: user.name ) end @@ -373,7 +373,7 @@ is_expected.to eq tag.img( alt: "#{user.name}'s avatar", src: avatar_icon_for_user(user, 16), - class: "gl-avatar gl-avatar-circle gl-avatar-s16", + class: "avatar s16", title: user.name ) end @@ -391,7 +391,7 @@ alt: "#{user.name}'s avatar", src: avatar_icon_for_user(user, 16), data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip", + class: "avatar s16 has-tooltip", title: user.name ) end @@ -402,7 +402,7 @@ alt: "#{options[:user_name]}'s avatar", src: helper.avatar_icon_for_email(options[:user_email], 16), data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip", + class: "avatar s16 has-tooltip", title: options[:user_name] ) end @@ -419,7 +419,7 @@ alt: "#{user_with_avatar.name}'s avatar", src: avatar_icon_for_user(user_with_avatar, 16, only_path: false), data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip", + class: "avatar s16 has-tooltip", title: user_with_avatar.name ) end @@ -433,7 +433,7 @@ alt: "#{user_with_avatar.username}'s avatar", src: helper.avatar_icon_for_email(user_with_avatar.email, 16, only_path: false), data: { container: 'body' }, - class: "gl-avatar gl-avatar-circle gl-avatar-s16 has-tooltip", + class: "avatar s16 has-tooltip", title: user_with_avatar.username ) end @@ -462,7 +462,7 @@ alt: "#{user.name}'s avatar", src: avatar_icon_for_user(user, 32), data: { container: 'body' }, - class: 'gl-avatar gl-avatar-circle gl-avatar-s32 has-tooltip', + class: 'avatar s32 has-tooltip', title: user.name ) end diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb index 1039939787d8c..89b63c4033531 100644 --- a/spec/helpers/projects_helper_spec.rb +++ b/spec/helpers/projects_helper_spec.rb @@ -335,13 +335,13 @@ end it 'returns image tag for member avatar' do - expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[gl-avatar gl-avatar-circle gl-avatar-s16], alt: "" }) + expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[avatar avatar-inline s16], alt: "" }) helper.link_to_member_avatar(user) end it 'returns image tag with avatar class' do - expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[gl-avatar gl-avatar-circle gl-avatar-s16 any-avatar-class], alt: "" }) + expect(helper).to receive(:image_tag).with(expected, { width: 16, class: %w[avatar avatar-inline s16 any-avatar-class], alt: "" }) helper.link_to_member_avatar(user, avatar_class: "any-avatar-class") end diff --git a/spec/helpers/wiki_page_version_helper_spec.rb b/spec/helpers/wiki_page_version_helper_spec.rb index 7e1b5f635abee..a43e25bbfd1d4 100644 --- a/spec/helpers/wiki_page_version_helper_spec.rb +++ b/spec/helpers/wiki_page_version_helper_spec.rb @@ -29,4 +29,18 @@ end end end + + describe '#wiki_page_version_author_avatar' do + let(:commit) { commit_with_user } + + subject { helper.wiki_page_version_author_avatar(wiki_page_version) } + + it 'returns the user avatar', :aggregate_failures do + avatar = Nokogiri::HTML.parse(subject) + + expect(avatar.css('img')[0].attr('class')).to eq('avatar s24 float-none !gl-mr-0 lazy') + expect(avatar.css('img')[0].attr('data-src')).not_to be_empty + expect(avatar.css('img')[0].attr('src')).not_to be_empty + end + end end -- GitLab