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';
35 type CssRules = 'container' | 'containerSearchViewOpened' | 'input' | 'view';
37 const styles: StyleRulesCallback<CssRules> = (theme: ArvadosTheme) => {
42 borderRadius: theme.spacing.unit / 2
44 containerSearchViewOpened: {
47 borderRadius: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 2}px 0 0`
51 padding: `0px ${theme.spacing.unit}px`
61 export type SearchBarDataProps = SearchBarViewDataProps
62 & SearchBarAutocompleteViewDataProps
63 & SearchBarAdvancedViewDataProps
64 & SearchBarBasicViewDataProps;
66 interface SearchBarViewDataProps {
68 isPopoverOpen: boolean;
72 export type SearchBarActionProps = SearchBarViewActionProps
73 & SearchBarAutocompleteViewActionProps
74 & SearchBarAdvancedViewActionProps
75 & SearchBarBasicViewActionProps;
77 interface SearchBarViewActionProps {
78 onSearch: (value: string) => any;
79 searchDataOnEnter: (value: string) => void;
80 onSetView: (currentView: string) => void;
81 closeView: () => void;
82 openSearchView: () => void;
83 saveRecentQuery: (query: string) => void;
84 loadRecentQueries: () => string[];
87 type SearchBarViewProps = SearchBarDataProps & SearchBarActionProps & WithStyles<CssRules>;
89 interface SearchBarState {
93 export const DEFAULT_SEARCH_DEBOUNCE = 1000;
95 export const SearchBarView = withStyles(styles)(
96 class extends React.Component<SearchBarViewProps> {
97 state: SearchBarState = {
104 const { classes, currentView, openSearchView, closeView, isPopoverOpen } = this.props;
105 return <ClickAwayListener onClickAway={closeView}>
106 <Paper className={isPopoverOpen ? classes.containerSearchViewOpened : classes.container} >
107 <form onSubmit={this.handleSubmit}>
109 className={classes.input}
110 onChange={this.handleChange}
112 value={this.state.value}
114 disableUnderline={true}
115 onClick={openSearchView}
117 <InputAdornment position="end">
118 <Tooltip title='Search'>
126 <div className={classes.view}>
127 {isPopoverOpen && this.getView(currentView)}
130 </ClickAwayListener>;
133 componentDidMount() {
134 this.setState({ value: this.props.searchValue });
137 componentWillReceiveProps(nextProps: SearchBarViewProps) {
138 if (nextProps.searchValue !== this.props.searchValue) {
139 this.setState({ value: nextProps.searchValue });
143 componentWillUnmount() {
144 clearTimeout(this.timeout);
147 getView = (currentView: string) => {
148 const { onSetView, loadRecentQueries, savedQueries, deleteSavedQuery, searchValue,
149 searchResults, saveQuery, onSearch, navigateTo, editSavedQuery, tags } = this.props;
150 switch (currentView) {
151 case SearchView.AUTOCOMPLETE:
152 return <SearchBarAutocompleteView
153 navigateTo={navigateTo}
154 searchResults={searchResults}
155 searchValue={searchValue} />;
156 case SearchView.ADVANCED:
157 return <SearchBarAdvancedView
158 onSetView={onSetView}
159 saveQuery={saveQuery}
162 return <SearchBarBasicView
163 onSetView={onSetView}
165 loadRecentQueries={loadRecentQueries}
166 savedQueries={savedQueries}
167 deleteSavedQuery={deleteSavedQuery}
168 editSavedQuery={editSavedQuery} />;
172 handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
173 event.preventDefault();
174 clearTimeout(this.timeout);
175 this.props.saveRecentQuery(this.state.value);
176 this.props.searchDataOnEnter(this.state.value);
177 this.props.loadRecentQueries();
180 // ToDo: nie pokazywac autocomplete jezeli jestesmy w advance
181 // currentView ze state.searchBar.currentView
182 handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
183 clearTimeout(this.timeout);
184 this.setState({ value: event.target.value });
185 this.timeout = window.setTimeout(
186 () => this.props.onSearch(this.state.value),
187 this.props.debounce || DEFAULT_SEARCH_DEBOUNCE
189 if (event.target.value.length > 0) {
190 this.props.onSetView(SearchView.AUTOCOMPLETE);
192 this.props.onSetView(SearchView.BASIC);