Skip to content

Commit

Permalink
Create search list item component for discussions with links to backs…
Browse files Browse the repository at this point in the history
…tage user
  • Loading branch information
minkimcello committed Nov 27, 2024
1 parent d673df4 commit ff79225
Show file tree
Hide file tree
Showing 3 changed files with 222 additions and 56 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import React, { ReactNode } from 'react';
import Box from '@material-ui/core/Box';
import Chip from '@material-ui/core/Chip';
import ListItemIcon from '@material-ui/core/ListItemIcon';
import ListItemText from '@material-ui/core/ListItemText';
import Typography from '@material-ui/core/Typography';
import { makeStyles } from '@material-ui/core/styles';
import { Link } from '@backstage/core-components';
import { ResultHighlight } from '@backstage/plugin-search-common';
import { HighlightedSearchResultText } from '@backstage/plugin-search-react';
import { IndexableDocument } from '@backstage/plugin-search-common';
import { EntityRefLink } from '@backstage/plugin-catalog-react';

export interface GithubDiscussionsDocument extends IndexableDocument {
author: string;
category: string;
labels: {
name: string;
color: string;
}[];
comments: {
author: string;
bodyText: string;
replies: {
author: string;
bodyText: string;
}[];
}[];
}

const useStyles = makeStyles(theme => ({
item: {
display: 'flex',
},
flexContainer: {
flexWrap: 'wrap',
},
itemText: {
width: '100%',
wordBreak: 'break-all',
marginBottom: '1rem',
},
user: {
display: 'inline-flex',
margin: theme.spacing(1),
},
}));

/**
* Props for {@link GithubDiscussionsSearchResultListItem}.
*
* @public
*/
export interface GithubDiscussionsSearchResultListItemProps {
icon?: ReactNode;
result?: GithubDiscussionsDocument;
highlight?: ResultHighlight;
lineClamp?: number;
}

/** @public */
export function GithubDiscussionsSearchResultListItem(
props: GithubDiscussionsSearchResultListItemProps,
) {
const { result, highlight, icon } = props;
const classes = useStyles();
if (!result) return null;

return (
<div className={classes.item}>
{icon && <ListItemIcon>{icon}</ListItemIcon>}
<div className={classes.flexContainer}>
<ListItemText
className={classes.itemText}
primaryTypographyProps={{ variant: 'h6' }}
primary={
<Link noTrack to={result.location}>
{highlight?.fields.title ? (
<HighlightedSearchResultText
text={highlight.fields.title}
preTag={highlight.preTag}
postTag={highlight.postTag}
/>
) : (
result.title
)}
</Link>
}
secondary={
<Typography
component="span"
style={{
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: props.lineClamp,
overflow: 'hidden',
}}
color="textSecondary"
variant="body2"
>
{highlight?.fields.text ? (
<HighlightedSearchResultText
text={highlight.fields.text}
preTag={highlight.preTag}
postTag={highlight.postTag}
/>
) : (
result.text
)}
</Typography>
}
/>
<Box>
{result.author && (
<div className={classes.user}>
<EntityRefLink entityRef={`user:default/${result.author}`} />
</div>
)}
{result.category && <Chip label={result.category} size="small" />}
{result.labels.length > 0 &&
result.labels.map(({ name }) => {
return <Chip key={name} label={name} size="small" />;
})}
</Box>
</div>
</div>
);
}
125 changes: 71 additions & 54 deletions packages/app/src/components/search/SearchResultCustomList.tsx
Original file line number Diff line number Diff line change
@@ -1,64 +1,81 @@
import React from 'react';

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

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

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>
)
}
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
icon={<DocsIcon />}
/>
);
case 'stack-overflow':
return (
<StackOverflowSearchResultListItem
key={document.location}
result={document}
icon={<StackOverflowIcon />}
/>
);
case 'github-discussions':
return (
<GithubDiscussionsSearchResultListItem
result={document as GithubDiscussionsDocument}
highlight={highlight}
/>
);
default:
return (
<DefaultResultListItem
key={document.location}
result={document}
highlight={highlight}
rank={rank}
/>
);
}
})}
</List>
)}
</SearchResult>
);
};

export const searchResultCustomList = <SearchResultCustomList />;
export const searchResultCustomList = <SearchResultCustomList />;
25 changes: 23 additions & 2 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10628,13 +10628,20 @@
resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb"
integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==

"@types/react-dom@*", "@types/react-dom@<18.0.0", "@types/react-dom@^18", "@types/react-dom@^18.0.0":
"@types/react-dom@*", "@types/react-dom@^18.0.0":
version "18.3.1"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.1.tgz#1e4654c08a9cdcfb6594c780ac59b55aad42fe07"
integrity sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==
dependencies:
"@types/react" "*"

"@types/react-dom@<18.0.0":
version "17.0.25"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5"
integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA==
dependencies:
"@types/react" "^17"

"@types/react-redux@^7.1.20":
version "7.1.34"
resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.34.tgz#83613e1957c481521e6776beeac4fd506d11bd0e"
Expand Down Expand Up @@ -10666,14 +10673,23 @@
dependencies:
"@types/react" "*"

"@types/react@*", "@types/react@^16.13.1 || ^17.0.0", "@types/react@^16.13.1 || ^17.0.0 || ^18.0.0", "@types/react@^18":
"@types/react@*", "@types/react@^16.13.1 || ^17.0.0 || ^18.0.0":
version "18.3.12"
resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60"
integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==
dependencies:
"@types/prop-types" "*"
csstype "^3.0.2"

"@types/react@^16.13.1 || ^17.0.0", "@types/react@^17":
version "17.0.83"
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.83.tgz#b477c56387b74279281149dcf5ba2a1e2216d131"
integrity sha512-l0m4ArKJvmFtR4e8UmKrj1pB4tUgOhJITf+mADyF/p69Ts1YAR/E+G9XEM0mHXKVRa1dQNHseyyDNzeuAXfXQw==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "^0.16"
csstype "^3.0.2"

"@types/request@^2.47.1", "@types/request@^2.48.8":
version "2.48.12"
resolved "https://registry.yarnpkg.com/@types/request/-/request-2.48.12.tgz#0f590f615a10f87da18e9790ac94c29ec4c5ef30"
Expand Down Expand Up @@ -10701,6 +10717,11 @@
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a"
integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==

"@types/scheduler@^0.16":
version "0.16.8"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff"
integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==

"@types/[email protected]", "@types/semver@^7.5.0":
version "7.5.8"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e"
Expand Down

0 comments on commit ff79225

Please sign in to comment.