From 23eb2cce1c0722228515ab4fb96d8ae46e383085 Mon Sep 17 00:00:00 2001 From: Galen Gray Date: Tue, 3 Oct 2023 10:55:55 -0700 Subject: [PATCH] Some code clean up and attributions --- packages/app/src/components/Root/Root.tsx | 70 ++----- .../app/src/components/search/CustomModal.tsx | 191 +++++++++++++----- .../search/SearchResultCustomList.tsx | 8 +- .../TechDocsSearchResultCustomListItem.tsx | 23 ++- 4 files changed, 184 insertions(+), 108 deletions(-) diff --git a/packages/app/src/components/Root/Root.tsx b/packages/app/src/components/Root/Root.tsx index 2d90f70..371cd69 100644 --- a/packages/app/src/components/Root/Root.tsx +++ b/packages/app/src/components/Root/Root.tsx @@ -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'; @@ -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, @@ -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'); @@ -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(); @@ -100,35 +74,25 @@ const SidebarLogo = () => { }; export const Root = ({ children }: PropsWithChildren<{}>) => { - const classes = useModalStyles(); - const navigate = useNavigate(); - const searchBarRef = useRef(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 ( } to="/search"> - - {({ toggleModal }) => CustomModal(toggleModal, classes, searchBarRef, handleSearchBarSubmit)} - + + + + }> diff --git a/packages/app/src/components/search/CustomModal.tsx b/packages/app/src/components/search/CustomModal.tsx index 92957bd..8978a5a 100644 --- a/packages/app/src/components/search/CustomModal.tsx +++ b/packages/app/src/components/search/CustomModal.tsx @@ -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 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(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 ( + <> - - - - - - + + + + + + + - - - - - - - - - {searchResultCustomList} - - - + + + + + + + + + {searchResultCustomList} + + + - + - + - + - - ); -}; + + ); + }; + +export const CustomSearchModal = (props: SearchModalProps) => { + const { open = true, hidden, toggleModal, children } = props; -export default CustomModal; \ No newline at end of file + const classes = useStyles(); + + return ( + + ); +}; \ No newline at end of file diff --git a/packages/app/src/components/search/SearchResultCustomList.tsx b/packages/app/src/components/search/SearchResultCustomList.tsx index f00b03b..4cfbc5b 100644 --- a/packages/app/src/components/search/SearchResultCustomList.tsx +++ b/packages/app/src/components/search/SearchResultCustomList.tsx @@ -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 = () => { @@ -34,12 +33,7 @@ const SearchResultCustomList = () => { highlight={highlight} rank={rank} asListItem={true} - icon={() => { - if (document.location.includes('platform-developer-docs')) - return - else - return - }} + icon={} /> ); case 'stack-overflow': diff --git a/packages/app/src/components/search/TechDocsSearchResultCustomListItem.tsx b/packages/app/src/components/search/TechDocsSearchResultCustomListItem.tsx index ec0fee3..e485998 100644 --- a/packages/app/src/components/search/TechDocsSearchResultCustomListItem.tsx +++ b/packages/app/src/components/search/TechDocsSearchResultCustomListItem.tsx @@ -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'; @@ -108,7 +129,7 @@ export const TechDocsSearchResultCustomListItem = ( title ) : ( <> - {resultTitle} | {entityTitle ?? resultName} docs + {resultTitle} docs )}