updates based on result list items extension changes

Signed-off-by: Emma Indal <emma.indahl@gmail.com>
This commit is contained in:
Emma Indal
2023-01-31 15:43:57 +01:00
parent 66e2aab4c4
commit f7e698636a
12 changed files with 77 additions and 108 deletions
@@ -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 />} />
@@ -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>
</>
);
}
@@ -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>
</>
);
}
@@ -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}</>,
}),
);
+7 -9
View File
@@ -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>
</>
),
});
+7 -3
View File
@@ -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>
);
};
@@ -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}</>
);