mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[UsersProfilePopover] Fix email sometimes is not visible (#184318)
## Summary fix https://github.com/elastic/kibana/issues/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:  After:  - Also adds email in a label to make it appear in a browser tooltip  - Also fixes https://github.com/elastic/kibana/issues/182561 and adds email to Avatar "name" so it appears in a native tooltip  - Increase popover width in TableListView
This commit is contained in:
parent
8a5ed874af
commit
db9e530da2
10 changed files with 64 additions and 62 deletions
|
@ -164,7 +164,7 @@ export const UserFilterPanel: FC<{}> = () => {
|
|||
},
|
||||
onSearchChange: setSearchTerm,
|
||||
}}
|
||||
panelProps={{ css: { minWidth: euiTheme.base * 18 } }}
|
||||
panelProps={{ css: { minWidth: euiTheme.base * 22 } }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -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)"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
@ -56,7 +56,7 @@ describe('UserAvatar', () => {
|
|||
color="#09e8ca"
|
||||
initials="DN"
|
||||
initialsLength={2}
|
||||
name="Delighted Nightingale"
|
||||
name="Delighted Nightingale (delighted_nightingale@elastic.co)"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
@ -76,7 +76,7 @@ describe('UserAvatar', () => {
|
|||
color="#AA6556"
|
||||
initials="DN"
|
||||
initialsLength={2}
|
||||
name="Delighted Nightingale"
|
||||
name="Delighted Nightingale (delighted_nightingale@elastic.co)"
|
||||
/>
|
||||
`);
|
||||
});
|
||||
|
|
|
@ -16,7 +16,7 @@ import type { UserProfile, UserProfileUserInfo } from './user_profile';
|
|||
import {
|
||||
getUserAvatarColor,
|
||||
getUserAvatarInitials,
|
||||
getUserDisplayName,
|
||||
getUserDisplayLabel,
|
||||
USER_AVATAR_MAX_INITIALS,
|
||||
} from './user_profile';
|
||||
|
||||
|
@ -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)}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ import {
|
|||
EuiText,
|
||||
EuiCallOut,
|
||||
EuiHighlight,
|
||||
EuiTextColor,
|
||||
} from '@elastic/eui';
|
||||
import type { ReactNode } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
@ -26,7 +25,7 @@ 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';
|
||||
|
||||
|
@ -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>;
|
||||
|
@ -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}`,
|
||||
};
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
@ -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>
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
"outDir": "target/types",
|
||||
"types": [
|
||||
"jest",
|
||||
"node"
|
||||
"node",
|
||||
"@emotion/react/types/css-prop",
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
|
|
|
@ -112,7 +112,7 @@ const AssigneesFilterPopoverComponent: React.FC<AssigneesFilterPopoverProps> = (
|
|||
isOpen={isPopoverOpen}
|
||||
closePopover={togglePopover}
|
||||
panelStyle={{
|
||||
minWidth: 520,
|
||||
width: 400,
|
||||
}}
|
||||
button={
|
||||
<EuiFilterButton
|
||||
|
|
|
@ -113,7 +113,7 @@ const SuggestUsersPopoverComponent: React.FC<SuggestUsersPopoverProps> = ({
|
|||
isOpen={isPopoverOpen}
|
||||
closePopover={onClosePopover}
|
||||
panelStyle={{
|
||||
minWidth: 520,
|
||||
width: 400,
|
||||
}}
|
||||
selectableProps={{
|
||||
onChange,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue