refactor(org): use BUI Avatar in GroupProfileCard and UserProfileCard titles

Signed-off-by: Johan Persson <johanopersson@gmail.com>
This commit is contained in:
Johan Persson
2026-03-02 11:27:19 +01:00
parent 809eefb91c
commit 951997f7f0
2 changed files with 70 additions and 72 deletions
@@ -22,8 +22,7 @@ import {
RELATION_PARENT_OF,
stringifyEntityRef,
} from '@backstage/catalog-model';
import { Avatar, Link } from '@backstage/core-components';
import Box from '@material-ui/core/Box';
import { Link } from '@backstage/core-components';
import IconButton from '@material-ui/core/IconButton';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
@@ -53,7 +52,7 @@ import { catalogEntityRefreshPermission } from '@backstage/plugin-catalog-common
import { useTranslationRef } from '@backstage/frontend-plugin-api';
import { orgTranslationRef } from '../../../../translation';
import { makeStyles } from '@material-ui/core/styles';
import { Flex, Text } from '@backstage/ui';
import { Avatar, Flex, Box, Text } from '@backstage/ui';
const useStyles = makeStyles(theme => ({
container: {
@@ -68,9 +67,14 @@ const useStyles = makeStyles(theme => ({
},
}));
const CardTitle = (props: { title: string }) => (
<Flex align="center" gap="1">
<GroupIcon fontSize="inherit" />
const CardTitle = (props: { title: string; pictureSrc?: string }) => (
<Flex align="center" gap="2">
<Avatar
size="small"
purpose="decoration"
name={props.title}
src={props.pictureSrc || ''}
/>
{props.title}
</Flex>
);
@@ -150,7 +154,7 @@ export const GroupProfileCard = (props: {
return (
<EntityInfoCard
title={<CardTitle title={displayName} />}
title={<CardTitle title={displayName} pictureSrc={profile?.picture} />}
headerActions={
<>
{allowRefresh && canRefresh && (
@@ -167,8 +171,7 @@ export const GroupProfileCard = (props: {
}
>
{description && <Text color="secondary">{description}</Text>}
<Box className={classes.container}>
<Avatar displayName={displayName} picture={profile?.picture} />
<Box p="2">
<List className={classes.list}>
<ListItem>
<ListItemIcon>
@@ -19,11 +19,10 @@ import {
RELATION_MEMBER_OF,
UserEntity,
} from '@backstage/catalog-model';
import { Avatar, Link } from '@backstage/core-components';
import { Link } from '@backstage/core-components';
import { EntityInfoCard } from '@backstage/plugin-catalog-react';
import { Flex, Text } from '@backstage/ui';
import { Avatar, Box, Flex, Text } from '@backstage/ui';
import { createStyles, makeStyles } from '@material-ui/core/styles';
import Grid from '@material-ui/core/Grid';
import BaseButton from '@material-ui/core/ButtonBase';
import IconButton from '@material-ui/core/IconButton';
import List from '@material-ui/core/List';
@@ -48,7 +47,6 @@ import EditIcon from '@material-ui/icons/Edit';
import EmailIcon from '@material-ui/icons/Email';
import GroupIcon from '@material-ui/icons/Group';
import { LinksGroup } from '../../Meta';
import PersonIcon from '@material-ui/icons/Person';
import { useCallback, useState } from 'react';
import { useTranslationRef } from '@backstage/frontend-plugin-api';
@@ -80,10 +78,15 @@ const useStyles = makeStyles(
{ name: 'PluginOrgUserProfileCard' },
);
const CardTitle = (props: { title?: string }) =>
const CardTitle = (props: { title: string; pictureSrc?: string }) =>
props.title ? (
<Flex align="center" gap="1">
<PersonIcon fontSize="inherit" />
<Flex align="center" gap="2">
<Avatar
size="small"
purpose="decoration"
name={props.title}
src={props.pictureSrc || ''}
/>
{props.title}
</Flex>
) : null;
@@ -132,7 +135,7 @@ export const UserProfileCard = (props: {
return (
<EntityInfoCard
title={<CardTitle title={displayName} />}
title={<CardTitle title={displayName} pictureSrc={profile?.picture} />}
headerActions={
<>
{entityMetadataEditUrl && (
@@ -149,62 +152,54 @@ export const UserProfileCard = (props: {
}
>
{description && <Text color="secondary">{description}</Text>}
<Grid container spacing={3} alignItems="flex-start">
<Grid item xs={12} sm={2} xl={1}>
<Avatar displayName={displayName} picture={profile?.picture} />
</Grid>
<Box p="2">
<List>
{profile?.email && (
<ListItem>
<ListItemIcon>
<Tooltip title={t('userProfileCard.listItemTitle.email')}>
<EmailIcon />
</Tooltip>
</ListItemIcon>
<ListItemText>
<Link to={emailHref ?? ''}>{profile.email}</Link>
</ListItemText>
</ListItem>
)}
<Grid item md={10} xl={11}>
<List>
{profile?.email && (
<ListItem>
<ListItemIcon>
<Tooltip title={t('userProfileCard.listItemTitle.email')}>
<EmailIcon />
</Tooltip>
</ListItemIcon>
<ListItemText>
<Link to={emailHref ?? ''}>{profile.email}</Link>
</ListItemText>
</ListItem>
)}
{maxRelations === undefined || maxRelations > 0 ? (
<ListItem>
<ListItemIcon>
<Tooltip title={t('userProfileCard.listItemTitle.memberOf')}>
<GroupIcon />
</Tooltip>
</ListItemIcon>
<ListItemText>
<EntityRefLinks
entityRefs={memberOfRelations.slice(0, maxRelations)}
defaultKind="Group"
hideIcons={hideIcons}
/>
{maxRelations && memberOfRelations.length > maxRelations ? (
<>
,
<BaseButton
className={classes.moreButton}
onClick={toggleAllGroupsDialog}
disableRipple
>
{t('userProfileCard.moreGroupButtonTitle', {
number: String(
memberOfRelations.length - maxRelations,
),
})}
</BaseButton>
</>
) : null}
</ListItemText>
</ListItem>
) : null}
{props?.showLinks && <LinksGroup links={links} />}
</List>
</Grid>
</Grid>
{maxRelations === undefined || maxRelations > 0 ? (
<ListItem>
<ListItemIcon>
<Tooltip title={t('userProfileCard.listItemTitle.memberOf')}>
<GroupIcon />
</Tooltip>
</ListItemIcon>
<ListItemText>
<EntityRefLinks
entityRefs={memberOfRelations.slice(0, maxRelations)}
defaultKind="Group"
hideIcons={hideIcons}
/>
{maxRelations && memberOfRelations.length > maxRelations ? (
<>
,
<BaseButton
className={classes.moreButton}
onClick={toggleAllGroupsDialog}
disableRipple
>
{t('userProfileCard.moreGroupButtonTitle', {
number: String(memberOfRelations.length - maxRelations),
})}
</BaseButton>
</>
) : null}
</ListItemText>
</ListItem>
) : null}
{props?.showLinks && <LinksGroup links={links} />}
</List>
</Box>
<Dialog
classes={{ paper: classes.dialogPaper }}