Commit 1e5f1eb8 authored by peterhegman's avatar peterhegman

Prevent duplicate tooltips when hovering over status emoji

Previously the user popover and the status tooltip were shown when
hovering over the user status emoji
parent 9191e87f
......@@ -2,6 +2,7 @@
import { mapActions } from 'vuex';
import timeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import GitlabTeamMemberBadge from '~/vue_shared/components/user_avatar/badges/gitlab_team_member_badge.vue';
import $ from 'jquery';
export default {
components: {
......@@ -45,6 +46,11 @@ export default {
default: true,
},
},
data() {
return {
isUsernameLinkHovered: false,
};
},
computed: {
toggleChevronClass() {
return this.expanded ? 'fa-chevron-up' : 'fa-chevron-down';
......@@ -58,6 +64,46 @@ export default {
showGitlabTeamMemberBadge() {
return this.author?.is_gitlab_employee;
},
authorLinkClasses() {
return {
hover: this.isUsernameLinkHovered,
'text-underline': this.isUsernameLinkHovered,
'author-name-link': true,
'js-user-link': true,
};
},
authorPath() {
return this.author.path;
},
authorName() {
return this.author.name;
},
authorUsername() {
return this.author.username;
},
authorId() {
return this.author.id;
},
authorStatus() {
return this.author.status_tooltip_html;
},
},
mounted() {
// Temporarily remove `title` attribute from emoji when tooltip is open
// Prevents duplicate tooltips (Bootstrap tooltip and browser title tooltip)
const { authorStatus } = this.$refs;
if (authorStatus && authorStatus.querySelector('.has-tooltip')) {
const emoji = authorStatus.querySelector('gl-emoji');
const emojiTitle = emoji.getAttribute('title');
$(this.$refs.authorStatus).on('show.bs.tooltip', () => {
emoji.removeAttribute('title');
});
$(this.$refs.authorStatus).on('hidden.bs.tooltip', () => {
emoji.setAttribute('title', emojiTitle);
});
}
},
methods: {
...mapActions(['setTargetNoteHash']),
......@@ -69,6 +115,16 @@ export default {
this.setTargetNoteHash(this.noteTimestampLink);
}
},
handleUsernameMouseEnter() {
this.$refs.authorNameLink.dispatchEvent(new Event('mouseenter'));
this.isUsernameLinkHovered = true;
},
handleUsernameMouseLeave() {
this.$refs.authorNameLink.dispatchEvent(new Event('mouseleave'));
this.isUsernameLinkHovered = false;
},
},
};
</script>
......@@ -87,18 +143,27 @@ export default {
</div>
<template v-if="hasAuthor">
<a
v-once
:href="author.path"
class="js-user-link"
:data-user-id="author.id"
:data-username="author.username"
ref="authorNameLink"
:href="authorPath"
:class="authorLinkClasses"
:data-user-id="authorId"
:data-username="authorUsername"
>
<slot name="note-header-info"></slot>
<span class="note-header-author-name bold">{{ author.name }}</span>
<span v-if="author.status_tooltip_html" v-html="author.status_tooltip_html"></span>
<span class="note-headline-light">@{{ author.username }}</span>
<span class="note-header-author-name bold">{{ authorName }}</span>
</a>
<gitlab-team-member-badge v-if="showGitlabTeamMemberBadge" />
<span v-if="authorStatus" ref="authorStatus" v-html="authorStatus"></span>
<span class="text-nowrap author-username">
<a
ref="authorUsernameLink"
class="author-username-link"
:href="authorPath"
@mouseenter="handleUsernameMouseEnter"
@mouseleave="handleUsernameMouseLeave"
><span class="note-headline-light">@{{ authorUsername }}</span>
</a>
<gitlab-team-member-badge v-if="showGitlabTeamMemberBadge" />
</span>
</template>
<span v-else>{{ __('A deleted user') }}</span>
<span class="note-headline-light note-headline-meta">
......
......@@ -588,7 +588,8 @@ $note-form-margin-left: 72px;
a {
color: inherit;
&:hover {
&:hover,
&.hover {
color: $blue-600;
}
......@@ -605,6 +606,21 @@ $note-form-margin-left: 72px;
.author-link {
color: $gl-text-color;
}
// Prevent flickering of link when hovering between `author-name-link` and `.author-username-link`
.author-name-link + .author-username .author-username-link {
position: relative;
&::before {
content: '';
position: absolute;
right: 100%;
width: 0.25rem;
height: 100%;
top: 0;
bottom: 0;
}
}
}
.discussion-header {
......
---
title: Prevent duplicate tooltips when hovering over status emoji in comments
merge_request: 29356
author:
type: fixed
......@@ -179,4 +179,26 @@ describe('NoteHeader component', () => {
expect(findTimestamp().exists()).toBe(true);
});
});
describe('author username link', () => {
it('proxies `mouseenter` event to author name link', () => {
createComponent({ author });
const dispatchEvent = jest.spyOn(wrapper.vm.$refs.authorNameLink, 'dispatchEvent');
wrapper.find({ ref: 'authorUsernameLink' }).trigger('mouseenter');
expect(dispatchEvent).toHaveBeenCalledWith(new Event('mouseenter'));
});
it('proxies `mouseleave` event to author name link', () => {
createComponent({ author });
const dispatchEvent = jest.spyOn(wrapper.vm.$refs.authorNameLink, 'dispatchEvent');
wrapper.find({ ref: 'authorUsernameLink' }).trigger('mouseleave');
expect(dispatchEvent).toHaveBeenCalledWith(new Event('mouseleave'));
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment