updates based on result list items extension changes
Signed-off-by: Emma Indal <emma.indahl@gmail.com>
This commit is contained in:
@@ -82,22 +82,14 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
searchBarRef?.current?.focus();
|
||||
});
|
||||
|
||||
<<<<<<< HEAD
|
||||
const handleSearchResultClick = useCallback(() => {
|
||||
toggleModal();
|
||||
setTimeout(focusContent, transitions.duration.leavingScreen);
|
||||
}, [toggleModal, focusContent, transitions]);
|
||||
|
||||
=======
|
||||
>>>>>>> c224202137 (make sure result list is structured with list elements only)
|
||||
const handleSearchBarKeyDown = useCallback(
|
||||
(e: KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
|
||||
if (e.key === 'Enter') {
|
||||
handleSearchResultClick();
|
||||
toggleModal();
|
||||
navigate(searchPagePath);
|
||||
}
|
||||
},
|
||||
[navigate, searchPagePath, handleSearchResultClick],
|
||||
[navigate, searchPagePath, toggleModal],
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -181,7 +173,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
alignItems="center"
|
||||
>
|
||||
<Grid item>
|
||||
<Link to={searchPagePath} onClick={handleSearchResultClick}>
|
||||
<Link to={searchPagePath} onClick={toggleModal}>
|
||||
<Typography
|
||||
component="span"
|
||||
className={classes.viewResultsLink}
|
||||
@@ -194,10 +186,7 @@ export const SearchModal = ({ toggleModal }: { toggleModal: () => void }) => {
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid item xs>
|
||||
<SearchResult
|
||||
onClick={handleSearchResultClick}
|
||||
onKeyDown={handleSearchResultClick}
|
||||
>
|
||||
<SearchResult onClick={toggleModal}>
|
||||
<CatalogSearchResultListItem icon={<CatalogIcon />} />
|
||||
<TechDocsSearchResultListItem icon={<DocsIcon />} />
|
||||
<ToolSearchResultListItem icon={<BuildIcon />} />
|
||||
|
||||
+4
-6
@@ -18,7 +18,6 @@ import React, { ReactNode } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Chip,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
@@ -51,7 +50,6 @@ export interface CatalogSearchResultListItemProps {
|
||||
result?: IndexableDocument;
|
||||
highlight?: ResultHighlight;
|
||||
rank?: number;
|
||||
toggleModal?: () => void;
|
||||
}
|
||||
|
||||
/** @public */
|
||||
@@ -66,7 +64,7 @@ export function CatalogSearchResultListItem(
|
||||
if (!result) return null;
|
||||
|
||||
return (
|
||||
<ListItem alignItems="flex-start" divider>
|
||||
<>
|
||||
{props.icon && <ListItemIcon>{props.icon}</ListItemIcon>}
|
||||
<div className={classes.flexContainer}>
|
||||
<ListItemText
|
||||
@@ -88,12 +86,12 @@ export function CatalogSearchResultListItem(
|
||||
secondary={
|
||||
highlight?.fields.text ? (
|
||||
<HighlightedSearchResultText
|
||||
text={highlight.fields.title}
|
||||
text={highlight.fields.text}
|
||||
preTag={highlight.preTag}
|
||||
postTag={highlight.postTag}
|
||||
/>
|
||||
) : (
|
||||
result.title
|
||||
result.text
|
||||
)
|
||||
}
|
||||
/>
|
||||
@@ -104,6 +102,6 @@ export function CatalogSearchResultListItem(
|
||||
)}
|
||||
</Box>
|
||||
</div>
|
||||
</ListItem>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
+2
-3
@@ -18,7 +18,6 @@ import React, { ReactNode } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Chip,
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
@@ -63,7 +62,7 @@ export function ToolSearchResultListItem(props: ToolSearchResultListItemProps) {
|
||||
if (!result) return null;
|
||||
|
||||
return (
|
||||
<ListItem alignItems="flex-start" divider>
|
||||
<>
|
||||
{props.icon && <ListItemIcon>{props.icon}</ListItemIcon>}
|
||||
<div className={classes.flexContainer}>
|
||||
<ListItemText
|
||||
@@ -99,6 +98,6 @@ export function ToolSearchResultListItem(props: ToolSearchResultListItemProps) {
|
||||
result.tags.map((tag: string) => <Chip label={tag} size="small" />)}
|
||||
</Box>
|
||||
</div>
|
||||
</ListItem>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
+4
-3
@@ -35,9 +35,10 @@ describe('DefaultResultListItem', () => {
|
||||
|
||||
it('Includes primary/secondary text (title / text)', async () => {
|
||||
await renderInTestApp(<DefaultResultListItem result={result} />);
|
||||
expect(screen.getByRole('listitem')).toHaveTextContent(
|
||||
result.title + result.text,
|
||||
);
|
||||
expect(
|
||||
screen.getByRole('link', { name: result.title }),
|
||||
).toBeInTheDocument();
|
||||
expect(screen.getByText(result.text)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render icon if prop is specified', async () => {
|
||||
|
||||
@@ -21,12 +21,12 @@ import {
|
||||
SearchDocument,
|
||||
} from '@backstage/plugin-search-common';
|
||||
import { HighlightedSearchResultText } from '../HighlightedSearchResultText';
|
||||
import { ListItem, ListItemIcon, ListItemText, Box } from '@material-ui/core';
|
||||
import { ListItemIcon, ListItemText, Box } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Link } from '@backstage/core-components';
|
||||
|
||||
/**
|
||||
* Props for {@link DefaultResultListItem}
|
||||
* Props for {@link DefaultResultListItemComponent}
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
@@ -55,7 +55,7 @@ export const DefaultResultListItemComponent = ({
|
||||
if (!result) return null;
|
||||
|
||||
return (
|
||||
<ListItem alignItems="center" divider>
|
||||
<>
|
||||
{icon && <ListItemIcon>{icon}</ListItemIcon>}
|
||||
<ListItemText
|
||||
primaryTypographyProps={{ variant: 'h6' }}
|
||||
@@ -95,7 +95,7 @@ export const DefaultResultListItemComponent = ({
|
||||
}
|
||||
/>
|
||||
{secondaryAction && <Box alignItems="flex-end">{secondaryAction}</Box>}
|
||||
</ListItem>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
import React from 'react';
|
||||
import { waitFor } from '@testing-library/react';
|
||||
|
||||
import { ListItem } from '@material-ui/core';
|
||||
import {
|
||||
wrapInTestApp,
|
||||
renderInTestApp,
|
||||
@@ -217,8 +215,7 @@ describe('SearchResult', () => {
|
||||
}).provide(
|
||||
createSearchResultListItemExtension({
|
||||
name: 'SearchResultExtension',
|
||||
component: async () => props =>
|
||||
<ListItem>Result: {props.result?.title}</ListItem>,
|
||||
component: async () => props => <>Result: {props.result?.title}</>,
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { ListItem, MenuItem } from '@material-ui/core';
|
||||
import { MenuItem } from '@material-ui/core';
|
||||
import DocsIcon from '@material-ui/icons/InsertDriveFile';
|
||||
|
||||
import {
|
||||
@@ -143,8 +143,7 @@ describe('SearchResultGroup', () => {
|
||||
}).provide(
|
||||
createSearchResultListItemExtension({
|
||||
name: 'SearchResultGroupItemExtension',
|
||||
component: async () => props =>
|
||||
<ListItem>Result: {props.result?.title}</ListItem>,
|
||||
component: async () => props => <>Result: {props.result?.title}</>,
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -226,8 +226,7 @@ describe('SearchResultList', () => {
|
||||
}).provide(
|
||||
createSearchResultListItemExtension({
|
||||
name: 'SearchResultListItemExtension',
|
||||
component: async () => props =>
|
||||
<ListItem>Result: {props.result?.title}</ListItem>,
|
||||
component: async () => props => <>Result: {props.result?.title}</>,
|
||||
}),
|
||||
);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
import { screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
import { ListItem, ListItemText } from '@material-ui/core';
|
||||
import { ListItemText } from '@material-ui/core';
|
||||
|
||||
import {
|
||||
wrapInTestApp,
|
||||
@@ -75,9 +75,9 @@ const createExtension = (
|
||||
predicate,
|
||||
component = async () => (props: { result?: SearchDocument }) =>
|
||||
(
|
||||
<ListItem>
|
||||
<>
|
||||
<ListItemText primary="Default" secondary={props.result?.title} />
|
||||
</ListItem>
|
||||
</>
|
||||
),
|
||||
} = options;
|
||||
return plugin.provide(
|
||||
@@ -120,7 +120,7 @@ describe('extensions', () => {
|
||||
);
|
||||
|
||||
await userEvent.click(
|
||||
screen.getByRole('button', { name: /Search Result 1/ }),
|
||||
screen.getByRole('link', { name: /Search Result 1/ }),
|
||||
);
|
||||
|
||||
expect(analyticsApiMock.getEvents()[0]).toMatchObject({
|
||||
@@ -146,9 +146,7 @@ describe('extensions', () => {
|
||||
expect(screen.getByText('Default')).toBeInTheDocument();
|
||||
expect(screen.getByText('Search Result 1')).toBeInTheDocument();
|
||||
|
||||
await userEvent.click(
|
||||
screen.getByRole('button', { name: /Search Result 1/ }),
|
||||
);
|
||||
await userEvent.click(screen.getByRole('listitem'));
|
||||
|
||||
expect(analyticsApiMock.getEvents()[0]).toMatchObject({
|
||||
action: 'discover',
|
||||
@@ -184,9 +182,9 @@ describe('extensions', () => {
|
||||
predicate: (result: SearchResult) => result.type === 'explore',
|
||||
component: async () => (props: { result?: SearchDocument }) =>
|
||||
(
|
||||
<ListItem>
|
||||
<>
|
||||
<ListItemText primary="Explore" secondary={props.result?.title} />
|
||||
</ListItem>
|
||||
</>
|
||||
),
|
||||
});
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
} from '@backstage/core-plugin-api';
|
||||
import { SearchDocument, SearchResult } from '@backstage/plugin-search-common';
|
||||
|
||||
import { Box, List, ListProps } from '@material-ui/core';
|
||||
import { ListItem, List, ListProps } from '@material-ui/core';
|
||||
|
||||
import { DefaultResultListItem } from './components';
|
||||
|
||||
@@ -105,9 +105,13 @@ const SearchResultListItemExtension = ({
|
||||
}, [rank, result, noTrack, analytics]);
|
||||
|
||||
return (
|
||||
<Box role="button" tabIndex={0} onClickCapture={handleClickCapture}>
|
||||
<ListItem
|
||||
divider
|
||||
alignItems="flex-start"
|
||||
onClickCapture={handleClickCapture}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
+38
-48
@@ -17,14 +17,7 @@
|
||||
import React from 'react';
|
||||
import _unescape from 'lodash/unescape';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import {
|
||||
Divider,
|
||||
ListItem,
|
||||
ListItemText,
|
||||
ListItemIcon,
|
||||
Box,
|
||||
Chip,
|
||||
} from '@material-ui/core';
|
||||
import { ListItemText, ListItemIcon, Box, Chip } from '@material-ui/core';
|
||||
import { useAnalytics } from '@backstage/core-plugin-api';
|
||||
import { ResultHighlight } from '@backstage/plugin-search-common';
|
||||
import { HighlightedSearchResultText } from '@backstage/plugin-search-react';
|
||||
@@ -52,47 +45,44 @@ export const StackOverflowSearchResultListItem = (
|
||||
|
||||
return (
|
||||
<>
|
||||
<ListItem alignItems="center">
|
||||
{props.icon && <ListItemIcon>{props.icon}</ListItemIcon>}
|
||||
<Box flexWrap="wrap">
|
||||
<ListItemText
|
||||
primaryTypographyProps={{ variant: 'h6' }}
|
||||
primary={
|
||||
<Link to={location} noTrack onClick={handleClick}>
|
||||
{highlight?.fields?.title ? (
|
||||
<HighlightedSearchResultText
|
||||
text={highlight.fields.title}
|
||||
preTag={highlight.preTag}
|
||||
postTag={highlight.postTag}
|
||||
/>
|
||||
) : (
|
||||
_unescape(title)
|
||||
)}
|
||||
</Link>
|
||||
}
|
||||
secondary={
|
||||
highlight?.fields?.text ? (
|
||||
<>
|
||||
Author:{' '}
|
||||
<HighlightedSearchResultText
|
||||
text={highlight.fields.text}
|
||||
preTag={highlight.preTag}
|
||||
postTag={highlight.postTag}
|
||||
/>
|
||||
</>
|
||||
{props.icon && <ListItemIcon>{props.icon}</ListItemIcon>}
|
||||
<Box flexWrap="wrap">
|
||||
<ListItemText
|
||||
primaryTypographyProps={{ variant: 'h6' }}
|
||||
primary={
|
||||
<Link to={location} noTrack onClick={handleClick}>
|
||||
{highlight?.fields?.title ? (
|
||||
<HighlightedSearchResultText
|
||||
text={highlight.fields.title}
|
||||
preTag={highlight.preTag}
|
||||
postTag={highlight.postTag}
|
||||
/>
|
||||
) : (
|
||||
`Author: ${text}`
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Chip label={`Answer(s): ${answers}`} size="small" />
|
||||
{tags &&
|
||||
tags.map((tag: string) => (
|
||||
<Chip key={tag} label={`Tag: ${tag}`} size="small" />
|
||||
))}
|
||||
</Box>
|
||||
</ListItem>
|
||||
<Divider />
|
||||
_unescape(title)
|
||||
)}
|
||||
</Link>
|
||||
}
|
||||
secondary={
|
||||
highlight?.fields?.text ? (
|
||||
<>
|
||||
Author:{' '}
|
||||
<HighlightedSearchResultText
|
||||
text={highlight.fields.text}
|
||||
preTag={highlight.preTag}
|
||||
postTag={highlight.postTag}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
`Author: ${text}`
|
||||
)
|
||||
}
|
||||
/>
|
||||
<Chip label={`Answer(s): ${answers}`} size="small" />
|
||||
{tags &&
|
||||
tags.map((tag: string) => (
|
||||
<Chip key={tag} label={`Tag: ${tag}`} size="small" />
|
||||
))}
|
||||
</Box>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -15,12 +15,7 @@
|
||||
*/
|
||||
|
||||
import React, { PropsWithChildren, ReactNode } from 'react';
|
||||
import {
|
||||
ListItem,
|
||||
ListItemIcon,
|
||||
ListItemText,
|
||||
makeStyles,
|
||||
} from '@material-ui/core';
|
||||
import { ListItemIcon, ListItemText, makeStyles } from '@material-ui/core';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Link } from '@backstage/core-components';
|
||||
import { ResultHighlight } from '@backstage/plugin-search-common';
|
||||
@@ -155,10 +150,10 @@ export const TechDocsSearchResultListItem = (
|
||||
|
||||
const ListItemWrapper = ({ children }: PropsWithChildren<{}>) =>
|
||||
asListItem ? (
|
||||
<ListItem alignItems="flex-start" divider>
|
||||
<>
|
||||
{icon && <ListItemIcon>{icon}</ListItemIcon>}
|
||||
<div className={classes.flexContainer}>{children}</div>
|
||||
</ListItem>
|
||||
</>
|
||||
) : (
|
||||
<>{children}</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user