Merge branch '21720-material-ui-upgrade'
[arvados.git] / services / workbench2 / src / views-components / search-bar / search-bar-autocomplete-view.tsx
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import React from 'react';
6 import { CustomStyleRulesCallback } from 'common/custom-theme';
7 import { Paper, List, ListItem, ListItemText } from '@mui/material';
8 import { WithStyles } from '@mui/styles';
9 import withStyles from '@mui/styles/withStyles';
10 import { GroupContentsResource } from 'services/groups-service/groups-service';
11 import Highlighter from "react-highlight-words";
12 import { SearchBarSelectedItem } from "store/search-bar/search-bar-reducer";
13
14 type CssRules = 'searchView' | 'list' | 'listItem';
15
16 const styles: CustomStyleRulesCallback<CssRules> = theme => {
17     return {
18         searchView: {
19             borderRadius: `0 0 ${theme.spacing(0.5)} ${theme.spacing(0.5)}`
20         },
21         list: {
22             padding: 0
23         },
24         listItem: {
25             paddingLeft: theme.spacing(1),
26             paddingRight: theme.spacing(2),
27         }
28     };
29 };
30
31 export interface SearchBarAutocompleteViewDataProps {
32     searchResults: GroupContentsResource[];
33     searchValue?: string;
34     selectedItem: SearchBarSelectedItem;
35 }
36
37 export interface SearchBarAutocompleteViewActionProps {
38     navigateTo: (uuid: string) => void;
39 }
40
41 type SearchBarAutocompleteViewProps = SearchBarAutocompleteViewDataProps & SearchBarAutocompleteViewActionProps & WithStyles<CssRules>;
42
43 export const SearchBarAutocompleteView = withStyles(styles)(
44     ({ classes, searchResults, searchValue, navigateTo, selectedItem }: SearchBarAutocompleteViewProps) => {
45         return <Paper className={classes.searchView}>
46             <List component="nav" className={classes.list}>
47                 <ListItem button className={classes.listItem} selected={!selectedItem || searchValue === selectedItem.id}>
48                     <ListItemText secondary={searchValue}/>
49                 </ListItem>
50                 {searchResults.map((item: GroupContentsResource) =>
51                     <ListItem button key={item.uuid} className={classes.listItem} selected={item.uuid === selectedItem.id}>
52                         <ListItemText secondary={getFormattedText(item.name, searchValue)}
53                                       onClick={() => navigateTo(item.uuid)}/>
54                     </ListItem>
55                 )}
56             </List>
57         </Paper>;
58     });
59
60 const getFormattedText = (textToHighlight: string, searchString = '') => {
61     return <Highlighter searchWords={[searchString]} autoEscape={true} textToHighlight={textToHighlight} />;
62 };