Skip to content

Commit

Permalink
[UsersProfilePopover] Fix email sometimes is not visible (#184318)
Browse files Browse the repository at this point in the history
## Summary

fix #182945


- This fixes `UsersProfilePopover` to always show email on the 2nd line.
To keep the list virtualized **had to increase the height a bit for
every row**

Before:


![image](https://github.com/elastic/kibana/assets/7784120/ee42530f-9b39-4139-bd81-12c0a8fd6498)


After:

![Screenshot 2024-05-27 at 15 28
05](https://github.com/elastic/kibana/assets/7784120/5d869cf3-194f-4b08-b4a8-945d5904452e)


- Also adds email in a label to make it appear in a browser tooltip 

![Screenshot 2024-05-27 at 16 20
12](https://github.com/elastic/kibana/assets/7784120/a9687ec2-a92a-44e9-a64d-e64a4e87b497)


- Also fixes #182561 and adds
email to Avatar "name" so it appears in a native tooltip

![Screenshot 2024-05-28 at 15 57
21](https://github.com/elastic/kibana/assets/7784120/67b0bb65-4ce4-4561-85cc-356175bc86c2)



- Increase popover width in TableListView
  • Loading branch information
Dosant committed Jun 5, 2024
1 parent 8a5ed87 commit db9e530
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export const UserFilterPanel: FC<{}> = () => {
},
onSearchChange: setSearchTerm,
}}
panelProps={{ css: { minWidth: euiTheme.base * 18 } }}
panelProps={{ css: { minWidth: euiTheme.base * 22 } }}
/>
</>
);
Expand Down
6 changes: 3 additions & 3 deletions packages/kbn-user-profile-components/src/user_avatar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ describe('UserAvatar', () => {
<EuiAvatar
color="plain"
imageUrl="https://source.unsplash.com/64x64/?cat"
name="Delighted Nightingale"
name="Delighted Nightingale (delighted_nightingale@elastic.co)"
/>
`);
});
Expand All @@ -56,7 +56,7 @@ describe('UserAvatar', () => {
color="#09e8ca"
initials="DN"
initialsLength={2}
name="Delighted Nightingale"
name="Delighted Nightingale (delighted_nightingale@elastic.co)"
/>
`);
});
Expand All @@ -76,7 +76,7 @@ describe('UserAvatar', () => {
color="#AA6556"
initials="DN"
initialsLength={2}
name="Delighted Nightingale"
name="Delighted Nightingale (delighted_nightingale@elastic.co)"
/>
`);
});
Expand Down
8 changes: 4 additions & 4 deletions packages/kbn-user-profile-components/src/user_avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { UserProfile, UserProfileUserInfo } from './user_profile';
import {
getUserAvatarColor,
getUserAvatarInitials,
getUserDisplayName,
getUserDisplayLabel,
USER_AVATAR_MAX_INITIALS,
} from './user_profile';

Expand Down Expand Up @@ -62,15 +62,15 @@ export const UserAvatar: FunctionComponent<UserAvatarProps> = ({ user, avatar, .
return <EuiAvatar name="" color={euiTheme.colors.lightestShade} initials="?" {...rest} />;
}

const displayName = getUserDisplayName(user);
const displayLabel = getUserDisplayLabel(user);

if (avatar?.imageUrl) {
return <EuiAvatar name={displayName} imageUrl={avatar.imageUrl} color="plain" {...rest} />;
return <EuiAvatar name={displayLabel} imageUrl={avatar.imageUrl} color="plain" {...rest} />;
}

return (
<EuiAvatar
name={displayName}
name={displayLabel}
initials={getUserAvatarInitials(user, avatar)}
initialsLength={USER_AVATAR_MAX_INITIALS}
color={getUserAvatarColor(user, avatar)}
Expand Down
13 changes: 13 additions & 0 deletions packages/kbn-user-profile-components/src/user_profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,16 @@ export interface GetUserDisplayNameParams {
export function getUserDisplayName(params: GetUserDisplayNameParams) {
return params.full_name || params.email || params.username;
}

/**
* Determines the display label for the provided user information.
* Includes the email if it is different from the display name.
* @param params Set of available user's name-related fields.
*/
export function getUserDisplayLabel(user: GetUserDisplayNameParams): string {
const displayName = getUserDisplayName(user);
if (user.email && user.email !== displayName) {
return `${displayName} (${user.email})`;
}
return displayName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,14 @@ import {
EuiText,
EuiCallOut,
EuiHighlight,
EuiTextColor,
} from '@elastic/eui';
import type { ReactNode } from 'react';
import React, { useEffect, useState } from 'react';

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';

import { getUserDisplayName } from './user_profile';
import { getUserDisplayLabel, getUserDisplayName } from './user_profile';
import type { UserProfileWithAvatar } from './user_avatar';
import { UserAvatar } from './user_avatar';

Expand Down Expand Up @@ -326,40 +325,33 @@ export const UserProfilesSelectable = <Option extends UserProfileWithAvatar | nu
id: searchInputId,
}}
isPreFiltered
listProps={{ onFocusBadge: false }}
listProps={{ onFocusBadge: false, rowHeight: 48 }}
loadingMessage={loadingMessage}
noMatchesMessage={noMatchesMessage}
emptyMessage={emptyMessage}
errorMessage={errorMessage}
renderOption={(option, searchValue) => {
if (option.user) {
const displayName = getUserDisplayName(option.user);
return (
<EuiFlexGroup
alignItems="center"
justifyContent="spaceBetween"
gutterSize="s"
responsive={false}
>
<EuiFlexItem css={{ maxWidth: '100%' }}>
<EuiHighlight className="eui-textTruncate" search={searchValue}>
{option.label}
</EuiHighlight>
</EuiFlexItem>
{option.user.email && option.user.email !== option.label ? (
<EuiFlexItem grow={false} css={{ minWidth: 0 }}>
<EuiTextColor
color={option.disabled ? 'disabled' : 'subdued'}
className="eui-textTruncate"
>
{searchValue ? (
<EuiHighlight search={searchValue}>{option.user.email}</EuiHighlight>
) : (
option.user.email
)}
</EuiTextColor>
</EuiFlexItem>
<>
<div className="eui-textTruncate">
<EuiHighlight search={searchValue}>{displayName}</EuiHighlight>
</div>
{option.user.email && option.user.email !== displayName ? (
<EuiText
size={'xs'}
color={option.disabled ? 'disabled' : 'subdued'}
className="eui-textTruncate"
>
{searchValue ? (
<EuiHighlight search={searchValue}>{option.user.email}</EuiHighlight>
) : (
option.user.email
)}
</EuiText>
) : undefined}
</EuiFlexGroup>
</>
);
}
return <EuiHighlight search={searchValue}>{option.label}</EuiHighlight>;
Expand Down Expand Up @@ -451,7 +443,7 @@ function toSelectableOption(
if (userProfile) {
return {
key: userProfile.uid,
label: getUserDisplayName(userProfile.user),
label: getUserDisplayLabel(userProfile.user),
data: userProfile,
'data-test-subj': `userProfileSelectableOption-${userProfile.user.username}`,
};
Expand Down
24 changes: 12 additions & 12 deletions packages/kbn-user-profile-components/src/user_tooltip.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@ describe('UserToolTip', () => {
</EuiFlexItem>
<EuiFlexItem
grow={true}
style={
Object {
"minWidth": 0,
}
}
>
<EuiFlexGroup
direction="column"
gutterSize="none"
<div>
Delighted Nightingale
</div>
<EuiText
size="xs"
>
<EuiFlexItem>
<strong>
Delighted Nightingale
</strong>
</EuiFlexItem>
<EuiFlexItem>
delighted_nightingale@elastic.co
</EuiFlexItem>
</EuiFlexGroup>
delighted_nightingale@elastic.co
</EuiText>
</EuiFlexItem>
</EuiFlexGroup>
}
Expand Down
16 changes: 6 additions & 10 deletions packages/kbn-user-profile-components/src/user_tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import type { EuiToolTipProps } from '@elastic/eui';
import { EuiText, EuiToolTipProps } from '@elastic/eui';
import { EuiToolTip, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import type { FunctionComponent } from 'react';
import React from 'react';
Expand Down Expand Up @@ -43,15 +43,11 @@ export const UserToolTip: FunctionComponent<UserToolTipProps> = ({ user, avatar,
<EuiFlexItem grow={false}>
<UserAvatar user={user} avatar={avatar} size="l" />
</EuiFlexItem>
<EuiFlexItem grow>
<EuiFlexGroup direction="column" gutterSize="none">
<EuiFlexItem>
<strong>{displayName}</strong>
</EuiFlexItem>
{user.email && user.email !== displayName ? (
<EuiFlexItem>{user.email}</EuiFlexItem>
) : undefined}
</EuiFlexGroup>
<EuiFlexItem grow style={{ minWidth: 0 }}>
<div>{displayName}</div>
{user.email && user.email !== displayName ? (
<EuiText size={'xs'}>{user.email}</EuiText>
) : undefined}
</EuiFlexItem>
</EuiFlexGroup>
}
Expand Down
3 changes: 2 additions & 1 deletion packages/kbn-user-profile-components/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"outDir": "target/types",
"types": [
"jest",
"node"
"node",
"@emotion/react/types/css-prop",
]
},
"include": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const AssigneesFilterPopoverComponent: React.FC<AssigneesFilterPopoverProps> = (
isOpen={isPopoverOpen}
closePopover={togglePopover}
panelStyle={{
minWidth: 520,
width: 400,
}}
button={
<EuiFilterButton
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const SuggestUsersPopoverComponent: React.FC<SuggestUsersPopoverProps> = ({
isOpen={isPopoverOpen}
closePopover={onClosePopover}
panelStyle={{
minWidth: 520,
width: 400,
}}
selectableProps={{
onChange,
Expand Down

0 comments on commit db9e530

Please sign in to comment.