Skip to content

Commit

Permalink
Some code clean up and attributions
Browse files Browse the repository at this point in the history
  • Loading branch information
oomIRL committed Oct 3, 2023
1 parent 96355ff commit 23eb2cc
Show file tree
Hide file tree
Showing 4 changed files with 184 additions and 108 deletions.
70 changes: 17 additions & 53 deletions packages/app/src/components/Root/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { PropsWithChildren, useCallback, useEffect, useRef } from 'react';
import { makeStyles, useTheme } from '@material-ui/core';
import React, { PropsWithChildren } from 'react';
import { makeStyles } from '@material-ui/core';
import HomeIcon from '@material-ui/icons/Home';
// import CatalogIcon from '@material-ui/icons/LocalLibrary';
// import ExtensionIcon from '@material-ui/icons/Extension';
Expand All @@ -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 @@ -26,13 +26,11 @@ import {
SidebarSpace,
useSidebarOpenState,
Link,
useContent,
} from '@backstage/core-components';
// import { useApp } from '@backstage/core-plugin-api';
import MenuIcon from '@material-ui/icons/Menu';
import SearchIcon from '@material-ui/icons/Search';
import CustomModal from '../search/CustomModal';
import { useNavigate } from 'react-router-dom';
import { CustomSearchModal } from '../search/CustomModal';

const storedTheme = localStorage.getItem('theme');

Expand Down Expand Up @@ -62,30 +60,6 @@ const useSidebarLogoStyles = makeStyles({
},
});

const useModalStyles = 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' },
}));

const SidebarLogo = () => {
const classes = useSidebarLogoStyles();
const { isOpen } = useSidebarOpenState();
Expand All @@ -100,35 +74,25 @@ const SidebarLogo = () => {
};

export const Root = ({ children }: PropsWithChildren<{}>) => {
const classes = useModalStyles();
const navigate = useNavigate();
const searchBarRef = useRef<HTMLInputElement | null>(null);

const { transitions } = useTheme();
const { focusContent } = useContent();

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

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

const handleSearchBarSubmit = useCallback(() => {
const query = searchBarRef.current?.value ?? '';
navigate(`/search?query=${query}`);
handleSearchResultClick();
}, [navigate, handleSearchResultClick]);
const { state, toggleModal } = useSearchModal();

return (
<SidebarPage>
<Sidebar>
<SidebarLogo />
<SidebarGroup label="Search" icon={<SearchIcon />} to="/search">
<SidebarSearchModal>
{({ toggleModal }) => CustomModal(toggleModal, classes, searchBarRef, handleSearchBarSubmit)}
</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
191 changes: 144 additions & 47 deletions packages/app/src/components/search/CustomModal.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,157 @@
import React from 'react';
import { SearchBar, SearchResultPager } from "@backstage/plugin-search-react";
import { Box, Button, DialogActions, DialogContent, DialogTitle, Divider, Grid, IconButton } from "@material-ui/core";
/*
* 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 : any, classes : any, searchBarRef : any, handleSearchBarSubmit : any) => {
return (
<>
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>
<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>
<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 container direction="row">
<Grid item xs={12}>
<SearchResultPager />
<SearchResultPager />
</Grid>
</Grid>
</Grid>
</DialogActions>
</>
);
};
</>
);
};

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

export default CustomModal;
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>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { SearchResult, DefaultResultListItem } from '@backstage/plugin-search-re
import { CatalogSearchResultListItem } from '@backstage/plugin-catalog';
import { StackOverflowSearchResultListItem, StackOverflowIcon } from '@backstage/plugin-stack-overflow';
import { CatalogIcon, DocsIcon } from '@backstage/core-components';
import { OpenShiftSvgIcon } from "../utils/icons";
import { TechDocsSearchResultCustomListItem } from './TechDocsSearchResultCustomListItem';

const SearchResultCustomList = () => {
Expand Down Expand Up @@ -34,12 +33,7 @@ const SearchResultCustomList = () => {
highlight={highlight}
rank={rank}
asListItem={true}
icon={() => {
if (document.location.includes('platform-developer-docs'))
return <OpenShiftSvgIcon />
else
return <DocsIcon />
}}
icon={<DocsIcon />}
/>
);
case 'stack-overflow':
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
/*
* TechDocsSearchResultCustomListItem.tsx is a customized version of the original TechDocsSearchResultListItem.tsx
* This version removes the entityTitle from the result title and places it as a tag instead
*/

/*
* 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, { PropsWithChildren, ReactNode } from 'react';
import { Box, Chip, Divider, ListItem, ListItemIcon, ListItemText, makeStyles } from '@material-ui/core';
import Typography from '@material-ui/core/Typography';
Expand Down Expand Up @@ -108,7 +129,7 @@ export const TechDocsSearchResultCustomListItem = (
title
) : (
<>
{resultTitle} | {entityTitle ?? resultName} docs
{resultTitle} docs
</>
)}
</LinkWrapper>
Expand Down

0 comments on commit 23eb2cc

Please sign in to comment.