Merge pull request #27705 from autodesk-forks/nikolarAutodesk/contribfestHomePageQuickStart
[plugins/home] Add Home Page Quick Start Card
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
---
|
||||
'@backstage/plugin-home': patch
|
||||
---
|
||||
|
||||
Added a new Quick Start Card to `plugin-home`, which can display basic info to get users the info they need to onboard to the Catalog.
|
||||
|
||||
```
|
||||
import { QuickStartCard } from '@backstage/plugin-home';
|
||||
<QuickStartCard
|
||||
title="Onboarding to the Catalog"
|
||||
modalTitle="Onboarding Quick Start"
|
||||
docsLinkTitle="Learn more with getting started docs"
|
||||
docsLink="https://backstage.io/docs/getting-started"
|
||||
image={
|
||||
<img
|
||||
src={ContentImage}
|
||||
alt="quick start"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
}
|
||||
cardDescription="Backstage system model will help you create new entities"
|
||||
video={
|
||||
<video
|
||||
controls
|
||||
preload="auto"
|
||||
poster={"./videoPoster.png"}
|
||||
>
|
||||
<source src={"OnboardingDemo.mp4"} type="video/mp4" />
|
||||
</video>
|
||||
}
|
||||
downloadImage={
|
||||
<Button
|
||||
href={QuickStartPDF}
|
||||
target={'_blank'}
|
||||
download={true}
|
||||
>
|
||||
Download infographic button
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
```
|
||||
|
||||
See the [storybook examples](https://backstage.io/storybook/?path=/story/plugins-home-components-quickstartcard--default)
|
||||
@@ -187,6 +187,17 @@ export type LayoutConfiguration = {
|
||||
// @public
|
||||
export type Operators = '<' | '<=' | '==' | '!=' | '>' | '>=' | 'contains';
|
||||
|
||||
// @public
|
||||
export type QuickStartCardProps = {
|
||||
modalTitle?: string | React_2.JSX.Element;
|
||||
docsLinkTitle?: string;
|
||||
docsLink?: string;
|
||||
video?: React_2.JSX.Element;
|
||||
image: React_2.JSX.Element;
|
||||
cardDescription?: string;
|
||||
downloadImage?: React_2.JSX.Element;
|
||||
};
|
||||
|
||||
// @public @deprecated (undocumented)
|
||||
export type RendererProps = RendererProps_2;
|
||||
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Content } from './Content';
|
||||
import React from 'react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { renderInTestApp } from '@backstage/test-utils';
|
||||
import ContentImage from './static/backstageSystemModel.png';
|
||||
|
||||
describe('<QuickStartCard />', () => {
|
||||
const renderContent = async () => {
|
||||
return await renderInTestApp(
|
||||
<Content
|
||||
image={
|
||||
<img
|
||||
src={ContentImage}
|
||||
data-testid="quick-start-image"
|
||||
alt="quick start"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
}
|
||||
docsLinkTitle="Testing docs link"
|
||||
/>,
|
||||
);
|
||||
};
|
||||
|
||||
it('should have expected card content', async () => {
|
||||
const { getByTestId } = await renderContent();
|
||||
const docsLink = getByTestId('quick-start-link-to-docs');
|
||||
expect(docsLink).toHaveTextContent('Testing docs link');
|
||||
expect(docsLink).toHaveAttribute('target', '_blank');
|
||||
});
|
||||
|
||||
it('clicking the link opens the modal', async () => {
|
||||
const { getByTestId, getByText } = await renderContent();
|
||||
// Find the link element
|
||||
const link = getByText('Onboarding');
|
||||
// Simulate a click event on the link
|
||||
await userEvent.click(link);
|
||||
// Assert that the modal is visible
|
||||
const modal = getByTestId('content-modal-open');
|
||||
expect(modal).toBeVisible();
|
||||
});
|
||||
|
||||
it('clicking the image opens the modal', async () => {
|
||||
const { getByTestId } = await renderContent();
|
||||
// Find the link element
|
||||
const link = getByTestId('quick-start-image');
|
||||
// Simulate a click event on the link
|
||||
await userEvent.click(link);
|
||||
// Assert that the modal is visible
|
||||
const modal = getByTestId('content-modal-open');
|
||||
expect(modal).toBeVisible();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import { ContentModal } from './ContentModal';
|
||||
import { useStyles } from './styles';
|
||||
|
||||
/**
|
||||
* Props customizing the <QuickStartCard/> component.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type QuickStartCardProps = {
|
||||
/** The modal link title */
|
||||
modalTitle?: string | React.JSX.Element;
|
||||
/** The link to docs title */
|
||||
docsLinkTitle?: string;
|
||||
/** The link to docs */
|
||||
docsLink?: string;
|
||||
/** The video to play on the card */
|
||||
video?: React.JSX.Element;
|
||||
/** A quickstart image to display on the card */
|
||||
image: React.JSX.Element;
|
||||
/** The card description*/
|
||||
cardDescription?: string;
|
||||
/** A component used to download a quickStart image*/
|
||||
downloadImage?: React.JSX.Element;
|
||||
};
|
||||
|
||||
/**
|
||||
* A component to display Quick Start info on the homepage.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const Content = (props: QuickStartCardProps): JSX.Element => {
|
||||
const styles = useStyles();
|
||||
return (
|
||||
<>
|
||||
<ContentModal
|
||||
modalContent={props.image}
|
||||
linkContent={props.modalTitle || 'Onboarding'}
|
||||
/>
|
||||
<Typography variant="body1" paragraph>
|
||||
{props.cardDescription || 'Get started with Backstage'}
|
||||
</Typography>
|
||||
<ContentModal modalContent={props.image} linkContent={props.image} />
|
||||
<Grid
|
||||
container
|
||||
alignItems="center"
|
||||
className={styles.contentActionContainer}
|
||||
>
|
||||
{props.downloadImage && <Grid item>{props.downloadImage}</Grid>}
|
||||
<Grid item>
|
||||
<Link
|
||||
to={props.docsLink || 'https://backstage.io/docs/getting-started/'}
|
||||
data-testid="quick-start-link-to-docs"
|
||||
underline="none"
|
||||
variant="h6"
|
||||
className={styles.link}
|
||||
>
|
||||
{props.docsLinkTitle || 'Learn more'}
|
||||
</Link>
|
||||
</Grid>
|
||||
</Grid>
|
||||
{props.video && props.video}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import Modal from '@material-ui/core/Modal';
|
||||
import Box from '@material-ui/core/Box';
|
||||
|
||||
import { useStyles } from './styles';
|
||||
|
||||
export type ContentModalProps = {
|
||||
modalContent: React.JSX.Element;
|
||||
linkContent: string | React.JSX.Element;
|
||||
};
|
||||
|
||||
export const ContentModal = (props: ContentModalProps) => {
|
||||
const { modalContent, linkContent } = props;
|
||||
const styles = useStyles();
|
||||
const [open, setOpen] = useState(false);
|
||||
|
||||
return (
|
||||
<div className={styles.linkText} data-testid="content-modal-container">
|
||||
<Link
|
||||
to="#"
|
||||
component="button"
|
||||
variant="h6"
|
||||
underline="none"
|
||||
onClick={() => setOpen(true)}
|
||||
>
|
||||
{linkContent}
|
||||
</Link>
|
||||
<Modal
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
aria-labelledby="content-modal"
|
||||
data-testid="content-modal"
|
||||
>
|
||||
<Box className={styles.contentModal} data-testid="content-modal-open">
|
||||
{modalContent}
|
||||
</Box>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { QuickStartCard } from '../../plugin';
|
||||
import React, { ComponentType, PropsWithChildren } from 'react';
|
||||
import { wrapInTestApp } from '@backstage/test-utils';
|
||||
import Grid from '@material-ui/core/Grid';
|
||||
import ContentImage from './static/backstageSystemModel.png';
|
||||
|
||||
export default {
|
||||
title: 'Plugins/Home/Components/QuickStartCard',
|
||||
decorators: [
|
||||
(Story: ComponentType<PropsWithChildren<{}>>) => wrapInTestApp(<Story />),
|
||||
],
|
||||
};
|
||||
|
||||
export const Default = () => {
|
||||
return (
|
||||
<Grid item xs={12} md={6}>
|
||||
<QuickStartCard
|
||||
image={
|
||||
<img
|
||||
src={ContentImage}
|
||||
alt="quick start"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
}
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
|
||||
export const Customized = () => {
|
||||
return (
|
||||
<Grid item xs={12} md={6}>
|
||||
<QuickStartCard
|
||||
title="Onboarding to the Catalog"
|
||||
modalTitle="Onboarding Quick Start"
|
||||
docsLinkTitle="Learn more with getting started docs"
|
||||
docsLink="https://backstage.io/docs/getting-started"
|
||||
image={
|
||||
<img
|
||||
src={ContentImage}
|
||||
alt="quick start"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
}
|
||||
cardDescription="Backstage system model will help you create new entities"
|
||||
/>
|
||||
</Grid>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { Content } from './Content';
|
||||
export type { QuickStartCardProps } from './Content';
|
||||
export type { QuickStartCardClassKey } from './styles';
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 269 KiB |
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2022 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { makeStyles, Theme } from '@material-ui/core/styles';
|
||||
|
||||
/** @public */
|
||||
export type QuickStartCardClassKey =
|
||||
| 'cardTitleIcon'
|
||||
| 'contentActionContainer'
|
||||
| 'contentModal'
|
||||
| 'imageSize'
|
||||
| 'link'
|
||||
| 'linkText'
|
||||
| 'videoContainer';
|
||||
|
||||
export const useStyles = makeStyles(
|
||||
(theme: Theme) => ({
|
||||
cardTitleIcon: {
|
||||
verticalAlign: 'bottom',
|
||||
marginLeft: '-4px',
|
||||
},
|
||||
contentActionContainer: {
|
||||
marginTop: theme.spacing(1.5),
|
||||
marginBottom: theme.spacing(1.5),
|
||||
},
|
||||
contentModal: {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)',
|
||||
width: '80%',
|
||||
height: 'auto',
|
||||
},
|
||||
imageSize: { width: '100%', height: '100%' },
|
||||
link: {
|
||||
display: 'inline-flex',
|
||||
alignItems: 'center',
|
||||
textDecoration: 'none',
|
||||
color: `${theme.palette.link}`,
|
||||
'&:hover': {
|
||||
background: 'transparent',
|
||||
},
|
||||
},
|
||||
linkText: {
|
||||
marginBottom: theme.spacing(1.5),
|
||||
},
|
||||
videoContainer: {
|
||||
borderRadius: '10px',
|
||||
width: '100%',
|
||||
height: 'auto',
|
||||
background: `${theme.palette.background.default}`,
|
||||
},
|
||||
}),
|
||||
{ name: 'HomeQuickStartCard' },
|
||||
);
|
||||
@@ -20,3 +20,4 @@ export type { WelcomeTitleLanguageProps } from './WelcomeTitle';
|
||||
export type { VisitedByTypeProps, VisitedByTypeKind } from './VisitedByType';
|
||||
export type { FeaturedDocsCardProps } from './FeaturedDocsCard';
|
||||
export type { StarredEntitiesProps } from './StarredEntities';
|
||||
export type { QuickStartCardProps } from './QuickStart';
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
ToolkitContentProps,
|
||||
VisitedByTypeProps,
|
||||
FeaturedDocsCardProps,
|
||||
QuickStartCardProps,
|
||||
} from './homePageComponents';
|
||||
import { rootRouteRef } from './routes';
|
||||
import { VisitsStorageApi, visitsApiRef } from './api';
|
||||
@@ -230,3 +231,16 @@ export const FeaturedDocsCard = homePlugin.provide(
|
||||
components: () => import('./homePageComponents/FeaturedDocsCard'),
|
||||
}),
|
||||
);
|
||||
|
||||
/**
|
||||
* A component to display Quick Start information.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export const QuickStartCard = homePlugin.provide(
|
||||
createCardExtension<QuickStartCardProps>({
|
||||
name: 'QuickStartCard',
|
||||
title: 'Quick Start',
|
||||
components: () => import('./homePageComponents/QuickStart'),
|
||||
}),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user