UNPKG

@grafana/ui

Version:
140 lines (137 loc) 4.92 kB
import { jsx, jsxs } from 'react/jsx-runtime'; import { cx, css } from '@emotion/css'; import { useMemo } from 'react'; import { dateTime } from '@grafana/data'; import { t, Trans } from '@grafana/i18n'; import { useTheme2 } from '../../themes/ThemeContext.mjs'; import { Tooltip } from '../Tooltip/Tooltip.mjs'; "use strict"; const formatViewed = (dateString) => { const date = dateTime(dateString); const diffHours = date.diff(dateTime(), "hours", false); return `Active last ${(Math.floor(-diffHours / 24) + 1) * 24}h`; }; const getUserInitials = (name) => { var _a, _b; if (!name) { return ""; } const [first, last] = name.split(" "); return `${(_a = first == null ? void 0 : first[0]) != null ? _a : ""}${(_b = last == null ? void 0 : last[0]) != null ? _b : ""}`.toUpperCase(); }; const UserIcon = ({ userView, className, children, onClick, showTooltip = true }) => { const { user, lastActiveAt } = userView; const hasActive = lastActiveAt !== void 0 && lastActiveAt !== null; const isActive = hasActive && dateTime(lastActiveAt).diff(dateTime(), "minutes", true) >= -15; const theme = useTheme2(); const styles = useMemo(() => getStyles(theme, isActive), [theme, isActive]); const content = children ? /* @__PURE__ */ jsx("div", { className: cx(styles.content, styles.textContent), children }) : user.avatarUrl ? /* @__PURE__ */ jsx("img", { className: styles.content, src: user.avatarUrl, alt: `${user.name} avatar` }) : /* @__PURE__ */ jsx("div", { className: cx(styles.content, styles.textContent), children: getUserInitials(user.name) }); const wrapper = onClick ? /* @__PURE__ */ jsx( "button", { type: "button", onClick, className: cx(styles.container, styles.hover, styles.pointer, className), "aria-label": t("grafana-ui.user-icon.label", "{{name}} icon", { name: user.name }), children: content } ) : ( // a11y: don't render an interactive button if icon is not clickable /* @__PURE__ */ jsx( "div", { "aria-label": t("grafana-ui.user-icon.label", "{{name}} icon", { name: user.name }), className: cx(styles.container, className), children: content } ) ); if (showTooltip) { const tooltip = /* @__PURE__ */ jsxs("div", { className: styles.tooltipContainer, "data-testid": "user-icon-tooltip", children: [ /* @__PURE__ */ jsx("div", { className: styles.tooltipName, children: user.name }), hasActive && /* @__PURE__ */ jsx("div", { className: styles.tooltipDate, children: isActive ? /* @__PURE__ */ jsxs("div", { className: styles.dotContainer, children: [ /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(Trans, { i18nKey: "grafana-ui.user-icon.active-text", children: "Active last 15m" }) }), /* @__PURE__ */ jsx("span", { className: styles.dot }) ] }) : formatViewed(lastActiveAt) }) ] }); return /* @__PURE__ */ jsx(Tooltip, { content: tooltip, children: wrapper }); } else { return wrapper; } }; const getIconBorder = (color) => { return `0 0 0 1px ${color}`; }; const getStyles = (theme, isActive) => { const shadowColor = isActive ? theme.colors.primary.main : theme.colors.border.medium; const shadowHoverColor = isActive ? theme.colors.primary.text : theme.colors.border.strong; return { container: css({ padding: 0, width: "30px", height: "30px", background: "none", border: "none", borderRadius: theme.shape.radius.circle, cursor: "default", "& > *": { borderRadius: theme.shape.radius.circle } }), content: css({ lineHeight: "24px", maxWidth: "100%", border: `3px ${theme.colors.background.primary} solid`, boxShadow: getIconBorder(shadowColor), backgroundClip: "padding-box" }), textContent: css({ background: theme.colors.background.primary, padding: 0, color: theme.colors.text.secondary, textAlign: "center", fontSize: theme.typography.size.sm, "&:focus": { boxShadow: getIconBorder(shadowColor) } }), tooltipContainer: css({ textAlign: "center", padding: theme.spacing(0, 1) }), tooltipName: css({ fontWeight: theme.typography.fontWeightBold }), tooltipDate: css({ fontWeight: theme.typography.fontWeightRegular }), dotContainer: css({ display: "flex", alignItems: "center" }), dot: css({ height: "6px", width: "6px", backgroundColor: theme.colors.primary.main, borderRadius: theme.shape.radius.circle, display: "inline-block", marginLeft: theme.spacing(1) }), pointer: css({ cursor: "pointer" }), hover: css({ "&:hover > *": { boxShadow: getIconBorder(shadowHoverColor) } }) }; }; export { UserIcon }; //# sourceMappingURL=UserIcon.mjs.map