Skip to content

Commit

Permalink
Use a unified text input for searching purpose
Browse files Browse the repository at this point in the history
  • Loading branch information
bipuladh committed May 4, 2020
1 parent 6ae5639 commit 3b5226e
Show file tree
Hide file tree
Showing 15 changed files with 57 additions and 91 deletions.
5 changes: 3 additions & 2 deletions frontend/__tests__/components/factory/list-page.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as React from 'react';
import { shallow, ShallowWrapper } from 'enzyme';
import { TextInput } from '@patternfly/react-core';
import {
TextFilter,
ListPageWrapper_,
Expand All @@ -22,11 +23,11 @@ describe(TextFilter.displayName, () => {
});

it('renders text input', () => {
const input: ShallowWrapper<React.InputHTMLAttributes<any>> = wrapper.find('input');
const input: ShallowWrapper<any> = wrapper.find(TextInput);

expect(input.props().type).toEqual('text');
expect(input.props().placeholder).toEqual(`Filter ${label}...`);
expect(input.props().onChange).toEqual(onChange);
expect(input.props().onChange()).toEqual(((e) => onChange(e))());
expect(input.props().defaultValue).toEqual(defaultValue);
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ export enum KeyEventModes {
FOCUS = 'FOCUS',
}

export const useDocumentListener = <T extends HTMLElement>(keyEventMap: KeyEventMap) => {
const textInputKeyHandler = {
Escape: KeyEventModes.HIDE,
'/': KeyEventModes.FOCUS,
};

export const useDocumentListener = <T extends HTMLElement>(
keyEventMap: KeyEventMap = textInputKeyHandler,
) => {
const [visible, setVisible] = React.useState(true);
const ref = React.useRef<T>(null);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const CustomResourceList: React.FC<CustomResourceListProps> = ({
{textFilterReducer && (
<div className="co-m-pane__filter-bar">
<div className="co-m-pane__filter-bar-group co-m-pane__filter-bar-group--filter">
<TextFilter label="by name" onChange={(e) => applyTextFilter(e.target.value)} />
<TextFilter label="by name" onChange={applyTextFilter} />
</div>
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ const TopologyFilterBar: React.FC<TopologyFilterBarProps> = ({
placeholder="Find by name..."
value={searchQuery}
autoFocus
onChange={(e) => onSearchQueryChange(e.target.value)}
onChange={onSearchQueryChange}
/>
</ToolbarItem>
<ToolbarItem>
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/components/RBAC/role.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class Details extends React.Component {
constructor(props) {
super(props);
this.state = {};
this.changeFilter = (e) => this.setState({ ruleFilter: e.target.value });
this.changeFilter = (e) => this.setState({ ruleFilter: e });
}

render() {
Expand Down
4 changes: 1 addition & 3 deletions frontend/public/components/api-explorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -536,8 +536,6 @@ const APIResourceAccessReview: React.FC<APIResourceTabProps> = ({
const sortedData = _.orderBy(filteredData, ['type', 'name'], ['asc', 'asc']);

// event handlers
const onFilterChange: React.ReactEventHandler<HTMLInputElement> = (e) =>
setFilter(e.currentTarget.value);
const toggleShowUsers = (e: React.MouseEvent<HTMLAnchorElement>) => {
e.preventDefault();
setShowUsers(!showUsers);
Expand Down Expand Up @@ -569,7 +567,7 @@ const APIResourceAccessReview: React.FC<APIResourceTabProps> = ({
/>
</div>
<div className="co-m-pane__filter-bar-group co-m-pane__filter-bar-group--filter">
<TextFilter defaultValue={filter} label="by subject" onChange={onFilterChange} />
<TextFilter defaultValue={filter} label="by subject" onChange={setFilter} />
</div>
</div>
<div className="co-m-pane__body">
Expand Down
14 changes: 2 additions & 12 deletions frontend/public/components/autocomplete.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import * as React from 'react';
import * as classNames from 'classnames';
import { TextInput } from '@patternfly/react-core';
import { useDocumentListener, getLabelsAsString } from '@console/shared';
import { KeyEventModes } from '@console/shared/src/hooks';
import { fuzzyCaseInsensitive } from './factory/table-filters';
import { K8sResourceCommon } from '../module/k8s';
import { TextFilter } from './factory';

const MAX_SUGGESTIONS = 5;

Expand All @@ -19,15 +19,9 @@ const suggestionBoxKeyHandler = {
Escape: KeyEventModes.HIDE,
};

const textInputKeyHandler = {
Escape: KeyEventModes.HIDE,
'/': KeyEventModes.FOCUS,
};

const AutocompleteInput: React.FC<AutocompleteInputProps> = (props) => {
const [suggestions, setSuggestions] = React.useState<string[]>();
const { visible, setVisible, ref } = useDocumentListener<HTMLDivElement>(suggestionBoxKeyHandler);
const { ref: textInputRef } = useDocumentListener<HTMLInputElement>(textInputKeyHandler);
const {
textValue,
setTextValue,
Expand Down Expand Up @@ -73,18 +67,14 @@ const AutocompleteInput: React.FC<AutocompleteInputProps> = (props) => {
return (
<div className="co-suggestion-box" ref={ref}>
<div className="has-feedback">
<TextInput
<TextFilter
data-test-id="list-page-search-input"
aria-label="Enter Query"
value={textValue}
onChange={handleInput}
placeholder={placeholder}
onFocus={activate}
ref={textInputRef}
/>
<span className="form-control-feedback form-control-feedback--keyboard-hint">
<kbd>/</kbd>
</span>
</div>
{showSuggestions && (
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class GlobalConfigPage_ extends React.Component<GlobalConfigPageProps, GlobalCon
<TextFilter
value={textFilter}
label="by name or description"
onChange={(e) => this.setState({ textFilter: e.target.value })}
onChange={(e) => this.setState({ textFilter: e })}
/>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/components/events.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ export class EventsList extends React.Component {
<TextFilter
autoFocus={autoFocus}
label="Events by name or message"
onChange={(e) => this.setState({ textFilter: e.target.value || '' })}
onChange={(e) => this.setState({ textFilter: e || '' })}
/>
</div>
<div className="form-group">
Expand Down
74 changes: 25 additions & 49 deletions frontend/public/components/factory/list-page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import * as PropTypes from 'prop-types';
import * as React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { Button } from '@patternfly/react-core';
import { Button, TextInput } from '@patternfly/react-core';

import { withFallback } from '@console/shared/src/components/error/error-boundary';
import { KEYBOARD_SHORTCUTS } from '@console/shared';
import { useDocumentListener } from '@console/shared';
import { filterList } from '../../actions/k8s';
import { storagePrefix } from '../row-filter';
import { ErrorPage404, ErrorBoundaryFallback } from '../error';
Expand All @@ -25,66 +25,42 @@ import {
} from '../utils';
import { FilterToolbar } from '../filter-toolbar';

/** @type {React.SFC<{disabled?: boolean, label?: string, onChange: React.ChangeEventHandler<any>, defaultValue?: string, value?: string, placeholder?: string, autoFocus?: boolean,}}>} */
export const TextFilter = ({
label,
onChange,
defaultValue,
style,
className,
value,
placeholder = `Filter ${label}...`,
autoFocus = false,
}) => {
const input = React.useRef();
const onKeyDown = (e) => {
const { nodeName } = e.target;
if (
nodeName === 'INPUT' ||
nodeName === 'TEXTAREA' ||
e.key !== KEYBOARD_SHORTCUTS.focusFilterInput
) {
return;
}

e.stopPropagation();
e.preventDefault();
input.current.focus();
};

React.useEffect(() => {
window.addEventListener('keydown', onKeyDown);
// Remove event listeners on cleanup
return () => {
window.removeEventListener('keydown', onKeyDown);
};
}, []);
/** @type {React.SFC<{disabled?: boolean, label?: string, onChange: (value: string) => void;, defaultValue?: string, value?: string, placeholder?: string, autoFocus?: boolean, onFocus?:any, name?:string, id?: string, onKeyDown?: any, parentClassName?: string }}>} */
export const TextFilter = (props) => {
const {
label,
defaultValue,
className,
value,
placeholder = `Filter ${label}...`,
autoFocus = false,
onChange,
parentClassName,
} = props;
const { ref } = useDocumentListener();

return (
<div className="has-feedback">
<input
ref={input}
autoCapitalize="none"
className={classNames('pf-c-form-control co-text-filter', className)}
<div className={classNames('has-feedback', parentClassName)}>
<TextInput
{...props}
className={classNames('co-text-filter', className)}
data-test-id="item-filter"
value={value}
defaultValue={defaultValue}
onChange={onChange}
onKeyDown={(e) => e.key === 'Escape' && e.target.blur()}
aria-label={placeholder}
placeholder={placeholder}
style={style}
onChange={(val) => onChange(val)}
ref={ref}
autoFocus={autoFocus}
defaultValue={defaultValue}
tabIndex={0}
value={value}
type="text"
autoFocus={autoFocus}
aria-label={placeholder}
/>
<span className="form-control-feedback form-control-feedback--keyboard-hint">
<kbd>/</kbd>
</span>
</div>
);
};

TextFilter.displayName = 'TextFilter';

// TODO (jon) make this into "withListPageFilters" HOC
Expand Down
2 changes: 1 addition & 1 deletion frontend/public/components/monitoring.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ const MonitoringListPage = connect(filtersToProps)(
}

applyTextFilter(e) {
const v = e.target.value;
const v = e;
const { nameFilterID, reduxID } = this.props;
store.dispatch(k8sActions.filterList(reduxID, nameFilterID, v));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -374,11 +374,7 @@ const Receivers = () => {
</Link>
</div>
<div className="co-m-pane__filter-bar-group co-m-pane__filter-bar-group--filter">
<TextFilter
defaultValue=""
label="Receivers by Name"
onChange={(e) => setReceiverFilter(e.target.value)}
/>
<TextFilter defaultValue="" label="Receivers by Name" onChange={setReceiverFilter} />
</div>
</div>
{numOfIncompleteReceivers > 0 && (
Expand Down
6 changes: 1 addition & 5 deletions frontend/public/components/overview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,7 @@ class OverviewHeading_ extends React.Component<OverviewHeadingProps> {
/>
</div>
<div className="co-m-pane__filter-bar-group co-m-pane__filter-bar-group--filter">
<TextFilter
defaultValue={filterValue}
label="by name"
onChange={(e) => changeFilter(e.target.value)}
/>
<TextFilter defaultValue={filterValue} label="by name" onChange={changeFilter} />
</div>
</div>
);
Expand Down
6 changes: 4 additions & 2 deletions frontend/public/components/search-filter-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { Dropdown, DropdownToggle, DropdownItem, TextInput } from '@patternfly/react-core';
import { Dropdown, DropdownToggle, DropdownItem } from '@patternfly/react-core';
import { CaretDownIcon, FilterIcon } from '@patternfly/react-icons';
import { TextFilter } from './factory';

export enum searchFilterValues {
Label = 'Label',
Expand Down Expand Up @@ -51,7 +52,8 @@ export const SearchFilterDropdown: React.SFC<SearchFilterDropdownProps> = (props
isOpen={isOpen}
dropdownItems={dropdownItems}
/>
<TextInput
<TextFilter
parentClassName="has-feedback--full-width"
onChange={handleInputValue}
placeholder={selected === searchFilterValues.Label ? 'app=frontend' : 'my-resource'}
name="search-filter-input"
Expand Down
12 changes: 6 additions & 6 deletions frontend/public/style/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,8 @@
}
}

.co-suggestion-box input:focus,
.co-text-filter:focus {
+ .form-control-feedback--keyboard-hint {
display: none;
}
.co-text-filter:focus + .form-control-feedback--keyboard-hint {
display: none;
}

.co-text-filter {
Expand All @@ -72,6 +69,10 @@
padding-right: 25px;
}

.has-feedback--full-width {
width: 100%;
}

.pf-c-form__actions--right {
justify-content: flex-end;
}
Expand All @@ -84,4 +85,3 @@
.pf-c-form__group--no-top-margin {
margin-top: 0 !important;
}

0 comments on commit 3b5226e

Please sign in to comment.