Skip to content

Commit

Permalink
Merge pull request #47 from bcgov/DEVX110-ImproveSearcg
Browse files Browse the repository at this point in the history
Devx110 improve searcg
  • Loading branch information
oomIRL authored Oct 5, 2023
2 parents fb4cf8f + 998cc9f commit 91bb91a
Show file tree
Hide file tree
Showing 7 changed files with 442 additions and 62 deletions.
23 changes: 19 additions & 4 deletions packages/app/src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
Settings as SidebarSettings,
UserSettingsSignInAvatar,
} from '@backstage/plugin-user-settings';
import { SidebarSearchModal } from '@backstage/plugin-search';
import { SearchModalProvider, useSearchModal } from '@backstage/plugin-search';
import {
Sidebar,
sidebarConfig,
Expand All @@ -30,6 +30,7 @@ import {
// import { useApp } from '@backstage/core-plugin-api';
import MenuIcon from '@material-ui/icons/Menu';
import SearchIcon from '@material-ui/icons/Search';
import { CustomSearchModal } from '../search/CustomModal';

import {useApi, configApiRef} from '@backstage/core-plugin-api';

Expand Down Expand Up @@ -118,13 +119,27 @@ const SidebarLogo = () => {
);
};

export const Root = ({ children }: PropsWithChildren<{}>) => (
export const Root = ({ children }: PropsWithChildren<{}>) => {
const { state, toggleModal } = useSearchModal();

return (
<SidebarPage>
<MyReactComponent/>
<Sidebar>
<SidebarLogo />
<SidebarGroup label="Search" icon={<SearchIcon />} to="/search">
<SidebarSearchModal />
<SearchModalProvider>
<SidebarItem
className="search-icon"
icon={SearchIcon}
text="Search"
onClick={toggleModal}
/>
<CustomSearchModal
{...state}
toggleModal={toggleModal}
/>
</SearchModalProvider>
</SidebarGroup>
<SidebarDivider />
<SidebarGroup label="Menu" icon={<MenuIcon />}>
Expand Down Expand Up @@ -191,4 +206,4 @@ export const Root = ({ children }: PropsWithChildren<{}>) => (
</Sidebar>
{children}
</SidebarPage>
);
)};
157 changes: 157 additions & 0 deletions packages/app/src/components/search/CustomModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/*
* CustomModal.tsx is a customized version of the original SearchModal.tsx
* The searchResultCustomList component is used rather than <SearchResult> element
*/

/*
* 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, useEffect, useRef } from 'react';
import { SearchBar, SearchContextProvider, SearchResultPager } from "@backstage/plugin-search-react";
import { Box, Button, Dialog, DialogActions, DialogContent, DialogTitle, Divider, Grid, IconButton, makeStyles, useTheme } from "@material-ui/core";
import CloseIcon from '@material-ui/icons/Close';
import ArrowForwardIcon from '@material-ui/icons/ArrowForward';
import { searchResultCustomList } from './SearchResultCustomList';
import { SearchModalChildrenProps, SearchModalProps } from '@backstage/plugin-search';
import { useNavigate } from 'react-router-dom';
import { useContent } from '@backstage/core-components';

const useStyles = makeStyles(theme => ({
dialogTitle: {
gap: theme.spacing(1),
display: 'grid',
alignItems: 'center',
gridTemplateColumns: '1fr auto',
'&> button': {
marginTop: theme.spacing(1),
},
},
input: {
flex: 1,
},
button: {
'&:hover': {
background: 'none',
},
},
// Reduces default height of the modal, keeping a gap of 128px between the top and bottom of the page.
paperFullWidth: { height: 'calc(100% - 128px)' },
dialogActionsContainer: { padding: theme.spacing(1, 3) },
viewResultsLink: { verticalAlign: '0.5em' },
}));

export const CustomModal = ({ toggleModal }: SearchModalChildrenProps) => {
const classes = useStyles();
const navigate = useNavigate();
const { transitions } = useTheme();
const { focusContent } = useContent();
const searchBarRef = useRef<HTMLInputElement | null>(null);

useEffect(() => {
searchBarRef?.current?.focus();
});

const handleSearchResultClick = useCallback(() => {
setTimeout(focusContent, transitions.duration.leavingScreen);
}, [focusContent, transitions]);

// This handler is called when "enter" is pressed
const handleSearchBarSubmit = useCallback(() => {
// Using ref to get the current field value without waiting for a query debounce
const query = searchBarRef.current?.value ?? '';
navigate(`/search?query=${query}`);
handleSearchResultClick();
}, [navigate, handleSearchResultClick]);

return (
<>
<DialogTitle>
<Box className={classes.dialogTitle}>
<SearchBar
className={classes.input}
inputProps={{ ref: searchBarRef }}
onSubmit={handleSearchBarSubmit}
/>

<IconButton aria-label="close" onClick={toggleModal}>
<CloseIcon />
</IconButton>
</Box>
</DialogTitle>
<DialogContent>
<Grid
container
direction="row-reverse"
justifyContent="flex-start"
alignItems="center"
>
<Grid item>
<Button
className={classes.button}
color="primary"
endIcon={<ArrowForwardIcon />}
onClick={handleSearchBarSubmit}
disableRipple
>
View Full Results
</Button>
</Grid>
</Grid>
<Divider />
<Grid container direction="column">
<Grid item>
{searchResultCustomList}
</Grid>
</Grid>
</DialogContent>
<DialogActions className={classes.dialogActionsContainer}>
<Grid container direction="row">
<Grid item xs={12}>
<SearchResultPager />
</Grid>
</Grid>
</DialogActions>
</>
);
};

export const CustomSearchModal = (props: SearchModalProps) => {
const { open = true, hidden, toggleModal, children } = props;

const classes = useStyles();

return (
<Dialog
classes={{
paperFullWidth: classes.paperFullWidth,
}}
onClose={toggleModal}
aria-labelledby="search-modal-title"
fullWidth
maxWidth="lg"
open={open}
hidden={hidden}
>
{open && (
<SearchContextProvider inheritParentContextIfAvailable>
{(children && children({ toggleModal })) ?? (
<CustomModal toggleModal={toggleModal} />
)}
</SearchContextProvider>
)}
</Dialog>
);
};
62 changes: 5 additions & 57 deletions packages/app/src/components/search/SearchPage.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import React from 'react';
import { makeStyles, Theme, Grid, Paper, List } from '@material-ui/core';
import { makeStyles, Theme, Grid, Paper } from '@material-ui/core';

import { CatalogSearchResultListItem } from '@backstage/plugin-catalog';
import {
catalogApiRef,
CATALOG_FILTER_EXISTS,
} from '@backstage/plugin-catalog-react';
import { TechDocsSearchResultListItem } from '@backstage/plugin-techdocs';

import { SearchType } from '@backstage/plugin-search';
import {
SearchBar,
SearchFilter,
SearchResult,
SearchPagination,
useSearch,
DefaultResultListItem
useSearch
} from '@backstage/plugin-search-react';
import {
CatalogIcon,
Expand All @@ -25,7 +21,8 @@ import {
Page,
} from '@backstage/core-components';
import { useApi } from '@backstage/core-plugin-api';
import { StackOverflowSearchResultListItem, StackOverflowIcon } from '@backstage/plugin-stack-overflow';
import { StackOverflowIcon } from '@backstage/plugin-stack-overflow';
import { searchResultCustomList } from './SearchResultCustomList';

const useStyles = makeStyles((theme: Theme) => ({
search: {
Expand Down Expand Up @@ -119,56 +116,7 @@ const SearchPage = () => {
</Grid>
<Grid item xs={9}>
<SearchPagination />
<SearchResult>
{({ results }) => (
<List>
{results.map(({ type, document, highlight, rank }) => {
switch (type) {
case 'software-catalog':
return (
<CatalogSearchResultListItem
key={document.location}
result={document}
highlight={highlight}
rank={rank}
icon={<CatalogIcon />}
/>
);
case 'techdocs':
return (
<TechDocsSearchResultListItem
key={document.location}
result={document}
highlight={highlight}
rank={rank}
icon={<DocsIcon />}
/>
);
case 'stack-overflow':
return (
<StackOverflowSearchResultListItem
key={document.location}
result={document}
icon={<StackOverflowIcon />}
/>
);
default:
return (
<DefaultResultListItem
key={document.location}
result={document}
highlight={highlight}
rank={rank}
/>
);
}
})}
</List>
)}
{/* <CatalogSearchResultListItem icon={<CatalogIcon />} />
<TechDocsSearchResultListItem icon={<DocsIcon />} />
<StackOverflowSearchResultListItem icon={<StackOverflowIcon />} /> */}
</SearchResult>
{searchResultCustomList}
</Grid>
</Grid>
</Content>
Expand Down
64 changes: 64 additions & 0 deletions packages/app/src/components/search/SearchResultCustomList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React from 'react';

import { List } from '@material-ui/core';
import { SearchResult, DefaultResultListItem } from '@backstage/plugin-search-react';

import { CatalogSearchResultListItem } from '@backstage/plugin-catalog';
import { StackOverflowSearchResultListItem, StackOverflowIcon } from '@backstage/plugin-stack-overflow';
import { CatalogIcon, DocsIcon } from '@backstage/core-components';
import { TechDocsSearchResultCustomListItem } from './TechDocsSearchResultCustomListItem';

const SearchResultCustomList = () => {
return (
<SearchResult>
{({ results }) => (
<List>
{results.map(({ type, document, highlight, rank }) => {
switch (type) {
case 'software-catalog':
return (
<CatalogSearchResultListItem
key={document.location}
result={document}
highlight={highlight}
rank={rank}
icon={<CatalogIcon />}
/>
);
case 'techdocs':
return (
<TechDocsSearchResultCustomListItem
key={document.location}
result={document}
highlight={highlight}
rank={rank}
asListItem={true}
icon={<DocsIcon />}
/>
);
case 'stack-overflow':
return (
<StackOverflowSearchResultListItem
key={document.location}
result={document}
icon={<StackOverflowIcon />}
/>
);
default:
return (
<DefaultResultListItem
key={document.location}
result={document}
highlight={highlight}
rank={rank}
/>
);
}
})}
</List>
)}
</SearchResult>
)
}

export const searchResultCustomList = <SearchResultCustomList />;
Loading

0 comments on commit 91bb91a

Please sign in to comment.