Commit a4b475ca authored by Brandon Labuschagne's avatar Brandon Labuschagne

Merge branch '297365-add-note-to-vue-admin-users' into 'master'

Add user note to admin avatar component

See merge request gitlab-org/gitlab!52673
parents 1d47a49c 69584779
<script>
import { GlAvatarLink, GlAvatarLabeled, GlBadge } from '@gitlab/ui';
import { USER_AVATAR_SIZE } from '../constants';
import { GlAvatarLink, GlAvatarLabeled, GlBadge, GlIcon, GlTooltipDirective } from '@gitlab/ui';
import { truncate } from '~/lib/utils/text_utility';
import { USER_AVATAR_SIZE, LENGTH_OF_USER_NOTE_TOOLTIP } from '../constants';
export default {
directives: {
GlTooltip: GlTooltipDirective,
},
components: {
GlAvatarLink,
GlAvatarLabeled,
GlBadge,
GlIcon,
},
props: {
user: {
......@@ -22,6 +27,9 @@ export default {
adminUserHref() {
return this.adminUserPath.replace('id', this.user.username);
},
userNoteShort() {
return truncate(this.user.note, LENGTH_OF_USER_NOTE_TOOLTIP);
},
},
USER_AVATAR_SIZE,
};
......@@ -42,6 +50,9 @@ export default {
:sub-label="user.email"
>
<template #meta>
<div v-if="user.note" class="gl-text-gray-500 gl-p-1">
<gl-icon v-gl-tooltip="userNoteShort" name="document" />
</div>
<div v-for="(badge, idx) in user.badges" :key="idx" class="gl-p-1">
<gl-badge class="gl-display-flex!" size="sm" :variant="badge.variant">{{
badge.text
......
export const USER_AVATAR_SIZE = 32;
export const SHORT_DATE_FORMAT = 'd mmm, yyyy';
export const LENGTH_OF_USER_NOTE_TOOLTIP = 100;
......@@ -10,6 +10,7 @@ module Admin
expose :email
expose :last_activity_on
expose :avatar_url
expose :note
expose :badges do |user|
user_badges_in_admin_section(user)
end
......
......@@ -2,6 +2,6 @@
module Admin
class UserSerializer < BaseSerializer
entity UserEntity
entity Admin::UserEntity
end
end
import { GlAvatarLink, GlAvatarLabeled, GlBadge } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { GlAvatarLink, GlAvatarLabeled, GlBadge, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import AdminUserAvatar from '~/admin/users/components/user_avatar.vue';
import { LENGTH_OF_USER_NOTE_TOOLTIP } from '~/admin/users/constants';
import { truncate } from '~/lib/utils/text_utility';
import { users, paths } from '../mock_data';
describe('AdminUserAvatar component', () => {
......@@ -9,17 +12,25 @@ describe('AdminUserAvatar component', () => {
const user = users[0];
const adminUserPath = paths.adminUser;
const findNote = () => wrapper.find(GlIcon);
const findAvatar = () => wrapper.find(GlAvatarLabeled);
const findAvatarLink = () => wrapper.find(GlAvatarLink);
const findAllBadges = () => wrapper.findAll(GlBadge);
const findTooltip = () => getBinding(findNote().element, 'gl-tooltip');
const initComponent = (props = {}) => {
wrapper = mount(AdminUserAvatar, {
wrapper = shallowMount(AdminUserAvatar, {
propsData: {
user,
adminUserPath,
...props,
},
directives: {
GlTooltip: createMockDirective(),
},
stubs: {
GlAvatarLabeled,
},
});
};
......@@ -53,11 +64,58 @@ describe('AdminUserAvatar component', () => {
expect(findAvatar().attributes('src')).toBe(user.avatarUrl);
});
it('renders a user note icon', () => {
expect(findNote().exists()).toBe(true);
expect(findNote().props('name')).toBe('document');
});
it("renders the user's note tooltip", () => {
const tooltip = findTooltip();
expect(tooltip).toBeDefined();
expect(tooltip.value).toBe(user.note);
});
it("renders the user's badges", () => {
findAllBadges().wrappers.forEach((badge, idx) => {
expect(badge.text()).toBe(user.badges[idx].text);
expect(badge.props('variant')).toBe(user.badges[idx].variant);
});
});
describe('and the user note is very long', () => {
const noteText = new Array(LENGTH_OF_USER_NOTE_TOOLTIP + 1).join('a');
beforeEach(() => {
initComponent({
user: {
...user,
note: noteText,
},
});
});
it("renders a truncated user's note tooltip", () => {
const tooltip = findTooltip();
expect(tooltip).toBeDefined();
expect(tooltip.value).toBe(truncate(noteText, LENGTH_OF_USER_NOTE_TOOLTIP));
});
});
describe('and the user does not have a note', () => {
beforeEach(() => {
initComponent({
user: {
...user,
note: null,
},
});
});
it('does not render a user note', () => {
expect(findNote().exists()).toBe(false);
});
});
});
});
......@@ -14,6 +14,7 @@ export const users = [
],
projectsCount: 0,
actions: [],
note: 'Create per issue #999',
},
];
......
......@@ -22,6 +22,7 @@ RSpec.describe Admin::UserEntity do
:username,
:last_activity_on,
:avatar_url,
:note,
:badges,
:projects_count,
:actions
......
......@@ -17,6 +17,7 @@ RSpec.describe Admin::UserSerializer do
:username,
:last_activity_on,
:avatar_url,
:note,
:badges,
:projects_count,
:actions
......
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