diff --git a/.changeset/slimy-icons-swim.md b/.changeset/slimy-icons-swim.md
new file mode 100644
index 0000000000..52e2769e51
--- /dev/null
+++ b/.changeset/slimy-icons-swim.md
@@ -0,0 +1,6 @@
+---
+'@backstage/plugin-org': patch
+---
+
+Add `relationsType` argument to `MembersListCard`.
+This can be used to display an aggregated user list for groups by default.
diff --git a/plugins/org/api-report.md b/plugins/org/api-report.md
index 922b25b610..1960ce839b 100644
--- a/plugins/org/api-report.md
+++ b/plugins/org/api-report.md
@@ -23,6 +23,7 @@ export const EntityMembersListCard: (props: {
memberDisplayTitle?: string | undefined;
pageSize?: number | undefined;
showAggregateMembersToggle?: boolean | undefined;
+ relationsType?: EntityRelationAggregation | undefined;
}) => JSX_2.Element;
// @public (undocumented)
@@ -54,6 +55,7 @@ export const MembersListCard: (props: {
memberDisplayTitle?: string;
pageSize?: number;
showAggregateMembersToggle?: boolean;
+ relationsType?: EntityRelationAggregation;
}) => React_2.JSX.Element;
// @public
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 cd5801ac71..06ec3b0ebd 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
@@ -311,15 +311,20 @@ describe('MemberTab Test', () => {
},
},
);
+
+ // Should show only direct users on initial load
+ const displayedMemberNamesBefore = screen.queryAllByTestId('user-link');
+ expect(displayedMemberNamesBefore).toHaveLength(2);
+
// Click the toggle switch
await userEvent.click(screen.getByRole('checkbox'));
- const displayedMemberNames = screen.queryAllByTestId('user-link');
+ const displayedMemberNamesAfter = screen.queryAllByTestId('user-link');
const duplicatedUserText = screen.getByText('Duplicated User');
const groupAUserOneText = screen.getByText('Group A User One');
const groupBUserOneText = screen.getByText('Group B User One');
const groupDUserOneText = screen.getByText('Group D User One');
const groupEUserOneText = screen.getByText('Group E User One');
- expect(displayedMemberNames).toHaveLength(5);
+ expect(displayedMemberNamesAfter).toHaveLength(5);
expect(duplicatedUserText).toBeInTheDocument();
expect(groupAUserOneText).toBeInTheDocument();
expect(groupBUserOneText).toBeInTheDocument();
@@ -339,4 +344,77 @@ describe('MemberTab Test', () => {
);
});
});
+
+ it('Can default to show aggregated members with the aggregate members toggle', async () => {
+ await renderInTestApp(
+
+
+
+
+
+
+
+
+ ,
+ {
+ mountedRoutes: {
+ '/catalog/:namespace/:kind/:name': entityRouteRef,
+ '/catalog': rootRouteRef,
+ },
+ },
+ );
+
+ // Should show aggregated users on initial load
+ const displayedMemberNamesBefore = screen.queryAllByTestId('user-link');
+ expect(displayedMemberNamesBefore).toHaveLength(5);
+
+ // Click the toggle switch
+ await userEvent.click(screen.getByRole('checkbox'));
+
+ // Should now show only direct users
+ const displayedMemberNamesAfter = screen.queryAllByTestId('user-link');
+ expect(displayedMemberNamesAfter).toHaveLength(2);
+ });
+
+ it('Can show aggregated members without the aggregate members toggle', async () => {
+ await renderInTestApp(
+
+
+
+
+
+
+
+
+ ,
+ {
+ mountedRoutes: {
+ '/catalog/:namespace/:kind/:name': entityRouteRef,
+ '/catalog': rootRouteRef,
+ },
+ },
+ );
+
+ // aggregated relations checkbox should not be rendered
+ expect(screen.queryByRole('checkbox')).toBeNull();
+
+ // Should show all descendant users on load
+ const displayedMemberNames = screen.queryAllByTestId('user-link');
+ expect(displayedMemberNames).toHaveLength(5);
+ });
});
diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
index 8967e7cdd7..005e426149 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
@@ -48,6 +48,7 @@ import {
removeDuplicateEntitiesFrom,
} from '../../../../helpers/helpers';
import { EntityRefLink } from '@backstage/plugin-catalog-react';
+import { EntityRelationAggregation } from '../../types';
const useStyles = makeStyles((theme: Theme) =>
createStyles({
@@ -138,11 +139,13 @@ export const MembersListCard = (props: {
memberDisplayTitle?: string;
pageSize?: number;
showAggregateMembersToggle?: boolean;
+ relationsType?: EntityRelationAggregation;
}) => {
const {
memberDisplayTitle = 'Members',
pageSize = 50,
showAggregateMembersToggle,
+ relationsType = 'direct',
} = props;
const classes = useListStyles();
@@ -162,11 +165,13 @@ export const MembersListCard = (props: {
setPage(pageIndex);
};
- const [showAggregateMembers, setShowAggregateMembers] = useState(false);
+ const [showAggregateMembers, setShowAggregateMembers] = useState(
+ relationsType === 'aggregated',
+ );
const { loading: loadingDescendantMembers, value: descendantMembers } =
useAsync(async () => {
- if (!showAggregateMembersToggle) {
+ if (!showAggregateMembers) {
return [] as UserEntity[];
}
@@ -174,7 +179,7 @@ export const MembersListCard = (props: {
groupEntity,
catalogApi,
);
- }, [catalogApi, groupEntity, showAggregateMembersToggle]);
+ }, [catalogApi, groupEntity, showAggregateMembers]);
const {
loading,
error,
@@ -229,7 +234,7 @@ export const MembersListCard = (props: {
memberList = (
{members.slice(pageSize * (page - 1), pageSize * page).map(member => (
-
+
))}
);
diff --git a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx
index 1eb2a95ff6..928f242e0d 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx
+++ b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx
@@ -33,7 +33,7 @@ import React from 'react';
import pluralize from 'pluralize';
import { catalogIndexRouteRef } from '../../../routes';
import { useGetEntities } from './useGetEntities';
-import { EntityRelationAggregation } from './types';
+import { EntityRelationAggregation } from '../types';
const useStyles = makeStyles(theme =>
createStyles({
diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx
index 278e2f4b70..0747f710ef 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx
+++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.tsx
@@ -27,7 +27,7 @@ import {
} from '@material-ui/core';
import React, { useEffect, useState } from 'react';
import { ComponentsGrid } from './ComponentsGrid';
-import { EntityRelationAggregation } from './types';
+import { EntityRelationAggregation } from '../types';
const useStyles = makeStyles(theme => ({
card: {
diff --git a/plugins/org/src/components/Cards/OwnershipCard/index.ts b/plugins/org/src/components/Cards/OwnershipCard/index.ts
index a4798cc4bf..dc0cef0226 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/index.ts
+++ b/plugins/org/src/components/Cards/OwnershipCard/index.ts
@@ -14,4 +14,3 @@
* limitations under the License.
*/
export * from './OwnershipCard';
-export * from './types';
diff --git a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts
index b6fa9cbfd1..c5bf4a7279 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts
+++ b/plugins/org/src/components/Cards/OwnershipCard/useGetEntities.ts
@@ -31,7 +31,7 @@ import limiterFactory from 'p-limit';
import { useApi } from '@backstage/core-plugin-api';
import useAsync from 'react-use/lib/useAsync';
import qs from 'qs';
-import { EntityRelationAggregation as EntityRelationsAggregation } from './types';
+import { EntityRelationAggregation } from '../types';
import { uniq } from 'lodash';
const limiter = limiterFactory(10);
@@ -125,7 +125,7 @@ const getChildOwnershipEntityRefs = async (
const getOwners = async (
entity: Entity,
- relations: EntityRelationsAggregation,
+ relations: EntityRelationAggregation,
catalogApi: CatalogApi,
): Promise => {
const isGroup = entity.kind === 'Group';
@@ -166,7 +166,7 @@ const getOwnedEntitiesByOwners = (
export function useGetEntities(
entity: Entity,
- relations: EntityRelationsAggregation,
+ relations: EntityRelationAggregation,
entityFilterKind?: string[],
entityLimit = 6,
): {
diff --git a/plugins/org/src/components/Cards/index.ts b/plugins/org/src/components/Cards/index.ts
index aec3d8da5e..4c57f5a422 100644
--- a/plugins/org/src/components/Cards/index.ts
+++ b/plugins/org/src/components/Cards/index.ts
@@ -16,3 +16,4 @@
export * from './Group';
export * from './User';
export * from './OwnershipCard';
+export type { EntityRelationAggregation } from './types';
diff --git a/plugins/org/src/components/Cards/OwnershipCard/types.ts b/plugins/org/src/components/Cards/types.ts
similarity index 100%
rename from plugins/org/src/components/Cards/OwnershipCard/types.ts
rename to plugins/org/src/components/Cards/types.ts