diff --git a/.changeset/perfect-goats-mate.md b/.changeset/perfect-goats-mate.md index c53075a5bb..6ad2884d08 100644 --- a/.changeset/perfect-goats-mate.md +++ b/.changeset/perfect-goats-mate.md @@ -1,7 +1,5 @@ --- -'@backstage/plugin-scaffolder': minor -'@backstage/plugin-techdocs': minor -'@backstage/plugin-catalog': minor +'@backstage/core-components': minor --- The SupportButton component will now be hidden if no support config is specified in app-config diff --git a/packages/core-components/src/components/SupportButton/SupportButton.test.tsx b/packages/core-components/src/components/SupportButton/SupportButton.test.tsx index 9ed8fb8401..4036884130 100644 --- a/packages/core-components/src/components/SupportButton/SupportButton.test.tsx +++ b/packages/core-components/src/components/SupportButton/SupportButton.test.tsx @@ -41,34 +41,50 @@ const configApi = mockApis.config({ }, }); +const noSupportConfigApi = mockApis.config({ + data: { + app: {}, + }, +}); + const SUPPORT_BUTTON_ID = 'support-button'; const POPOVER_ID = 'support-button-popover'; describe('', () => { it('renders without exploding', async () => { - await renderInTestApp(); + await renderInTestApp( + + + , + ); await expect( screen.findByTestId(SUPPORT_BUTTON_ID), ).resolves.toBeInTheDocument(); }); it('supports passing a title', async () => { - await renderInTestApp(); + await renderInTestApp( + + + , + ); fireEvent.click(screen.getByTestId(SUPPORT_BUTTON_ID)); expect(screen.getByText('Custom title')).toBeInTheDocument(); }); it('supports passing link items through props', async () => { await renderInTestApp( - , + + + , ); const supportButton = screen.getByTestId(SUPPORT_BUTTON_ID); @@ -97,7 +113,11 @@ describe('', () => { }); it('shows popover on click', async () => { - await renderInTestApp(); + await renderInTestApp( + + + , + ); await expect( screen.findByTestId(SUPPORT_BUTTON_ID), @@ -108,4 +128,14 @@ describe('', () => { await expect(screen.findByTestId(POPOVER_ID)).resolves.toBeInTheDocument(); }); + + it('hides button if config is missing', async () => { + await renderInTestApp( + + + , + ); + + await expect(screen.findByTestId(SUPPORT_BUTTON_ID)).rejects.toThrow(); + }); }); diff --git a/packages/core-components/src/components/SupportButton/SupportButton.tsx b/packages/core-components/src/components/SupportButton/SupportButton.tsx index 9e51e23119..c3a6e283b6 100644 --- a/packages/core-components/src/components/SupportButton/SupportButton.tsx +++ b/packages/core-components/src/components/SupportButton/SupportButton.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import { useApp } from '@backstage/core-plugin-api'; +import { configApiRef, useApi, useApp } from '@backstage/core-plugin-api'; import Box from '@material-ui/core/Box'; import Button from '@material-ui/core/Button'; import DialogActions from '@material-ui/core/DialogActions'; @@ -94,6 +94,7 @@ export function SupportButton(props: SupportButtonProps) { const [popoverOpen, setPopoverOpen] = useState(false); const [anchorEl, setAnchorEl] = useState(null); const classes = useStyles(); + const supportConfig = useApi(configApiRef).getOptionalConfig('app.support'); const isSmallScreen = useMediaQuery(theme => theme.breakpoints.down('sm'), ); @@ -107,6 +108,10 @@ export function SupportButton(props: SupportButtonProps) { setPopoverOpen(false); }; + if (!supportConfig) { + return null; + } + return ( <> diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index 7e091050df..366427d33d 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -58,7 +58,6 @@ export function BaseCatalogPage(props: BaseCatalogPageProps) { const { allowed } = usePermission({ permission: catalogEntityCreatePermission, }); - const supportConfig = useApi(configApiRef).getOptionalConfig('app.support'); return ( @@ -70,9 +69,7 @@ export function BaseCatalogPage(props: BaseCatalogPageProps) { to={createComponentLink && createComponentLink()} /> )} - {supportConfig && ( - {t('indexPage.supportButtonContent')} - )} + {t('indexPage.supportButtonContent')} diff --git a/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx index 486b10ab4b..8d0c73f0a7 100644 --- a/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx +++ b/plugins/scaffolder/src/alpha/components/TemplateListPage/TemplateListPage.tsx @@ -17,12 +17,7 @@ import React, { useCallback } from 'react'; import { useNavigate } from 'react-router-dom'; import { TemplateEntityV1beta3 } from '@backstage/plugin-scaffolder-common'; -import { - configApiRef, - useApi, - useApp, - useRouteRef, -} from '@backstage/core-plugin-api'; +import { useApp, useRouteRef } from '@backstage/core-plugin-api'; import { Content, @@ -115,7 +110,6 @@ export const TemplateListPage = (props: TemplateListPageProps) => { const templateRoute = useRouteRef(selectedTemplateRouteRef); const app = useApp(); const { t } = useTranslationRef(scaffolderTranslationRef); - const supportConfig = useApi(configApiRef).getOptionalConfig('app.support'); const groups = givenGroups.length ? createGroupsWithOther(givenGroups, t) @@ -190,11 +184,9 @@ export const TemplateListPage = (props: TemplateListPageProps) => { )} to={registerComponentLink && registerComponentLink()} /> - {supportConfig && ( - - {t('templateListPage.contentHeader.supportButtonTitle')} - - )} + + {t('templateListPage.contentHeader.supportButtonTitle')} + diff --git a/plugins/techdocs/src/home/components/DefaultTechDocsHome.tsx b/plugins/techdocs/src/home/components/DefaultTechDocsHome.tsx index 7aae9b242e..2fbd5bb50a 100644 --- a/plugins/techdocs/src/home/components/DefaultTechDocsHome.tsx +++ b/plugins/techdocs/src/home/components/DefaultTechDocsHome.tsx @@ -31,7 +31,6 @@ import { TechDocsPageWrapper } from './TechDocsPageWrapper'; import { TechDocsPicker } from './TechDocsPicker'; import { EntityListDocsTable } from './Tables'; import { TechDocsIndexPageProps } from './TechDocsIndexPage'; -import { configApiRef, useApi } from '@backstage/core-plugin-api'; /** * Props for {@link DefaultTechDocsHome} @@ -48,16 +47,13 @@ export type DefaultTechDocsHomeProps = TechDocsIndexPageProps; */ export const DefaultTechDocsHome = (props: TechDocsIndexPageProps) => { const { initialFilter = 'owned', columns, actions, ownerPickerMode } = props; - const supportConfig = useApi(configApiRef).getOptionalConfig('app.support'); return ( - {supportConfig && ( - - Discover documentation in your ecosystem. - - )} + + Discover documentation in your ecosystem. +