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 ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
18 import { ArvadosTheme } from '~/common/custom-theme';
19 import { SearchView } from '~/store/search-bar/search-bar-reducer';
22 SearchBarBasicViewDataProps,
23 SearchBarBasicViewActionProps
24 } from '~/views-components/search-bar/search-bar-basic-view';
26 SearchBarAutocompleteView,
27 SearchBarAutocompleteViewDataProps,
28 SearchBarAutocompleteViewActionProps
29 } from '~/views-components/search-bar/search-bar-autocomplete-view';
31 SearchBarAdvancedView,
32 SearchBarAdvancedViewDataProps,
33 SearchBarAdvancedViewActionProps
34 } from '~/views-components/search-bar/search-bar-advanced-view';
35 import { KEY_CODE_DOWN, KEY_CODE_ESC, KEY_CODE_UP, KEY_ENTER } from "~/common/codes";
37 type CssRules = 'container' | 'containerSearchViewOpened' | 'input' | 'view';
39 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => {
44 borderRadius: theme.spacing.unit / 2
46 containerSearchViewOpened: {
49 borderRadius: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 2}px 0 0`
63 export type SearchBarDataProps = SearchBarViewDataProps
64 & SearchBarAutocompleteViewDataProps
65 & SearchBarAdvancedViewDataProps
66 & SearchBarBasicViewDataProps;
68 interface SearchBarViewDataProps {
71 isPopoverOpen: boolean;
75 export type SearchBarActionProps = SearchBarViewActionProps
76 & SearchBarAutocompleteViewActionProps
77 & SearchBarAdvancedViewActionProps
78 & SearchBarBasicViewActionProps;
80 interface SearchBarViewActionProps {
81 onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
82 onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
83 onSetView: (currentView: string) => void;
84 closeView: () => void;
85 openSearchView: () => void;
86 loadRecentQueries: () => string[];
91 type SearchBarViewProps = SearchBarDataProps & SearchBarActionProps & WithStyles<CssRules>;
93 const handleKeyDown = (e: React.KeyboardEvent, props: SearchBarViewProps) => {
94 if (e.keyCode === KEY_CODE_DOWN) {
96 if (!props.isPopoverOpen) {
97 props.openSearchView();
101 } else if (e.keyCode === KEY_CODE_UP) {
104 } else if (e.keyCode === KEY_CODE_ESC) {
107 } else if (e.keyCode === KEY_ENTER) {
108 if (props.currentView === SearchView.BASIC) {
110 props.onSearch(props.selectedItem.query);
111 } else if (props.currentView === SearchView.AUTOCOMPLETE) {
112 if (props.selectedItem.id !== props.searchValue) {
114 props.navigateTo(props.selectedItem.id);
120 export const SearchBarView = withStyles(styles)(
121 (props : SearchBarViewProps) => {
122 const { classes, isPopoverOpen } = props;
124 <ClickAwayListener onClickAway={props.closeView}>
125 <Paper className={isPopoverOpen ? classes.containerSearchViewOpened : classes.container} >
126 <form onSubmit={props.onSubmit}>
128 className={classes.input}
129 onChange={props.onChange}
131 value={props.searchValue}
133 disableUnderline={true}
134 onClick={props.openSearchView}
135 onKeyDown={e => handleKeyDown(e, props)}
137 <InputAdornment position="start">
138 <Tooltip title='Search'>
139 <IconButton type="submit">
146 <InputAdornment position="end">
147 <Tooltip title='Advanced search'>
148 <IconButton onClick={() => props.onSetView(SearchView.ADVANCED)}>
149 <ArrowDropDownIcon />
155 <div className={classes.view}>
156 {isPopoverOpen && getView({...props})}
164 const getView = (props: SearchBarViewProps) => {
165 switch (props.currentView) {
166 case SearchView.AUTOCOMPLETE:
167 return <SearchBarAutocompleteView
168 navigateTo={props.navigateTo}
169 searchResults={props.searchResults}
170 searchValue={props.searchValue}
171 selectedItem={props.selectedItem} />;
172 case SearchView.ADVANCED:
173 return <SearchBarAdvancedView
174 closeAdvanceView={props.closeAdvanceView}
175 tags={props.tags} />;
177 return <SearchBarBasicView
178 onSetView={props.onSetView}
179 onSearch={props.onSearch}
180 loadRecentQueries={props.loadRecentQueries}
181 savedQueries={props.savedQueries}
182 deleteSavedQuery={props.deleteSavedQuery}
183 editSavedQuery={props.editSavedQuery}
184 selectedItem={props.selectedItem} />;