@backstage/plugin-search 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-655809db.esm.js","sources":["../../src/apis.ts","../../src/components/DefaultResultListItem/DefaultResultListItem.tsx","../../src/components/Filters/FiltersButton.tsx","../../src/components/Filters/Filters.tsx","../../src/components/SearchContext/SearchContext.tsx","../../src/components/SearchBar/SearchBar.tsx","../../src/components/SearchFilter/SearchFilter.tsx","../../../../node_modules/@material-ui/icons/esm/Launch.js","../../src/components/SearchResult/SearchResult.tsx","../../src/components/SearchResultPager/SearchResultPager.tsx","../../src/plugin.ts","../../src/components/SearchModal/SearchModal.tsx","../../src/components/LegacySearchPage/LegacySearchBar.tsx","../../src/components/LegacySearchPage/Filters/FiltersButton.tsx","../../src/components/LegacySearchPage/Filters/Filters.tsx","../../src/components/LegacySearchPage/LegacySearchResult.tsx","../../src/components/LegacySearchPage/LegacySearchPage.tsx","../../src/components/SearchPage/SearchPage.tsx","../../src/components/SearchType/SearchType.tsx","../../src/components/SidebarSearch/SidebarSearch.tsx","../../src/components/util.ts","../../src/components/HomePageComponent/HomePageSearchBar.tsx"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n createApiRef,\n DiscoveryApi,\n IdentityApi,\n} from '@backstage/core-plugin-api';\nimport { ResponseError } from '@backstage/errors';\nimport { SearchQuery, SearchResultSet } from '@backstage/search-common';\nimport qs from 'qs';\n\nexport const searchApiRef = createApiRef<SearchApi>({\n id: 'plugin.search.queryservice',\n});\n\nexport interface SearchApi {\n query(query: SearchQuery): Promise<SearchResultSet>;\n}\n\nexport class SearchClient implements SearchApi {\n private readonly discoveryApi: DiscoveryApi;\n private readonly identityApi: IdentityApi;\n\n constructor(options: {\n discoveryApi: DiscoveryApi;\n identityApi: IdentityApi;\n }) {\n this.discoveryApi = options.discoveryApi;\n this.identityApi = options.identityApi;\n }\n\n async query(query: SearchQuery): Promise<SearchResultSet> {\n const token = await this.identityApi.getIdToken();\n const queryString = qs.stringify(query);\n const url = `${await this.discoveryApi.getBaseUrl(\n 'search/query',\n )}?${queryString}`;\n const response = await fetch(url, {\n headers: token ? { Authorization: `Bearer ${token}` } : {},\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n return response.json();\n }\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ReactNode } from 'react';\nimport { IndexableDocument } from '@backstage/search-common';\nimport {\n ListItem,\n ListItemIcon,\n ListItemText,\n Box,\n Divider,\n} from '@material-ui/core';\nimport { Link } from '@backstage/core-components';\n\ntype Props = {\n icon?: ReactNode;\n secondaryAction?: ReactNode;\n result: IndexableDocument;\n};\n\nexport const DefaultResultListItem = ({\n result,\n icon,\n secondaryAction,\n}: Props) => {\n return (\n <Link to={result.location}>\n <ListItem alignItems=\"center\">\n {icon && <ListItemIcon>{icon}</ListItemIcon>}\n <ListItemText\n primaryTypographyProps={{ variant: 'h6' }}\n primary={result.title}\n secondary={result.text}\n />\n {secondaryAction && <Box alignItems=\"flex-end\">{secondaryAction}</Box>}\n </ListItem>\n <Divider />\n </Link>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport FilterListIcon from '@material-ui/icons/FilterList';\nimport { makeStyles, IconButton, Typography } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n width: '250px',\n display: 'flex',\n },\n icon: {\n margin: theme.spacing(-1, 0, 0, 0),\n },\n}));\n\ntype FiltersButtonProps = {\n numberOfSelectedFilters: number;\n handleToggleFilters: () => void;\n};\n\nexport const FiltersButton = ({\n numberOfSelectedFilters,\n handleToggleFilters,\n}: FiltersButtonProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.filters}>\n <IconButton\n className={classes.icon}\n aria-label=\"settings\"\n onClick={handleToggleFilters}\n >\n <FilterListIcon />\n </IconButton>\n <Typography variant=\"h6\">\n Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0})\n </Typography>\n </div>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n makeStyles,\n Typography,\n Divider,\n Card,\n CardHeader,\n Button,\n CardContent,\n Select,\n Checkbox,\n List,\n ListItem,\n ListItemText,\n MenuItem,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n background: 'transparent',\n boxShadow: '0px 0px 0px 0px',\n },\n checkbox: {\n padding: theme.spacing(0, 1, 0, 1),\n },\n dropdown: {\n width: '100%',\n },\n}));\n\nexport type FiltersState = {\n selected: string;\n checked: Array<string>;\n};\n\nexport type FilterOptions = {\n kind: Array<string>;\n lifecycle: Array<string>;\n};\n\ntype FiltersProps = {\n filters: FiltersState;\n filterOptions: FilterOptions;\n resetFilters: () => void;\n updateSelected: (filter: string) => void;\n updateChecked: (filter: string) => void;\n};\n\nexport const Filters = ({\n filters,\n filterOptions,\n resetFilters,\n updateSelected,\n updateChecked,\n}: FiltersProps) => {\n const classes = useStyles();\n\n return (\n <Card className={classes.filters}>\n <CardHeader\n title={<Typography variant=\"h6\">Filters</Typography>}\n action={\n <Button color=\"primary\" onClick={() => resetFilters()}>\n CLEAR ALL\n </Button>\n }\n />\n <Divider />\n {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">\n Filters cannot be applied to available results\n </Typography>\n </CardContent>\n )}\n {filterOptions.kind.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Kind</Typography>\n <Select\n id=\"outlined-select\"\n onChange={(e: React.ChangeEvent<any>) =>\n updateSelected(e?.target?.value)\n }\n variant=\"outlined\"\n className={classes.dropdown}\n value={filters.selected}\n >\n {filterOptions.kind.map(filter => (\n <MenuItem\n selected={filter === ''}\n dense\n key={filter}\n value={filter}\n >\n {filter}\n </MenuItem>\n ))}\n </Select>\n </CardContent>\n )}\n {filterOptions.lifecycle.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Lifecycle</Typography>\n <List disablePadding dense>\n {filterOptions.lifecycle.map(filter => (\n <ListItem\n key={filter}\n dense\n button\n onClick={() => updateChecked(filter)}\n >\n <Checkbox\n edge=\"start\"\n disableRipple\n className={classes.checkbox}\n color=\"primary\"\n checked={filters.checked.includes(filter)}\n tabIndex={-1}\n value={filter}\n name={filter}\n />\n <ListItemText id={filter} primary={filter} />\n </ListItem>\n ))}\n </List>\n </CardContent>\n )}\n </Card>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { JsonObject } from '@backstage/types';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { SearchResultSet } from '@backstage/search-common';\nimport React, {\n createContext,\n PropsWithChildren,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport { useAsync, usePrevious } from 'react-use';\nimport { AsyncState } from 'react-use/lib/useAsync';\nimport { searchApiRef } from '../../apis';\n\ntype SearchContextValue = {\n result: AsyncState<SearchResultSet>;\n term: string;\n setTerm: React.Dispatch<React.SetStateAction<string>>;\n types: string[];\n setTypes: React.Dispatch<React.SetStateAction<string[]>>;\n filters: JsonObject;\n setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;\n open?: boolean;\n toggleModal: () => void;\n pageCursor?: string;\n setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;\n fetchNextPage?: React.DispatchWithoutAction;\n fetchPreviousPage?: React.DispatchWithoutAction;\n};\n\ntype SettableSearchContext = Omit<\n SearchContextValue,\n | 'result'\n | 'setTerm'\n | 'setTypes'\n | 'setFilters'\n | 'toggleModal'\n | 'setPageCursor'\n | 'fetchNextPage'\n | 'fetchPreviousPage'\n>;\n\nexport const SearchContext = createContext<SearchContextValue | undefined>(\n undefined,\n);\n\nexport const SearchContextProvider = ({\n initialState = {\n term: '',\n pageCursor: undefined,\n filters: {},\n types: [],\n },\n children,\n}: PropsWithChildren<{ initialState?: SettableSearchContext }>) => {\n const searchApi = useApi(searchApiRef);\n const [pageCursor, setPageCursor] = useState<string | undefined>(\n initialState.pageCursor,\n );\n const [filters, setFilters] = useState<JsonObject>(initialState.filters);\n const [term, setTerm] = useState<string>(initialState.term);\n const [types, setTypes] = useState<string[]>(initialState.types);\n const [open, setOpen] = useState<boolean>(false);\n const toggleModal = useCallback(\n (): void => setOpen(prevState => !prevState),\n [],\n );\n\n const prevTerm = usePrevious(term);\n\n const result = useAsync(\n () =>\n searchApi.query({\n term,\n filters,\n pageCursor: pageCursor,\n types,\n }),\n [term, filters, types, pageCursor],\n );\n\n const hasNextPage =\n !result.loading && !result.error && result.value?.nextPageCursor;\n const hasPreviousPage =\n !result.loading && !result.error && result.value?.previousPageCursor;\n const fetchNextPage = useCallback(() => {\n setPageCursor(result.value?.nextPageCursor);\n }, [result.value?.nextPageCursor]);\n const fetchPreviousPage = useCallback(() => {\n setPageCursor(result.value?.previousPageCursor);\n }, [result.value?.previousPageCursor]);\n\n useEffect(() => {\n // Any time a term is reset, we want to start from page 0.\n if (term && prevTerm && term !== prevTerm) {\n setPageCursor(undefined);\n }\n }, [term, prevTerm, initialState.pageCursor]);\n\n const value: SearchContextValue = {\n result,\n filters,\n setFilters,\n open,\n toggleModal,\n term,\n setTerm,\n types,\n setTypes,\n pageCursor,\n setPageCursor,\n fetchNextPage: hasNextPage ? fetchNextPage : undefined,\n fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,\n };\n\n return <SearchContext.Provider value={value} children={children} />;\n};\n\nexport const useSearch = () => {\n const context = useContext(SearchContext);\n if (context === undefined) {\n throw new Error('useSearch must be used within a SearchContextProvider');\n }\n return context;\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, {\n ChangeEvent,\n KeyboardEvent,\n useState,\n useEffect,\n useCallback,\n} from 'react';\nimport { useDebounce } from 'react-use';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\nimport {\n InputBase,\n InputBaseProps,\n InputAdornment,\n IconButton,\n} from '@material-ui/core';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nimport { useSearch } from '../SearchContext';\n\n/**\n * Props for {@link SearchBarBase}.\n *\n * @public\n */\nexport type SearchBarBaseProps = Omit<InputBaseProps, 'onChange'> & {\n debounceTime?: number;\n clearButton?: boolean;\n onClear?: () => void;\n onSubmit?: () => void;\n onChange: (value: string) => void;\n};\n\n/**\n * All search boxes exported by the search plugin are based on the <SearchBarBase />,\n * and this one is based on the <InputBase /> component from Material UI.\n * Recommended if you don't use Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBarBase = ({\n onChange,\n onKeyDown,\n onSubmit,\n debounceTime = 200,\n clearButton = true,\n fullWidth = true,\n value: defaultValue,\n inputProps: defaultInputProps = {},\n endAdornment: defaultEndAdornment,\n ...props\n}: SearchBarBaseProps) => {\n const configApi = useApi(configApiRef);\n const [value, setValue] = useState<string>(defaultValue as string);\n\n useEffect(() => {\n setValue(prevValue =>\n prevValue !== defaultValue ? (defaultValue as string) : prevValue,\n );\n }, [defaultValue]);\n\n useDebounce(() => onChange(value), debounceTime, [value]);\n\n const handleChange = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n setValue(e.target.value);\n },\n [setValue],\n );\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLInputElement>) => {\n if (onKeyDown) onKeyDown(e);\n if (onSubmit && e.key === 'Enter') {\n onSubmit();\n }\n },\n [onKeyDown, onSubmit],\n );\n\n const handleClear = useCallback(() => {\n onChange('');\n }, [onChange]);\n\n const placeholder = `Search in ${\n configApi.getOptionalString('app.title') || 'Backstage'\n }`;\n\n const startAdornment = (\n <InputAdornment position=\"start\">\n <IconButton aria-label=\"Query\" disabled>\n <SearchIcon />\n </IconButton>\n </InputAdornment>\n );\n\n const endAdornment = (\n <InputAdornment position=\"end\">\n <IconButton aria-label=\"Clear\" onClick={handleClear}>\n <ClearButton />\n </IconButton>\n </InputAdornment>\n );\n\n return (\n <InputBase\n data-testid=\"search-bar-next\"\n value={value}\n placeholder={placeholder}\n startAdornment={startAdornment}\n endAdornment={clearButton ? endAdornment : defaultEndAdornment}\n inputProps={{ 'aria-label': 'Search', ...defaultInputProps }}\n fullWidth={fullWidth}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n {...props}\n />\n );\n};\n\n/**\n * Props for {@link SearchBar}.\n *\n * @public\n */\nexport type SearchBarProps = Partial<SearchBarBaseProps>;\n\n/**\n * Recommended search bar when you use the Search Provider or Search Context.\n *\n * @public\n */\nexport const SearchBar = ({ onChange, ...props }: SearchBarProps) => {\n const { term, setTerm } = useSearch();\n\n const handleChange = (newValue: string) => {\n setTerm(newValue);\n if (onChange) onChange(newValue);\n };\n\n return <SearchBarBase value={term} onChange={handleChange} {...props} />;\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { ReactElement, ChangeEvent, useEffect } from 'react';\nimport {\n makeStyles,\n FormControl,\n FormControlLabel,\n InputLabel,\n Checkbox,\n Select,\n MenuItem,\n FormLabel,\n} from '@material-ui/core';\n\nimport { useSearch } from '../SearchContext';\n\nconst useStyles = makeStyles({\n label: {\n textTransform: 'capitalize',\n },\n});\n\nexport type Component = {\n className?: string;\n name: string;\n values?: string[];\n defaultValue?: string[] | string | null;\n};\n\nexport type Props = Component & {\n component: (props: Component) => ReactElement;\n debug?: boolean;\n};\n\nconst CheckboxFilter = ({\n className,\n name,\n defaultValue,\n values = [],\n}: Component) => {\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n\n useEffect(() => {\n if (Array.isArray(defaultValue)) {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleChange = (e: ChangeEvent<HTMLInputElement>) => {\n const {\n target: { value, checked },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n const rest = ((filter as string[]) || []).filter(i => i !== value);\n const items = checked ? [...rest, value] : rest;\n return items.length ? { ...others, [name]: items } : others;\n });\n };\n\n return (\n <FormControl\n className={className}\n fullWidth\n data-testid=\"search-checkboxfilter-next\"\n >\n <FormLabel className={classes.label}>{name}</FormLabel>\n {values.map((value: string) => (\n <FormControlLabel\n key={value}\n control={\n <Checkbox\n color=\"primary\"\n tabIndex={-1}\n inputProps={{ 'aria-labelledby': value }}\n value={value}\n name={value}\n onChange={handleChange}\n checked={((filters[name] as string[]) ?? []).includes(value)}\n />\n }\n label={value}\n />\n ))}\n </FormControl>\n );\n};\n\nconst SelectFilter = ({\n className,\n name,\n defaultValue,\n values = [],\n}: Component) => {\n const classes = useStyles();\n const { filters, setFilters } = useSearch();\n\n useEffect(() => {\n if (typeof defaultValue === 'string') {\n setFilters(prevFilters => ({\n ...prevFilters,\n [name]: defaultValue,\n }));\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const {\n target: { value },\n } = e;\n\n setFilters(prevFilters => {\n const { [name]: filter, ...others } = prevFilters;\n return value ? { ...others, [name]: value as string } : others;\n });\n };\n\n return (\n <FormControl\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-selectfilter-next\"\n >\n <InputLabel className={classes.label} margin=\"dense\">\n {name}\n </InputLabel>\n <Select\n variant=\"outlined\"\n value={filters[name] || ''}\n onChange={handleChange}\n >\n <MenuItem value=\"\">\n <em>All</em>\n </MenuItem>\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n {value}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\nconst SearchFilter = ({ component: Element, ...props }: Props) => (\n <Element {...props} />\n);\n\nSearchFilter.Checkbox = (props: Omit<Props, 'component'> & Component) => (\n <SearchFilter {...props} component={CheckboxFilter} />\n);\n\nSearchFilter.Select = (props: Omit<Props, 'component'> & Component) => (\n <SearchFilter {...props} component={SelectFilter} />\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchFilter /> component instead. This component will be removed in an\n * upcoming release.\n */\nconst SearchFilterNext = SearchFilter;\n\nexport { SearchFilter, SearchFilterNext };\n","import * as React from 'react';\nimport createSvgIcon from './utils/createSvgIcon';\nexport default createSvgIcon( /*#__PURE__*/React.createElement(\"path\", {\n d: \"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2v7zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3h-7z\"\n}), 'Launch');","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EmptyState,\n Progress,\n ResponseErrorPanel,\n} from '@backstage/core-components';\nimport { SearchResult } from '@backstage/search-common';\nimport React from 'react';\nimport { useSearch } from '../SearchContext';\n\ntype Props = {\n children: (results: { results: SearchResult[] }) => JSX.Element;\n};\n\nexport const SearchResultComponent = ({ children }: Props) => {\n const {\n result: { loading, error, value },\n } = useSearch();\n\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return (\n <ResponseErrorPanel\n title=\"Error encountered while fetching search results\"\n error={error}\n />\n );\n }\n\n if (!value?.results.length) {\n return <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n return <>{children({ results: value.results })}</>;\n};\n\nexport { SearchResultComponent as SearchResult };\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Button, makeStyles } from '@material-ui/core';\nimport ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos';\nimport ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos';\nimport React from 'react';\nimport { useSearch } from '../SearchContext';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n display: 'flex',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n margin: theme.spacing(2, 0),\n },\n}));\n\nexport const SearchResultPager = () => {\n const { fetchNextPage, fetchPreviousPage } = useSearch();\n const classes = useStyles();\n\n if (!fetchNextPage && !fetchPreviousPage) {\n return <></>;\n }\n\n return (\n <nav arial-label=\"pagination navigation\" className={classes.root}>\n <Button\n aria-label=\"previous page\"\n disabled={!fetchPreviousPage}\n onClick={fetchPreviousPage}\n startIcon={<ArrowBackIosIcon />}\n >\n Previous\n </Button>\n\n <Button\n aria-label=\"next page\"\n disabled={!fetchNextPage}\n onClick={fetchNextPage}\n endIcon={<ArrowForwardIosIcon />}\n >\n Next\n </Button>\n </nav>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { SearchClient, searchApiRef } from './apis';\nimport {\n createApiFactory,\n createPlugin,\n createRouteRef,\n createRoutableExtension,\n discoveryApiRef,\n createComponentExtension,\n identityApiRef,\n} from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'search',\n});\n\nexport const rootNextRouteRef = createRouteRef({\n id: 'search:next',\n});\n\nexport const searchPlugin = createPlugin({\n id: 'search',\n apis: [\n createApiFactory({\n api: searchApiRef,\n deps: { discoveryApi: discoveryApiRef, identityApi: identityApiRef },\n factory: ({ discoveryApi, identityApi }) => {\n return new SearchClient({ discoveryApi, identityApi });\n },\n }),\n ],\n routes: {\n root: rootRouteRef,\n nextRoot: rootNextRouteRef,\n },\n});\n\nexport const SearchPage = searchPlugin.provide(\n createRoutableExtension({\n name: 'SearchPage',\n component: () => import('./components/SearchPage').then(m => m.SearchPage),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchPage /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchPageNext = searchPlugin.provide(\n createRoutableExtension({\n name: 'SearchPageNext',\n component: () => import('./components/SearchPage').then(m => m.SearchPage),\n mountPoint: rootNextRouteRef,\n }),\n);\n\nexport const SearchBar = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchBar',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchBar /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchBarNext = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchBarNext',\n component: {\n lazy: () => import('./components/SearchBar').then(m => m.SearchBar),\n },\n }),\n);\n\nexport const SearchResult = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchResult',\n component: {\n lazy: () => import('./components/SearchResult').then(m => m.SearchResult),\n },\n }),\n);\n\n/**\n * @deprecated This component was used for rapid prototyping of the Backstage\n * Search platform. Now that the API has stabilized, you should use the\n * <SearchResult /> component instead. This component will be removed in an\n * upcoming release.\n */\nexport const SearchResultNext = searchPlugin.provide(\n createComponentExtension({\n name: 'SearchResultNext',\n component: {\n lazy: () => import('./components/SearchResult').then(m => m.SearchResult),\n },\n }),\n);\n\nexport const SidebarSearchModal = searchPlugin.provide(\n createComponentExtension({\n name: 'SidebarSearchModal',\n component: {\n lazy: () =>\n import('./components/SidebarSearchModal').then(\n m => m.SidebarSearchModal,\n ),\n },\n }),\n);\n\nexport const DefaultResultListItem = searchPlugin.provide(\n createComponentExtension({\n name: 'DefaultResultListItem',\n component: {\n lazy: () =>\n import('./components/DefaultResultListItem').then(\n m => m.DefaultResultListItem,\n ),\n },\n }),\n);\n\nexport const HomePageSearchBar = searchPlugin.provide(\n createComponentExtension({\n name: 'HomePageSearchBar',\n component: {\n lazy: () =>\n import('./components/HomePageComponent').then(m => m.HomePageSearchBar),\n },\n }),\n);\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport {\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n Divider,\n Grid,\n List,\n Paper,\n} from '@material-ui/core';\nimport { Launch } from '@material-ui/icons/';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { SearchBar } from '../SearchBar';\nimport { DefaultResultListItem } from '../DefaultResultListItem';\nimport { SearchResult } from '../SearchResult';\nimport { SearchContextProvider, useSearch } from '../SearchContext';\nimport { SearchResultPager } from '../SearchResultPager';\nimport { useRouteRef } from '@backstage/core-plugin-api';\nimport { Link } from '@backstage/core-components';\nimport { rootRouteRef } from '../../plugin';\n\nexport interface SearchModalProps {\n open?: boolean;\n toggleModal: () => void;\n}\n\nconst useStyles = makeStyles(theme => ({\n container: {\n borderRadius: 30,\n display: 'flex',\n height: '2.4em',\n },\n input: {\n flex: 1,\n },\n // Reduces default height of the modal, keeping a gap of 128px between the top and bottom of the page.\n paperFullWidth: { height: 'calc(100% - 128px)' },\n dialogActionsContainer: { padding: theme.spacing(1, 3) },\n viewResultsLink: { verticalAlign: '0.5em' },\n}));\n\nexport const Modal = ({ open = true, toggleModal }: SearchModalProps) => {\n const getSearchLink = useRouteRef(rootRouteRef);\n const classes = useStyles();\n\n const { term } = useSearch();\n\n const handleResultClick = () => {\n toggleModal();\n };\n\n const handleKeyPress = () => {\n handleResultClick();\n };\n\n return (\n <Dialog\n classes={{\n paperFullWidth: classes.paperFullWidth,\n }}\n onClose={toggleModal}\n aria-labelledby=\"search-modal-title\"\n open={open}\n fullWidth\n maxWidth=\"lg\"\n >\n <DialogTitle>\n <Paper className={classes.container}>\n <SearchBar className={classes.input} />\n </Paper>\n </DialogTitle>\n <DialogContent>\n <Grid\n container\n direction=\"row-reverse\"\n justifyContent=\"flex-start\"\n alignItems=\"center\"\n >\n <Grid item>\n <Link onClick={toggleModal} to={`${getSearchLink()}?query=${term}`}>\n <span className={classes.viewResultsLink}>View Full Results</span>\n <Launch color=\"primary\" />\n </Link>\n </Grid>\n </Grid>\n <Divider />\n <SearchResult>\n {({ results }) => (\n <List>\n {results.map(({ document }) => (\n <div\n role=\"button\"\n tabIndex={0}\n key={`${document.location}-btn`}\n onClick={handleResultClick}\n onKeyPress={handleKeyPress}\n >\n <DefaultResultListItem\n key={document.location}\n result={document}\n />\n </div>\n ))}\n </List>\n )}\n </SearchResult>\n </DialogContent>\n <DialogActions className={classes.dialogActionsContainer}>\n <Grid container direction=\"row\">\n <Grid item xs={12}>\n <SearchResultPager />\n </Grid>\n </Grid>\n </DialogActions>\n </Dialog>\n );\n};\n\nexport const SearchModal = ({ open = true, toggleModal }: SearchModalProps) => {\n return (\n <SearchContextProvider>\n <Modal open={open} toggleModal={toggleModal} />\n </SearchContextProvider>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Paper } from '@material-ui/core';\nimport InputBase from '@material-ui/core/InputBase';\nimport IconButton from '@material-ui/core/IconButton';\nimport SearchIcon from '@material-ui/icons/Search';\nimport ClearButton from '@material-ui/icons/Clear';\n\nconst useStyles = makeStyles(() => ({\n root: {\n display: 'flex',\n alignItems: 'center',\n },\n input: {\n flex: 1,\n },\n}));\n\ntype SearchBarProps = {\n searchQuery: string;\n handleSearch: any;\n handleClearSearchBar: any;\n};\n\nexport const SearchBar = ({\n searchQuery,\n handleSearch,\n handleClearSearchBar,\n}: SearchBarProps) => {\n const classes = useStyles();\n\n return (\n <Paper\n component=\"form\"\n onSubmit={e => handleSearch(e)}\n className={classes.root}\n >\n <IconButton disabled type=\"submit\" aria-label=\"search\">\n <SearchIcon />\n </IconButton>\n <InputBase\n className={classes.input}\n placeholder=\"Search in Backstage\"\n value={searchQuery}\n onChange={e => handleSearch(e)}\n inputProps={{ 'aria-label': 'search backstage' }}\n />\n <IconButton aria-label=\"search\" onClick={() => handleClearSearchBar()}>\n <ClearButton />\n </IconButton>\n </Paper>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport FilterListIcon from '@material-ui/icons/FilterList';\nimport { makeStyles, IconButton, Typography } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n width: '250px',\n display: 'flex',\n },\n icon: {\n margin: theme.spacing(-1, 0, 0, 0),\n },\n}));\n\ntype FiltersButtonProps = {\n numberOfSelectedFilters: number;\n handleToggleFilters: () => void;\n};\n\nexport const FiltersButton = ({\n numberOfSelectedFilters,\n handleToggleFilters,\n}: FiltersButtonProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.filters}>\n <IconButton\n className={classes.icon}\n aria-label=\"settings\"\n onClick={handleToggleFilters}\n >\n <FilterListIcon />\n </IconButton>\n <Typography variant=\"h6\">\n Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0})\n </Typography>\n </div>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React from 'react';\nimport {\n makeStyles,\n Typography,\n Divider,\n Card,\n CardHeader,\n Button,\n CardContent,\n Select,\n Checkbox,\n List,\n ListItem,\n ListItemText,\n MenuItem,\n} from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n filters: {\n background: 'transparent',\n boxShadow: '0px 0px 0px 0px',\n },\n checkbox: {\n padding: theme.spacing(0, 1, 0, 1),\n },\n dropdown: {\n width: '100%',\n },\n}));\n\nexport type FiltersState = {\n selected: string;\n checked: Array<string>;\n};\n\nexport type FilterOptions = {\n kind: Array<string>;\n lifecycle: Array<string>;\n};\n\ntype FiltersProps = {\n filters: FiltersState;\n filterOptions: FilterOptions;\n resetFilters: () => void;\n updateSelected: (filter: string) => void;\n updateChecked: (filter: string) => void;\n};\n\nexport const Filters = ({\n filters,\n filterOptions,\n resetFilters,\n updateSelected,\n updateChecked,\n}: FiltersProps) => {\n const classes = useStyles();\n\n return (\n <Card className={classes.filters}>\n <CardHeader\n title={<Typography variant=\"h6\">Filters</Typography>}\n action={\n <Button color=\"primary\" onClick={() => resetFilters()}>\n CLEAR ALL\n </Button>\n }\n />\n <Divider />\n {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">\n Filters cannot be applied to available results\n </Typography>\n </CardContent>\n )}\n {filterOptions.kind.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Kind</Typography>\n <Select\n id=\"outlined-select\"\n onChange={(e: React.ChangeEvent<any>) =>\n updateSelected(e?.target?.value)\n }\n variant=\"outlined\"\n className={classes.dropdown}\n value={filters.selected}\n >\n {filterOptions.kind.map(filter => (\n <MenuItem\n selected={filter === ''}\n dense\n key={filter}\n value={filter}\n >\n {filter}\n </MenuItem>\n ))}\n </Select>\n </CardContent>\n )}\n {filterOptions.lifecycle.length > 0 && (\n <CardContent>\n <Typography variant=\"subtitle2\">Lifecycle</Typography>\n <List disablePadding dense>\n {filterOptions.lifecycle.map(filter => (\n <ListItem\n key={filter}\n dense\n button\n onClick={() => updateChecked(filter)}\n >\n <Checkbox\n edge=\"start\"\n disableRipple\n className={classes.checkbox}\n color=\"primary\"\n checked={filters.checked.includes(filter)}\n tabIndex={-1}\n value={filter}\n name={filter}\n />\n <ListItemText id={filter} primary={filter} />\n </ListItem>\n ))}\n </List>\n </CardContent>\n )}\n </Card>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Divider, Grid, makeStyles, Typography } from '@material-ui/core';\nimport { Alert } from '@material-ui/lab';\nimport React, { useEffect, useState } from 'react';\nimport { useAsync } from 'react-use';\nimport { catalogApiRef } from '@backstage/plugin-catalog-react';\n\nimport { Filters, FiltersButton, FiltersState } from './Filters';\nimport { Entity, ENTITY_DEFAULT_NAMESPACE } from '@backstage/catalog-model';\n\nimport {\n EmptyState,\n Link,\n Progress,\n Table,\n TableColumn,\n} from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\n\ntype Result = {\n name: string;\n description: string | undefined;\n owner: string | undefined;\n kind: string;\n lifecycle: string | undefined;\n url: string;\n};\ntype SearchResults = Array<Result>;\n\nconst useStyles = makeStyles(theme => ({\n searchQuery: {\n color: theme.palette.text.primary,\n background: theme.palette.background.default,\n borderRadius: '10%',\n },\n tableHeader: {\n margin: theme.spacing(1, 0, 0, 0),\n display: 'flex',\n },\n divider: {\n width: '1px',\n margin: theme.spacing(0, 2),\n padding: theme.spacing(2, 0),\n },\n}));\n\ntype SearchResultProps = {\n searchQuery?: string;\n};\n\ntype TableHeaderProps = {\n searchQuery?: string;\n numberOfSelectedFilters: number;\n numberOfResults: number;\n handleToggleFilters: () => void;\n};\n\n// TODO: move out column to make the search result component more generic\nconst columns: TableColumn[] = [\n {\n title: 'Name',\n field: 'name',\n highlight: true,\n render: (result: Partial<Result>) => (\n <Link to={result.url || ''}>{result.name}</Link>\n ),\n },\n {\n title: 'Description',\n field: 'description',\n },\n {\n title: 'Owner',\n field: 'owner',\n },\n {\n title: 'Kind',\n field: 'kind',\n },\n {\n title: 'LifeCycle',\n field: 'lifecycle',\n },\n];\n\nconst TableHeader = ({\n searchQuery,\n numberOfSelectedFilters,\n numberOfResults,\n handleToggleFilters,\n}: TableHeaderProps) => {\n const classes = useStyles();\n\n return (\n <div className={classes.tableHeader}>\n <FiltersButton\n numberOfSelectedFilters={numberOfSelectedFilters}\n handleToggleFilters={handleToggleFilters}\n />\n <Divider className={classes.divider} orientation=\"vertical\" />\n <Grid item xs={12}>\n {searchQuery ? (\n <Typography variant=\"h6\">\n {`${numberOfResults} `}\n {numberOfResults > 1 ? `results for ` : `result for `}\n <span className={classes.searchQuery}>\"{searchQuery}\"</span>{' '}\n </Typography>\n ) : (\n <Typography variant=\"h6\">{`${numberOfResults} results`}</Typography>\n )}\n </Grid>\n </div>\n );\n};\n\nexport const SearchResult = ({ searchQuery }: SearchResultProps) => {\n const catalogApi = useApi(catalogApiRef);\n\n const [showFilters, toggleFilters] = useState(false);\n const [selectedFilters, setSelectedFilters] = useState<FiltersState>({\n selected: '',\n checked: [],\n });\n\n const [filteredResults, setFilteredResults] = useState<SearchResults>([]);\n\n const {\n loading,\n error,\n value: results,\n } = useAsync(async () => {\n const entities = await catalogApi.getEntities();\n return entities.items.map((entity: Entity) => ({\n name: entity.metadata.name,\n description: entity.metadata.description,\n owner:\n typeof entity.spec?.owner === 'string' ? entity.spec?.owner : undefined,\n kind: entity.kind,\n lifecycle:\n typeof entity.spec?.lifecycle === 'string'\n ? entity.spec?.lifecycle\n : undefined,\n url: `/catalog/${\n entity.metadata.namespace?.toLocaleLowerCase('en-US') ||\n ENTITY_DEFAULT_NAMESPACE\n }/${entity.kind.toLocaleLowerCase('en-US')}/${entity.metadata.name}`,\n }));\n }, []);\n\n useEffect(() => {\n if (results) {\n let withFilters = results;\n\n // apply filters\n\n // filter on selected\n if (selectedFilters.selected !== '') {\n withFilters = results.filter((result: Result) =>\n selectedFilters.selected.includes(result.kind),\n );\n }\n\n // filter on checked\n if (selectedFilters.checked.length > 0) {\n withFilters = withFilters.filter(\n (result: Result) =>\n result.lifecycle &&\n selectedFilters.checked.includes(result.lifecycle),\n );\n }\n\n // filter on searchQuery\n if (searchQuery) {\n withFilters = withFilters.filter(\n (result: Result) =>\n result.name?.toLocaleLowerCase('en-US').includes(searchQuery) ||\n result.name\n ?.toLocaleLowerCase('en-US')\n .includes(searchQuery.split(' ').join('-')) ||\n result.description\n ?.toLocaleLowerCase('en-US')\n .includes(searchQuery),\n );\n }\n\n setFilteredResults(withFilters);\n }\n }, [selectedFilters, searchQuery, results]);\n if (loading) {\n return <Progress />;\n }\n if (error) {\n return (\n <Alert severity=\"error\">\n Error encountered while fetching search results. {error.toString()}\n </Alert>\n );\n }\n if (!results || results.length === 0) {\n return <EmptyState missing=\"data\" title=\"Sorry, no results were found\" />;\n }\n\n const resetFilters = () => {\n setSelectedFilters({\n selected: '',\n checked: [],\n });\n };\n\n const updateSelected = (filter: string) => {\n setSelectedFilters(prevState => ({\n ...prevState,\n selected: filter,\n }));\n };\n\n const updateChecked = (filter: string) => {\n if (selectedFilters.checked.includes(filter)) {\n setSelectedFilters(prevState => ({\n ...prevState,\n checked: prevState.checked.filter(item => item !== filter),\n }));\n return;\n }\n\n setSelectedFilters(prevState => ({\n ...prevState,\n checked: [...prevState.checked, filter],\n }));\n };\n\n const filterOptions = results.reduce(\n (acc, curr) => {\n if (curr.kind && acc.kind.indexOf(curr.kind) < 0) {\n acc.kind.push(curr.kind);\n }\n if (curr.lifecycle && acc.lifecycle.indexOf(curr.lifecycle) < 0) {\n acc.lifecycle.push(curr.lifecycle);\n }\n return acc;\n },\n {\n kind: [] as Array<string>,\n lifecycle: [] as Array<string>,\n },\n );\n\n return (\n <>\n <Grid container>\n {showFilters && (\n <Grid item xs={3}>\n <Filters\n filters={selectedFilters}\n filterOptions={filterOptions}\n resetFilters={resetFilters}\n updateSelected={updateSelected}\n updateChecked={updateChecked}\n />\n </Grid>\n )}\n <Grid item xs={showFilters ? 9 : 12}>\n <Table\n options={{ paging: true, pageSize: 20, search: false }}\n data={filteredResults}\n columns={columns}\n title={\n <TableHeader\n searchQuery={searchQuery}\n numberOfResults={filteredResults.length}\n numberOfSelectedFilters={\n (selectedFilters.selected !== '' ? 1 : 0) +\n selectedFilters.checked.length\n }\n handleToggleFilters={() => toggleFilters(!showFilters)}\n />\n }\n />\n </Grid>\n </Grid>\n </>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Grid } from '@material-ui/core';\nimport React, { useEffect, useState } from 'react';\nimport { useDebounce } from 'react-use';\nimport { SearchBar } from './LegacySearchBar';\nimport { SearchResult } from './LegacySearchResult';\nimport {\n Content,\n Header,\n Page,\n useQueryParamState,\n} from '@backstage/core-components';\n\n/**\n * @deprecated This SearchPage, powered directly by the Catalog API, will be\n * removed from a future release of this plugin.\n */\nexport const LegacySearchPage = () => {\n const [queryString, setQueryString] = useQueryParamState<string>('query');\n const [searchQuery, setSearchQuery] = useState(queryString ?? '');\n\n const handleSearch = (event: React.ChangeEvent<HTMLInputElement>) => {\n event.preventDefault();\n setSearchQuery(event.target.value);\n };\n\n useEffect(() => setSearchQuery(queryString ?? ''), [queryString]);\n\n useDebounce(\n () => {\n setQueryString(searchQuery);\n },\n 200,\n [searchQuery],\n );\n\n const handleClearSearchBar = () => {\n setSearchQuery('');\n };\n\n return (\n <Page themeId=\"home\">\n <Header title=\"Search\" />\n <Content>\n <Grid container direction=\"row\">\n <Grid item xs={12}>\n <SearchBar\n handleSearch={handleSearch}\n handleClearSearchBar={handleClearSearchBar}\n searchQuery={searchQuery}\n />\n </Grid>\n <Grid item xs={12}>\n <SearchResult\n searchQuery={(queryString ?? '').toLocaleLowerCase('en-US')}\n />\n </Grid>\n </Grid>\n </Content>\n </Page>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useEffect } from 'react';\nimport { usePrevious } from 'react-use';\nimport qs from 'qs';\nimport { useLocation, useOutlet } from 'react-router';\nimport { SearchContextProvider, useSearch } from '../SearchContext';\nimport { JsonObject } from '@backstage/types';\nimport { LegacySearchPage } from '../LegacySearchPage';\n\nexport const UrlUpdater = () => {\n const location = useLocation();\n const {\n term,\n setTerm,\n types,\n setTypes,\n pageCursor,\n setPageCursor,\n filters,\n setFilters,\n } = useSearch();\n\n const prevQueryParams = usePrevious(location.search);\n useEffect(() => {\n // Only respond to changes to url query params\n if (location.search === prevQueryParams) {\n return;\n }\n\n const query =\n qs.parse(location.search.substring(1), { arrayLimit: 0 }) || {};\n\n if (query.filters) {\n setFilters(query.filters as JsonObject);\n }\n\n if (query.query) {\n setTerm(query.query as string);\n }\n\n if (query.pageCursor) {\n setPageCursor(query.pageCursor as string);\n }\n\n if (query.types) {\n setTypes(query.types as string[]);\n }\n }, [prevQueryParams, location, setTerm, setTypes, setPageCursor, setFilters]);\n\n useEffect(() => {\n const newParams = qs.stringify(\n {\n query: term,\n types,\n pageCursor,\n filters,\n },\n { arrayFormat: 'brackets' },\n );\n const newUrl = `${window.location.pathname}?${newParams}`;\n\n // We directly manipulate window history here in order to not re-render\n // infinitely (state => location => state => etc). The intention of this\n // code is just to ensure the right query/filters are loaded when a user\n // clicks the \"back\" button after clicking a result.\n window.history.replaceState(null, document.title, newUrl);\n }, [term, types, pageCursor, filters]);\n\n return null;\n};\n\nexport const SearchPage = () => {\n const outlet = useOutlet();\n\n return (\n <SearchContextProvider>\n <UrlUpdater />\n {outlet || <LegacySearchPage />}\n </SearchContextProvider>\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport {\n Checkbox,\n Chip,\n FormControl,\n InputLabel,\n ListItemText,\n makeStyles,\n MenuItem,\n Select,\n} from '@material-ui/core';\nimport React, { ChangeEvent } from 'react';\nimport { useEffectOnce } from 'react-use';\nimport { useSearch } from '../SearchContext';\n\nconst useStyles = makeStyles(theme => ({\n label: {\n textTransform: 'capitalize',\n },\n chips: {\n display: 'flex',\n flexWrap: 'wrap',\n marginTop: theme.spacing(1),\n },\n chip: {\n margin: 2,\n },\n}));\n\nexport type SearchTypeProps = {\n className?: string;\n name: string;\n values?: string[];\n defaultValue?: string[] | string | null;\n};\n\nconst SearchType = ({\n values = [],\n className,\n name,\n defaultValue,\n}: SearchTypeProps) => {\n const classes = useStyles();\n const { types, setTypes } = useSearch();\n\n useEffectOnce(() => {\n if (!types.length) {\n if (defaultValue && Array.isArray(defaultValue)) {\n setTypes(defaultValue);\n } else if (defaultValue) {\n setTypes([defaultValue]);\n }\n }\n });\n\n const handleChange = (e: ChangeEvent<{ value: unknown }>) => {\n const value = e.target.value as string[];\n setTypes(value as string[]);\n };\n\n return (\n <FormControl\n className={className}\n variant=\"filled\"\n fullWidth\n data-testid=\"search-typefilter-next\"\n >\n <InputLabel className={classes.label} margin=\"dense\">\n {name}\n </InputLabel>\n <Select\n multiple\n variant=\"outlined\"\n value={types}\n onChange={handleChange}\n placeholder=\"All Results\"\n renderValue={selected => (\n <div className={classes.chips}>\n {(selected as string[]).map(value => (\n <Chip\n key={value}\n label={value}\n className={classes.chip}\n size=\"small\"\n />\n ))}\n </div>\n )}\n >\n {values.map((value: string) => (\n <MenuItem key={value} value={value}>\n <Checkbox checked={types.indexOf(value) > -1} />\n <ListItemText primary={value} />\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n );\n};\n\nexport { SearchType };\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport qs from 'qs';\nimport React, { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { rootRouteRef } from '../../plugin';\n\nimport { SidebarSearchField } from '@backstage/core-components';\nimport { useRouteRef, IconComponent } from '@backstage/core-plugin-api';\n\nexport type SidebarSearchProps = {\n icon?: IconComponent;\n};\n\nexport const SidebarSearch = (props: SidebarSearchProps) => {\n const searchRoute = useRouteRef(rootRouteRef);\n const navigate = useNavigate();\n const handleSearch = useCallback(\n (query: string): void => {\n const queryString = qs.stringify({ query }, { addQueryPrefix: true });\n\n navigate(`${searchRoute()}${queryString}`);\n },\n [navigate, searchRoute],\n );\n\n return (\n <SidebarSearchField\n icon={props.icon}\n onSearch={handleSearch}\n to=\"/search\"\n />\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport qs from 'qs';\nimport { useCallback } from 'react';\nimport { useNavigate } from 'react-router-dom';\nimport { rootRouteRef } from '../plugin';\n\nimport { useRouteRef } from '@backstage/core-plugin-api';\n\nexport const useNavigateToQuery = () => {\n const searchRoute = useRouteRef(rootRouteRef);\n const navigate = useNavigate();\n return useCallback(\n ({ query }: { query: string }): void => {\n const queryString = qs.stringify({ query }, { addQueryPrefix: true });\n\n navigate(`${searchRoute()}${queryString}`);\n },\n [navigate, searchRoute],\n );\n};\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport React, { useCallback, useState } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport { SearchBarBase, SearchBarBaseProps } from '../SearchBar';\nimport { useNavigateToQuery } from '../util';\n\nconst useStyles = makeStyles({\n searchBar: {\n border: '1px solid #555',\n borderRadius: '6px',\n fontSize: '1.5em',\n },\n});\n\n/**\n * Props for {@link HomePageSearchBar}.\n *\n * @public\n */\nexport type HomePageSearchBarProps = Partial<\n Omit<SearchBarBaseProps, 'onChange' | 'onSubmit'>\n>;\n\n/**\n * The search bar created specifically for the composable home page\n *\n * @public\n */\nexport const HomePageSearchBar = ({\n className: defaultClassName,\n ...props\n}: HomePageSearchBarProps) => {\n const classes = useStyles();\n const [query, setQuery] = useState('');\n const handleSearch = useNavigateToQuery();\n\n const className = defaultClassName\n ? `${classes.searchBar} ${defaultClassName}`\n : classes.searchBar;\n\n const handleSubmit = () => {\n handleSearch({ query });\n };\n\n const handleChange = useCallback(\n value => {\n setQuery(value);\n },\n [setQuery],\n );\n\n return (\n <SearchBarBase\n className={className}\n value={query}\n onSubmit={handleSubmit}\n onChange={handleChange}\n {...props}\n />\n );\n};\n"],"names":["DefaultResultListItem","useStyles","FiltersButton","Filters","SearchBar","SearchPage","SearchResult","HomePageSearchBar","makeStyles","IconButton","InputBase"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-a71e930d.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}
@@ -1,23 +0,0 @@
1
- export { a as SearchBar, b as SearchBarBase } from './index-655809db.esm.js';
2
- import '@backstage/core-plugin-api';
3
- import '@backstage/errors';
4
- import 'qs';
5
- import 'react';
6
- import '@material-ui/core';
7
- import '@backstage/core-components';
8
- import '@material-ui/icons/FilterList';
9
- import 'react-use';
10
- import '@material-ui/icons/Search';
11
- import '@material-ui/icons/Clear';
12
- import '@material-ui/core/styles';
13
- import '@material-ui/icons/ArrowBackIos';
14
- import '@material-ui/icons/ArrowForwardIos';
15
- import '@material-ui/core/utils';
16
- import 'react-router';
17
- import '@material-ui/core/InputBase';
18
- import '@material-ui/core/IconButton';
19
- import '@material-ui/lab';
20
- import '@backstage/plugin-catalog-react';
21
- import '@backstage/catalog-model';
22
- import 'react-router-dom';
23
- //# sourceMappingURL=index-d5ddea91.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-d5ddea91.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;"}