diff --git a/plugins/search-react/api-report.md b/plugins/search-react/api-report.md index 09dd3d77a8..5558fd3257 100644 --- a/plugins/search-react/api-report.md +++ b/plugins/search-react/api-report.md @@ -124,6 +124,9 @@ export type SearchFilterWrapperProps = SearchFilterComponentProps & { // @public (undocumented) export const SearchResult: ({ children }: SearchResultProps) => JSX.Element; +// @public (undocumented) +export const SearchResultPager: () => JSX.Element; + // @public (undocumented) export type SearchResultProps = { children: (results: { results: SearchResult_2[] }) => JSX.Element; diff --git a/plugins/search-react/package.json b/plugins/search-react/package.json index 04932bd5ea..95507e64b7 100644 --- a/plugins/search-react/package.json +++ b/plugins/search-react/package.json @@ -38,6 +38,7 @@ "@backstage/version-bridge": "^1.0.1", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", + "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", "react-router": "6.0.0-beta.0", "react-use": "^17.3.2" diff --git a/plugins/search-react/src/components/SearchResultPager/SearchResultPager.test.tsx b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.test.tsx new file mode 100644 index 0000000000..24d9a76e51 --- /dev/null +++ b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.test.tsx @@ -0,0 +1,58 @@ +/* + * Copyright 2022 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 { renderInTestApp } from '@backstage/test-utils'; +import { waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; + +import { useSearch } from '../../context'; +import { SearchResultPager } from './SearchResultPager'; + +jest.mock('../../context', () => ({ + ...jest.requireActual('../../context'), + 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-react/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx new file mode 100644 index 0000000000..68f8223ca0 --- /dev/null +++ b/plugins/search-react/src/components/SearchResultPager/SearchResultPager.tsx @@ -0,0 +1,66 @@ +/* + * Copyright 2022 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 { Button, makeStyles } from '@material-ui/core'; +import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos'; +import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos'; + +import { useSearch } from '../../context'; + +const useStyles = makeStyles(theme => ({ + root: { + display: 'flex', + justifyContent: 'space-between', + gap: theme.spacing(2), + margin: theme.spacing(2, 0), + }, +})); + +/** + * @public + */ +export const SearchResultPager = () => { + const { fetchNextPage, fetchPreviousPage } = useSearch(); + const classes = useStyles(); + + if (!fetchNextPage && !fetchPreviousPage) { + return <>; + } + + return ( + + ); +}; diff --git a/plugins/search-react/src/components/SearchResultPager/index.ts b/plugins/search-react/src/components/SearchResultPager/index.ts new file mode 100644 index 0000000000..5ff203b15d --- /dev/null +++ b/plugins/search-react/src/components/SearchResultPager/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 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-react/src/components/index.ts b/plugins/search-react/src/components/index.ts index db9214d299..bfd65d471f 100644 --- a/plugins/search-react/src/components/index.ts +++ b/plugins/search-react/src/components/index.ts @@ -17,3 +17,4 @@ export * from './HighlightedSearchResultText'; export * from './SearchFilter'; export * from './SearchResult'; +export * from './SearchResultPager'; diff --git a/plugins/search/api-report.md b/plugins/search/api-report.md index ec60569af4..25a7f40394 100644 --- a/plugins/search/api-report.md +++ b/plugins/search/api-report.md @@ -237,7 +237,7 @@ export const SearchResult: ({ // Warning: (ae-missing-release-tag) "SearchResultPager" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public @deprecated (undocumented) export const SearchResultPager: () => JSX.Element; // Warning: (ae-missing-release-tag) "SearchType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx index 6f4c8628a6..0e8d59a694 100644 --- a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx +++ b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx @@ -29,6 +29,9 @@ const useStyles = makeStyles(theme => ({ }, })); +/** + * @deprecated Moved to `@backstage/plugin-search-react`. + */ export const SearchResultPager = () => { const { fetchNextPage, fetchPreviousPage } = useSearch(); const classes = useStyles();