From 49f9b7346dcb777edd0904954c069e74fdb3d3b3 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Thu, 18 Feb 2021 11:05:29 +0100 Subject: [PATCH 1/3] Rename `type` of `ItemCard` to `subtitle` and allow to pass react nodes Signed-off-by: Oliver Sand --- .changeset/popular-nails-agree.md | 6 ++++++ .../src/layout/ItemCard/ItemCard.stories.tsx | 4 ++-- .../core/src/layout/ItemCard/ItemCard.test.tsx | 18 ++++++++++++++---- packages/core/src/layout/ItemCard/ItemCard.tsx | 9 +++++++-- 4 files changed, 29 insertions(+), 8 deletions(-) create mode 100644 .changeset/popular-nails-agree.md diff --git a/.changeset/popular-nails-agree.md b/.changeset/popular-nails-agree.md new file mode 100644 index 0000000000..361ff4745d --- /dev/null +++ b/.changeset/popular-nails-agree.md @@ -0,0 +1,6 @@ +--- +'@backstage/core': patch +--- + +Deprecate `type` of `ItemCard` and introduce new `subtitle` which allows passing +react nodes. diff --git a/packages/core/src/layout/ItemCard/ItemCard.stories.tsx b/packages/core/src/layout/ItemCard/ItemCard.stories.tsx index b53fa9eb7a..eea78562e8 100644 --- a/packages/core/src/layout/ItemCard/ItemCard.stories.tsx +++ b/packages/core/src/layout/ItemCard/ItemCard.stories.tsx @@ -30,7 +30,7 @@ export const Default = () => ( title="Item Card" description="This is the description of an Item Card" label="Button" - type="Pretitle" + subtitle="Pretitle" onClick={() => {}} /> @@ -39,7 +39,7 @@ export const Default = () => ( title="Item Card" description="This is the description of an Item Card" label="Button" - type="Pretitle" + subtitle="Pretitle" onClick={() => {}} /> diff --git a/packages/core/src/layout/ItemCard/ItemCard.test.tsx b/packages/core/src/layout/ItemCard/ItemCard.test.tsx index 6afeb16c5b..30cf95fd85 100644 --- a/packages/core/src/layout/ItemCard/ItemCard.test.tsx +++ b/packages/core/src/layout/ItemCard/ItemCard.test.tsx @@ -14,25 +14,35 @@ * limitations under the License. */ -import React from 'react'; import { renderInTestApp } from '@backstage/test-utils'; +import React from 'react'; import { ItemCard } from './ItemCard'; const minProps = { description: 'This is the description of an Item Card', label: 'Button', title: 'Item Card', - type: 'Pretitle', }; describe('', () => { it('renders default without exploding', async () => { - const { description, label, title, type } = minProps; + const { description, label, title } = minProps; const { getByText } = await renderInTestApp(); expect(getByText(description)).toBeInTheDocument(); expect(getByText(title)).toBeInTheDocument(); expect(getByText(label)).toBeInTheDocument(); - expect(getByText(type)).toBeInTheDocument(); + }); + + it('renders with subtitle without exploding', async () => { + const { description, label, title } = minProps; + const subtitle = 'Pretitle'; + const { getByText } = await renderInTestApp( + , + ); + expect(getByText(description)).toBeInTheDocument(); + expect(getByText(title)).toBeInTheDocument(); + expect(getByText(label)).toBeInTheDocument(); + expect(getByText(subtitle)).toBeInTheDocument(); }); it('renders with tags without exploding', async () => { diff --git a/packages/core/src/layout/ItemCard/ItemCard.tsx b/packages/core/src/layout/ItemCard/ItemCard.tsx index 4242cd6381..9e16def5d3 100644 --- a/packages/core/src/layout/ItemCard/ItemCard.tsx +++ b/packages/core/src/layout/ItemCard/ItemCard.tsx @@ -15,7 +15,7 @@ */ import { Button, Card, Chip, makeStyles, Typography } from '@material-ui/core'; import clsx from 'clsx'; -import React from 'react'; +import React, { ReactNode } from 'react'; import { Link } from '../../components'; const useStyles = makeStyles(theme => ({ @@ -45,7 +45,9 @@ type ItemCardProps = { description?: string; tags?: string[]; title: string; + /** @deprecated Use subtitle instead */ type?: string; + subtitle?: ReactNode; label: string; onClick?: () => void; href?: string; @@ -56,6 +58,7 @@ export const ItemCard = ({ tags, title, type, + subtitle, label, onClick, href, @@ -65,7 +68,9 @@ export const ItemCard = ({ return (
- {type ?? {type}} + {(subtitle || type) && ( + {subtitle ?? type} + )} {title}
From 9615e68fb6382fbb08847a89a84ad9c46d4a48fb Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Thu, 18 Feb 2021 11:07:11 +0100 Subject: [PATCH 2/3] Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling `Link` Signed-off-by: Oliver Sand --- .changeset/kind-eels-run.md | 7 +++++ packages/core/src/components/Link/Link.tsx | 6 ++-- packages/core/src/components/Link/index.ts | 1 + .../EntityRefLink/EntityRefLink.tsx | 14 +++++----- .../EntityRefLink/EntityRefLinks.tsx | 28 +++++++++---------- 5 files changed, 32 insertions(+), 24 deletions(-) create mode 100644 .changeset/kind-eels-run.md diff --git a/.changeset/kind-eels-run.md b/.changeset/kind-eels-run.md new file mode 100644 index 0000000000..0d890b0478 --- /dev/null +++ b/.changeset/kind-eels-run.md @@ -0,0 +1,7 @@ +--- +'@backstage/core': patch +'@backstage/plugin-catalog-react': patch +--- + +Forward link styling of `EntityRefLink` and `EnriryRefLinks` into the underling +`Link`. diff --git a/packages/core/src/components/Link/Link.tsx b/packages/core/src/components/Link/Link.tsx index b551b0511d..cd74b681db 100644 --- a/packages/core/src/components/Link/Link.tsx +++ b/packages/core/src/components/Link/Link.tsx @@ -14,17 +14,17 @@ * limitations under the License. */ -import React, { ElementType } from 'react'; import { Link as MaterialLink, LinkProps as MaterialLinkProps, } from '@material-ui/core'; +import React, { ElementType } from 'react'; import { Link as RouterLink, LinkProps as RouterLinkProps, } from 'react-router-dom'; -type Props = MaterialLinkProps & +export type LinkProps = MaterialLinkProps & RouterLinkProps & { component?: ElementType; }; @@ -33,7 +33,7 @@ type Props = MaterialLinkProps & * Thin wrapper on top of material-ui's Link component * Makes the Link to utilise react-router */ -export const Link = React.forwardRef((props, ref) => { +export const Link = React.forwardRef((props, ref) => { const to = String(props.to); return /^https?:\/\//.test(to) ? ( // External links diff --git a/packages/core/src/components/Link/index.ts b/packages/core/src/components/Link/index.ts index 18e990181c..9be779feb7 100644 --- a/packages/core/src/components/Link/index.ts +++ b/packages/core/src/components/Link/index.ts @@ -15,3 +15,4 @@ */ export { Link } from './Link'; +export type { LinkProps } from './Link'; diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx index 50a80af12a..73e3824d98 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLink.tsx @@ -15,22 +15,22 @@ */ import { Entity, - ENTITY_DEFAULT_NAMESPACE, EntityName, + ENTITY_DEFAULT_NAMESPACE, } from '@backstage/catalog-model'; -import { Link } from '@backstage/core'; -import React from 'react'; +import { Link, LinkProps } from '@backstage/core'; +import React, { forwardRef } from 'react'; import { generatePath } from 'react-router'; import { entityRoute } from '../../routes'; import { formatEntityRefTitle } from './format'; -type EntityRefLinkProps = { +export type EntityRefLinkProps = { entityRef: Entity | EntityName; defaultKind?: string; children?: React.ReactNode; -}; +} & Omit; -export const EntityRefLink = React.forwardRef( +export const EntityRefLink = forwardRef( (props, ref) => { const { entityRef, defaultKind, children, ...linkProps } = props; @@ -59,9 +59,9 @@ export const EntityRefLink = React.forwardRef( // TODO: Use useRouteRef here to generate the path return ( {children} {!children && formatEntityRefTitle(entityRef, { defaultKind })} diff --git a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx index fb99fad176..52ed87c80b 100644 --- a/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx +++ b/plugins/catalog-react/src/components/EntityRefLink/EntityRefLinks.tsx @@ -14,26 +14,26 @@ * limitations under the License. */ import { Entity, EntityName } from '@backstage/catalog-model'; +import { LinkProps } from '@backstage/core'; import React from 'react'; import { EntityRefLink } from './EntityRefLink'; -type EntityRefLinksProps = { +export type EntityRefLinksProps = { entityRefs: (Entity | EntityName)[]; defaultKind?: string; -}; +} & Omit; export const EntityRefLinks = ({ entityRefs, defaultKind, -}: EntityRefLinksProps) => { - return ( - <> - {entityRefs.map((r, i) => ( - - {i > 0 && ', '} - - - ))} - - ); -}; + ...linkProps +}: EntityRefLinksProps) => ( + <> + {entityRefs.map((r, i) => ( + + {i > 0 && ', '} + + + ))} + +); From 347137ccf217ab2cc7e7f84929e4cbb76db28944 Mon Sep 17 00:00:00 2001 From: Oliver Sand Date: Thu, 18 Feb 2021 11:07:54 +0100 Subject: [PATCH 3/3] Display the owner of a domain on the domain card Signed-off-by: Oliver Sand --- .changeset/eight-chefs-reply.md | 5 +++ .../src/components/DomainCard/DomainCard.tsx | 41 ++++++++++++------- 2 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 .changeset/eight-chefs-reply.md diff --git a/.changeset/eight-chefs-reply.md b/.changeset/eight-chefs-reply.md new file mode 100644 index 0000000000..9e133e2722 --- /dev/null +++ b/.changeset/eight-chefs-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-explore': patch +--- + +Display the owner of a domain on the domain card. diff --git a/plugins/explore/src/components/DomainCard/DomainCard.tsx b/plugins/explore/src/components/DomainCard/DomainCard.tsx index 2c0126b94a..e5efc543b2 100644 --- a/plugins/explore/src/components/DomainCard/DomainCard.tsx +++ b/plugins/explore/src/components/DomainCard/DomainCard.tsx @@ -13,11 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { DomainEntity } from '@backstage/catalog-model'; +import { DomainEntity, RELATION_OWNED_BY } from '@backstage/catalog-model'; import { ItemCard } from '@backstage/core'; import { + EntityRefLinks, entityRoute, entityRouteParams, + getEntityRelations, } from '@backstage/plugin-catalog-react'; import React from 'react'; import { generatePath } from 'react-router-dom'; @@ -26,16 +28,27 @@ type DomainCardProps = { entity: DomainEntity; }; -export const DomainCard = ({ entity }: DomainCardProps) => ( - -); +export const DomainCard = ({ entity }: DomainCardProps) => { + const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY); + + return ( + + } + label="Explore" + // TODO: Use useRouteRef here to generate the path + href={generatePath( + `/catalog/${entityRoute.path}`, + entityRouteParams(entity), + )} + /> + ); +};