import { css, cx } from '@emotion/css'; import React, { FC } from 'react'; import { GrafanaTheme, dateTime } from '@grafana/data'; import { Button, stylesFactory, Tooltip, useTheme } from '@grafana/ui'; import { UserViewDTO } from './api'; const getIconBorder = (color: string): string => { return `0 0 0 1px ${color}`; }; export const getUserIconStyles = stylesFactory((theme: GrafanaTheme, isActive: boolean, showBorder: boolean) => { const shadowColor = isActive ? theme.palette.blue80 : theme.colors.border2; const shadowHoverColor = isActive ? theme.palette.blue95 : theme.colors.border3; const borderColor = showBorder ? theme.colors.dashboardBg : 'transparent'; return { icon: css` border-radius: 50%; width: 30px; height: 30px; margin-left: -6px; border: 3px ${borderColor} solid; box-shadow: ${getIconBorder(shadowColor)}; background-clip: padding-box; &:hover { background-clip: padding-box; box-shadow: ${getIconBorder(shadowHoverColor)}; } `, textIcon: css` padding: 0px; text-align: center; line-height: 22px; justify-content: center; color: ${theme.colors.textSemiWeak}; cursor: auto; font-size: ${theme.typography.size.sm}; background: ${theme.isDark ? theme.palette.dark9 : theme.palette.gray90}; &:focus { box-shadow: ${getIconBorder(shadowColor)}; } &:hover { background: ${theme.isDark ? theme.palette.dark10 : theme.palette.gray95}; } `, tooltipContainer: css` text-align: center; padding: 0px ${theme.spacing.sm}; `, tooltipName: css` font-weight: ${theme.typography.weight.bold}; `, tooltipDate: css` font-weight: ${theme.typography.weight.regular}; `, dot: css` height: 6px; width: 6px; background-color: ${theme.palette.blue80}; border-radius: 50%; display: inline-block; margin-left: 6px; margin-bottom: 1px; `, }; }); export interface UserIconProps { userView: UserViewDTO; showTooltip?: boolean; showBorder?: boolean; className?: string; } const formatViewed = (dateString: string): string => { const date = dateTime(dateString); const diffHours = date.diff(dateTime(), 'hours', false); return `Active last ${(Math.floor(-diffHours / 24) + 1) * 24}h`; }; export const UserIcon: FC = ({ userView, showTooltip = true, showBorder = false, className }) => { const { user, viewed } = userView; const isActive = dateTime(viewed).diff(dateTime(), 'minutes', true) >= -15; const theme = useTheme(); const styles = getUserIconStyles(theme, isActive, showBorder); const userDisplayName = user.name || user.login; const initialsArray = userDisplayName.split(' '); const initials = ( (initialsArray.shift()?.slice(0, 1) || '') + (initialsArray.pop()?.slice(0, 1) || '') ).toUpperCase(); const content = user.avatarUrl && user.hasCustomAvatar ? ( {`${initials} ) : ( ); if (showTooltip) { const tooltip = (
{userDisplayName}
{isActive ? ( <> Active last 15m ) : ( formatViewed(viewed) )}
); return ( {content} ); } else { return content; } };