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) {
105 } else if (e.keyCode === KEY_ENTER) {
106 if (props.currentView === SearchView.BASIC) {
108 props.onSearch(props.selectedItem.query);
109 } else if (props.currentView === SearchView.AUTOCOMPLETE) {
110 if (props.selectedItem.id !== props.searchValue) {
112 props.navigateTo(props.selectedItem.id);
118 export const SearchBarView = withStyles(styles)(
119 (props : SearchBarViewProps) => {
120 const { classes, isPopoverOpen } = props;
122 <ClickAwayListener onClickAway={props.closeView}>
123 <Paper className={isPopoverOpen ? classes.containerSearchViewOpened : classes.container} >
124 <form onSubmit={props.onSubmit}>
126 className={classes.input}
127 onChange={props.onChange}
129 value={props.searchValue}
131 disableUnderline={true}
132 onClick={props.openSearchView}
133 onKeyDown={e => handleKeyDown(e, props)}
135 <InputAdornment position="end">
136 <Tooltip title='Search'>
137 <IconButton type="submit">
144 <div className={classes.view}>
145 {isPopoverOpen && getView({...props})}
153 const getView = (props: SearchBarViewProps) => {
154 switch (props.currentView) {
155 case SearchView.AUTOCOMPLETE:
156 return <SearchBarAutocompleteView
157 navigateTo={props.navigateTo}
158 searchResults={props.searchResults}
159 searchValue={props.searchValue}
160 selectedItem={props.selectedItem} />;
161 case SearchView.ADVANCED:
162 return <SearchBarAdvancedView
163 closeAdvanceView={props.closeAdvanceView}
164 tags={props.tags} />;
166 return <SearchBarBasicView
167 onSetView={props.onSetView}
168 onSearch={props.onSearch}
169 loadRecentQueries={props.loadRecentQueries}
170 savedQueries={props.savedQueries}
171 deleteSavedQuery={props.deleteSavedQuery}
172 editSavedQuery={props.editSavedQuery}
173 selectedItem={props.selectedItem} />;