UI: Allow lastActiveAt to be optional for UserIcon UserView (#115887)

Allow lastActiveAt to be optional for UserIcon UserView
This commit is contained in:
Matt Cowley
2026-01-06 16:18:25 +00:00
committed by GitHub
parent 5eb0e6f432
commit 8ff88036e7
5 changed files with 22 additions and 19 deletions
@@ -66,6 +66,6 @@ export interface UserView {
avatarUrl?: string;
};
/** Datetime string when the user was last active */
lastActiveAt: DateTimeInput;
lastActiveAt?: DateTimeInput;
}
```
@@ -10,7 +10,7 @@ import { Tooltip } from '../Tooltip/Tooltip';
import { UserView } from './types';
export interface UserIconProps {
/** An object that contains the user's details and 'lastActiveAt' status */
/** An object that contains the user's details and an optional 'lastActiveAt' status */
userView: UserView;
/** A boolean value that determines whether the tooltip should be shown or not */
showTooltip?: boolean;
@@ -64,7 +64,8 @@ export const UserIcon = ({
showTooltip = true,
}: PropsWithChildren<UserIconProps>) => {
const { user, lastActiveAt } = userView;
const isActive = dateTime(lastActiveAt).diff(dateTime(), 'minutes', true) >= -15;
const hasActive = lastActiveAt !== undefined && 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 = (
@@ -88,18 +89,20 @@ export const UserIcon = ({
const tooltip = (
<div className={styles.tooltipContainer}>
<div className={styles.tooltipName}>{user.name}</div>
<div className={styles.tooltipDate}>
{isActive ? (
<div className={styles.dotContainer}>
<span>
<Trans i18nKey="grafana-ui.user-icon.active-text">Active last 15m</Trans>
</span>
<span className={styles.dot}></span>
</div>
) : (
formatViewed(lastActiveAt)
)}
</div>
{hasActive && (
<div className={styles.tooltipDate}>
{isActive ? (
<div className={styles.dotContainer}>
<span>
<Trans i18nKey="grafana-ui.user-icon.active-text">Active last 15m</Trans>
</span>
<span className={styles.dot}></span>
</div>
) : (
formatViewed(lastActiveAt)
)}
</div>
)}
</div>
);
@@ -60,6 +60,6 @@ export interface UserView {
avatarUrl?: string;
};
/** Datetime string when the user was last active */
lastActiveAt: DateTimeInput;
lastActiveAt?: DateTimeInput;
}
```
@@ -9,7 +9,7 @@ import { UserIcon } from './UserIcon';
import { UserView } from './types';
export interface UsersIndicatorProps {
/** An object that contains the user's details and 'lastActiveAt' status */
/** An object that contains the user's details and an optional 'lastActiveAt' status */
users: UserView[];
/** A limit of how many user icons to show before collapsing them and showing a number of users instead */
limit?: number;
@@ -40,7 +40,7 @@ export const UsersIndicator = ({ users, onClick, limit = 4 }: UsersIndicatorProp
aria-label={t('grafana-ui.users-indicator.container-label', 'Users indicator container')}
>
{limitReached && (
<UserIcon onClick={onClick} userView={{ user: { name: 'Extra users' }, lastActiveAt: '' }} showTooltip={false}>
<UserIcon onClick={onClick} userView={{ user: { name: 'Extra users' } }} showTooltip={false}>
{tooManyUsers
? // eslint-disable-next-line @grafana/i18n/no-untranslated-strings
'...'
@@ -8,5 +8,5 @@ export interface UserView {
avatarUrl?: string;
};
/** Datetime string when the user was last active */
lastActiveAt: DateTimeInput;
lastActiveAt?: DateTimeInput;
}