diff --git a/.changeset/selfish-hats-wait.md b/.changeset/selfish-hats-wait.md
new file mode 100644
index 0000000000..d706d42e8e
--- /dev/null
+++ b/.changeset/selfish-hats-wait.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-org': patch
+---
+
+Add styling to the `MembersListCard` and `ComponentsGrid` to handle overflow text.
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 c98cc3eb32..cc524b60a2 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.test.tsx
@@ -28,6 +28,19 @@ import {
import React from 'react';
import { MembersListCard } from './MembersListCard';
+// Mock needed because jsdom doesn't correctly implement box-sizing
+// https://github.com/ShinyChang/React-Text-Truncate/issues/70
+// https://stackoverflow.com/questions/71916701/how-to-mock-a-react-function-component-that-takes-a-ref-prop
+jest.mock('react-text-truncate', () => {
+ const { forwardRef } = jest.requireActual('react');
+ return {
+ __esModule: true,
+ default: forwardRef((props: any, ref: any) => (
+
{props.text}
+ )),
+ };
+});
+
describe('MemberTab Test', () => {
const groupEntity: GroupEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -95,7 +108,7 @@ describe('MemberTab Test', () => {
expect(
rendered.getByText('tara-macgovern@example.com'),
).toBeInTheDocument();
- expect(rendered.getByText('Tara MacGovern')).toHaveAttribute(
+ expect(rendered.getByText('Tara MacGovern').closest('a')).toHaveAttribute(
'href',
'/catalog/foo-bar/user/tara.macgovern',
);
diff --git a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
index c41a73ab9c..eb61989144 100644
--- a/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
+++ b/plugins/org/src/components/Cards/Group/MembersList/MembersListCard.tsx
@@ -44,6 +44,7 @@ import {
Progress,
ResponseErrorPanel,
Link,
+ OverflowTooltip,
} from '@backstage/core-components';
import { useApi } from '@backstage/core-plugin-api';
@@ -59,18 +60,6 @@ const useStyles = makeStyles((theme: Theme) =>
flex: '1',
minWidth: '0px',
},
- email: {
- overflow: 'hidden',
- whiteSpace: 'nowrap',
- textOverflow: 'ellipsis',
- display: 'inline-block',
- verticalAlign: 'middle',
- maxWidth: '100%',
- '&:hover': {
- overflow: 'visible',
- whiteSpace: 'normal',
- },
- },
}),
);
@@ -103,23 +92,23 @@ const MemberComponent = (props: { member: UserEntity }) => {
-
+
- {displayName}
+
{profile?.email && (
-
- {profile.email}
+
+
)}
{description && (
diff --git a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx
index b130057fe3..dbd569abff 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx
+++ b/plugins/org/src/components/Cards/OwnershipCard/ComponentsGrid.tsx
@@ -15,7 +15,12 @@
*/
import { Entity } from '@backstage/catalog-model';
-import { Link, Progress, ResponseErrorPanel } from '@backstage/core-components';
+import {
+ Link,
+ OverflowTooltip,
+ Progress,
+ ResponseErrorPanel,
+} from '@backstage/core-components';
import { useRouteRef } from '@backstage/core-plugin-api';
import { BackstageTheme } from '@backstage/theme';
import {
@@ -47,6 +52,9 @@ const useStyles = makeStyles((theme: BackstageTheme) =>
bold: {
fontWeight: theme.typography.fontWeightBold,
},
+ smallFont: {
+ fontSize: theme.typography.body2.fontSize,
+ },
entityTypeBox: {
background: (props: { type: string }) =>
theme.getPageTheme({ themeId: props.type }).backgroundImage,
@@ -68,6 +76,7 @@ const EntityCountTile = ({
const classes = useStyles({ type: type ?? kind });
const rawTitle = type ?? kind;
+ const isLongText = rawTitle.length > 10;
return (
@@ -80,9 +89,16 @@ const EntityCountTile = ({
{counter}
-
- {pluralize(rawTitle.toLocaleUpperCase('en-US'), counter)}
-
+
+
+
+
+
{type && {kind}}
diff --git a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx
index 84f27fa183..30b7dee2de 100644
--- a/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx
+++ b/plugins/org/src/components/Cards/OwnershipCard/OwnershipCard.test.tsx
@@ -120,6 +120,19 @@ const getEntitiesMock = (
} as GetEntitiesResponse);
};
+// Mock needed because jsdom doesn't correctly implement box-sizing
+// https://github.com/ShinyChang/React-Text-Truncate/issues/70
+// https://stackoverflow.com/questions/71916701/how-to-mock-a-react-function-component-that-takes-a-ref-prop
+jest.mock('react-text-truncate', () => {
+ const { forwardRef } = jest.requireActual('react');
+ return {
+ __esModule: true,
+ default: forwardRef((props: any, ref: any) => (
+ {props.text}
+ )),
+ };
+});
+
describe('OwnershipCard', () => {
const groupEntity: GroupEntity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -177,19 +190,19 @@ describe('OwnershipCard', () => {
expect(getByText('OPENAPI')).toBeInTheDocument();
expect(
- queryByText(getByText('OPENAPI').parentElement!, '1'),
+ queryByText(getByText('OPENAPI').closest('a')!, '1'),
).toBeInTheDocument();
expect(getByText('SERVICE')).toBeInTheDocument();
expect(
- queryByText(getByText('SERVICE').parentElement!, '1'),
+ queryByText(getByText('SERVICE').closest('a')!, '1'),
).toBeInTheDocument();
expect(getByText('LIBRARY')).toBeInTheDocument();
expect(
- queryByText(getByText('LIBRARY').parentElement!, '1'),
+ queryByText(getByText('LIBRARY').closest('a')!, '1'),
).toBeInTheDocument();
expect(getByText('SYSTEM')).toBeInTheDocument();
expect(
- queryByText(getByText('SYSTEM').parentElement!, '1'),
+ queryByText(getByText('SYSTEM').closest('a')!, '1'),
).toBeInTheDocument();
});
@@ -215,17 +228,17 @@ describe('OwnershipCard', () => {
expect(getByText('SYSTEM')).toBeInTheDocument();
expect(
- queryByText(getByText('SYSTEM').parentElement!, '1'),
+ queryByText(getByText('SYSTEM').closest('a')!, '1'),
).toBeInTheDocument();
expect(
- queryByText(getByText('SYSTEM').parentElement!, 'System'),
+ queryByText(getByText('SYSTEM').closest('a')!, 'System'),
).not.toBeInTheDocument();
expect(getByText('OPENAPI')).toBeInTheDocument();
expect(
- queryByText(getByText('OPENAPI').parentElement!, '1'),
+ queryByText(getByText('OPENAPI').closest('a')!, '1'),
).toBeInTheDocument();
expect(
- queryByText(getByText('OPENAPI').parentElement!, 'API'),
+ queryByText(getByText('OPENAPI').closest('a')!, 'API'),
).toBeInTheDocument();
expect(() => getByText('LIBRARY')).toThrow();
});