use createCardExtension

Signed-off-by: nikolar <reyna.nikolayev@autodesk.com>
This commit is contained in:
nikolar
2023-11-13 12:42:23 -08:00
parent 73f927b60c
commit 12cc038643
7 changed files with 75 additions and 89 deletions
-1
View File
@@ -12,7 +12,6 @@ import { FeaturedDocsCard } from '@backstage/plugin-home';
'spec.type': 'documentation',
'metadata.name': 'getting-started-with-backstage',
}}
title={cardTitleReactNode}
subLinkText="More Details"
emptyState={emptyStateReactNode}
linkDestination={'/customPath'}
+4 -3
View File
@@ -103,16 +103,17 @@ export type CustomHomepageGridProps = {
};
// @public
export const FeaturedDocsCard: (props: FeaturedDocsCardProps) => JSX_2.Element;
export const FeaturedDocsCard: (
props: CardExtensionProps_2<FeaturedDocsCardProps>,
) => JSX_2.Element;
// @public
export type FeaturedDocsCardProps = {
filter: EntityFilterQuery;
emptyState?: React_2.ReactNode;
emptyState?: React_2.JSX.Element;
linkDestination?: string;
responseLimit?: number;
subLinkText?: string;
title?: React_2.ReactNode;
};
// @public
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { FeaturedDocsCard } from './FeaturedDocsCard';
import { Content } from './Content';
import React from 'react';
import { catalogApiRef, entityRouteRef } from '@backstage/plugin-catalog-react';
import { renderInTestApp, TestApiProvider } from '@backstage/test-utils';
@@ -51,13 +51,12 @@ describe('<FeaturedDocsCard />', () => {
it('should show expected featured doc and title', async () => {
const { getByTestId, getByText } = await renderInTestApp(
<Wrapper>
<FeaturedDocsCard
<Content
filter={{
'spec.type': 'documentation',
'metadata.name': 'getting-started-with-idp',
}}
emptyState={undefined}
title="Featured Doc"
/>
</Wrapper>,
{
@@ -68,9 +67,7 @@ describe('<FeaturedDocsCard />', () => {
);
const docsCardContent = getByTestId('docs-card-content');
const docsEntity = getByText('Getting Started Docs');
const docsTitle = getByText('Featured Doc');
expect(docsCardContent).toContainElement(docsEntity);
expect(docsTitle).toBeInTheDocument();
});
});
@@ -20,7 +20,6 @@ import {
LinkButton,
EmptyState,
Link,
InfoCard,
Progress,
ErrorPanel,
} from '@backstage/core-components';
@@ -39,15 +38,13 @@ export type FeaturedDocsCardProps = {
/** The entity filter used to display only the intended item/s */
filter: EntityFilterQuery;
/** An optional ReactNode for empty states */
emptyState?: React.ReactNode;
emptyState?: React.JSX.Element;
/** An optional linkDestination to set for the Featured Doc */
linkDestination?: string;
/** An optional limit to set for link destination */
responseLimit?: number;
/** An optional string to customize sublink text */
subLinkText?: string;
/** An optional string or ReactNode to customize the card title */
title?: React.ReactNode;
};
const useStyles = makeStyles<Theme>(
@@ -77,15 +74,9 @@ const useStyles = makeStyles<Theme>(
*
* @public
*/
export const FeaturedDocsCard = (props: FeaturedDocsCardProps) => {
const {
emptyState,
filter,
linkDestination,
responseLimit,
subLinkText,
title,
} = props;
export const Content = (props: FeaturedDocsCardProps): JSX.Element => {
const { emptyState, filter, linkDestination, responseLimit, subLinkText } =
props;
const linkText = subLinkText || 'LEARN MORE';
const styles = useStyles();
const catalogApi: CatalogApi = useApi(catalogApiRef);
@@ -108,60 +99,60 @@ export const FeaturedDocsCard = (props: FeaturedDocsCardProps) => {
return <ErrorPanel error={error} />;
}
return (
<InfoCard variant="gridItem" title={title || 'Featured Docs'}>
{entities?.length
? entities.map(d => (
<div
key={`${d.metadata.name}-${d.kind}-${d.metadata.namespace}`}
data-testid="docs-card-content"
>
<Link
className={styles.docsTitleLink}
data-testid="docs-card-title"
to={
linkDestination ||
`/docs/${d.metadata.namespace || 'default'}/${d.kind}/${
d.metadata.name
}/`
}
>
{d.metadata.title}
</Link>
{d.metadata.description && (
<Typography className={styles.docDescription}>
{d.metadata.description}
</Typography>
)}
<Link
className={styles.docSubLink}
data-testid="docs-card-sub-link"
to={
linkDestination ||
`/docs/${d.metadata.namespace || 'default'}/${d.kind}/${
d.metadata.name
}/`
}
>
{linkText}
</Link>
</div>
))
: emptyState || (
<EmptyState
missing="data"
title="No documents to show"
description="Create your own document. Check out our Getting Started Information"
action={
<LinkButton
to="https://backstage.io/docs/features/techdocs/getting-started"
variant="contained"
>
DOCS
</LinkButton>
}
/>
return entities?.length ? (
<>
{entities.map(d => (
<div
key={`${d.metadata.name}-${d.kind}-${d.metadata.namespace}`}
data-testid="docs-card-content"
>
<Link
className={styles.docsTitleLink}
data-testid="docs-card-title"
to={
linkDestination ||
`/docs/${d.metadata.namespace || 'default'}/${d.kind}/${
d.metadata.name
}/`
}
>
{d.metadata.title}
</Link>
{d.metadata.description && (
<Typography className={styles.docDescription}>
{d.metadata.description}
</Typography>
)}
</InfoCard>
<Link
className={styles.docSubLink}
data-testid="docs-card-sub-link"
to={
linkDestination ||
`/docs/${d.metadata.namespace || 'default'}/${d.kind}/${
d.metadata.name
}/`
}
>
{linkText}
</Link>
</div>
))}
</>
) : (
emptyState || (
<EmptyState
missing="data"
title="No documents to show"
description="Create your own document. Check out our Getting Started Information"
action={
<LinkButton
to="https://backstage.io/docs/features/techdocs/getting-started"
variant="contained"
>
DOCS
</LinkButton>
}
/>
)
);
};
@@ -65,7 +65,6 @@ export const Default = () => {
'spec.type': 'documentation',
'metadata.name': 'getting-started-with-backstage',
}}
title="Featured Doc"
/>
</Grid>
);
@@ -14,5 +14,5 @@
* limitations under the License.
*/
export { FeaturedDocsCard } from './FeaturedDocsCard';
export type { FeaturedDocsCardProps } from './FeaturedDocsCard';
export { Content } from './Content';
export type { FeaturedDocsCardProps } from './Content';
+9 -10
View File
@@ -19,12 +19,15 @@ import {
createComponentExtension,
createPlugin,
createRoutableExtension,
createReactExtension,
identityApiRef,
storageApiRef,
} from '@backstage/core-plugin-api';
import { createCardExtension } from '@backstage/plugin-home-react';
import { ToolkitContentProps, VisitedByTypeProps } from './homePageComponents';
import {
ToolkitContentProps,
VisitedByTypeProps,
FeaturedDocsCardProps,
} from './homePageComponents';
import { rootRouteRef } from './routes';
import { VisitsStorageApi, visitsApiRef } from './api';
@@ -218,13 +221,9 @@ export const HomePageRecentlyVisited = homePlugin.provide(
* @public
*/
export const FeaturedDocsCard = homePlugin.provide(
createReactExtension({
name: 'FeaturedDocs',
component: {
lazy: () =>
import('./homePageComponents/FeaturedDocsCard').then(
m => m.FeaturedDocsCard,
),
},
createCardExtension<FeaturedDocsCardProps>({
name: 'FeaturedDocsCard',
title: 'Featured Docs',
components: () => import('./homePageComponents/FeaturedDocsCard'),
}),
);