diff --git a/docs/features/search/concepts.md b/docs/features/search/concepts.md index 6a927d73c0..42e0421440 100644 --- a/docs/features/search/concepts.md +++ b/docs/features/search/concepts.md @@ -10,12 +10,16 @@ Backstage Search is _blah_. To get started, you should get familiar with these core concepts: +TODO: Link these like a real TOC + - Search Engines - Query Translators - Documents and Indices - Collators - Decorators - The Scheduler +- The Search Page +- Search Context and Components ### Search Engines @@ -23,8 +27,8 @@ Backstage Search isn't a search engine itself, rather, it provides an interface between your Backstage instance and a Search Engine of your choice. More concretely, a `SearchEngine` is an interface whose concrete implementations facilitate communication with different search engines (like ElasticSearch, -Solr, Algolia, etc). This abstraction exists in order to support your -organization's needs. +Solr, etc). This abstraction exists in order to support your organization's +needs. Out of the box, Backstage Search comes pre-packaged with an in-memory search engine implementation built on top of Lunr. @@ -39,7 +43,7 @@ search engine. Search Engines come pre-packaged with simple translators that do rudimentary transformations of search terms and filters, but you may want to provide your -own to help tune seearch results in the context of your organization. +own to help tune search results in the context of your organization. ### Documents and Indices @@ -78,11 +82,30 @@ Search chooses to completely rebuild indices on a schedule. Different collators can be configured to refresh at different intervals, depending on how often the source information is updated. -TODO: There should probably be some front-end concepts here too? +### The Search Page -- Search Page -- Search Components -- Search Context +Search pages are very custom things. Not every Backstage instance will want the +same interface! In order to allow you to customize your search experience to +your heart's content, the Search Plugin takes care of state management and other +search logic for you, but most of the layout of a search page lives in a search +page component defined in your Backstage App. -[Primarily solves for “As an App Integrator, I should know how to add do uments -to the search index”] +For an example of a simple search page, check [getting started](TODO) + +### Search Context and Components + +A search experience, like a page, is composed of any number of search +components, which are all wired up using a search context. + +Each search experience's context consists of details like a search term, +filters, types, results, and a page cursor for handling pagination. Different +components use this context in different ways, for example the `` +can set the search term, `` components can set filters, and +search results can be displayed using the `` component. + +The `` and `` components are special, in that +they themselves are extensible. For an example of how to extend these +components, [check this out](TODO). + +If you need even more customization, you can use the search context like any +other React context to create custom search components of your own. diff --git a/docs/features/search/getting-started.md b/docs/features/search/getting-started.md index 867b71c8d4..6218afbcb0 100644 --- a/docs/features/search/getting-started.md +++ b/docs/features/search/getting-started.md @@ -12,9 +12,9 @@ use Search. If you haven't setup Backstage already, start [here](../../getting-started/index.md). -> If you used `npx @backstage/create-app`, Search may already be present. -> -> You should skip to [`Customizing Search`](#customizing-search) below. +> If you used `npx @backstage/create-app`, and you have a search page defined in +> `packages/app/src/components/search`, skip to +> [`Customizing Search`](#customizing-search) below. ## Adding Search to the Frontend @@ -24,7 +24,92 @@ cd packages/app yarn add @backstage/plugin-search ``` -TODO: Add frontend instructions here. +Create a new `packages/app/src/components/search/SearchPage.tsx` file in your +Backstage app with the following contents: + +```tsx +import React from 'react'; +import { Content, Header, Page } from '@backstage/core'; +import { Grid, List, Card, CardContent } from '@material-ui/core'; +import { + SearchBar, + SearchResult, + DefaultResultListItem, + SearchFilter, +} from '@backstage/plugin-search'; +import { CatalogResultListItem } from '@backstage/plugin-catalog'; + +export const searchPage = ( + +
+ + + + + + + + + + + + + + + + + + {({ results }) => ( + + {results.map(result => { + switch (result.type) { + case 'software-catalog': + return ( + + ); + default: + return ( + + ); + } + })} + + )} + + + + + +); +``` + +Bind the above Search Page to the `/search` route in your +`packages/app/src/App.tsx` file, like this: + +```tsx +import { SearchPage } from '@backstage/plugin-search'; +import { searchPage } from './components/search/SearchPage'; + +const routes = ( + + }> + {searchPage} + + +); +``` ## Adding Search to the Backend @@ -96,6 +181,75 @@ apiRouter.use('/search', await search(searchEnv)); ## Customizing Search +### Frontend + +The Search Plugin exposes several default filter types as static properties, +including `` and ``. These allow +you to provide values relevant to your Backstage instance that, when selected, +get passed to the backend. + +```tsx {2-5,8-11} + + + + + + +``` + +If you have advanced filter needs, you can specify your own filter component +like this (although contributions are welcome): + +```tsx +import { useSearch, SearchFilter } from '@backstage/plugin-search'; + +const MyCustomFilter = () => { + // Note: filters contain filter data from other filter components. Be sure + // not to clobber other filters' data! + const { filters, setFilters } = useSearch(); + + return (/* ... */); +}; + +// Which could be rendered like this: + +``` + +It's good practice for search results to highlight information that was used to +return it in the first place! The code below highlights how you might specify a +custom result item component, using the `` component as +an example: + +```tsx {7-13} + + {({ results }) => ( + + {results.map(result => { + // result.type is the index type defined by the collator. + switch (result.type) { + case 'software-catalog': + return ( + + ); + // ... + } + })} + + )} + +``` + +### Backend + Backstage Search isn't a search engine itself, rather, it provides an interface between your Backstage instance and a Search Engine of your choice. Currently, we only support one, in-memory search Engine called Lunr. It can be instantiated @@ -139,17 +293,3 @@ indexBuilder.addCollator({ collator: new DefaultCatalogCollator({ discovery }), }); ``` - ---- - -[Primarily solves for “As an App Integrator, I should be able to install out-of -the-box Search”] - -Backend: Different for new Backstage instances (created via create-app) vs. -people enabling search on existing Backstage instances (see catalog install for -example). - -Frontend: Search Page Route…? Customizing result components…? - -Conceptually… What’s the difference between “out-of-the-box” or “basic” and the -recommended deployment (which will come)