X-Git-Url: https://git.arvados.org/arvados-workbench2.git/blobdiff_plain/fe5d65e4e704358fab18d91dae5a97ff7659f5df..7776b799eed223b9318443c1e319e01957a8fb45:/src/views-components/search-bar/search-bar-view.tsx diff --git a/src/views-components/search-bar/search-bar-view.tsx b/src/views-components/search-bar/search-bar-view.tsx index 8d767b2b..20536fd7 100644 --- a/src/views-components/search-bar/search-bar-view.tsx +++ b/src/views-components/search-bar/search-bar-view.tsx @@ -3,6 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import * as React from 'react'; +import { compose } from 'redux'; import { IconButton, Paper, @@ -11,7 +12,6 @@ import { WithStyles, Tooltip, InputAdornment, Input, - Popover, } from '@material-ui/core'; import SearchIcon from '@material-ui/icons/Search'; import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown'; @@ -33,6 +33,9 @@ import { SearchBarAdvancedViewActionProps } from '~/views-components/search-bar/search-bar-advanced-view'; import { KEY_CODE_DOWN, KEY_CODE_ESC, KEY_CODE_UP, KEY_ENTER } from "~/common/codes"; +import { debounce } from 'debounce'; +import { Vocabulary } from '~/models/vocabulary'; +import { connectVocabulary } from '../resource-properties-form/property-field-common'; type CssRules = 'container' | 'containerSearchViewOpened' | 'input' | 'view'; @@ -41,12 +44,14 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => { container: { position: 'relative', width: '100%', - borderRadius: theme.spacing.unit / 2 + borderRadius: theme.spacing.unit / 2, + zIndex: theme.zIndex.modal, }, containerSearchViewOpened: { position: 'relative', width: '100%', - borderRadius: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 2}px 0 0` + borderRadius: `${theme.spacing.unit / 2}px ${theme.spacing.unit / 2}px 0 0`, + zIndex: theme.zIndex.modal, }, input: { border: 'none', @@ -70,6 +75,7 @@ interface SearchBarViewDataProps { currentView: string; isPopoverOpen: boolean; debounce?: number; + vocabulary?: Vocabulary; } export type SearchBarActionProps = SearchBarViewActionProps @@ -86,7 +92,7 @@ interface SearchBarViewActionProps { loadRecentQueries: () => string[]; moveUp: () => void; moveDown: () => void; - setAdvancedDataFromSearchValue: (search: string) => void; + setAdvancedDataFromSearchValue: (search: string, vocabulary?: Vocabulary) => void; } type SearchBarViewProps = SearchBarDataProps & SearchBarActionProps & WithStyles; @@ -130,112 +136,83 @@ const handleInputClick = (e: React.MouseEvent, props: SearchBarViewProps) => { const handleDropdownClick = (e: React.MouseEvent, props: SearchBarViewProps) => { e.stopPropagation(); - if (props.isPopoverOpen) { - if (props.currentView === SearchView.ADVANCED) { - props.closeView(); - } else { - props.setAdvancedDataFromSearchValue(props.searchValue); - props.onSetView(SearchView.ADVANCED); - } + if (props.isPopoverOpen && props.currentView === SearchView.ADVANCED) { + props.closeView(); } else { - props.setAdvancedDataFromSearchValue(props.searchValue); + props.setAdvancedDataFromSearchValue(props.searchValue, props.vocabulary); props.onSetView(SearchView.ADVANCED); } }; -export const SearchBarView = withStyles(styles)( - class SearchBarView extends React.Component { +export const SearchBarView = compose(connectVocabulary, withStyles(styles))( + class extends React.Component { - viewAnchorRef = React.createRef(); + debouncedSearch = debounce(() => { + this.props.onSearch(this.props.searchValue); + }, 1000); - render() { - const { children, ...props } = this.props; - const { classes } = props; - return ( - -
-
- - -
- -
- - - {getView({ ...props })} -
-
- ); + handleChange = (event: React.ChangeEvent) => { + this.debouncedSearch(); + this.props.onChange(event); } - getViewWidth() { - const { current } = this.viewAnchorRef; - return current ? current.offsetWidth : 0; + handleSubmit = (event: React.FormEvent) => { + this.debouncedSearch.clear(); + this.props.onSubmit(event); } - } -); - -const SearchInput = (props: SearchBarViewProps & { disableClickHandler?: boolean; autoFocus?: boolean }) => { - const { classes } = props; - return !props.disableClickHandler && handleInputClick(e, props)} - onKeyDown={e => handleKeyDown(e, props)} - startAdornment={ - - - - - - - + componentWillUnmount() { + this.debouncedSearch.clear(); } - endAdornment={ - - - handleDropdownClick(e, props)}> - - - - - } />; -}; -const SearchViewContainer = (props: SearchBarViewProps & { width: number, anchorEl: HTMLElement | null, children: React.ReactNode }) => - - { - props.children + render() { + const { children, ...props } = this.props; + const { classes, isPopoverOpen } = this.props; + return ( + <> + + {isPopoverOpen && + } + + +
+ handleInputClick(e, props)} + onKeyDown={e => handleKeyDown(e, props)} + startAdornment={ + + + + + + + + } + endAdornment={ + + + handleDropdownClick(e, props)}> + + + + + } /> +
+
+ {isPopoverOpen && getView({ ...props })} +
+
+ + ); } -
; - + }); const getView = (props: SearchBarViewProps) => { switch (props.currentView) { @@ -261,3 +238,16 @@ const getView = (props: SearchBarViewProps) => { selectedItem={props.selectedItem} />; } }; + +const Backdrop = withStyles<'backdrop'>(theme => ({ + backdrop: { + position: 'fixed', + top: 0, + right: 0, + bottom: 0, + left: 0, + zIndex: theme.zIndex.modal + } +}))( + ({ classes, ...props }: WithStyles<'backdrop'> & React.HTMLProps) => +
);