1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import * as React from 'react';
13 InputAdornment, Input,
15 } from '@material-ui/core';
16 import SearchIcon from '@material-ui/icons/Search';
17 import { ArvadosTheme } from '~/common/custom-theme';
18 import { SearchView } from '~/store/search-bar/search-bar-reducer';
21 SearchBarBasicViewDataProps,
22 SearchBarBasicViewActionProps
23 } from '~/views-components/search-bar/search-bar-basic-view';
25 SearchBarAutocompleteView,
26 SearchBarAutocompleteViewDataProps,
27 SearchBarAutocompleteViewActionProps
28 } from '~/views-components/search-bar/search-bar-autocomplete-view';
30 SearchBarAdvancedView,
31 SearchBarAdvancedViewDataProps,
32 SearchBarAdvancedViewActionProps
33 } from '~/views-components/search-bar/search-bar-advanced-view';
34 import { KEY_CODE_DOWN, KEY_CODE_ESC, KEY_CODE_UP, KEY_ENTER } from "~/common/codes";
36 type CssRules = 'container' | 'containerSearchViewOpened' | 'input' | 'view';
38 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => {
43 borderRadius: theme.spacing.unit / 2
45 containerSearchViewOpened: {
48 borderRadius: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 2}px 0 0`
52 padding: `0px ${theme.spacing.unit}px`
62 export type SearchBarDataProps = SearchBarViewDataProps
63 & SearchBarAutocompleteViewDataProps
64 & SearchBarAdvancedViewDataProps
65 & SearchBarBasicViewDataProps;
67 interface SearchBarViewDataProps {
70 isPopoverOpen: boolean;
74 export type SearchBarActionProps = SearchBarViewActionProps
75 & SearchBarAutocompleteViewActionProps
76 & SearchBarAdvancedViewActionProps
77 & SearchBarBasicViewActionProps;
79 interface SearchBarViewActionProps {
80 onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
81 onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
82 onSetView: (currentView: string) => void;
83 closeView: () => void;
84 openSearchView: () => void;
85 loadRecentQueries: () => string[];
90 type SearchBarViewProps = SearchBarDataProps & SearchBarActionProps & WithStyles<CssRules>;
92 const handleKeyDown = (e: React.KeyboardEvent, props: SearchBarViewProps) => {
93 if (e.keyCode === KEY_CODE_DOWN) {
95 if (!props.isPopoverOpen) {
96 props.openSearchView();
100 } else if (e.keyCode === KEY_CODE_UP) {
103 } else if (e.keyCode === KEY_CODE_ESC) {
106 } else if (e.keyCode === KEY_ENTER) {
107 if (props.currentView === SearchView.BASIC) {
109 props.onSearch(props.selectedItem.query);
110 } else if (props.currentView === SearchView.AUTOCOMPLETE) {
111 if (props.selectedItem.id !== props.searchValue) {
113 props.navigateTo(props.selectedItem.id);
119 export const SearchBarView = withStyles(styles)(
120 (props : SearchBarViewProps) => {
121 const { classes, isPopoverOpen } = props;
123 <ClickAwayListener onClickAway={props.closeView}>
124 <Paper className={isPopoverOpen ? classes.containerSearchViewOpened : classes.container} >
125 <form onSubmit={props.onSubmit}>
127 className={classes.input}
128 onChange={props.onChange}
130 value={props.searchValue}
132 disableUnderline={true}
133 onClick={props.openSearchView}
134 onKeyDown={e => handleKeyDown(e, props)}
136 <InputAdornment position="end">
137 <Tooltip title='Search'>
138 <IconButton type="submit">
145 <div className={classes.view}>
146 {isPopoverOpen && getView({...props})}
154 const getView = (props: SearchBarViewProps) => {
155 switch (props.currentView) {
156 case SearchView.AUTOCOMPLETE:
157 return <SearchBarAutocompleteView
158 navigateTo={props.navigateTo}
159 searchResults={props.searchResults}
160 searchValue={props.searchValue}
161 selectedItem={props.selectedItem} />;
162 case SearchView.ADVANCED:
163 return <SearchBarAdvancedView
164 closeAdvanceView={props.closeAdvanceView}
165 tags={props.tags} />;
167 return <SearchBarBasicView
168 onSetView={props.onSetView}
169 onSearch={props.onSearch}
170 loadRecentQueries={props.loadRecentQueries}
171 savedQueries={props.savedQueries}
172 deleteSavedQuery={props.deleteSavedQuery}
173 editSavedQuery={props.editSavedQuery}
174 selectedItem={props.selectedItem} />;