feat(search): move the modal state to context

Co-authored-by: Emma Indal <emma.indahl@gmail.com>
Signed-off-by: Camila Belo <camilaibs@gmail.com>
This commit is contained in:
Camila Belo
2021-12-01 16:05:38 +01:00
parent ab393eb0ee
commit 662636227b
6 changed files with 50 additions and 29 deletions
+4 -2
View File
@@ -114,13 +114,15 @@ const routes = (
In `Root.tsx`, add the `SidebarSearchModal` component:
```bash
import { SidebarSearchModal } from '@backstage/plugin-search';
import { SidebarSearchModal, SearchContextProvider } from '@backstage/plugin-search';
export const Root = ({ children }: PropsWithChildren<{}>) => (
<SidebarPage>
<Sidebar>
<SidebarLogo />
<SidebarSearchModal />
<SearchContextProvider>
<SidebarSearchModal />
</SearchContextProvider>
<SidebarDivider />
...
```
+7 -2
View File
@@ -29,7 +29,10 @@ import LogoIcon from './LogoIcon';
import { NavLink } from 'react-router-dom';
import { GraphiQLIcon } from '@backstage/plugin-graphiql';
import { Settings as SidebarSettings } from '@backstage/plugin-user-settings';
import { SidebarSearchModal } from '@backstage/plugin-search';
import {
SidebarSearchModal,
SearchContextProvider,
} from '@backstage/plugin-search';
import { Shortcuts } from '@backstage/plugin-shortcuts';
import {
Sidebar,
@@ -80,7 +83,9 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
<SidebarPage>
<Sidebar>
<SidebarLogo />
<SidebarSearchModal />
<SearchContextProvider>
<SidebarSearchModal />
</SearchContextProvider>
<SidebarDivider />
{/* Global nav, not org-specific */}
<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
@@ -25,7 +25,7 @@ import LogoFull from './LogoFull';
import LogoIcon from './LogoIcon';
import { NavLink } from 'react-router-dom';
import { Settings as SidebarSettings } from '@backstage/plugin-user-settings';
import { SidebarSearchModal } from '@backstage/plugin-search';
import { SidebarSearchModal, SearchContextProvider } from '@backstage/plugin-search';
import {
Sidebar,
SidebarPage,
@@ -74,7 +74,9 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
<SidebarPage>
<Sidebar>
<SidebarLogo />
<SidebarSearchModal />
<SearchContextProvider>
<SidebarSearchModal />
</SearchContextProvider>
<SidebarDivider />
{/* Global nav, not org-specific */}
<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
@@ -37,6 +37,8 @@ type SearchContextValue = {
setTypes: React.Dispatch<React.SetStateAction<string[]>>;
filters: JsonObject;
setFilters: React.Dispatch<React.SetStateAction<JsonObject>>;
open?: boolean;
toggleModal: () => void;
pageCursor?: string;
setPageCursor: React.Dispatch<React.SetStateAction<string | undefined>>;
fetchNextPage?: React.DispatchWithoutAction;
@@ -49,6 +51,7 @@ type SettableSearchContext = Omit<
| 'setTerm'
| 'setTypes'
| 'setFilters'
| 'toggleModal'
| 'setPageCursor'
| 'fetchNextPage'
| 'fetchPreviousPage'
@@ -74,6 +77,9 @@ export const SearchContextProvider = ({
const [filters, setFilters] = useState<JsonObject>(initialState.filters);
const [term, setTerm] = useState<string>(initialState.term);
const [types, setTypes] = useState<string[]>(initialState.types);
const [open, setOpen] = useState<boolean>(false);
const toggleModal = (): void => setOpen(prevState => !prevState);
const prevTerm = usePrevious(term);
const result = useAsync(
@@ -109,6 +115,8 @@ export const SearchContextProvider = ({
result,
filters,
setFilters,
open,
toggleModal,
term,
setTerm,
types,
@@ -14,28 +14,15 @@
* limitations under the License.
*/
import React, { useState, ComponentType } from 'react';
import React, { ComponentType } from 'react';
import { Button } from '@material-ui/core';
import { ApiProvider, ApiRegistry } from '@backstage/core-app-api';
import { wrapInTestApp } from '@backstage/test-utils';
import { SearchModal } from '../index';
import { useSearch, SearchContextProvider } from '../SearchContext';
import { searchApiRef } from '../../apis';
import { rootRouteRef } from '../../plugin';
export default {
title: 'Plugins/Search/SearchModal',
component: SearchModal,
decorators: [
(Story: ComponentType<{}>) =>
wrapInTestApp(
<>
<Story />
</>,
{ mountedRoutes: { '/search': rootRouteRef } },
),
],
};
const mockSearchApi = {
query: () =>
Promise.resolve({
@@ -70,16 +57,33 @@ const mockSearchApi = {
const apiRegistry = () => ApiRegistry.from([[searchApiRef, mockSearchApi]]);
export default {
title: 'Plugins/Search/SearchModal',
component: SearchModal,
decorators: [
(Story: ComponentType<{}>) =>
wrapInTestApp(
<>
<ApiProvider apis={apiRegistry()}>
<SearchContextProvider>
<Story />
</SearchContextProvider>
</ApiProvider>
</>,
{ mountedRoutes: { '/search': rootRouteRef } },
),
],
};
export const Default = () => {
const [open, setOpen] = useState<boolean>(false);
const toggleModal = (): void => setOpen(prevState => !prevState);
const { open, toggleModal } = useSearch();
return (
<ApiProvider apis={apiRegistry()}>
<>
<Button variant="contained" color="primary" onClick={toggleModal}>
Toggle Search Modal
</Button>
<SearchModal open={open} toggleModal={toggleModal} />
</ApiProvider>
</>
);
};
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React, { useState } from 'react';
import React from 'react';
import SearchIcon from '@material-ui/icons/Search';
import { SearchModal } from '../SearchModal';
import { SidebarItem } from '@backstage/core-components';
import { SearchModal } from '../SearchModal';
import { useSearch } from '../SearchContext';
export const SidebarSearchModal = () => {
const [open, setOpen] = useState<boolean>(false);
const toggleModal = (): void => setOpen(prevState => !prevState);
const { open, toggleModal } = useSearch();
return (
<>