diff --git a/frontend/src/component/common/UserAvatar/UserAvatar.tsx b/frontend/src/component/common/UserAvatar/UserAvatar.tsx index 69f2ce4020..ae4732398c 100644 --- a/frontend/src/component/common/UserAvatar/UserAvatar.tsx +++ b/frontend/src/component/common/UserAvatar/UserAvatar.tsx @@ -25,7 +25,7 @@ const StyledAvatar = styled(Avatar, { }; }); -interface IUserAvatarProps extends AvatarProps { +export interface IUserAvatarProps extends AvatarProps { user?: Partial< Pick >; @@ -77,7 +77,7 @@ export const UserAvatar: FC = ({ sx={sx} {...props} data-loading - alt='Gravatar' + alt={user?.name || user?.email || user?.username || 'Gravatar'} src={src} title={title} onMouseEnter={onMouseEnter} diff --git a/frontend/src/component/common/UserAvatar/UserAvatarWithPopover.tsx b/frontend/src/component/common/UserAvatar/UserAvatarWithPopover.tsx new file mode 100644 index 0000000000..8796e7f93b --- /dev/null +++ b/frontend/src/component/common/UserAvatar/UserAvatarWithPopover.tsx @@ -0,0 +1,92 @@ +import { styled, Popover } from '@mui/material'; +import { useState, type FC } from 'react'; +import type React from 'react'; +import { type IUserAvatarProps, UserAvatar } from './UserAvatar'; + +type PopoverProps = { + mainText: string; + open: boolean; + anchorEl: HTMLElement | null; + onPopoverClose(event: React.MouseEvent): void; +}; + +const StyledPopover = styled(Popover)(({ theme }) => ({ + pointerEvents: 'none', + '.MuiPaper-root': { + padding: theme.spacing(1), + }, +})); + +const AvatarPopover = ({ + mainText, + open, + anchorEl, + onPopoverClose, +}: PopoverProps) => { + return ( + +

{mainText}

+
+ ); +}; + +type UserAvatarWithPopoverProps = Omit< + IUserAvatarProps, + 'user' | 'onMouseEnter' | 'onMouseLeave' +> & { + user: { + name: string; + id?: number; + imageUrl?: string; + }; +}; + +export const UserAvatarWithPopover: FC = ({ + user, + ...userAvatarProps +}) => { + const [anchorEl, setAnchorEl] = useState(null); + const onPopoverOpen = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget); + }; + + const onPopoverClose = () => { + setAnchorEl(null); + }; + + const avatarOpen = Boolean(anchorEl); + + return ( + <> + { + onPopoverOpen(event); + }} + onMouseLeave={onPopoverClose} + /> + + + ); +}; diff --git a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx index cee05ff05f..ac8df912f6 100644 --- a/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx +++ b/frontend/src/component/project/Project/PaginatedProjectFeatureToggles/ProjectFeatureToggles.tsx @@ -39,7 +39,8 @@ import { useProjectFeatureSearch, useProjectFeatureSearchActions, } from './useProjectFeatureSearch'; -import { UserAvatar } from '../../../common/UserAvatar/UserAvatar'; +import { UserAvatarWithPopover } from '../../../common/UserAvatar/UserAvatarWithPopover'; +import type { Theme } from '@mui/material'; interface IPaginatedProjectFeatureTogglesProps { environments: string[]; @@ -176,13 +177,15 @@ export const ProjectFeatureToggles = ({ header: 'By', cell: ({ row: { original } }) => { return ( - theme.spacing(3)} + avatarWidth={(theme: Theme) => + theme.spacing(3) + } /> ); },