@grafana/ui
Version:
Grafana Components Library
125 lines (122 loc) • 4.39 kB
JavaScript
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 isActive = dateTime(lastActiveAt).diff(dateTime(), "minutes", true) >= -15;
const theme = useTheme2();
const styles = useMemo(() => getStyles(theme, isActive), [theme, isActive]);
const content = /* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick,
className: cx(styles.container, onClick && styles.pointer, className),
"aria-label": t("grafana-ui.user-icon.label", "{{name}} icon", { name: user.name }),
children: 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) })
}
);
if (showTooltip) {
const tooltip = /* @__PURE__ */ jsxs("div", { className: styles.tooltipContainer, children: [
/* @__PURE__ */ jsx("div", { className: styles.tooltipName, children: user.name }),
/* @__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: content });
} else {
return content;
}
};
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,
"& > *": {
borderRadius: theme.shape.radius.circle
}
}),
content: css({
lineHeight: "24px",
maxWidth: "100%",
border: `3px ${theme.colors.background.primary} solid`,
boxShadow: getIconBorder(shadowColor),
backgroundClip: "padding-box",
"&:hover": {
boxShadow: getIconBorder(shadowHoverColor)
}
}),
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"
})
};
};
export { UserIcon, getStyles };
//# sourceMappingURL=UserIcon.mjs.map