From f22df2248da04523fa6af32ef254e848d7cfce33 Mon Sep 17 00:00:00 2001 From: Emma Indal Date: Thu, 30 Jun 2022 14:45:17 +0200 Subject: [PATCH] delete deprecations Signed-off-by: Emma Indal --- .../search-backend-module-pg/api-report.md | 2 +- .../src/PgSearchEngine/PgSearchEngine.ts | 2 +- plugins/search-backend-node/api-report.md | 2 - .../src/IndexBuilder.test.ts | 3 +- plugins/search-backend-node/src/index.ts | 5 - plugins/search-backend/api-report.md | 2 +- .../search-backend/src/service/router.test.ts | 6 +- plugins/search-backend/src/service/router.ts | 2 +- plugins/search/api-report.md | 131 +----- .../search/src/components/Filters/Filters.tsx | 168 ------- .../src/components/Filters/FiltersButton.tsx | 67 --- .../search/src/components/Filters/index.tsx | 20 - .../LegacySearchPage/Filters/Filters.tsx | 146 ------- .../Filters/FiltersButton.tsx | 56 --- .../LegacySearchPage/Filters/index.ts | 19 - .../LegacySearchPage/LegacySearchBar.tsx | 69 --- .../LegacySearchPage/LegacySearchPage.tsx | 77 ---- .../LegacySearchPage/LegacySearchResult.tsx | 297 ------------- .../src/components/LegacySearchPage/index.ts | 17 - .../src/components/SearchBar/SearchBar.tsx | 79 ---- .../search/src/components/SearchBar/index.tsx | 18 - .../SearchFilter.Autocomplete.test.tsx | 363 ---------------- .../SearchFilter.Autocomplete.tsx | 27 -- .../SearchFilter/SearchFilter.test.tsx | 409 ------------------ .../components/SearchFilter/SearchFilter.tsx | 95 ---- .../src/components/SearchFilter/index.ts | 22 - .../SearchModal/SearchModal.stories.tsx | 2 +- .../src/components/SearchPage/SearchPage.tsx | 3 +- .../SearchResultPager.test.tsx | 56 --- .../SearchResultPager/SearchResultPager.tsx | 65 --- .../src/components/SearchResultPager/index.ts | 17 - plugins/search/src/index.ts | 22 +- plugins/search/src/plugin.ts | 18 +- 33 files changed, 15 insertions(+), 2272 deletions(-) delete mode 100644 plugins/search/src/components/Filters/Filters.tsx delete mode 100644 plugins/search/src/components/Filters/FiltersButton.tsx delete mode 100644 plugins/search/src/components/Filters/index.tsx delete mode 100644 plugins/search/src/components/LegacySearchPage/Filters/Filters.tsx delete mode 100644 plugins/search/src/components/LegacySearchPage/Filters/FiltersButton.tsx delete mode 100644 plugins/search/src/components/LegacySearchPage/Filters/index.ts delete mode 100644 plugins/search/src/components/LegacySearchPage/LegacySearchBar.tsx delete mode 100644 plugins/search/src/components/LegacySearchPage/LegacySearchPage.tsx delete mode 100644 plugins/search/src/components/LegacySearchPage/LegacySearchResult.tsx delete mode 100644 plugins/search/src/components/LegacySearchPage/index.ts delete mode 100644 plugins/search/src/components/SearchBar/SearchBar.tsx delete mode 100644 plugins/search/src/components/SearchBar/index.tsx delete mode 100644 plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx delete mode 100644 plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx delete mode 100644 plugins/search/src/components/SearchFilter/SearchFilter.test.tsx delete mode 100644 plugins/search/src/components/SearchFilter/SearchFilter.tsx delete mode 100644 plugins/search/src/components/SearchFilter/index.ts delete mode 100644 plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx delete mode 100644 plugins/search/src/components/SearchResultPager/SearchResultPager.tsx delete mode 100644 plugins/search/src/components/SearchResultPager/index.ts diff --git a/plugins/search-backend-module-pg/api-report.md b/plugins/search-backend-module-pg/api-report.md index f7a188a14e..d1913a535d 100644 --- a/plugins/search-backend-module-pg/api-report.md +++ b/plugins/search-backend-module-pg/api-report.md @@ -9,7 +9,7 @@ import { IndexableDocument } from '@backstage/plugin-search-common'; import { IndexableResultSet } from '@backstage/plugin-search-common'; import { Knex } from 'knex'; import { PluginDatabaseManager } from '@backstage/backend-common'; -import { SearchEngine } from '@backstage/plugin-search-backend-node'; +import { SearchEngine } from '@backstage/plugin-search-common'; import { SearchQuery } from '@backstage/plugin-search-common'; // @public diff --git a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts index abf7cdbf5c..9da5ceec0e 100644 --- a/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts +++ b/plugins/search-backend-module-pg/src/PgSearchEngine/PgSearchEngine.ts @@ -14,7 +14,7 @@ * limitations under the License. */ import { PluginDatabaseManager } from '@backstage/backend-common'; -import { SearchEngine } from '@backstage/plugin-search-backend-node'; +import { SearchEngine } from '@backstage/plugin-search-common'; import { SearchQuery, IndexableResultSet, diff --git a/plugins/search-backend-node/api-report.md b/plugins/search-backend-node/api-report.md index ff9480c19d..64957f6366 100644 --- a/plugins/search-backend-node/api-report.md +++ b/plugins/search-backend-node/api-report.md @@ -170,8 +170,6 @@ export type ScheduleTaskParameters = { scheduledRunner: TaskRunner; }; -export { SearchEngine }; - // @public export class TestPipeline { execute(): Promise; diff --git a/plugins/search-backend-node/src/IndexBuilder.test.ts b/plugins/search-backend-node/src/IndexBuilder.test.ts index 70d00f6974..4a2760dde1 100644 --- a/plugins/search-backend-node/src/IndexBuilder.test.ts +++ b/plugins/search-backend-node/src/IndexBuilder.test.ts @@ -19,10 +19,11 @@ import { TaskInvocationDefinition, TaskRunner } from '@backstage/backend-tasks'; import { DocumentCollatorFactory, DocumentDecoratorFactory, + SearchEngine, } from '@backstage/plugin-search-common'; import { Readable, Transform } from 'stream'; import { IndexBuilder } from './IndexBuilder'; -import { LunrSearchEngine, SearchEngine } from './index'; +import { LunrSearchEngine } from './index'; class TestDocumentCollatorFactory implements DocumentCollatorFactory { readonly type: string = 'anything'; diff --git a/plugins/search-backend-node/src/index.ts b/plugins/search-backend-node/src/index.ts index 854881829c..a188509c1c 100644 --- a/plugins/search-backend-node/src/index.ts +++ b/plugins/search-backend-node/src/index.ts @@ -39,8 +39,3 @@ export * from './indexing'; export * from './test-utils'; export type { ScheduleTaskParameters } from './Scheduler'; - -/** - * @deprecated Import from @backstage/plugin-search-common instead - */ -export type { SearchEngine } from '@backstage/plugin-search-common'; diff --git a/plugins/search-backend/api-report.md b/plugins/search-backend/api-report.md index eed61069da..d6274d9a94 100644 --- a/plugins/search-backend/api-report.md +++ b/plugins/search-backend/api-report.md @@ -9,7 +9,7 @@ import express from 'express'; import { Logger } from 'winston'; import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; -import { SearchEngine } from '@backstage/plugin-search-backend-node'; +import { SearchEngine } from '@backstage/plugin-search-common'; // @public (undocumented) export function createRouter(options: RouterOptions): Promise; diff --git a/plugins/search-backend/src/service/router.test.ts b/plugins/search-backend/src/service/router.test.ts index 26d901e519..1437e65b84 100644 --- a/plugins/search-backend/src/service/router.test.ts +++ b/plugins/search-backend/src/service/router.test.ts @@ -17,10 +17,8 @@ import { getVoidLogger } from '@backstage/backend-common'; import { ConfigReader } from '@backstage/config'; import { PermissionEvaluator } from '@backstage/plugin-permission-common'; -import { - IndexBuilder, - SearchEngine, -} from '@backstage/plugin-search-backend-node'; +import { IndexBuilder } from '@backstage/plugin-search-backend-node'; +import { SearchEngine } from '@backstage/plugin-search-common'; import express from 'express'; import request from 'supertest'; diff --git a/plugins/search-backend/src/service/router.ts b/plugins/search-backend/src/service/router.ts index e4ac233406..cf9abff675 100644 --- a/plugins/search-backend/src/service/router.ts +++ b/plugins/search-backend/src/service/router.ts @@ -33,7 +33,7 @@ import { IndexableResultSet, SearchResultSet, } from '@backstage/plugin-search-common'; -import { SearchEngine } from '@backstage/plugin-search-backend-node'; +import { SearchEngine } from '@backstage/plugin-search-common'; import { AuthorizedSearchEngine } from './AuthorizedSearchEngine'; const jsonObjectSchema: z.ZodSchema = z.lazy(() => { diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index 800fa7e7fc..e9d8591f92 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -6,143 +6,24 @@ /// import { BackstagePlugin } from '@backstage/core-plugin-api'; -import { DefaultResultListItemProps } from '@backstage/plugin-search-react'; import { IconComponent } from '@backstage/core-plugin-api'; -import { InputBaseProps } from '@material-ui/core'; -import { ReactElement } from 'react'; import { ReactNode } from 'react'; import { RouteRef } from '@backstage/core-plugin-api'; -import { SearchAutocompleteFilterProps as SearchAutocompleteFilterProps_2 } from '@backstage/plugin-search-react'; -import { SearchBarBaseProps as SearchBarBaseProps_2 } from '@backstage/plugin-search-react'; -import { SearchFilterComponentProps as SearchFilterComponentProps_2 } from '@backstage/plugin-search-react'; -import { SearchResultProps } from '@backstage/plugin-search-react'; - -// @public @deprecated (undocumented) -export const DefaultResultListItem: ( - props: DefaultResultListItemProps, -) => JSX.Element; - -// @public @deprecated (undocumented) -export type FilterOptions = { - kind: Array; - lifecycle: Array; -}; - -// @public @deprecated (undocumented) -export const Filters: ({ - filters, - filterOptions, - resetFilters, - updateSelected, - updateChecked, -}: FiltersProps) => JSX.Element; - -// @public @deprecated (undocumented) -export const FiltersButton: ({ - numberOfSelectedFilters, - handleToggleFilters, -}: FiltersButtonProps) => JSX.Element; - -// @public @deprecated -export type FiltersButtonProps = { - numberOfSelectedFilters: number; - handleToggleFilters: () => void; -}; - -// @public @deprecated -export type FiltersProps = { - filters: FiltersState; - filterOptions: FilterOptions; - resetFilters: () => void; - updateSelected: (filter: string) => void; - updateChecked: (filter: string) => void; -}; - -// @public @deprecated (undocumented) -export type FiltersState = { - selected: string; - checked: Array; -}; +import { SearchBarBaseProps } from '@backstage/plugin-search-react'; // @public (undocumented) export const HomePageSearchBar: ({ ...props -}: Partial>) => JSX.Element; +}: Partial>) => JSX.Element; // @public export type HomePageSearchBarProps = Partial< - Omit + Omit >; // @public (undocumented) export const Router: () => JSX.Element; -// @public @deprecated (undocumented) -export type SearchAutocompleteFilterProps = SearchFilterComponentProps_2 & { - filterSelectedOptions?: boolean; - limitTags?: number; - multiple?: boolean; -}; - -// @public @deprecated -export const SearchBar: ({ onChange, ...props }: SearchBarProps) => JSX.Element; - -// @public @deprecated -export const SearchBarBase: ({ - onChange, - onKeyDown, - onSubmit, - debounceTime, - clearButton, - fullWidth, - value: defaultValue, - inputProps: defaultInputProps, - endAdornment: defaultEndAdornment, - ...props -}: SearchBarBaseProps_2) => JSX.Element; - -// @public @deprecated -export type SearchBarBaseProps = Omit & { - debounceTime?: number; - clearButton?: boolean; - onClear?: () => void; - onSubmit?: () => void; - onChange: (value: string) => void; -}; - -// @public @deprecated -export type SearchBarProps = Partial; - -// @public @deprecated (undocumented) -export const SearchFilter: { - ({ component: Element, ...props }: SearchFilterWrapperProps): JSX.Element; - Checkbox( - props: Omit & - SearchFilterComponentProps, - ): JSX.Element; - Select( - props: Omit & - SearchFilterComponentProps, - ): JSX.Element; - Autocomplete(props: SearchAutocompleteFilterProps_2): JSX.Element; -}; - -// @public @deprecated (undocumented) -export type SearchFilterComponentProps = { - className?: string; - name: string; - label?: string; - values?: string[] | ((partial: string) => Promise); - defaultValue?: string[] | string | null; - valuesDebounceMs?: number; -}; - -// @public @deprecated (undocumented) -export type SearchFilterWrapperProps = SearchFilterComponentProps & { - component: (props: SearchFilterComponentProps) => ReactElement; - debug?: boolean; -}; - // @public (undocumented) export const SearchModal: ({ open, @@ -199,12 +80,6 @@ const searchPlugin: BackstagePlugin< export { searchPlugin as plugin }; export { searchPlugin }; -// @public @deprecated (undocumented) -export const SearchResult: (props: SearchResultProps) => JSX.Element; - -// @public @deprecated (undocumented) -export const SearchResultPager: () => JSX.Element; - // @public (undocumented) export const SearchType: { (props: SearchTypeProps): JSX.Element; diff --git a/plugins/search/src/components/Filters/Filters.tsx b/plugins/search/src/components/Filters/Filters.tsx deleted file mode 100644 index 9170961e18..0000000000 --- a/plugins/search/src/components/Filters/Filters.tsx +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { - makeStyles, - Typography, - Divider, - Card, - CardHeader, - Button, - CardContent, - Select, - Checkbox, - List, - ListItem, - ListItemText, - MenuItem, -} from '@material-ui/core'; - -const useStyles = makeStyles(theme => ({ - filters: { - background: 'transparent', - boxShadow: '0px 0px 0px 0px', - }, - checkbox: { - padding: theme.spacing(0, 1, 0, 1), - }, - dropdown: { - width: '100%', - }, -})); - -/** - * @public - * @deprecated This type and corresponding component will be removed in a - * future release. - */ -export type FiltersState = { - selected: string; - checked: Array; -}; - -/** - * @public - * @deprecated This type and corresponding component will be removed in a - * future release. - */ -export type FilterOptions = { - kind: Array; - lifecycle: Array; -}; - -/** - * Props for {@link Filters}. - * - * @public - * @deprecated This type and corresponding component will be removed in a - * future release. - */ -export type FiltersProps = { - filters: FiltersState; - filterOptions: FilterOptions; - resetFilters: () => void; - updateSelected: (filter: string) => void; - updateChecked: (filter: string) => void; -}; - -/** - * @public - * @deprecated This component will be removed in a future release. Use - * `SearchFilter` from `@backstage/plugin-search-react` instead. - */ -export const Filters = ({ - filters, - filterOptions, - resetFilters, - updateSelected, - updateChecked, -}: FiltersProps) => { - const classes = useStyles(); - - return ( - - Filters} - action={ - - } - /> - - {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && ( - - - Filters cannot be applied to available results - - - )} - {filterOptions.kind.length > 0 && ( - - Kind - - - )} - {filterOptions.lifecycle.length > 0 && ( - - Lifecycle - - {filterOptions.lifecycle.map(filter => ( - updateChecked(filter)} - > - - - - ))} - - - )} - - ); -}; diff --git a/plugins/search/src/components/Filters/FiltersButton.tsx b/plugins/search/src/components/Filters/FiltersButton.tsx deleted file mode 100644 index 890c787689..0000000000 --- a/plugins/search/src/components/Filters/FiltersButton.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import FilterListIcon from '@material-ui/icons/FilterList'; -import { makeStyles, IconButton, Typography } from '@material-ui/core'; - -const useStyles = makeStyles(theme => ({ - filters: { - width: '250px', - display: 'flex', - }, - icon: { - margin: theme.spacing(-1, 0, 0, 0), - }, -})); - -/** - * Props for {@link FiltersButton}. - * - * @public - * @deprecated This type and corresponding component will be removed in a - * future release. - */ -export type FiltersButtonProps = { - numberOfSelectedFilters: number; - handleToggleFilters: () => void; -}; - -/** - * @public - * @deprecated See `SearchFilter` in `@backstage/plugin-search-react` instead. - */ -export const FiltersButton = ({ - numberOfSelectedFilters, - handleToggleFilters, -}: FiltersButtonProps) => { - const classes = useStyles(); - - return ( -
- - - - - Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0}) - -
- ); -}; diff --git a/plugins/search/src/components/Filters/index.tsx b/plugins/search/src/components/Filters/index.tsx deleted file mode 100644 index dc4d811dbd..0000000000 --- a/plugins/search/src/components/Filters/index.tsx +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { FiltersButton } from './FiltersButton'; -export type { FiltersButtonProps } from './FiltersButton'; -export { Filters } from './Filters'; -export type { FilterOptions, FiltersProps, FiltersState } from './Filters'; diff --git a/plugins/search/src/components/LegacySearchPage/Filters/Filters.tsx b/plugins/search/src/components/LegacySearchPage/Filters/Filters.tsx deleted file mode 100644 index a0ca4914a2..0000000000 --- a/plugins/search/src/components/LegacySearchPage/Filters/Filters.tsx +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { - makeStyles, - Typography, - Divider, - Card, - CardHeader, - Button, - CardContent, - Select, - Checkbox, - List, - ListItem, - ListItemText, - MenuItem, -} from '@material-ui/core'; - -const useStyles = makeStyles(theme => ({ - filters: { - background: 'transparent', - boxShadow: '0px 0px 0px 0px', - }, - checkbox: { - padding: theme.spacing(0, 1, 0, 1), - }, - dropdown: { - width: '100%', - }, -})); - -export type FiltersState = { - selected: string; - checked: Array; -}; - -export type FilterOptions = { - kind: Array; - lifecycle: Array; -}; - -type FiltersProps = { - filters: FiltersState; - filterOptions: FilterOptions; - resetFilters: () => void; - updateSelected: (filter: string) => void; - updateChecked: (filter: string) => void; -}; - -export const Filters = ({ - filters, - filterOptions, - resetFilters, - updateSelected, - updateChecked, -}: FiltersProps) => { - const classes = useStyles(); - - return ( - - Filters} - action={ - - } - /> - - {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && ( - - - Filters cannot be applied to available results - - - )} - {filterOptions.kind.length > 0 && ( - - Kind - - - )} - {filterOptions.lifecycle.length > 0 && ( - - Lifecycle - - {filterOptions.lifecycle.map(filter => ( - updateChecked(filter)} - > - - - - ))} - - - )} - - ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/Filters/FiltersButton.tsx b/plugins/search/src/components/LegacySearchPage/Filters/FiltersButton.tsx deleted file mode 100644 index 1c2829defe..0000000000 --- a/plugins/search/src/components/LegacySearchPage/Filters/FiltersButton.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import FilterListIcon from '@material-ui/icons/FilterList'; -import { makeStyles, IconButton, Typography } from '@material-ui/core'; - -const useStyles = makeStyles(theme => ({ - filters: { - width: '250px', - display: 'flex', - }, - icon: { - margin: theme.spacing(-1, 0, 0, 0), - }, -})); - -type FiltersButtonProps = { - numberOfSelectedFilters: number; - handleToggleFilters: () => void; -}; - -export const FiltersButton = ({ - numberOfSelectedFilters, - handleToggleFilters, -}: FiltersButtonProps) => { - const classes = useStyles(); - - return ( -
- - - - - Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0}) - -
- ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/Filters/index.ts b/plugins/search/src/components/LegacySearchPage/Filters/index.ts deleted file mode 100644 index de890e0eaf..0000000000 --- a/plugins/search/src/components/LegacySearchPage/Filters/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { FiltersButton } from './FiltersButton'; -export { Filters } from './Filters'; -export type { FiltersState } from './Filters'; diff --git a/plugins/search/src/components/LegacySearchPage/LegacySearchBar.tsx b/plugins/search/src/components/LegacySearchPage/LegacySearchBar.tsx deleted file mode 100644 index 44fb006af3..0000000000 --- a/plugins/search/src/components/LegacySearchPage/LegacySearchBar.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; -import { Paper } from '@material-ui/core'; -import InputBase from '@material-ui/core/InputBase'; -import IconButton from '@material-ui/core/IconButton'; -import SearchIcon from '@material-ui/icons/Search'; -import ClearButton from '@material-ui/icons/Clear'; - -const useStyles = makeStyles(() => ({ - root: { - display: 'flex', - alignItems: 'center', - }, - input: { - flex: 1, - }, -})); - -type SearchBarProps = { - searchQuery: string; - handleSearch: any; - handleClearSearchBar: any; -}; - -export const SearchBar = ({ - searchQuery, - handleSearch, - handleClearSearchBar, -}: SearchBarProps) => { - const classes = useStyles(); - - return ( - handleSearch(e)} - className={classes.root} - > - - - - handleSearch(e)} - inputProps={{ 'aria-label': 'search backstage' }} - /> - handleClearSearchBar()}> - - - - ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/LegacySearchPage.tsx b/plugins/search/src/components/LegacySearchPage/LegacySearchPage.tsx deleted file mode 100644 index 09a33b9b74..0000000000 --- a/plugins/search/src/components/LegacySearchPage/LegacySearchPage.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Grid } from '@material-ui/core'; -import React, { useEffect, useState } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; -import { SearchBar } from './LegacySearchBar'; -import { SearchResult } from './LegacySearchResult'; -import { - Content, - Header, - Page, - useQueryParamState, -} from '@backstage/core-components'; - -/** - * @deprecated This SearchPage, powered directly by the Catalog API, will be - * removed from a future release of this plugin. - */ -export const LegacySearchPage = () => { - const [queryString, setQueryString] = useQueryParamState('query'); - const [searchQuery, setSearchQuery] = useState(queryString ?? ''); - - const handleSearch = (event: React.ChangeEvent) => { - event.preventDefault(); - setSearchQuery(event.target.value); - }; - - useEffect(() => setSearchQuery(queryString ?? ''), [queryString]); - - useDebounce( - () => { - setQueryString(searchQuery); - }, - 200, - [searchQuery], - ); - - const handleClearSearchBar = () => { - setSearchQuery(''); - }; - - return ( - -
- - - - - - - - - - - - ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/LegacySearchResult.tsx b/plugins/search/src/components/LegacySearchPage/LegacySearchResult.tsx deleted file mode 100644 index ba92dba710..0000000000 --- a/plugins/search/src/components/LegacySearchPage/LegacySearchResult.tsx +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Divider, Grid, makeStyles, Typography } from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; -import React, { useEffect, useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { catalogApiRef } from '@backstage/plugin-catalog-react'; - -import { Filters, FiltersButton, FiltersState } from './Filters'; -import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; - -import { - EmptyState, - Link, - Progress, - Table, - TableColumn, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; - -type Result = { - name: string; - description: string | undefined; - owner: string | undefined; - kind: string; - lifecycle: string | undefined; - url: string; -}; -type SearchResults = Array; - -const useStyles = makeStyles(theme => ({ - searchQuery: { - color: theme.palette.text.primary, - background: theme.palette.background.default, - borderRadius: '10%', - }, - tableHeader: { - margin: theme.spacing(1, 0, 0, 0), - display: 'flex', - }, - divider: { - width: '1px', - margin: theme.spacing(0, 2), - padding: theme.spacing(2, 0), - }, -})); - -type SearchResultProps = { - searchQuery?: string; -}; - -type TableHeaderProps = { - searchQuery?: string; - numberOfSelectedFilters: number; - numberOfResults: number; - handleToggleFilters: () => void; -}; - -// TODO: move out column to make the search result component more generic -const columns: TableColumn[] = [ - { - title: 'Name', - field: 'name', - highlight: true, - render: (result: Partial) => ( - {result.name} - ), - }, - { - title: 'Description', - field: 'description', - }, - { - title: 'Owner', - field: 'owner', - }, - { - title: 'Kind', - field: 'kind', - }, - { - title: 'LifeCycle', - field: 'lifecycle', - }, -]; - -const TableHeader = ({ - searchQuery, - numberOfSelectedFilters, - numberOfResults, - handleToggleFilters, -}: TableHeaderProps) => { - const classes = useStyles(); - - return ( -
- - - - {searchQuery ? ( - - {`${numberOfResults} `} - {numberOfResults > 1 ? `results for ` : `result for `} - "{searchQuery}"{' '} - - ) : ( - {`${numberOfResults} results`} - )} - -
- ); -}; - -export const SearchResult = ({ searchQuery }: SearchResultProps) => { - const catalogApi = useApi(catalogApiRef); - - const [showFilters, toggleFilters] = useState(false); - const [selectedFilters, setSelectedFilters] = useState({ - selected: '', - checked: [], - }); - - const [filteredResults, setFilteredResults] = useState([]); - - const { - loading, - error, - value: results, - } = useAsync(async () => { - const entities = await catalogApi.getEntities(); - return entities.items.map((entity: Entity) => ({ - name: entity.metadata.name, - description: entity.metadata.description, - owner: - typeof entity.spec?.owner === 'string' ? entity.spec?.owner : undefined, - kind: entity.kind, - lifecycle: - typeof entity.spec?.lifecycle === 'string' - ? entity.spec?.lifecycle - : undefined, - url: `/catalog/${ - entity.metadata.namespace?.toLocaleLowerCase('en-US') || - DEFAULT_NAMESPACE - }/${entity.kind.toLocaleLowerCase('en-US')}/${entity.metadata.name}`, - })); - }, []); - - useEffect(() => { - if (results) { - let withFilters = results; - - // apply filters - - // filter on selected - if (selectedFilters.selected !== '') { - withFilters = results.filter((result: Result) => - selectedFilters.selected.includes(result.kind), - ); - } - - // filter on checked - if (selectedFilters.checked.length > 0) { - withFilters = withFilters.filter( - (result: Result) => - result.lifecycle && - selectedFilters.checked.includes(result.lifecycle), - ); - } - - // filter on searchQuery - if (searchQuery) { - withFilters = withFilters.filter( - (result: Result) => - result.name?.toLocaleLowerCase('en-US').includes(searchQuery) || - result.name - ?.toLocaleLowerCase('en-US') - .includes(searchQuery.split(' ').join('-')) || - result.description - ?.toLocaleLowerCase('en-US') - .includes(searchQuery), - ); - } - - setFilteredResults(withFilters); - } - }, [selectedFilters, searchQuery, results]); - if (loading) { - return ; - } - if (error) { - return ( - - Error encountered while fetching search results. {error.toString()} - - ); - } - if (!results || results.length === 0) { - return ; - } - - const resetFilters = () => { - setSelectedFilters({ - selected: '', - checked: [], - }); - }; - - const updateSelected = (filter: string) => { - setSelectedFilters(prevState => ({ - ...prevState, - selected: filter, - })); - }; - - const updateChecked = (filter: string) => { - if (selectedFilters.checked.includes(filter)) { - setSelectedFilters(prevState => ({ - ...prevState, - checked: prevState.checked.filter(item => item !== filter), - })); - return; - } - - setSelectedFilters(prevState => ({ - ...prevState, - checked: [...prevState.checked, filter], - })); - }; - - const filterOptions = results.reduce( - (acc, curr) => { - if (curr.kind && acc.kind.indexOf(curr.kind) < 0) { - acc.kind.push(curr.kind); - } - if (curr.lifecycle && acc.lifecycle.indexOf(curr.lifecycle) < 0) { - acc.lifecycle.push(curr.lifecycle); - } - return acc; - }, - { - kind: [] as Array, - lifecycle: [] as Array, - }, - ); - - return ( - <> - - {showFilters && ( - - - - )} - - toggleFilters(!showFilters)} - /> - } - /> - - - - ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/index.ts b/plugins/search/src/components/LegacySearchPage/index.ts deleted file mode 100644 index 5b64054f8d..0000000000 --- a/plugins/search/src/components/LegacySearchPage/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { LegacySearchPage } from './LegacySearchPage'; diff --git a/plugins/search/src/components/SearchBar/SearchBar.tsx b/plugins/search/src/components/SearchBar/SearchBar.tsx deleted file mode 100644 index a854869976..0000000000 --- a/plugins/search/src/components/SearchBar/SearchBar.tsx +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { useCallback } from 'react'; - -import { InputBaseProps } from '@material-ui/core'; - -import { - SearchBarBase as RealSearchBarBase, - useSearch, -} from '@backstage/plugin-search-react'; - -/** - * Props for {@link SearchBarBase}. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchBarBaseProps = Omit & { - debounceTime?: number; - clearButton?: boolean; - onClear?: () => void; - onSubmit?: () => void; - onChange: (value: string) => void; -}; - -/** - * All search boxes exported by the search plugin are based on the , - * and this one is based on the component from Material UI. - * Recommended if you don't use Search Provider or Search Context. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchBarBase = RealSearchBarBase; - -/** - * Props for {@link SearchBar}. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchBarProps = Partial; - -/** - * Recommended search bar when you use the Search Provider or Search Context. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchBar = ({ onChange, ...props }: SearchBarProps) => { - const { term, setTerm } = useSearch(); - - const handleChange = useCallback( - (newValue: string) => { - if (onChange) { - onChange(newValue); - } else { - setTerm(newValue); - } - }, - [onChange, setTerm], - ); - - return ; -}; diff --git a/plugins/search/src/components/SearchBar/index.tsx b/plugins/search/src/components/SearchBar/index.tsx deleted file mode 100644 index f95d2ec0fc..0000000000 --- a/plugins/search/src/components/SearchBar/index.tsx +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { SearchBar, SearchBarBase } from './SearchBar'; -export type { SearchBarProps, SearchBarBaseProps } from './SearchBar'; diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx deleted file mode 100644 index 15ad348bd4..0000000000 --- a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TestApiProvider } from '@backstage/test-utils'; -import { screen, render, waitFor, within } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import React from 'react'; -import { - SearchContextProvider, - useSearch, - searchApiRef, -} from '@backstage/plugin-search-react'; -import { SearchFilter } from './SearchFilter'; - -const SearchContextFilterSpy = ({ name }: { name: string }) => { - const { filters } = useSearch(); - const value = filters[name]; - return ( - - {Array.isArray(value) ? value.join(',') : value} - - ); -}; - -describe('SearchFilter.Autocomplete', () => { - const query = jest.fn().mockResolvedValue({}); - const emptySearchContext = { - term: '', - types: [], - filters: {}, - }; - - const name = 'field'; - const values = ['value1', 'value2']; - - it('renders as expected', async () => { - render( - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - - await waitFor(() => { - screen.getByRole('listbox'); - }); - - expect(screen.getByRole('option', { name: values[0] })).toBeInTheDocument(); - expect(screen.getByRole('option', { name: values[1] })).toBeInTheDocument(); - }); - - it('renders as expected with async values', async () => { - render( - - - values} /> - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - - await waitFor(() => { - screen.getByRole('listbox'); - }); - - expect(screen.getByRole('option', { name: values[0] })).toBeInTheDocument(); - expect(screen.getByRole('option', { name: values[1] })).toBeInTheDocument(); - }); - - it('does not affect unrelated filter state', async () => { - render( - - - - - - - , - ); - - // The spy should show the initial value. - expect(screen.getByTestId('unrelated-filter-spy')).toHaveTextContent( - 'value', - ); - - // Select a value from the autocomplete filter. - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[1] })); - - // Wait for the autocomplete filter's value to change. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[1], - ); - }); - - // Unrelated filter spy should maintain the same value. - expect(screen.getByTestId('unrelated-filter-spy')).toHaveTextContent( - 'value', - ); - }); - - describe('single', () => { - it('renders as expected with defaultValue', async () => { - render( - - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - - await waitFor(() => { - expect(input).toHaveValue(values[1]); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[1], - ); - }); - }); - - it('renders as expected with initial context', async () => { - render( - - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - - await waitFor(() => { - expect(input).toHaveValue(values[0]); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[0], - ); - }); - }); - - it('sets filter state when selecting a value', async () => { - render( - - - - - - , - ); - - // Select the first option in the autocomplete. - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[0] })); - - // The value should be present in the context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[0], - ); - }); - - // Click the "Clear" button to remove the value. - const clearButton = within(autocomplete).getByLabelText('Clear'); - await userEvent.click(clearButton); - - // That value should have been unset from the context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent(''); - }); - }); - }); - - describe('multiple', () => { - it('renders as expected with defaultValue', async () => { - render( - - - - - - , - ); - - await waitFor(() => { - expect(screen.getByText(values[0])).toBeInTheDocument(); - expect(screen.getByText(values[1])).toBeInTheDocument(); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values.join(','), - ); - }); - }); - - it('renders as expected with initial context', async () => { - render( - - - - - - , - ); - - await waitFor(() => { - expect(screen.getByText(values[0])).toBeInTheDocument(); - expect(screen.getByText(values[1])).toBeInTheDocument(); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values.join(','), - ); - }); - }); - - it('respects tag limit configuration', async () => { - render( - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - - // Select the second value. - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[1] })); - await waitFor(() => { - expect( - screen.getByRole('button', { name: values[1] }), - ).toBeInTheDocument(); - }); - - // Select the first value. - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[0] })); - await waitFor(() => { - expect( - screen.getByRole('button', { name: values[0] }), - ).toBeInTheDocument(); - }); - - // Blur the field and only one tag should be shown with a +1. - input.blur(); - expect( - screen.queryByRole('button', { name: values[0] }), - ).not.toBeInTheDocument(); - expect(screen.getByText('+1')).toBeInTheDocument(); - }); - - it('sets filter state when selecting a value', async () => { - render( - - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - - // Select both values in the autocomplete. - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[0] })); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[1] })); - - // Both options should be present in the context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values.join(','), - ); - }); - - // Click the "Clear" button to remove the value. - const clearButton = within(autocomplete).getByLabelText('Clear'); - await userEvent.click(clearButton); - - // There should be no content in the filter context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent(''); - }); - }); - }); -}); diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx deleted file mode 100644 index 3db5112b88..0000000000 --- a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { SearchFilterComponentProps } from '@backstage/plugin-search-react'; - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchAutocompleteFilterProps = SearchFilterComponentProps & { - filterSelectedOptions?: boolean; - limitTags?: number; - multiple?: boolean; -}; diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx deleted file mode 100644 index 2d652df483..0000000000 --- a/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { screen, render, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { SearchFilter } from './SearchFilter'; - -import { SearchContextProvider } from '@backstage/plugin-search-react'; -import { useApi } from '@backstage/core-plugin-api'; - -jest.mock('@backstage/core-plugin-api', () => ({ - ...jest.requireActual('@backstage/core-plugin-api'), - useApi: jest.fn().mockReturnValue({}), -})); - -describe('SearchFilter', () => { - const initialState = { - term: '', - filters: {}, - types: [], - }; - - const label = 'Field'; - const name = 'field'; - const values = ['value1', 'value2']; - const filters = { unrelated: 'unrelated' }; - - const query = jest.fn().mockResolvedValue({}); - (useApi as jest.Mock).mockReturnValue({ query: query }); - - afterAll(() => { - jest.resetAllMocks(); - }); - - it('Check that element was rendered and received props', async () => { - const CustomFilter = (props: { name: string }) =>
{props.name}
; - - render(); - - expect(screen.getByRole('heading', { name })).toBeInTheDocument(); - }); - - describe('Checkbox', () => { - it('Renders field name and values when provided as props', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - expect( - screen.getByRole('checkbox', { name: values[0] }), - ).toBeInTheDocument(); - expect( - screen.getByRole('checkbox', { name: values[1] }), - ).toBeInTheDocument(); - }); - - it('Renders correctly based on filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - expect( - screen.getByRole('checkbox', { name: values[0] }), - ).not.toBeChecked(); - expect(screen.getByRole('checkbox', { name: values[1] })).toBeChecked(); - }); - - it('Renders correctly based on defaultValue', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - expect(screen.getByRole('checkbox', { name: values[0] })).toBeChecked(); - expect( - screen.getByRole('checkbox', { name: values[1] }), - ).not.toBeChecked(); - }); - - it('Checking / unchecking a value sets filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const checkBox = screen.getByRole('checkbox', { name: values[0] }); - - // Check the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters: { field: [values[0]] } }), - ); - }); - - // Uncheck the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters: {} }), - ); - }); - }); - - it('Checking / unchecking a value maintains unrelated filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const checkBox = screen.getByRole('checkbox', { name: values[0] }); - - // Check the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: { ...filters, field: [values[0]] }, - }), - ); - }); - - // Uncheck the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters }), - ); - }); - }); - }); - - describe('Select', () => { - it('Renders field name and values when provided as props', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect( - screen.getByRole('option', { name: values[0] }), - ).toBeInTheDocument(); - expect( - screen.getByRole('option', { name: values[1] }), - ).toBeInTheDocument(); - }); - - it('Renders values when provided asynchronously', async () => { - render( - - values} - /> - , - ); - - await waitFor(() => { - expect(screen.getByRole('button')).toBeInTheDocument(); - expect( - screen.getByRole('button').getAttribute('aria-disabled'), - ).not.toBe('true'); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect( - screen.getByRole('option', { name: values[0] }), - ).toBeInTheDocument(); - expect( - screen.getByRole('option', { name: values[1] }), - ).toBeInTheDocument(); - }); - - it('Renders correctly based on filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect(screen.getByRole('option', { name: values[0] })).toHaveAttribute( - 'aria-selected', - 'true', - ); - expect( - screen.getByRole('option', { name: values[1] }), - ).not.toHaveAttribute('aria-selected'); - expect(screen.getByRole('option', { name: 'All' })).not.toHaveAttribute( - 'aria-selected', - ); - }); - - it('Renders correctly based on defaultValue', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect(screen.getByRole('option', { name: values[0] })).toHaveAttribute( - 'aria-selected', - 'true', - ); - expect( - screen.getByRole('option', { name: values[1] }), - ).not.toHaveAttribute('aria-selected'); - expect(screen.getByRole('option', { name: 'All' })).not.toHaveAttribute( - 'aria-selected', - ); - }); - - it('Selecting a value sets filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const button = screen.getByRole('button'); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: values[0] })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: { [name]: values[0] }, - }), - ); - }); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: 'All' })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: {}, - }), - ); - }); - }); - - it('Selecting a value maintains unrelated filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const button = screen.getByRole('button'); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: values[0] })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: { ...filters, [name]: values[0] }, - }), - ); - }); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: 'All' })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters }), - ); - }); - }); - }); -}); diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.tsx deleted file mode 100644 index e58bbd5c14..0000000000 --- a/plugins/search/src/components/SearchFilter/SearchFilter.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { ReactElement } from 'react'; - -import { - AutocompleteFilter, - CheckboxFilter, - SearchAutocompleteFilterProps, - SelectFilter, -} from '@backstage/plugin-search-react'; - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchFilterComponentProps = { - className?: string; - name: string; - label?: string; - /** - * Either an array of values directly, or an async function to return a list - * of values to be used in the filter. In the autocomplete filter, the last - * input value is provided as an input to allow values to be filtered. This - * function is debounced and values cached. - */ - values?: string[] | ((partial: string) => Promise); - defaultValue?: string[] | string | null; - /** - * Debounce time in milliseconds, used when values is an async callback. - * Defaults to 250ms. - */ - valuesDebounceMs?: number; -}; - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchFilterWrapperProps = SearchFilterComponentProps & { - component: (props: SearchFilterComponentProps) => ReactElement; - debug?: boolean; -}; - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -const SearchFilter = ({ - component: Element, - ...props -}: SearchFilterWrapperProps) => ; - -/** - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -SearchFilter.Checkbox = ( - props: Omit & - SearchFilterComponentProps, -) => ; - -/** - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -SearchFilter.Select = ( - props: Omit & - SearchFilterComponentProps, -) => ; - -/** - * A control surface for a given filter field name, rendered as an autocomplete - * textfield. A hard-coded list of values may be provided, or an async function - * which returns values may be provided instead. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -SearchFilter.Autocomplete = (props: SearchAutocompleteFilterProps) => ( - -); - -export { SearchFilter }; diff --git a/plugins/search/src/components/SearchFilter/index.ts b/plugins/search/src/components/SearchFilter/index.ts deleted file mode 100644 index 3050330038..0000000000 --- a/plugins/search/src/components/SearchFilter/index.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { SearchFilter } from './SearchFilter'; -export type { - SearchFilterComponentProps, - SearchFilterWrapperProps, -} from './SearchFilter'; -export type { SearchAutocompleteFilterProps } from './SearchFilter.Autocomplete'; diff --git a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx index aad018c334..eac01cceb8 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx @@ -27,8 +27,8 @@ import { import { makeStyles } from '@material-ui/core/styles'; import React, { ComponentType } from 'react'; import { rootRouteRef } from '../../plugin'; -import { SearchBar } from '../SearchBar'; import { + SearchBar, DefaultResultListItem, searchApiRef, MockSearchApi, diff --git a/plugins/search/src/components/SearchPage/SearchPage.tsx b/plugins/search/src/components/SearchPage/SearchPage.tsx index 7145c7a5ef..f267918e12 100644 --- a/plugins/search/src/components/SearchPage/SearchPage.tsx +++ b/plugins/search/src/components/SearchPage/SearchPage.tsx @@ -23,7 +23,6 @@ import { useSearch, } from '@backstage/plugin-search-react'; import { JsonObject } from '@backstage/types'; -import { LegacySearchPage } from '../LegacySearchPage'; export const UrlUpdater = () => { const location = useLocation(); @@ -96,7 +95,7 @@ export const SearchPage = () => { return ( - {outlet || } + {outlet} ); }; diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx deleted file mode 100644 index b1cad8d748..0000000000 --- a/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { renderInTestApp } from '@backstage/test-utils'; -import { waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import React from 'react'; -import { useSearch } from '@backstage/plugin-search-react'; -import { SearchResultPager } from './SearchResultPager'; - -jest.mock('@backstage/plugin-search-react', () => ({ - ...jest.requireActual('@backstage/plugin-search-react'), - useSearch: jest.fn().mockReturnValue({ - result: {}, - }), -})); - -describe('SearchResultPager', () => { - it('renders pager buttons', async () => { - const fetchNextPage = jest.fn(); - const fetchPreviousPage = jest.fn(); - (useSearch as jest.Mock).mockReturnValueOnce({ - result: { loading: false, value: [] }, - fetchNextPage, - fetchPreviousPage, - }); - - const { getByLabelText } = await renderInTestApp(); - - await waitFor(() => { - expect(getByLabelText('previous page')).toBeInTheDocument(); - }); - await userEvent.click(getByLabelText('previous page')); - expect(fetchPreviousPage).toBeCalled(); - - await waitFor(() => { - expect(getByLabelText('next page')).toBeInTheDocument(); - }); - await userEvent.click(getByLabelText('next page')); - - expect(fetchNextPage).toBeCalled(); - }); -}); diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx deleted file mode 100644 index 287e485dd1..0000000000 --- a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Button, makeStyles } from '@material-ui/core'; -import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos'; -import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos'; -import React from 'react'; -import { useSearch } from '@backstage/plugin-search-react'; - -const useStyles = makeStyles(theme => ({ - root: { - display: 'flex', - justifyContent: 'space-between', - gap: theme.spacing(2), - margin: theme.spacing(2, 0), - }, -})); - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchResultPager = () => { - const { fetchNextPage, fetchPreviousPage } = useSearch(); - const classes = useStyles(); - - if (!fetchNextPage && !fetchPreviousPage) { - return <>; - } - - return ( - - ); -}; diff --git a/plugins/search/src/components/SearchResultPager/index.ts b/plugins/search/src/components/SearchResultPager/index.ts deleted file mode 100644 index 39b72ec71f..0000000000 --- a/plugins/search/src/components/SearchResultPager/index.ts +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -export { SearchResultPager } from './SearchResultPager'; diff --git a/plugins/search/src/index.ts b/plugins/search/src/index.ts index fd0e70c61a..8e1db7c2b8 100644 --- a/plugins/search/src/index.ts +++ b/plugins/search/src/index.ts @@ -20,25 +20,8 @@ * @packageDocumentation */ -export { Filters, FiltersButton } from './components/Filters'; -export type { - FilterOptions, - FiltersState, - FiltersProps, - FiltersButtonProps, -} from './components/Filters'; export type { HomePageSearchBarProps } from './components/HomePageComponent'; -export { SearchBar, SearchBarBase } from './components/SearchBar'; -export type { - SearchBarBaseProps, - SearchBarProps, -} from './components/SearchBar'; -export { SearchFilter } from './components/SearchFilter'; -export type { - SearchAutocompleteFilterProps, - SearchFilterComponentProps, - SearchFilterWrapperProps, -} from './components/SearchFilter'; + export { SearchModal, SearchModalProvider, @@ -51,7 +34,6 @@ export type { SearchModalValue, } from './components/SearchModal'; export { SearchPage as Router } from './components/SearchPage'; -export { SearchResultPager } from './components/SearchResultPager'; export { SearchType } from './components/SearchType'; export type { SearchTypeAccordionProps, @@ -63,11 +45,9 @@ export type { SidebarSearchProps } from './components/SidebarSearch'; export type { SidebarSearchModalProps } from './components/SidebarSearchModal'; export { - DefaultResultListItem, HomePageSearchBar, SearchPage, searchPlugin as plugin, searchPlugin, - SearchResult, SidebarSearchModal, } from './plugin'; diff --git a/plugins/search/src/plugin.ts b/plugins/search/src/plugin.ts index 19fd501129..07a645f73e 100644 --- a/plugins/search/src/plugin.ts +++ b/plugins/search/src/plugin.ts @@ -15,11 +15,7 @@ */ import { SearchClient } from './apis'; -import { - searchApiRef, - SearchResult as RealSearchResult, - DefaultResultListItem as RealDefaultResultListItem, -} from '@backstage/plugin-search-react'; +import { searchApiRef } from '@backstage/plugin-search-react'; import { createApiFactory, createPlugin, @@ -64,12 +60,6 @@ export const SearchPage = searchPlugin.provide( }), ); -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchResult = RealSearchResult; - /** * @public */ @@ -85,12 +75,6 @@ export const SidebarSearchModal = searchPlugin.provide( }), ); -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const DefaultResultListItem = RealDefaultResultListItem; - /** * @public */