feat(search-react): add use parent context prop
Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
@@ -101,28 +101,20 @@ const searchInitialState: SearchContextState = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Props for {@link SearchContextProvider}
|
||||
*
|
||||
* @public
|
||||
* Creates a new local search context.
|
||||
* @remarks Use it for isolating this context from parent search contexts.
|
||||
* @internal
|
||||
*/
|
||||
export type SearchContextProviderProps = PropsWithChildren<{
|
||||
initialState?: SearchContextState;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
*
|
||||
* Search context provider which gives you access to shared state between search components
|
||||
*/
|
||||
export const SearchContextProvider = (props: SearchContextProviderProps) => {
|
||||
const { initialState = searchInitialState, children } = props;
|
||||
const useSearchContextValue = (
|
||||
initialValue: SearchContextState = searchInitialState,
|
||||
) => {
|
||||
const searchApi = useApi(searchApiRef);
|
||||
const [pageCursor, setPageCursor] = useState<string | undefined>(
|
||||
initialState.pageCursor,
|
||||
initialValue.pageCursor,
|
||||
);
|
||||
const [filters, setFilters] = useState<JsonObject>(initialState.filters);
|
||||
const [term, setTerm] = useState<string>(initialState.term);
|
||||
const [types, setTypes] = useState<string[]>(initialState.types);
|
||||
const [filters, setFilters] = useState<JsonObject>(initialValue.filters);
|
||||
const [term, setTerm] = useState<string>(initialValue.term);
|
||||
const [types, setTypes] = useState<string[]>(initialValue.types);
|
||||
|
||||
const prevTerm = usePrevious(term);
|
||||
|
||||
@@ -170,11 +162,41 @@ export const SearchContextProvider = (props: SearchContextProviderProps) => {
|
||||
fetchPreviousPage: hasPreviousPage ? fetchPreviousPage : undefined,
|
||||
};
|
||||
|
||||
const versionedValue = createVersionedValueMap({ 1: value });
|
||||
return value;
|
||||
};
|
||||
|
||||
return (
|
||||
<AnalyticsContext attributes={{ searchTypes: types.sort().join(',') }}>
|
||||
<SearchContext.Provider value={versionedValue} children={children} />
|
||||
/**
|
||||
* Props for {@link SearchContextProvider}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export type SearchContextProviderProps = PropsWithChildren<{
|
||||
initialState?: SearchContextState;
|
||||
/**
|
||||
* If true, don't create a child context if there is a parent one already defined.
|
||||
* @remarks Default to false.
|
||||
*/
|
||||
useParentContext?: boolean;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* @public
|
||||
* Search context provider which gives you access to shared state between search components
|
||||
*/
|
||||
export const SearchContextProvider = (props: SearchContextProviderProps) => {
|
||||
const { initialState, useParentContext, children } = props;
|
||||
const hasParentContext = useSearchContextCheck();
|
||||
const value = useSearchContextValue(initialState);
|
||||
|
||||
return useParentContext && hasParentContext ? (
|
||||
<>{children}</>
|
||||
) : (
|
||||
<AnalyticsContext
|
||||
attributes={{ searchTypes: value.types.sort().join(',') }}
|
||||
>
|
||||
<SearchContext.Provider value={createVersionedValueMap({ 1: value })}>
|
||||
{children}
|
||||
</SearchContext.Provider>
|
||||
</AnalyticsContext>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -55,7 +55,7 @@ describe('SearchModal', () => {
|
||||
);
|
||||
|
||||
expect(screen.getByRole('dialog')).toBeInTheDocument();
|
||||
expect(query).toHaveBeenCalledTimes(1);
|
||||
expect(query).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('Should use parent search context if defined', async () => {
|
||||
@@ -133,7 +133,7 @@ describe('SearchModal', () => {
|
||||
},
|
||||
);
|
||||
|
||||
expect(query).toHaveBeenCalledTimes(1);
|
||||
expect(query).toHaveBeenCalledTimes(2);
|
||||
await userEvent.keyboard('{Escape}');
|
||||
expect(toggleModal).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { PropsWithChildren } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogActions,
|
||||
@@ -35,7 +35,6 @@ import {
|
||||
SearchResult,
|
||||
SearchResultPager,
|
||||
useSearch,
|
||||
useSearchContextCheck,
|
||||
} from '@backstage/plugin-search-react';
|
||||
import { useRouteRef } from '@backstage/core-plugin-api';
|
||||
import { Link, useContent } from '@backstage/core-components';
|
||||
@@ -171,15 +170,6 @@ export const Modal = ({ toggleModal }: SearchModalProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
const Context = ({ children }: PropsWithChildren<{}>) => {
|
||||
// Checks if there is a parent context already defined and, if not, creates a new local context.
|
||||
const hasParentContext = useSearchContextCheck();
|
||||
if (hasParentContext) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
return <SearchContextProvider>{children}</SearchContextProvider>;
|
||||
};
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
@@ -204,11 +194,11 @@ export const SearchModal = ({
|
||||
hidden={hidden}
|
||||
>
|
||||
{open && (
|
||||
<Context>
|
||||
<SearchContextProvider useParentContext>
|
||||
{(children && children({ toggleModal })) ?? (
|
||||
<Modal toggleModal={toggleModal} />
|
||||
)}
|
||||
</Context>
|
||||
</SearchContextProvider>
|
||||
)}
|
||||
</Dialog>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user