tweak the org plugin to better use builtin facilities

Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
Fredrik Adelöw
2021-03-26 10:14:02 +01:00
parent 22c5b750ad
commit 9f48b548c0
8 changed files with 73 additions and 118 deletions
@@ -15,14 +15,13 @@
*/
import {
Entity,
GroupEntity,
RELATION_CHILD_OF,
RELATION_PARENT_OF,
} from '@backstage/catalog-model';
import { Avatar, InfoCard, InfoCardVariants } from '@backstage/core';
import {
entityRouteParams,
EntityRefLinks,
getEntityRelations,
useEntity,
} from '@backstage/plugin-catalog-react';
@@ -41,34 +40,7 @@ import EmailIcon from '@material-ui/icons/Email';
import GroupIcon from '@material-ui/icons/Group';
import Alert from '@material-ui/lab/Alert';
import React from 'react';
import { generatePath, Link as RouterLink } from 'react-router-dom';
const GroupLink = ({
groupName,
index = 0,
}: {
groupName: string;
index?: number;
/** @deprecated The entity is now grabbed from context instead */
entity?: Entity;
}) => {
const { entity } = useEntity();
return (
<>
{index >= 1 ? ', ' : ''}
<Link
component={RouterLink}
to={generatePath(
`/catalog/:namespace/group/${groupName}`,
entityRouteParams(entity),
)}
>
[{groupName}]
</Link>
</>
);
};
const CardTitle = ({ title }: { title: string }) => (
<Box display="flex" alignItems="center">
<GroupIcon fontSize="inherit" />
@@ -83,23 +55,25 @@ export const GroupProfileCard = ({
entity?: GroupEntity;
variant?: InfoCardVariants;
}) => {
const group = useEntity().entity as GroupEntity;
const group = useEntity<GroupEntity>().entity;
if (!group) {
return <Alert severity="error">User not found</Alert>;
}
const {
metadata: { name, description },
spec: { profile },
} = group;
const parent = group?.relations
?.filter(r => r.type === RELATION_CHILD_OF)
?.map(groupItem => groupItem.target.name)
.toString();
const childRelations = getEntityRelations(group, RELATION_PARENT_OF, {
kind: 'Group',
});
const parentRelations = getEntityRelations(group, RELATION_CHILD_OF, {
kind: 'group',
});
const displayName = profile?.displayName ?? name;
if (!group) return <Alert severity="error">User not found</Alert>;
const emailHref = profile?.email ? `mailto:${profile.email}` : undefined;
return (
<InfoCard
@@ -120,10 +94,13 @@ export const GroupProfileCard = ({
<EmailIcon />
</Tooltip>
</ListItemIcon>
<ListItemText>{profile.email}</ListItemText>
<ListItemText>
<Link href={emailHref}>{profile.email}</Link>
</ListItemText>
</ListItem>
)}
{parent ? (
{parentRelations.length ? (
<ListItem>
<ListItemIcon>
<Tooltip title="Parent Group">
@@ -131,11 +108,15 @@ export const GroupProfileCard = ({
</Tooltip>
</ListItemIcon>
<ListItemText>
<GroupLink groupName={parent} entity={group} />
<EntityRefLinks
entityRefs={parentRelations}
defaultKind="Group"
/>
</ListItemText>
</ListItem>
) : null}
{childRelations?.length ? (
{childRelations.length ? (
<ListItem>
<ListItemIcon>
<Tooltip title="Child Groups">
@@ -143,13 +124,10 @@ export const GroupProfileCard = ({
</Tooltip>
</ListItemIcon>
<ListItemText>
{childRelations.map((children, index) => (
<GroupLink
groupName={children.name}
entity={group}
index={index}
/>
))}
<EntityRefLinks
entityRefs={childRelations}
defaultKind="Group"
/>
</ListItemText>
</ListItem>
) : null}
@@ -21,9 +21,9 @@ import {
} from '@backstage/catalog-model';
import { Avatar, InfoCard, Progress, useApi } from '@backstage/core';
import {
useEntity,
catalogApiRef,
entityRouteParams,
useEntity,
} from '@backstage/plugin-catalog-react';
import {
Box,
@@ -110,7 +110,7 @@ export const MembersListCard = (_props: {
/** @deprecated The entity is now grabbed from context instead */
entity?: GroupEntity;
}) => {
const groupEntity = useEntity().entity as GroupEntity;
const groupEntity = useEntity<GroupEntity>().entity;
const {
metadata: { name: groupName },
spec: { profile },
@@ -121,11 +121,9 @@ export const MembersListCard = (_props: {
const { loading, error, value: members } = useAsync(async () => {
const membersList = await catalogApi.getEntities({
filter: {
kind: 'User',
},
filter: { kind: 'User' },
});
const groupMembersList = ((membersList.items as unknown) as Array<UserEntity>).filter(
const groupMembersList = (membersList.items as UserEntity[]).filter(
member =>
member?.relations?.some(
r =>
@@ -150,7 +148,7 @@ export const MembersListCard = (_props: {
subheader={`of ${displayName}`}
>
<Grid container spacing={3}>
{members && members.length ? (
{members && members.length > 0 ? (
members.map(member => (
<MemberComponent
member={member}
@@ -61,7 +61,7 @@ describe('UserSummary Test', () => {
'src',
'https://example.com/staff/calum.jpeg',
);
expect(rendered.getByText('[ExampleGroup]')).toHaveAttribute(
expect(rendered.getByText('ExampleGroup')).toHaveAttribute(
'href',
'/catalog/default/group/ExampleGroup',
);
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
Entity,
RELATION_MEMBER_OF,
UserEntity,
} from '@backstage/catalog-model';
import { RELATION_MEMBER_OF, UserEntity } from '@backstage/catalog-model';
import { Avatar, InfoCard, InfoCardVariants } from '@backstage/core';
import { entityRouteParams, useEntity } from '@backstage/plugin-catalog-react';
import {
EntityRefLinks,
getEntityRelations,
useEntity,
} from '@backstage/plugin-catalog-react';
import {
Box,
Grid,
@@ -35,30 +35,6 @@ import GroupIcon from '@material-ui/icons/Group';
import PersonIcon from '@material-ui/icons/Person';
import Alert from '@material-ui/lab/Alert';
import React from 'react';
import { generatePath, Link as RouterLink } from 'react-router-dom';
const GroupLink = ({
groupName,
index,
entity,
}: {
groupName: string;
index: number;
entity: Entity;
}) => (
<>
{index >= 1 ? ', ' : ''}
<Link
component={RouterLink}
to={generatePath(
`/catalog/:namespace/group/${groupName}`,
entityRouteParams(entity),
)}
>
[{groupName}]
</Link>
</>
);
const CardTitle = ({ title }: { title?: string }) =>
title ? (
@@ -75,22 +51,20 @@ export const UserProfileCard = ({
entity?: UserEntity;
variant?: InfoCardVariants;
}) => {
const user = useEntity().entity as UserEntity;
const {
metadata: { name: metaName },
spec: { profile },
} = user;
const groupNames =
user?.relations
?.filter(r => r.type === RELATION_MEMBER_OF)
?.map(group => group.target.name) || [];
const displayName = profile?.displayName ?? metaName;
const user = useEntity<UserEntity>().entity;
if (!user) {
return <Alert severity="error">User not found</Alert>;
}
const emailHref = profile?.email ? `mailto:${profile.email}` : '';
const {
metadata: { name: metaName },
spec: { profile },
} = user;
const displayName = profile?.displayName ?? metaName;
const emailHref = profile?.email ? `mailto:${profile.email}` : undefined;
const memberOfRelations = getEntityRelations(user, RELATION_MEMBER_OF, {
kind: 'Group',
});
return (
<InfoCard title={<CardTitle title={displayName} />} variant={variant}>
@@ -104,7 +78,9 @@ export const UserProfileCard = ({
{profile?.email && (
<ListItem>
<ListItemIcon>
<EmailIcon />
<Tooltip title="Email">
<EmailIcon />
</Tooltip>
</ListItemIcon>
<ListItemText>
<Link href={emailHref}>{profile.email}</Link>
@@ -119,14 +95,10 @@ export const UserProfileCard = ({
</Tooltip>
</ListItemIcon>
<ListItemText>
{groupNames.map((groupName, index) => (
<GroupLink
groupName={groupName}
index={index}
key={groupName}
entity={user}
/>
))}
<EntityRefLinks
entityRefs={memberOfRelations}
defaultKind="Group"
/>
</ListItemText>
</ListItem>
</List>