import type { Component, More, Results } from './utils';
import RecentHistory from '../../components/RecentHistory';
import DeferredSpinner from '../../../components/common/DeferredSpinner';
+import ClockIcon from '../../../components/common/ClockIcon';
import { getSuggestions } from '../../../api/components';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { scrollToElement } from '../../../helpers/scrolling';
};
search = (query: string) => {
- this.setState({ loading: true });
- const recentlyBrowsed = RecentHistory.get().map(component => component.key);
- getSuggestions(query, recentlyBrowsed).then(response => {
- // compare `this.state.query` and `query` to handle two request done almost at the same time
- // in this case only the request that matches the current query should be taken
- if (this.mounted && this.state.query === query) {
- const results = {};
- const more = {};
- response.results.forEach(group => {
- results[group.q] = group.items.map(item => ({ ...item, qualifier: group.q }));
- more[group.q] = group.more;
- });
- const list = this.getPlainComponentsList(results, more);
- this.setState(state => ({
- loading: false,
- more,
- organizations: { ...state.organizations, ...keyBy(response.organizations, 'key') },
- projects: { ...state.projects, ...keyBy(response.projects, 'key') },
- results,
- selected: list.length > 0 ? list[0] : null,
- shortQuery: response.warning === 'short_input'
- }));
- }
- });
+ if (query.length === 0 || query.length >= 2) {
+ this.setState({ loading: true });
+ const recentlyBrowsed = RecentHistory.get().map(component => component.key);
+ getSuggestions(query, recentlyBrowsed).then(response => {
+ // compare `this.state.query` and `query` to handle two request done almost at the same time
+ // in this case only the request that matches the current query should be taken
+ if (this.mounted && this.state.query === query) {
+ const results = {};
+ const more = {};
+ response.results.forEach(group => {
+ results[group.q] = group.items.map(item => ({ ...item, qualifier: group.q }));
+ more[group.q] = group.more;
+ });
+ const list = this.getPlainComponentsList(results, more);
+ this.setState(state => ({
+ loading: false,
+ more,
+ organizations: { ...state.organizations, ...keyBy(response.organizations, 'key') },
+ projects: { ...state.projects, ...keyBy(response.projects, 'key') },
+ results,
+ selected: list.length > 0 ? list[0] : null,
+ shortQuery: response.warning === 'short_input'
+ }));
+ }
+ });
+ } else {
+ this.setState({ loading: false });
+ }
};
searchMore = (qualifier: string) => {
handleQueryChange = (event: { currentTarget: HTMLInputElement }) => {
const query = event.currentTarget.value;
this.setState({ query, shortQuery: query.length === 1 });
- if (query.length === 0 || query.length >= 2) {
- this.search(query);
- }
+ this.search(query);
};
selectPrevious = () => {
results={this.state.results}
selected={this.state.selected}
/>
- <div
- className="navbar-search-shortcut-hint"
- dangerouslySetInnerHTML={{
- __html: translateWithParameters(
- 'search.shortcut_hint',
- '<span class="shortcut-button shortcut-button-small">s</span>'
- )
- }}
- />
+ <div className="navbar-search-shortcut-hint">
+ <div className="pull-right">
+ <ClockIcon className="little-spacer-right" size={12} />
+ {translate('recently_browsed')}
+ </div>
+ <div
+ dangerouslySetInnerHTML={{
+ __html: translateWithParameters(
+ 'search.shortcut_hint',
+ '<span class="shortcut-button shortcut-button-small">s</span>'
+ )
+ }}
+ />
+ </div>
</div>}
</li>
);
selected: boolean
|};
+type State = {
+ tooltipVisible: boolean
+};
+
+const TOOLTIP_DELAY = 1000;
+
export default class SearchResult extends React.PureComponent {
+ interval: ?number;
props: Props;
+ state: State = { tooltipVisible: false };
+
+ componentDidMount() {
+ if (this.props.selected) {
+ this.scheduleTooltip();
+ }
+ }
+
+ componentWillReceiveProps(nextProps: Props) {
+ if (!this.props.selected && nextProps.selected) {
+ this.scheduleTooltip();
+ } else if (this.props.selected && !nextProps.selected) {
+ this.unscheduleTooltip();
+ this.setState({ tooltipVisible: false });
+ }
+ }
+
+ componentWillUnmount() {
+ this.unscheduleTooltip();
+ }
+
+ scheduleTooltip = () => {
+ this.interval = setTimeout(() => this.setState({ tooltipVisible: true }), TOOLTIP_DELAY);
+ };
+
+ unscheduleTooltip = () => {
+ if (this.interval) {
+ clearInterval(this.interval);
+ }
+ };
handleMouseEnter = () => {
this.props.onSelect(this.props.component.key);
className={this.props.selected ? 'active' : undefined}
key={component.key}
ref={node => this.props.innerRef(component.key, node)}>
- <Tooltip mouseEnterDelay={1.0} overlay={component.key} placement="left">
+ <Tooltip
+ mouseEnterDelay={TOOLTIP_DELAY / 1000}
+ overlay={component.key}
+ placement="left"
+ visible={this.state.tooltipVisible}>
<Link
className="navbar-search-item-link"
data-key={component.key}
postcss "^5.0.4"
uniqs "^2.0.0"
-postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.6, postcss@^5.0.8, postcss@^5.1.2:
- version "5.2.8"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.8.tgz#05720c49df23c79bda51fd01daeb1e9222e94390"
+postcss@^5.0.10, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0.14, postcss@^5.0.16, postcss@^5.0.2, postcss@^5.0.4, postcss@^5.0.5, postcss@^5.0.8, postcss@^5.2.17:
+ version "5.2.17"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b"
dependencies:
chalk "^1.1.3"
js-base64 "^2.1.9"
source-map "^0.5.6"
- supports-color "^3.1.2"
+ supports-color "^3.2.3"
-postcss@^5.2.17:
- version "5.2.17"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.17.tgz#cf4f597b864d65c8a492b2eabe9d706c879c388b"
+postcss@^5.0.11, postcss@^5.0.6, postcss@^5.1.2:
+ version "5.2.8"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.8.tgz#05720c49df23c79bda51fd01daeb1e9222e94390"
dependencies:
chalk "^1.1.3"
js-base64 "^2.1.9"
source-map "^0.5.6"
- supports-color "^3.2.3"
+ supports-color "^3.1.2"
prelude-ls@~1.1.2:
version "1.1.2"