diff --git a/workspaces/global-header/plugins/global-header/package.json b/workspaces/global-header/plugins/global-header/package.json
index 9ab5d0648..383c1e4c2 100644
--- a/workspaces/global-header/plugins/global-header/package.json
+++ b/workspaces/global-header/plugins/global-header/package.json
@@ -27,6 +27,7 @@
"start": "backstage-cli package start",
"build": "backstage-cli package build",
"lint": "backstage-cli package lint",
+ "lint:fix": "backstage-cli package lint --fix",
"test": "backstage-cli package test",
"clean": "backstage-cli package clean",
"prepack": "backstage-cli package prepack",
@@ -40,6 +41,7 @@
"@backstage/plugin-search-backend-module-catalog": "^0.2.6",
"@backstage/plugin-search-backend-module-pg": "^0.5.39",
"@backstage/plugin-search-backend-module-techdocs": "^0.3.4",
+ "@backstage/plugin-search-common": "^1.2.16",
"@backstage/plugin-search-react": "1.8.4",
"@backstage/theme": "^0.6.2",
"@mui/icons-material": "5.16.13",
@@ -57,6 +59,7 @@
"@backstage/cli": "^0.29.0",
"@backstage/core-app-api": "^1.15.2",
"@backstage/dev-utils": "^1.1.4",
+ "@backstage/plugin-search-common": "^1.2.16",
"@backstage/test-utils": "^1.7.2",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^14.0.0",
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchBar.test.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchBar.test.tsx
new file mode 100644
index 000000000..9b3838681
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchBar.test.tsx
@@ -0,0 +1,146 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 { render, screen, fireEvent, waitFor } from '@testing-library/react';
+import { SearchBar } from './SearchBar';
+import {
+ searchApiRef,
+ SearchContextProvider,
+} from '@backstage/plugin-search-react';
+import { mockApis, TestApiProvider } from '@backstage/test-utils';
+import { MemoryRouter, useNavigate } from 'react-router-dom';
+import { configApiRef } from '@backstage/core-plugin-api';
+
+const createInitialState = ({
+ term = '',
+ filters = {},
+ types = ['*'],
+ pageCursor = '',
+} = {}) => ({
+ term,
+ filters,
+ types,
+ pageCursor,
+});
+
+const mockSearchApi = {
+ query: jest.fn().mockResolvedValue({
+ results: [
+ {
+ type: 'software-catalog',
+ document: {
+ title: 'Example Result',
+ location: '/catalog/default/component/example',
+ },
+ },
+ ],
+ }),
+};
+
+const mockConfig = mockApis.config({
+ data: {
+ app: {
+ url: 'https://example.com',
+ },
+ },
+});
+
+jest.mock('../../utils/stringUtils', () => ({
+ ...jest.requireActual('../../utils/stringUtils'),
+ highlightMatch: jest.fn(text => text),
+}));
+
+jest.mock('react-router-dom', () => ({
+ ...jest.requireActual('react-router-dom'),
+ useNavigate: jest.fn(),
+}));
+
+describe('SearchBar', () => {
+ const setup = (term = '') => {
+ const setSearchTerm = jest.fn();
+ const navigate = jest.fn();
+ jest.mocked(useNavigate).mockReturnValue(navigate);
+
+ render(
+
+
+
+
+
+
+ ,
+ );
+ return { setSearchTerm, navigate };
+ };
+
+ it('renders the search input', () => {
+ setup();
+ expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument();
+ });
+
+ it('calls setSearchTerm on input change', () => {
+ const { setSearchTerm } = setup();
+ fireEvent.change(screen.getByPlaceholderText('Search...'), {
+ target: { value: 'test' },
+ });
+ expect(setSearchTerm).toHaveBeenCalledWith('test');
+ });
+
+ it('displays "No results found" when there are no results', async () => {
+ mockSearchApi.query.mockResolvedValueOnce({ results: [] });
+ setup('test');
+ fireEvent.change(screen.getByPlaceholderText('Search...'), {
+ target: { value: 'test' },
+ });
+ await waitFor(() => {
+ expect(screen.getByText('No results found')).toBeInTheDocument();
+ });
+ });
+
+ it('displays search results', async () => {
+ setup('example');
+ fireEvent.change(screen.getByPlaceholderText('Search...'), {
+ target: { value: 'example' },
+ });
+ await waitFor(() => {
+ expect(screen.getByText('Example Result')).toBeInTheDocument();
+ });
+ });
+
+ it('navigates to the search page on Enter key press', async () => {
+ const { navigate } = setup('example');
+ fireEvent.change(screen.getByPlaceholderText('Search...'), {
+ target: { value: 'example' },
+ });
+ await waitFor(() => {
+ expect(screen.getByText('Example Result')).toBeInTheDocument();
+ });
+
+ fireEvent.keyDown(screen.getByPlaceholderText('Search...'), {
+ key: 'Enter',
+ code: 'Enter',
+ });
+ await waitFor(() => {
+ expect(navigate).toHaveBeenCalledWith('/search?query=example');
+ });
+ });
+});
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchBar.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchBar.tsx
index c635ee3e4..243c18565 100644
--- a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchBar.tsx
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchBar.tsx
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Backstage Authors
+ * Copyright Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,19 +19,11 @@ import {
SearchResultState,
SearchResultProps,
} from '@backstage/plugin-search-react';
-import Typography from '@mui/material/Typography';
-import { Link } from '@backstage/core-components';
-import ListItem from '@mui/material/ListItem';
-import Box from '@mui/material/Box';
-import Divider from '@mui/material/Divider';
-import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
import Autocomplete from '@mui/material/Autocomplete';
-import TextField from '@mui/material/TextField';
-import InputAdornment from '@mui/material/InputAdornment';
-import SearchIcon from '@mui/icons-material/Search';
-import { createSearchLink, highlightMatch } from '../../utils/stringUtils';
-import styles from './SearchBar.module.css';
+import { createSearchLink } from '../../utils/stringUtils';
import { useNavigate } from 'react-router-dom';
+import { SearchInput } from './SearchInput';
+import { SearchOption } from './SearchOption';
interface SearchBarProps {
query: SearchResultProps['query'];
@@ -75,72 +67,23 @@ export const SearchBar = (props: SearchBarProps) => {
}
}}
renderInput={params => (
-
-
-
- ),
- }}
- sx={{
- pt: '6px',
- input: { color: '#fff' },
- button: { color: '#fff' },
- }}
/>
)}
- renderOption={(renderProps, option, { index }) => {
- if (option === query?.term && index === options.length - 1) {
- return (
-
-
-
-
-
-
- All results
-
-
-
-
-
-
- );
- }
-
- const result = results.find(r => r.document.title === option);
- return (
-
-
-
-
- {option === 'No results found'
- ? option
- : highlightMatch(option, query?.term ?? '')}
-
-
-
-
- );
- }}
+ renderOption={(renderProps, option, { index }) => (
+
+ )}
ListboxProps={{
style: { maxHeight: 600 },
}}
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchComponent.test.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchComponent.test.tsx
new file mode 100644
index 000000000..1fcfc7a6f
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchComponent.test.tsx
@@ -0,0 +1,100 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 { render, screen, fireEvent } from '@testing-library/react';
+import { SearchComponent } from './SearchComponent';
+import {
+ searchApiRef,
+ SearchContextProvider,
+} from '@backstage/plugin-search-react';
+import { mockApis, TestApiProvider } from '@backstage/test-utils';
+import { configApiRef } from '@backstage/core-plugin-api';
+
+jest.mock('./SearchBar', () => ({
+ SearchBar: ({
+ query,
+ setSearchTerm,
+ }: {
+ query: { term: string };
+ setSearchTerm: (term: string) => void;
+ }) => (
+ setSearchTerm(e.target.value)}
+ />
+ ),
+}));
+
+const mockSearchApi = {
+ query: jest.fn().mockResolvedValue({
+ results: [
+ {
+ type: 'software-catalog',
+ document: {
+ title: 'Example Result',
+ location: '/catalog/default/component/example',
+ },
+ },
+ ],
+ }),
+};
+
+const mockConfig = mockApis.config({
+ data: { app: { baseUrl: 'https://example.com' } },
+});
+
+describe('SearchComponent', () => {
+ it('should render the SearchBar with initial state', () => {
+ render(
+
+
+
+
+ ,
+ );
+
+ const searchBar = screen.getByTestId('search-bar');
+ expect(searchBar).toBeInTheDocument();
+ expect(searchBar).toHaveValue('');
+ });
+
+ it('should update the search term when typing in the SearchBar', () => {
+ render(
+
+
+
+
+ ,
+ );
+
+ const searchBar = screen.getByTestId('search-bar');
+ fireEvent.change(searchBar, { target: { value: 'example' } });
+
+ expect(searchBar).toHaveValue('example');
+ });
+});
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchInput.test.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchInput.test.tsx
new file mode 100644
index 000000000..0fce4d101
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchInput.test.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 { render, screen } from '@testing-library/react';
+import { SearchInput } from './SearchInput';
+import InputAdornment from '@mui/material/InputAdornment';
+import SearchIcon from '@mui/icons-material/Search';
+
+describe('SearchInput', () => {
+ const params = {
+ InputProps: {
+ startAdornment: (
+
+
+
+ ),
+ },
+ };
+
+ it('renders search input with placeholder', () => {
+ render();
+ expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument();
+ });
+
+ it('displays error state', () => {
+ render(
+ ,
+ );
+ expect(screen.getByText('Error fetching results')).toBeInTheDocument();
+ expect(screen.getByRole('textbox')).toHaveAttribute('aria-invalid', 'true');
+ });
+
+ it('renders input adornment', () => {
+ render();
+ expect(screen.getByTestId('SearchIcon')).toBeInTheDocument();
+ });
+});
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchInput.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchInput.tsx
new file mode 100644
index 000000000..0ed2b4fe4
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchInput.tsx
@@ -0,0 +1,54 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 TextField from '@mui/material/TextField';
+import InputAdornment from '@mui/material/InputAdornment';
+import SearchIcon from '@mui/icons-material/Search';
+
+interface SearchInputProps {
+ params: any;
+ error: boolean;
+ helperText: string;
+}
+
+export const SearchInput = ({
+ params,
+ error,
+ helperText,
+}: SearchInputProps) => (
+
+
+
+ ),
+ }}
+ sx={{
+ pt: '6px',
+ input: { color: '#fff' },
+ button: { color: '#fff' },
+ }}
+ />
+);
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchOption.test.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchOption.test.tsx
new file mode 100644
index 000000000..6fea6c384
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchOption.test.tsx
@@ -0,0 +1,90 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 { render, screen } from '@testing-library/react';
+import { SearchOption } from './SearchOption';
+import { BrowserRouter as Router } from 'react-router-dom';
+import { Result, SearchDocument } from '@backstage/plugin-search-common';
+
+jest.mock('./SearchResultItem', () => ({
+ SearchResultItem: jest.fn(({ option }) =>
{option}
),
+}));
+
+describe('SearchOption', () => {
+ const renderProps = {};
+ const searchLink = '/search-link';
+ const query = { term: 'test' };
+ const results = [
+ {
+ document: { title: 'Result 1', location: '/result-1' },
+ } as Result,
+ ];
+
+ it('renders "All results" option', () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByText('All results')).toBeInTheDocument();
+ });
+
+ it('renders search result item', () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByText('Result 1')).toBeInTheDocument();
+ });
+
+ it('renders "No results found" option', () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByText('No results found')).toBeInTheDocument();
+ });
+});
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchOption.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchOption.tsx
new file mode 100644
index 000000000..78e6205f3
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchOption.tsx
@@ -0,0 +1,77 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 Box from '@mui/material/Box';
+import Divider from '@mui/material/Divider';
+import { Link } from '@backstage/core-components';
+import ListItem from '@mui/material/ListItem';
+import Typography from '@mui/material/Typography';
+import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
+import { SearchResultItem } from './SearchResultItem';
+import { Result, SearchDocument } from '@backstage/plugin-search-common';
+import { SearchResultProps } from '@backstage/plugin-search-react';
+
+interface SearchOptionProps {
+ option: string;
+ index: number;
+ options: string[];
+ query: SearchResultProps['query'];
+ results: Result[];
+ renderProps: any;
+ searchLink: string;
+}
+
+export const SearchOption = ({
+ option,
+ index,
+ options,
+ query,
+ results,
+ renderProps,
+ searchLink,
+}: SearchOptionProps) => {
+ if (option === query?.term && index === options.length - 1) {
+ return (
+
+
+
+
+
+ All results
+
+
+
+
+
+ );
+ }
+
+ const result = results.find(r => r.document.title === option);
+ return (
+
+ );
+};
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchResultItem.test.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchResultItem.test.tsx
new file mode 100644
index 000000000..41b4ea10a
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchResultItem.test.tsx
@@ -0,0 +1,96 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 { render, screen } from '@testing-library/react';
+import { SearchResultItem } from './SearchResultItem';
+import { BrowserRouter as Router } from 'react-router-dom';
+import { Result, SearchDocument } from '@backstage/plugin-search-common';
+
+jest.mock('../../utils/stringUtils', () => ({
+ highlightMatch: jest.fn((text, _) => text),
+}));
+
+describe('SearchResultItem', () => {
+ const renderProps = {};
+ const query = { term: 'test' };
+
+ it('renders "No results found" option', () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByText('No results found')).toBeInTheDocument();
+ });
+
+ it('renders search result item with highlighted match', () => {
+ const result = {
+ document: { title: 'Result 1', location: '/result-1' },
+ } as Result;
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByText('Result 1')).toBeInTheDocument();
+ });
+
+ it('links to the correct location', () => {
+ const result = {
+ document: { title: 'Result 1', location: '/result-1' },
+ } as Result;
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByRole('link')).toHaveAttribute('href', '/result-1');
+ });
+
+ it('links to "#" when location is undefined', () => {
+ render(
+
+
+ ,
+ );
+
+ expect(screen.getByRole('link')).toHaveAttribute('href', '/');
+ });
+});
diff --git a/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchResultItem.tsx b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchResultItem.tsx
new file mode 100644
index 000000000..9543b0075
--- /dev/null
+++ b/workspaces/global-header/plugins/global-header/src/components/SearchComponent/SearchResultItem.tsx
@@ -0,0 +1,50 @@
+/*
+ * Copyright Red Hat, Inc.
+ *
+ * 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 { Link } from '@backstage/core-components';
+import ListItem from '@mui/material/ListItem';
+import Box from '@mui/material/Box';
+import Typography from '@mui/material/Typography';
+import { highlightMatch } from '../../utils/stringUtils';
+import { SearchResultProps } from '@backstage/plugin-search-react';
+import { Result, SearchDocument } from '@backstage/plugin-search-common';
+
+interface SearchResultItemProps {
+ option: string;
+ query: SearchResultProps['query'];
+ result: Result | undefined;
+ renderProps: any;
+}
+
+export const SearchResultItem = ({
+ option,
+ query,
+ result,
+ renderProps,
+}: SearchResultItemProps) => (
+
+
+
+
+ {option === 'No results found'
+ ? option
+ : highlightMatch(option, query?.term ?? '')}
+
+
+
+
+);
diff --git a/workspaces/global-header/plugins/global-header/src/utils/stringUtils.test.tsx b/workspaces/global-header/plugins/global-header/src/utils/stringUtils.test.tsx
index ecc1db469..d4a4b0482 100644
--- a/workspaces/global-header/plugins/global-header/src/utils/stringUtils.test.tsx
+++ b/workspaces/global-header/plugins/global-header/src/utils/stringUtils.test.tsx
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Backstage Authors
+ * Copyright Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/workspaces/global-header/plugins/global-header/src/utils/stringUtils.tsx b/workspaces/global-header/plugins/global-header/src/utils/stringUtils.tsx
index 218fcebad..982466645 100644
--- a/workspaces/global-header/plugins/global-header/src/utils/stringUtils.tsx
+++ b/workspaces/global-header/plugins/global-header/src/utils/stringUtils.tsx
@@ -1,5 +1,5 @@
/*
- * Copyright 2024 The Backstage Authors
+ * Copyright Red Hat, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/workspaces/global-header/yarn.lock b/workspaces/global-header/yarn.lock
index 706168763..c389c6ae1 100644
--- a/workspaces/global-header/yarn.lock
+++ b/workspaces/global-header/yarn.lock
@@ -9985,6 +9985,7 @@ __metadata:
"@backstage/plugin-search-backend-module-catalog": ^0.2.6
"@backstage/plugin-search-backend-module-pg": ^0.5.39
"@backstage/plugin-search-backend-module-techdocs": ^0.3.4
+ "@backstage/plugin-search-common": ^1.2.16
"@backstage/plugin-search-react": 1.8.4
"@backstage/test-utils": ^1.7.2
"@backstage/theme": ^0.6.2