diff --git a/.changeset/groups_profile.png b/.changeset/groups_profile.png
new file mode 100644
index 0000000000..417faaa4af
Binary files /dev/null and b/.changeset/groups_profile.png differ
diff --git a/.changeset/tender-coats-unite.md b/.changeset/tender-coats-unite.md
new file mode 100644
index 0000000000..018660bcfa
--- /dev/null
+++ b/.changeset/tender-coats-unite.md
@@ -0,0 +1,11 @@
+---
+'@backstage/plugin-org': patch
+---
+
+Display the new `profile` fields (`displayName`, `email`, and `picture`) for
+groups on the `GroupProfileCard`.
+
+
+
+This also resolves some cases where `profile` fields are missing for users or
+groups and for example falls back to displaying the entity name. Adds additional test data to the ACME Corp dataset.
diff --git a/packages/catalog-model/examples-relative/acme/backstage-group.yaml b/packages/catalog-model/examples-relative/acme/backstage-group.yaml
index f992d155bc..1cfd469e99 100644
--- a/packages/catalog-model/examples-relative/acme/backstage-group.yaml
+++ b/packages/catalog-model/examples-relative/acme/backstage-group.yaml
@@ -5,6 +5,10 @@ metadata:
description: The backstage sub-department
spec:
type: sub-department
+ profile:
+ displayName: Backstage
+ email: backstage@example.com
+ picture: https://example.com/groups/backstage.jpeg
parent: infrastructure
ancestors: [infrastructure, acme-corp]
children: [team-a, team-b]
diff --git a/packages/catalog-model/examples-relative/acme/boxoffice-group.yaml b/packages/catalog-model/examples-relative/acme/boxoffice-group.yaml
index 0be1fe58cb..4bb742bdb1 100644
--- a/packages/catalog-model/examples-relative/acme/boxoffice-group.yaml
+++ b/packages/catalog-model/examples-relative/acme/boxoffice-group.yaml
@@ -5,6 +5,10 @@ metadata:
description: The boxoffice sub-department
spec:
type: sub-department
+ profile:
+ displayName: Box Office
+ email: boxoffice@example.com
+ # Intentional no picture for testing
parent: infrastructure
ancestors: [infrastructure, acme-corp]
children: [team-c, team-d]
diff --git a/packages/catalog-model/examples-relative/acme/infrastructure-group.yaml b/packages/catalog-model/examples-relative/acme/infrastructure-group.yaml
index 2341782944..acfeef642c 100644
--- a/packages/catalog-model/examples-relative/acme/infrastructure-group.yaml
+++ b/packages/catalog-model/examples-relative/acme/infrastructure-group.yaml
@@ -5,6 +5,7 @@ metadata:
description: The infra department
spec:
type: department
+ # Intentional no profile for testing
parent: acme-corp
ancestors: [acme-corp]
children: [backstage, boxoffice]
diff --git a/packages/catalog-model/examples-relative/acme/org.yaml b/packages/catalog-model/examples-relative/acme/org.yaml
index fe368962b1..58cce827ff 100644
--- a/packages/catalog-model/examples-relative/acme/org.yaml
+++ b/packages/catalog-model/examples-relative/acme/org.yaml
@@ -5,6 +5,10 @@ metadata:
description: The acme-corp organization
spec:
type: organization
+ profile:
+ displayName: ACME Corp
+ email: info@example.com
+ picture: https://example.com/logo.jpeg
ancestors: []
children: [infrastructure]
descendants:
diff --git a/packages/catalog-model/examples-relative/acme/team-a-group.yaml b/packages/catalog-model/examples-relative/acme/team-a-group.yaml
index 8dbf0bb839..53d4bb8d80 100644
--- a/packages/catalog-model/examples-relative/acme/team-a-group.yaml
+++ b/packages/catalog-model/examples-relative/acme/team-a-group.yaml
@@ -5,6 +5,10 @@ metadata:
description: Team A
spec:
type: team
+ profile:
+ # Intentional no displayName for testing
+ email: team-a@example.com
+ picture: https://example.com/groups/team-a.jpeg
parent: backstage
ancestors: [backstage, infrastructure, acme-corp]
children: []
@@ -16,7 +20,7 @@ metadata:
name: breanna.davison
spec:
profile:
- displayName: Breanna Davison
+ # Intentional no displayName for testing
email: breanna-davison@example.com
picture: https://example.com/staff/breanna.jpeg
memberOf: [team-a]
diff --git a/packages/catalog-model/examples-relative/acme/team-b-group.yaml b/packages/catalog-model/examples-relative/acme/team-b-group.yaml
index 00e9e41d80..a59a24317d 100644
--- a/packages/catalog-model/examples-relative/acme/team-b-group.yaml
+++ b/packages/catalog-model/examples-relative/acme/team-b-group.yaml
@@ -5,6 +5,10 @@ metadata:
description: Team B
spec:
type: team
+ profile:
+ displayName: Team B
+ email: team-b@example.com
+ picture: https://example.com/groups/team-b.jpeg
parent: backstage
ancestors: [backstage, infrastructure, acme-corp]
children: []
diff --git a/packages/catalog-model/examples-relative/acme/team-c-group.yaml b/packages/catalog-model/examples-relative/acme/team-c-group.yaml
index 0f97f69cb3..31f67ac362 100644
--- a/packages/catalog-model/examples-relative/acme/team-c-group.yaml
+++ b/packages/catalog-model/examples-relative/acme/team-c-group.yaml
@@ -5,6 +5,10 @@ metadata:
description: Team C
spec:
type: team
+ profile:
+ displayName: Team C
+ email: team-c@example.com
+ picture: https://example.com/groups/team-c.jpeg
parent: boxoffice
ancestors: [boxoffice, infrastructure, acme-corp]
children: []
diff --git a/packages/catalog-model/examples-relative/acme/team-d-group.yaml b/packages/catalog-model/examples-relative/acme/team-d-group.yaml
index 5a1a53a2e6..c4f87b3ac3 100644
--- a/packages/catalog-model/examples-relative/acme/team-d-group.yaml
+++ b/packages/catalog-model/examples-relative/acme/team-d-group.yaml
@@ -5,6 +5,10 @@ metadata:
description: Team D
spec:
type: team
+ profile:
+ displayName: Team D
+ email: team-d@example.com
+ picture: https://example.com/groups/team-d.jpeg
parent: boxoffice
ancestors: [boxoffice, infrastructure, acme-corp]
children: []
diff --git a/plugins/catalog-backend/src/ingestion/processors/microsoftGraph/read.test.ts b/plugins/catalog-backend/src/ingestion/processors/microsoftGraph/read.test.ts
index d8598da1a9..07d540c848 100644
--- a/plugins/catalog-backend/src/ingestion/processors/microsoftGraph/read.test.ts
+++ b/plugins/catalog-backend/src/ingestion/processors/microsoftGraph/read.test.ts
@@ -253,8 +253,10 @@ describe('read microsoft graph', () => {
});
expect(client.getGroupMembers).toBeCalledTimes(1);
expect(client.getGroupMembers).toBeCalledWith('groupid');
- expect(client.getGroupPhotoWithSizeLimit).toBeCalledTimes(1);
- expect(client.getGroupPhotoWithSizeLimit).toBeCalledWith('groupid', 120);
+ // TODO: Loading groups doesn't work right now as Microsoft Graph
+ // doesn't allows this yet
+ // expect(client.getGroupPhotoWithSizeLimit).toBeCalledTimes(1);
+ // expect(client.getGroupPhotoWithSizeLimit).toBeCalledWith('groupid', 120);
});
});
diff --git a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx
index a2582195b9..779cb1d92d 100644
--- a/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx
+++ b/plugins/org/src/components/Cards/Group/GroupProfile/GroupProfileCard.tsx
@@ -14,20 +14,21 @@
* limitations under the License.
*/
-import React from 'react';
-import { Box, Grid, Link, Tooltip, Typography } from '@material-ui/core';
-import Alert from '@material-ui/lab/Alert';
-import { InfoCard } from '@backstage/core';
-import { entityRouteParams } from '@backstage/plugin-catalog';
import {
Entity,
GroupEntity,
RELATION_CHILD_OF,
RELATION_PARENT_OF,
} from '@backstage/catalog-model';
+import { Avatar, InfoCard } from '@backstage/core';
+import { entityRouteParams } from '@backstage/plugin-catalog';
+import { Box, Grid, Link, Tooltip, Typography } from '@material-ui/core';
import AccountTreeIcon from '@material-ui/icons/AccountTree';
+import EmailIcon from '@material-ui/icons/Email';
import GroupIcon from '@material-ui/icons/Group';
-import { Link as RouterLink, generatePath } from 'react-router-dom';
+import Alert from '@material-ui/lab/Alert';
+import React from 'react';
+import { generatePath, Link as RouterLink } from 'react-router-dom';
const GroupLink = ({
groupName,
@@ -68,6 +69,7 @@ export const GroupProfileCard = ({
}) => {
const {
metadata: { name, description },
+ spec: { profile },
} = group;
const parent = group?.relations
?.filter(r => r.type === RELATION_CHILD_OF)
@@ -78,16 +80,42 @@ export const GroupProfileCard = ({
?.filter(r => r.type === RELATION_PARENT_OF)
?.map(group => group.target.name);
+ const displayName = profile?.displayName ?? name;
+
if (!group) return User not found;
return (
}
+ title={}
subheader={description}
variant={variant}
>
-
+
+
+
+
+
+
+ {profile?.email && (
+
+
+
+
+
+
+
+ {profile.email}
+
+
+
+ )}
{parent ? (
diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
index 0c188afc57..535b2acd0e 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
@@ -18,12 +18,12 @@ import { renderWithEffects, wrapInTestApp } from '@backstage/test-utils';
import React from 'react';
import { ApiProvider, ApiRegistry } from '@backstage/core';
import { CatalogApi, catalogApiRef } from '@backstage/plugin-catalog';
-import { Entity } from '@backstage/catalog-model';
+import { Entity, GroupEntity } from '@backstage/catalog-model';
import { MembersListCard } from './MembersListCard';
describe('MemberTab Test', () => {
- const groupEntity = {
- apiVersion: 'v1',
+ const groupEntity: GroupEntity = {
+ apiVersion: 'backstage.io/v1alpha1',
kind: 'Group',
metadata: {
name: 'team-d',
@@ -33,9 +33,7 @@ describe('MemberTab Test', () => {
spec: {
type: 'team',
parent: 'boxoffice',
- ancestors: ['boxoffice', 'acme-corp'],
children: [],
- descendants: [],
},
};
diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
index 6f1986d2b4..579db9d9a5 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
@@ -15,6 +15,7 @@
*/
import {
Entity,
+ GroupEntity,
RELATION_MEMBER_OF,
UserEntity,
} from '@backstage/catalog-model';
@@ -42,7 +43,9 @@ const useStyles = makeStyles((theme: Theme) =>
borderRadius: '4px',
overflow: 'visible',
position: 'relative',
- margin: theme.spacing(3, 0, 0),
+ margin: theme.spacing(3, 0, 1),
+ flex: '1',
+ minWidth: '0px',
},
}),
);
@@ -55,12 +58,14 @@ const MemberComponent = ({
groupEntity: Entity;
}) => {
const classes = useStyles();
- const { name: metaName } = member.metadata;
- const { profile } = member.spec;
+ const {
+ metadata: { name: metaName },
+ spec: { profile },
+ } = member;
const displayName = profile?.displayName ?? metaName;
return (
-
+
{
const {
metadata: { name: groupName },
+ spec: { profile },
} = groupEntity;
const catalogApi = useApi(catalogApiRef);
+ const displayName = profile?.displayName ?? groupName;
+
const { loading, error, value: members } = useAsync(async () => {
const membersList = await catalogApi.getEntities({
filter: {
@@ -133,7 +141,7 @@ export const MembersListCard = ({
{members && members.length ? (
diff --git a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx
index c984d347e7..99048c0cd8 100644
--- a/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx
+++ b/plugins/org/src/components/Cards/User/UserProfileCard/UserProfileCard.tsx
@@ -74,7 +74,6 @@ export const UserProfileCard = ({
user?.relations
?.filter(r => r.type === RELATION_MEMBER_OF)
?.map(group => group.target.name) || [];
-
const displayName = profile?.displayName ?? metaName;
if (!user) {
@@ -96,18 +95,19 @@ export const UserProfileCard = ({
-
-
-
-
-
- {profile?.email && (
+ {profile?.email && (
+
+
+
+
+
+
{profile.email}
- )}
-
-
+
+
+ )}