diff --git a/packages/create-app/templates/default-app/packages/app/src/App.test.tsx b/packages/create-app/templates/default-app/packages/app/src/App.test.tsx index 15af99f6d9..b6ca21d422 100644 --- a/packages/create-app/templates/default-app/packages/app/src/App.test.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/App.test.tsx @@ -1,28 +1,28 @@ -import { render, waitFor } from '@testing-library/react'; -import App from './App'; - -describe('App', () => { - it('should render', async () => { - process.env = { - NODE_ENV: 'test', - APP_CONFIG: [ - { - data: { - app: { title: 'Test' }, - backend: { baseUrl: 'http://localhost:7007' }, - techdocs: { - storageUrl: 'http://localhost:7007/api/techdocs/static/docs', - }, - }, - context: 'test', - }, - ] as any, - }; - - const rendered = render(); - - await waitFor(() => { - expect(rendered.baseElement).toBeInTheDocument(); - }); - }); -}); +import { render, waitFor } from '@testing-library/react'; +import App from './App'; + +describe('App', () => { + it('should render', async () => { + process.env = { + NODE_ENV: 'test', + APP_CONFIG: [ + { + data: { + app: { title: 'Test' }, + backend: { baseUrl: 'http://localhost:7007' }, + techdocs: { + storageUrl: 'http://localhost:7007/api/techdocs/static/docs', + }, + }, + context: 'test', + }, + ] as any, + }; + + const rendered = render(); + + await waitFor(() => { + expect(rendered.baseElement).toBeInTheDocument(); + }); + }); +}); diff --git a/packages/create-app/templates/default-app/packages/app/src/App.tsx b/packages/create-app/templates/default-app/packages/app/src/App.tsx index 3ff552f95c..89b199c8d3 100644 --- a/packages/create-app/templates/default-app/packages/app/src/App.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/App.tsx @@ -1,108 +1,108 @@ -import { Navigate, Route } from 'react-router-dom'; -import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs'; -import { - CatalogEntityPage, - CatalogIndexPage, - catalogPlugin, -} from '@backstage/plugin-catalog'; -import { - CatalogImportPage, - catalogImportPlugin, -} from '@backstage/plugin-catalog-import'; -import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder'; -import { orgPlugin } from '@backstage/plugin-org'; -import { SearchPage } from '@backstage/plugin-search'; -import { - TechDocsIndexPage, - techdocsPlugin, - TechDocsReaderPage, -} from '@backstage/plugin-techdocs'; -import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; -import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; -import { UserSettingsPage } from '@backstage/plugin-user-settings'; -import { apis } from './apis'; -import { entityPage } from './components/catalog/EntityPage'; -import { searchPage } from './components/search/SearchPage'; -import { Root } from './components/Root'; - -import { - AlertDisplay, - OAuthRequestDialog, - SignInPage, -} from '@backstage/core-components'; -import { createApp } from '@backstage/app-defaults'; -import { AppRouter, FlatRoutes } from '@backstage/core-app-api'; -import { CatalogGraphPage } from '@backstage/plugin-catalog-graph'; -import { RequirePermission } from '@backstage/plugin-permission-react'; -import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; - -const app = createApp({ - apis, - bindRoutes({ bind }) { - bind(catalogPlugin.externalRoutes, { - createComponent: scaffolderPlugin.routes.root, - viewTechDoc: techdocsPlugin.routes.docRoot, - createFromTemplate: scaffolderPlugin.routes.selectedTemplate, - }); - bind(apiDocsPlugin.externalRoutes, { - registerApi: catalogImportPlugin.routes.importPage, - }); - bind(scaffolderPlugin.externalRoutes, { - registerComponent: catalogImportPlugin.routes.importPage, - viewTechDoc: techdocsPlugin.routes.docRoot, - }); - bind(orgPlugin.externalRoutes, { - catalogIndex: catalogPlugin.routes.catalogIndex, - }); - }, - components: { - SignInPage: props => , - }, -}); - -const routes = ( - - } /> - } /> - } - > - {entityPage} - - } /> - } - > - - - - - } /> - } /> - - - - } - /> - }> - {searchPage} - - } /> - } /> - -); - -export default app.createRoot( - <> - - - - {routes} - - , -); +import { Navigate, Route } from 'react-router-dom'; +import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs'; +import { + CatalogEntityPage, + CatalogIndexPage, + catalogPlugin, +} from '@backstage/plugin-catalog'; +import { + CatalogImportPage, + catalogImportPlugin, +} from '@backstage/plugin-catalog-import'; +import { ScaffolderPage, scaffolderPlugin } from '@backstage/plugin-scaffolder'; +import { orgPlugin } from '@backstage/plugin-org'; +import { SearchPage } from '@backstage/plugin-search'; +import { + TechDocsIndexPage, + techdocsPlugin, + TechDocsReaderPage, +} from '@backstage/plugin-techdocs'; +import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; +import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; +import { UserSettingsPage } from '@backstage/plugin-user-settings'; +import { apis } from './apis'; +import { entityPage } from './components/catalog/EntityPage'; +import { searchPage } from './components/search/SearchPage'; +import { Root } from './components/Root'; + +import { + AlertDisplay, + OAuthRequestDialog, + SignInPage, +} from '@backstage/core-components'; +import { createApp } from '@backstage/app-defaults'; +import { AppRouter, FlatRoutes } from '@backstage/core-app-api'; +import { CatalogGraphPage } from '@backstage/plugin-catalog-graph'; +import { RequirePermission } from '@backstage/plugin-permission-react'; +import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/alpha'; + +const app = createApp({ + apis, + bindRoutes({ bind }) { + bind(catalogPlugin.externalRoutes, { + createComponent: scaffolderPlugin.routes.root, + viewTechDoc: techdocsPlugin.routes.docRoot, + createFromTemplate: scaffolderPlugin.routes.selectedTemplate, + }); + bind(apiDocsPlugin.externalRoutes, { + registerApi: catalogImportPlugin.routes.importPage, + }); + bind(scaffolderPlugin.externalRoutes, { + registerComponent: catalogImportPlugin.routes.importPage, + viewTechDoc: techdocsPlugin.routes.docRoot, + }); + bind(orgPlugin.externalRoutes, { + catalogIndex: catalogPlugin.routes.catalogIndex, + }); + }, + components: { + SignInPage: props => , + }, +}); + +const routes = ( + + } /> + } /> + } + > + {entityPage} + + } /> + } + > + + + + + } /> + } /> + + + + } + /> + }> + {searchPage} + + } /> + } /> + +); + +export default app.createRoot( + <> + + + + {routes} + + , +); diff --git a/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoFull.tsx b/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoFull.tsx index 43a5934400..ce6365164a 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoFull.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoFull.tsx @@ -1,29 +1,29 @@ -import { makeStyles } from '@material-ui/core'; - -const useStyles = makeStyles({ - svg: { - width: 'auto', - height: 30, - }, - path: { - fill: '#7df3e1', - }, -}); -const LogoFull = () => { - const classes = useStyles(); - - return ( - - - - ); -}; - -export default LogoFull; +import { makeStyles } from '@material-ui/core'; + +const useStyles = makeStyles({ + svg: { + width: 'auto', + height: 30, + }, + path: { + fill: '#7df3e1', + }, +}); +const LogoFull = () => { + const classes = useStyles(); + + return ( + + + + ); +}; + +export default LogoFull; diff --git a/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoIcon.tsx b/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoIcon.tsx index d7615e075f..c60ba627c9 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoIcon.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/Root/LogoIcon.tsx @@ -1,30 +1,30 @@ -import { makeStyles } from '@material-ui/core'; - -const useStyles = makeStyles({ - svg: { - width: 'auto', - height: 28, - }, - path: { - fill: '#7df3e1', - }, -}); - -const LogoIcon = () => { - const classes = useStyles(); - - return ( - - - - ); -}; - -export default LogoIcon; +import { makeStyles } from '@material-ui/core'; + +const useStyles = makeStyles({ + svg: { + width: 'auto', + height: 28, + }, + path: { + fill: '#7df3e1', + }, +}); + +const LogoIcon = () => { + const classes = useStyles(); + + return ( + + + + ); +}; + +export default LogoIcon; diff --git a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx index 861610f4bf..31fc08db7f 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/Root/Root.tsx @@ -1,96 +1,96 @@ -import { PropsWithChildren } from 'react'; -import { makeStyles } from '@material-ui/core'; -import HomeIcon from '@material-ui/icons/Home'; -import ExtensionIcon from '@material-ui/icons/Extension'; -import LibraryBooks from '@material-ui/icons/LibraryBooks'; -import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; -import LogoFull from './LogoFull'; -import LogoIcon from './LogoIcon'; -import { - Settings as SidebarSettings, - UserSettingsSignInAvatar, -} from '@backstage/plugin-user-settings'; -import { SidebarSearchModal } from '@backstage/plugin-search'; -import { - Sidebar, - sidebarConfig, - SidebarDivider, - SidebarGroup, - SidebarItem, - SidebarPage, - SidebarScrollWrapper, - SidebarSpace, - useSidebarOpenState, - Link, -} from '@backstage/core-components'; -import MenuIcon from '@material-ui/icons/Menu'; -import SearchIcon from '@material-ui/icons/Search'; -import { MyGroupsSidebarItem } from '@backstage/plugin-org'; -import GroupIcon from '@material-ui/icons/People'; - -const useSidebarLogoStyles = makeStyles({ - root: { - width: sidebarConfig.drawerWidthClosed, - height: 3 * sidebarConfig.logoHeight, - display: 'flex', - flexFlow: 'row nowrap', - alignItems: 'center', - marginBottom: -14, - }, - link: { - width: sidebarConfig.drawerWidthClosed, - marginLeft: 24, - }, -}); - -const SidebarLogo = () => { - const classes = useSidebarLogoStyles(); - const { isOpen } = useSidebarOpenState(); - - return ( -
- - {isOpen ? : } - -
- ); -}; - -export const Root = ({ children }: PropsWithChildren<{}>) => ( - - - - } to="/search"> - - - - }> - {/* Global nav, not org-specific */} - - - - - - {/* End global nav */} - - - {/* Items in this group will be scrollable if they run out of space */} - - - - - } - to="/settings" - > - - - - {children} - -); +import { PropsWithChildren } from 'react'; +import { makeStyles } from '@material-ui/core'; +import HomeIcon from '@material-ui/icons/Home'; +import ExtensionIcon from '@material-ui/icons/Extension'; +import LibraryBooks from '@material-ui/icons/LibraryBooks'; +import CreateComponentIcon from '@material-ui/icons/AddCircleOutline'; +import LogoFull from './LogoFull'; +import LogoIcon from './LogoIcon'; +import { + Settings as SidebarSettings, + UserSettingsSignInAvatar, +} from '@backstage/plugin-user-settings'; +import { SidebarSearchModal } from '@backstage/plugin-search'; +import { + Sidebar, + sidebarConfig, + SidebarDivider, + SidebarGroup, + SidebarItem, + SidebarPage, + SidebarScrollWrapper, + SidebarSpace, + useSidebarOpenState, + Link, +} from '@backstage/core-components'; +import MenuIcon from '@material-ui/icons/Menu'; +import SearchIcon from '@material-ui/icons/Search'; +import { MyGroupsSidebarItem } from '@backstage/plugin-org'; +import GroupIcon from '@material-ui/icons/People'; + +const useSidebarLogoStyles = makeStyles({ + root: { + width: sidebarConfig.drawerWidthClosed, + height: 3 * sidebarConfig.logoHeight, + display: 'flex', + flexFlow: 'row nowrap', + alignItems: 'center', + marginBottom: -14, + }, + link: { + width: sidebarConfig.drawerWidthClosed, + marginLeft: 24, + }, +}); + +const SidebarLogo = () => { + const classes = useSidebarLogoStyles(); + const { isOpen } = useSidebarOpenState(); + + return ( +
+ + {isOpen ? : } + +
+ ); +}; + +export const Root = ({ children }: PropsWithChildren<{}>) => ( + + + + } to="/search"> + + + + }> + {/* Global nav, not org-specific */} + + + + + + {/* End global nav */} + + + {/* Items in this group will be scrollable if they run out of space */} + + + + + } + to="/settings" + > + + + + {children} + +); diff --git a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx index c0ce900d75..f75d984366 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/catalog/EntityPage.tsx @@ -1,410 +1,410 @@ -import { Button, Grid } from '@material-ui/core'; -import { - EntityApiDefinitionCard, - EntityConsumedApisCard, - EntityConsumingComponentsCard, - EntityHasApisCard, - EntityProvidedApisCard, - EntityProvidingComponentsCard, -} from '@backstage/plugin-api-docs'; -import { - EntityAboutCard, - EntityDependsOnComponentsCard, - EntityDependsOnResourcesCard, - EntityHasComponentsCard, - EntityHasResourcesCard, - EntityHasSubcomponentsCard, - EntityHasSystemsCard, - EntityLayout, - EntityLinksCard, - EntitySwitch, - EntityOrphanWarning, - EntityProcessingErrorsPanel, - isComponentType, - isKind, - hasCatalogProcessingErrors, - isOrphan, - hasRelationWarnings, - EntityRelationWarning, -} from '@backstage/plugin-catalog'; -import { - EntityUserProfileCard, - EntityGroupProfileCard, - EntityMembersListCard, - EntityOwnershipCard, -} from '@backstage/plugin-org'; -import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; -import { EmptyState } from '@backstage/core-components'; -import { - Direction, - EntityCatalogGraphCard, -} from '@backstage/plugin-catalog-graph'; -import { - RELATION_API_CONSUMED_BY, - RELATION_API_PROVIDED_BY, - RELATION_CONSUMES_API, - RELATION_DEPENDENCY_OF, - RELATION_DEPENDS_ON, - RELATION_HAS_PART, - RELATION_PART_OF, - RELATION_PROVIDES_API, -} from '@backstage/catalog-model'; - -import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; -import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; - -import { - EntityKubernetesContent, - isKubernetesAvailable, -} from '@backstage/plugin-kubernetes'; - -const techdocsContent = ( - - - - - -); - -const cicdContent = ( - // This is an example of how you can implement your company's logic in entity page. - // You can for example enforce that all components of type 'service' should use GitHubActions - ( - {/* - Here you can add support for different CI/CD services, for example - using @backstage-community/plugin-github-actions as follows: - - - - */} - - - Read more - - } - /> - - ) -); - -const entityWarningContent = ( - <> - - - - - - - - - - - - - - - - - - - - - - - - -); - -const overviewContent = ( - - {entityWarningContent} - - - - - - - - - - - - - - -); - -const serviceEntityPage = ( - - - {overviewContent} - - - - {cicdContent} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {techdocsContent} - - -); - -const websiteEntityPage = ( - - - {overviewContent} - - - - {cicdContent} - - - - - - - - - - - - - - - - - - - {techdocsContent} - - -); - -/** - * NOTE: This page is designed to work on small screens such as mobile devices. - * This is based on Material UI Grid. If breakpoints are used, each grid item must set the `xs` prop to a column size or to `true`, - * since this does not default. If no breakpoints are used, the items will equitably share the available space. - * https://material-ui.com/components/grid/#basic-grid. - */ - -const defaultEntityPage = ( - - - {overviewContent} - - - - {techdocsContent} - - -); - -const componentPage = ( - - - {serviceEntityPage} - - - - {websiteEntityPage} - - - {defaultEntityPage} - -); - -const apiPage = ( - - - - {entityWarningContent} - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -const userPage = ( - - - - {entityWarningContent} - - - - - - - - - -); - -const groupPage = ( - - - - {entityWarningContent} - - - - - - - - - - - - - - - -); - -const systemPage = ( - - - - {entityWarningContent} - - - - - - - - - - - - - - - - - - - - - - - - -); - -const domainPage = ( - - - - {entityWarningContent} - - - - - - - - - - - - -); - -export const entityPage = ( - - - - - - - - - {defaultEntityPage} - -); +import { Button, Grid } from '@material-ui/core'; +import { + EntityApiDefinitionCard, + EntityConsumedApisCard, + EntityConsumingComponentsCard, + EntityHasApisCard, + EntityProvidedApisCard, + EntityProvidingComponentsCard, +} from '@backstage/plugin-api-docs'; +import { + EntityAboutCard, + EntityDependsOnComponentsCard, + EntityDependsOnResourcesCard, + EntityHasComponentsCard, + EntityHasResourcesCard, + EntityHasSubcomponentsCard, + EntityHasSystemsCard, + EntityLayout, + EntityLinksCard, + EntitySwitch, + EntityOrphanWarning, + EntityProcessingErrorsPanel, + isComponentType, + isKind, + hasCatalogProcessingErrors, + isOrphan, + hasRelationWarnings, + EntityRelationWarning, +} from '@backstage/plugin-catalog'; +import { + EntityUserProfileCard, + EntityGroupProfileCard, + EntityMembersListCard, + EntityOwnershipCard, +} from '@backstage/plugin-org'; +import { EntityTechdocsContent } from '@backstage/plugin-techdocs'; +import { EmptyState } from '@backstage/core-components'; +import { + Direction, + EntityCatalogGraphCard, +} from '@backstage/plugin-catalog-graph'; +import { + RELATION_API_CONSUMED_BY, + RELATION_API_PROVIDED_BY, + RELATION_CONSUMES_API, + RELATION_DEPENDENCY_OF, + RELATION_DEPENDS_ON, + RELATION_HAS_PART, + RELATION_PART_OF, + RELATION_PROVIDES_API, +} from '@backstage/catalog-model'; + +import { TechDocsAddons } from '@backstage/plugin-techdocs-react'; +import { ReportIssue } from '@backstage/plugin-techdocs-module-addons-contrib'; + +import { + EntityKubernetesContent, + isKubernetesAvailable, +} from '@backstage/plugin-kubernetes'; + +const techdocsContent = ( + + + + + +); + +const cicdContent = ( + // This is an example of how you can implement your company's logic in entity page. + // You can for example enforce that all components of type 'service' should use GitHubActions + + {/* + Here you can add support for different CI/CD services, for example + using @backstage-community/plugin-github-actions as follows: + + + + */} + + + Read more + + } + /> + + +); + +const entityWarningContent = ( + <> + + + + + + + + + + + + + + + + + + + + + + + + +); + +const overviewContent = ( + + {entityWarningContent} + + + + + + + + + + + + + + +); + +const serviceEntityPage = ( + + + {overviewContent} + + + + {cicdContent} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {techdocsContent} + + +); + +const websiteEntityPage = ( + + + {overviewContent} + + + + {cicdContent} + + + + + + + + + + + + + + + + + + + {techdocsContent} + + +); + +/** + * NOTE: This page is designed to work on small screens such as mobile devices. + * This is based on Material UI Grid. If breakpoints are used, each grid item must set the `xs` prop to a column size or to `true`, + * since this does not default. If no breakpoints are used, the items will equitably share the available space. + * https://material-ui.com/components/grid/#basic-grid. + */ + +const defaultEntityPage = ( + + + {overviewContent} + + + + {techdocsContent} + + +); + +const componentPage = ( + + + {serviceEntityPage} + + + + {websiteEntityPage} + + + {defaultEntityPage} + +); + +const apiPage = ( + + + + {entityWarningContent} + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); + +const userPage = ( + + + + {entityWarningContent} + + + + + + + + + +); + +const groupPage = ( + + + + {entityWarningContent} + + + + + + + + + + + + + + + +); + +const systemPage = ( + + + + {entityWarningContent} + + + + + + + + + + + + + + + + + + + + + + + + +); + +const domainPage = ( + + + + {entityWarningContent} + + + + + + + + + + + + +); + +export const entityPage = ( + + + + + + + + + {defaultEntityPage} + +); diff --git a/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx b/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx index 779088ad11..08a774b1f5 100644 --- a/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx +++ b/packages/create-app/templates/default-app/packages/app/src/components/search/SearchPage.tsx @@ -1,123 +1,123 @@ -import { makeStyles, Theme, Grid, Paper } from '@material-ui/core'; - -import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; -import { - catalogApiRef, - CATALOG_FILTER_EXISTS, -} from '@backstage/plugin-catalog-react'; -import { TechDocsSearchResultListItem } from '@backstage/plugin-techdocs'; - -import { SearchType } from '@backstage/plugin-search'; -import { - SearchBar, - SearchFilter, - SearchResult, - SearchPagination, - useSearch, -} from '@backstage/plugin-search-react'; -import { - CatalogIcon, - Content, - DocsIcon, - Header, - Page, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; - -const useStyles = makeStyles((theme: Theme) => ({ - bar: { - padding: theme.spacing(1, 0), - }, - filters: { - padding: theme.spacing(2), - marginTop: theme.spacing(2), - }, - filter: { - '& + &': { - marginTop: theme.spacing(2.5), - }, - }, -})); - -const SearchPage = () => { - const classes = useStyles(); - const { types } = useSearch(); - const catalogApi = useApi(catalogApiRef); - - return ( - -
- - - - - - - - - , - }, - { - value: 'techdocs', - name: 'Documentation', - icon: , - }, - ]} - /> - - {types.includes('techdocs') && ( - { - // Return a list of entities which are documented. - const { items } = await catalogApi.getEntities({ - fields: ['metadata.name'], - filter: { - 'metadata.annotations.backstage.io/techdocs-ref': - CATALOG_FILTER_EXISTS, - }, - }); - - const names = items.map(entity => entity.metadata.name); - names.sort(); - return names; - }} - /> - )} - - - - - - - - } /> - } /> - - - - - - ); -}; - -export const searchPage = ; +import { makeStyles, Theme, Grid, Paper } from '@material-ui/core'; + +import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; +import { + catalogApiRef, + CATALOG_FILTER_EXISTS, +} from '@backstage/plugin-catalog-react'; +import { TechDocsSearchResultListItem } from '@backstage/plugin-techdocs'; + +import { SearchType } from '@backstage/plugin-search'; +import { + SearchBar, + SearchFilter, + SearchResult, + SearchPagination, + useSearch, +} from '@backstage/plugin-search-react'; +import { + CatalogIcon, + Content, + DocsIcon, + Header, + Page, +} from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; + +const useStyles = makeStyles((theme: Theme) => ({ + bar: { + padding: theme.spacing(1, 0), + }, + filters: { + padding: theme.spacing(2), + marginTop: theme.spacing(2), + }, + filter: { + '& + &': { + marginTop: theme.spacing(2.5), + }, + }, +})); + +const SearchPage = () => { + const classes = useStyles(); + const { types } = useSearch(); + const catalogApi = useApi(catalogApiRef); + + return ( + +
+ + + + + + + + + , + }, + { + value: 'techdocs', + name: 'Documentation', + icon: , + }, + ]} + /> + + {types.includes('techdocs') && ( + { + // Return a list of entities which are documented. + const { items } = await catalogApi.getEntities({ + fields: ['metadata.name'], + filter: { + 'metadata.annotations.backstage.io/techdocs-ref': + CATALOG_FILTER_EXISTS, + }, + }); + + const names = items.map(entity => entity.metadata.name); + names.sort(); + return names; + }} + /> + )} + + + + + + + + } /> + } /> + + + + + + ); +}; + +export const searchPage = ;