From 957dfb7e736149e949aee20b80973423272a6893 Mon Sep 17 00:00:00 2001 From: wangqianliang Date: Sun, 3 Feb 2019 13:44:54 +0800 Subject: [PATCH] fix(code/frontend): fix project filter press enter location change --- x-pack/plugins/code/public/actions/search.ts | 5 ++- .../code/public/components/diff_page/diff.tsx | 3 ++ .../code/public/components/main/content.tsx | 3 ++ .../public/components/main/search_bar.tsx | 9 +++- .../code/public/components/main/top_bar.tsx | 6 ++- .../__snapshots__/query_bar.test.tsx.snap | 8 ++-- .../query_bar/components/options.tsx | 42 ++++++++++++------- .../query_bar/components/query_bar.test.tsx | 4 +- .../query_bar/components/query_bar.tsx | 8 +++- .../suggestions/file_suggestions_provider.ts | 12 +++++- .../suggestions/suggestions_provider.ts | 16 +++++-- .../symbol_suggestions_provider.ts | 12 +++++- .../public/components/search_page/search.tsx | 4 +- .../components/search_page/search_bar.tsx | 2 + x-pack/plugins/code/public/reducers/search.ts | 3 +- x-pack/plugins/code/public/sagas/search.ts | 10 ++++- 16 files changed, 106 insertions(+), 41 deletions(-) diff --git a/x-pack/plugins/code/public/actions/search.ts b/x-pack/plugins/code/public/actions/search.ts index d6b27bbad5395..3e7210e09488c 100644 --- a/x-pack/plugins/code/public/actions/search.ts +++ b/x-pack/plugins/code/public/actions/search.ts @@ -5,13 +5,14 @@ */ import { createAction } from 'redux-actions'; -import { DocumentSearchResult, SearchScope } from '../../model'; +import { DocumentSearchResult, Repository, SearchScope } from '../../model'; export interface DocumentSearchPayload { query: string; page?: string; languages?: string; repositories?: string; + repoScope?: string; } export interface RepositorySearchPayload { @@ -19,7 +20,7 @@ export interface RepositorySearchPayload { } export interface SearchOptions { - repoScopes: string[]; + repoScope: Repository[]; } // For document search page diff --git a/x-pack/plugins/code/public/components/diff_page/diff.tsx b/x-pack/plugins/code/public/components/diff_page/diff.tsx index 8769746835919..b2b677d79ccc6 100644 --- a/x-pack/plugins/code/public/components/diff_page/diff.tsx +++ b/x-pack/plugins/code/public/components/diff_page/diff.tsx @@ -90,6 +90,7 @@ interface Props extends RouteComponentProps<{ resource: string; org: string; rep commit: CommitDiff | null; query: string; onSearchScopeChanged: (s: SearchScope) => void; + repoScope: string[]; } export enum DiffLayout { @@ -192,6 +193,7 @@ export class DiffPage extends React.Component { return (
@@ -229,6 +231,7 @@ export class DiffPage extends React.Component { const mapStateToProps = (state: RootState) => ({ commit: state.commit.commit, query: state.search.query, + repoScope: state.search.searchOptions.repoScope.map(r => r.uri), }); const mapDispatchToProps = { diff --git a/x-pack/plugins/code/public/components/main/content.tsx b/x-pack/plugins/code/public/components/main/content.tsx index 7a459c8df6601..f2cd930b0d6bb 100644 --- a/x-pack/plugins/code/public/components/main/content.tsx +++ b/x-pack/plugins/code/public/components/main/content.tsx @@ -77,6 +77,7 @@ interface Props extends RouteComponentProps { hasMoreCommits: boolean; loadingCommits: boolean; onSearchScopeChanged: (s: SearchScope) => void; + repoScope: string[]; fetchMoreCommits(repoUri: string): void; } @@ -224,6 +225,7 @@ class CodeContent extends React.PureComponent { routeParams={this.props.match.params} onSearchScopeChanged={this.props.onSearchScopeChanged} buttons={this.renderButtons()} + repoScope={this.props.repoScope} /> {this.renderContent()} @@ -373,6 +375,7 @@ const mapStateToProps = (state: RootState) => ({ hasMoreCommits: hasMoreCommitsSelector(state), loadingCommits: state.file.loadingCommits, repoStatus: statusSelector(state), + repoScope: state.search.searchOptions.repoScope.map(r => r.uri), }); const mapDispatchToProps = { diff --git a/x-pack/plugins/code/public/components/main/search_bar.tsx b/x-pack/plugins/code/public/components/main/search_bar.tsx index 164777fab519c..5729e3620e4d0 100644 --- a/x-pack/plugins/code/public/components/main/search_bar.tsx +++ b/x-pack/plugins/code/public/components/main/search_bar.tsx @@ -24,6 +24,7 @@ const SearchBarContainer = styled.div` interface Props extends RouteComponentProps { onSearchScopeChanged: (s: SearchScope) => void; + repoScope: string[]; } export class CodeSearchBar extends React.Component { @@ -42,10 +43,14 @@ export class CodeSearchBar extends React.Component { if (query.trim().length === 0) { return; } + let qs = ''; + if (this.props.repoScope) { + qs = `&repoScope=${this.props.repoScope.join(',')}`; + } if (this.state.searchScope === SearchScope.REPOSITORY) { - history.push(`/search?q=${query}&scope=${SearchScope.REPOSITORY}`); + history.push(`/search?q=${query}&scope=${SearchScope.REPOSITORY}${qs}`); } else { - history.push(`/search?q=${query}`); + history.push(`/search?q=${query}${qs}`); } }; diff --git a/x-pack/plugins/code/public/components/main/top_bar.tsx b/x-pack/plugins/code/public/components/main/top_bar.tsx index b1377871e5f49..4c1afcdcfd50f 100644 --- a/x-pack/plugins/code/public/components/main/top_bar.tsx +++ b/x-pack/plugins/code/public/components/main/top_bar.tsx @@ -35,13 +35,17 @@ interface Props { routeParams: MainRouteParams; onSearchScopeChanged: (s: SearchScope) => void; buttons: React.ReactNode; + repoScope: string[]; } export class TopBar extends React.Component { public render() { return ( - + diff --git a/x-pack/plugins/code/public/components/query_bar/components/__snapshots__/query_bar.test.tsx.snap b/x-pack/plugins/code/public/components/query_bar/components/__snapshots__/query_bar.test.tsx.snap index fa00370a2b706..81d0bb4c8e732 100644 --- a/x-pack/plugins/code/public/components/query_bar/components/__snapshots__/query_bar.test.tsx.snap +++ b/x-pack/plugins/code/public/components/query_bar/components/__snapshots__/query_bar.test.tsx.snap @@ -14,7 +14,7 @@ exports[`render correctly with empty query string 1`] = ` searchLoading={false} searchOptions={ Object { - "repoScopes": Array [], + "repoScope": Array [], } } searchScope="default" @@ -645,7 +645,7 @@ exports[`render correctly with empty query string 1`] = ` searchLoading={false} searchOptions={ Object { - "repoScopes": Array [], + "repoScope": Array [], } } > @@ -757,7 +757,7 @@ exports[`render correctly with input query string changed 1`] = ` searchLoading={false} searchOptions={ Object { - "repoScopes": Array [], + "repoScope": Array [], } } searchScope="default" @@ -1400,7 +1400,7 @@ exports[`render correctly with input query string changed 1`] = ` searchLoading={false} searchOptions={ Object { - "repoScopes": Array [], + "repoScope": Array [], } } > diff --git a/x-pack/plugins/code/public/components/query_bar/components/options.tsx b/x-pack/plugins/code/public/components/query_bar/components/options.tsx index 59fd06f5d3e31..6e0a466ae2722 100644 --- a/x-pack/plugins/code/public/components/query_bar/components/options.tsx +++ b/x-pack/plugins/code/public/components/query_bar/components/options.tsx @@ -15,16 +15,18 @@ import { EuiPanel, EuiSpacer, EuiText, + EuiTextColor, EuiTitle, } from '@elastic/eui'; import { EuiIcon } from '@elastic/eui'; import { unique } from 'lodash'; import React, { Component } from 'react'; import styled from 'styled-components'; +import { Repository } from '../../../../model'; import { SearchOptions as ISearchOptions } from '../../../actions'; const SelectedRepo = styled.div` - max-width: 60%; + max-width: 90%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; @@ -36,7 +38,7 @@ const Icon = styled(EuiIcon)` interface State { isFlyoutOpen: boolean; - repoScopes: any[]; + repoScope: Repository[]; } interface Props { @@ -50,30 +52,35 @@ interface Props { export class SearchOptions extends Component { public state: State = { isFlyoutOpen: false, - repoScopes: this.props.searchOptions.repoScopes, + repoScope: this.props.searchOptions.repoScope, }; public applyAndClose = () => { - this.props.saveSearchOptions({ repoScopes: this.state.repoScopes }); + this.props.saveSearchOptions({ repoScope: this.state.repoScope }); this.setState({ isFlyoutOpen: false }); }; public removeRepoScope = (r: string) => () => { this.setState(prevState => ({ - repoScopes: prevState.repoScopes.filter(rs => rs !== r), + repoScope: prevState.repoScope.filter(rs => rs.uri !== r), })); }; public render() { let optionsFlyout; if (this.state.isFlyoutOpen) { - const selectedRepos = this.state.repoScopes.map((r: string) => { + const selectedRepos = this.state.repoScope.map(r => { return ( -
+
- - {r} - + + + + {r.org}/ + {r.name} + + + @@ -98,9 +105,7 @@ export class SearchOptions extends Component { placeholder="Search to add repos" async={true} options={this.props.repoSearchResults.map(repo => ({ - id: repo.name, label: repo.name, - uri: repo.uri, }))} selectedOptions={[]} isLoading={this.props.searchLoading} @@ -134,13 +139,18 @@ export class SearchOptions extends Component { } private onRepoSearchChange = (searchValue: string) => { - this.props.repositorySearch({ query: searchValue }); + if (searchValue) { + this.props.repositorySearch({ query: searchValue }); + } }; private onRepoChange = (repos: any) => { - this.setState({ - repoScopes: unique(repos.map((r: any) => r.uri)), - }); + this.setState(prevState => ({ + repoScope: unique([ + ...prevState.repoScope, + ...repos.map((r: any) => this.props.repoSearchResults.find(rs => rs.name === r.label)), + ]), + })); }; private toggleOptionsFlyout = () => { diff --git a/x-pack/plugins/code/public/components/query_bar/components/query_bar.test.tsx b/x-pack/plugins/code/public/components/query_bar/components/query_bar.test.tsx index 7252ee1b1d891..8b8b54006109d 100644 --- a/x-pack/plugins/code/public/components/query_bar/components/query_bar.test.tsx +++ b/x-pack/plugins/code/public/components/query_bar/components/query_bar.test.tsx @@ -30,7 +30,7 @@ test('render correctly with empty query string', () => { saveSearchOptions={emptyFn} repoSearchResults={[]} searchLoading={false} - searchOptions={{ repoScopes: [] }} + searchOptions={{ repoScope: [] }} query="" disableAutoFocus={false} appName="mockapp" @@ -85,7 +85,7 @@ test('render correctly with input query string changed', done => { saveSearchOptions={emptyFn} repoSearchResults={[]} searchLoading={false} - searchOptions={{ repoScopes: [] }} + searchOptions={{ repoScope: [] }} query="mockquery" disableAutoFocus={false} appName="mockapp" diff --git a/x-pack/plugins/code/public/components/query_bar/components/query_bar.tsx b/x-pack/plugins/code/public/components/query_bar/components/query_bar.tsx index 145234943904f..830a7c13c9d97 100644 --- a/x-pack/plugins/code/public/components/query_bar/components/query_bar.tsx +++ b/x-pack/plugins/code/public/components/query_bar/components/query_bar.tsx @@ -186,7 +186,11 @@ export class CodeQueryBar extends Component { const res = await Promise.all( this.props.suggestionProviders.map((provider: SuggestionsProvider) => { - return provider.getSuggestions(query, this.props.searchScope); + return provider.getSuggestions( + query, + this.props.searchScope, + this.props.searchOptions.repoScope.map(repo => repo.uri) + ); }) ); @@ -461,7 +465,7 @@ const mapStateToProps = (state: RootState) => ({ : [], searchLoading: state.search.isLoading, searchScope: state.search.scope, - searchOptions: state.search.searchOptions || { repoScopes: [] }, + searchOptions: state.search.searchOptions, }); const mapDispatchToProps = { diff --git a/x-pack/plugins/code/public/components/query_bar/suggestions/file_suggestions_provider.ts b/x-pack/plugins/code/public/components/query_bar/suggestions/file_suggestions_provider.ts index b8590ba2f43b0..50d1ee0a2b603 100644 --- a/x-pack/plugins/code/public/components/query_bar/suggestions/file_suggestions_provider.ts +++ b/x-pack/plugins/code/public/components/query_bar/suggestions/file_suggestions_provider.ts @@ -18,11 +18,19 @@ export class FileSuggestionsProvider extends AbstractSuggestionsProvider { return scope === SearchScope.DEFAULT || scope === SearchScope.FILE; } - protected async fetchSuggestions(query: string): Promise { + protected async fetchSuggestions( + query: string, + repoScope: string[] + ): Promise { + const queryParams: { q: string; repoScope?: string } = { q: query }; + if (repoScope) { + const qs = repoScope.join('&repoScope='); + queryParams.repoScope = qs; + } const res = await kfetch({ pathname: `../api/code/suggestions/doc`, method: 'get', - query: { q: query }, + query: queryParams, }); const suggestions = Array.from(res.results as SearchResultItem[]) .slice(0, this.MAX_SUGGESTIONS_PER_GROUP) diff --git a/x-pack/plugins/code/public/components/query_bar/suggestions/suggestions_provider.ts b/x-pack/plugins/code/public/components/query_bar/suggestions/suggestions_provider.ts index db7052d7cf673..ef9846bd4aed9 100644 --- a/x-pack/plugins/code/public/components/query_bar/suggestions/suggestions_provider.ts +++ b/x-pack/plugins/code/public/components/query_bar/suggestions/suggestions_provider.ts @@ -8,7 +8,11 @@ import { AutocompleteSuggestionGroup, AutocompleteSuggestionType } from '.'; import { SearchScope } from '../../../../model'; export interface SuggestionsProvider { - getSuggestions(query: string, scope: SearchScope): Promise; + getSuggestions( + query: string, + scope: SearchScope, + repoScope?: string[] + ): Promise; } export abstract class AbstractSuggestionsProvider implements SuggestionsProvider { @@ -16,10 +20,11 @@ export abstract class AbstractSuggestionsProvider implements SuggestionsProvider public async getSuggestions( query: string, - scope: SearchScope + scope: SearchScope, + repoScope?: string[] ): Promise { if (this.matchSearchScope(scope)) { - return await this.fetchSuggestions(query); + return await this.fetchSuggestions(query, repoScope); } else { // This is an abstract class. Do nothing here. You should override this. return new Promise((resolve, reject) => { @@ -33,7 +38,10 @@ export abstract class AbstractSuggestionsProvider implements SuggestionsProvider } } - protected async fetchSuggestions(_: string): Promise { + protected async fetchSuggestions( + query: string, + repoScope?: string[] + ): Promise { // This is an abstract class. Do nothing here. You should override this. return new Promise((resolve, reject) => { resolve({ diff --git a/x-pack/plugins/code/public/components/query_bar/suggestions/symbol_suggestions_provider.ts b/x-pack/plugins/code/public/components/query_bar/suggestions/symbol_suggestions_provider.ts index ee3655c5212f6..907b62c5960e6 100644 --- a/x-pack/plugins/code/public/components/query_bar/suggestions/symbol_suggestions_provider.ts +++ b/x-pack/plugins/code/public/components/query_bar/suggestions/symbol_suggestions_provider.ts @@ -23,11 +23,19 @@ export class SymbolSuggestionsProvider extends AbstractSuggestionsProvider { return scope === SearchScope.DEFAULT || scope === SearchScope.SYMBOL; } - protected async fetchSuggestions(query: string): Promise { + protected async fetchSuggestions( + query: string, + repoScope?: string[] + ): Promise { + const queryParams: { q: string; repoScope?: string } = { q: query }; + if (repoScope) { + const qs = repoScope.join('&repoScope='); + queryParams.repoScope = qs; + } const res = await kfetch({ pathname: `../api/code/suggestions/symbol`, method: 'get', - query: { q: query }, + query: queryParams, }); const suggestions = Array.from(res.symbols as DetailSymbolInformation[]) .slice(0, this.MAX_SUGGESTIONS_PER_GROUP) diff --git a/x-pack/plugins/code/public/components/search_page/search.tsx b/x-pack/plugins/code/public/components/search_page/search.tsx index 657bb4ba364a9..dda8912181813 100644 --- a/x-pack/plugins/code/public/components/search_page/search.tsx +++ b/x-pack/plugins/code/public/components/search_page/search.tsx @@ -13,7 +13,7 @@ import Url from 'url'; import theme from '@elastic/eui/dist/eui_theme_light.json'; import { DocumentSearchResult, SearchScope } from '../../../model'; -import { changeSearchScope } from '../../actions'; +import { changeSearchScope, SearchOptions } from '../../actions'; import { RootState } from '../../reducers'; import { history } from '../../utils/url'; import { ProjectItem } from '../admin_page/project_item'; @@ -44,6 +44,7 @@ const CodeResultContainer = styled.div` const RepositoryResultContainer = CodeResultContainer; interface Props { + searchOptions: SearchOptions; query: string; scope: SearchScope; page?: number; @@ -211,6 +212,7 @@ class SearchPage extends React.PureComponent { r.uri)} query={this.props.query} onSearchScopeChanged={this.props.onSearchScopeChanged} /> diff --git a/x-pack/plugins/code/public/components/search_page/search_bar.tsx b/x-pack/plugins/code/public/components/search_page/search_bar.tsx index 0df04dfcbe1c0..d9e391f1a3dfa 100644 --- a/x-pack/plugins/code/public/components/search_page/search_bar.tsx +++ b/x-pack/plugins/code/public/components/search_page/search_bar.tsx @@ -32,6 +32,7 @@ const SearchBarContainer = styled.div` interface Props { query: string; onSearchScopeChanged: (s: SearchScope) => void; + repoScope: string[]; } export class SearchBar extends React.PureComponent { @@ -44,6 +45,7 @@ export class SearchBar extends React.PureComponent { query: { ...queries, q: query, + repoScope: this.props.repoScope, }, }) ); diff --git a/x-pack/plugins/code/public/reducers/search.ts b/x-pack/plugins/code/public/reducers/search.ts index abe56a478cded..155aaaba7d9af 100644 --- a/x-pack/plugins/code/public/reducers/search.ts +++ b/x-pack/plugins/code/public/reducers/search.ts @@ -33,13 +33,14 @@ export interface SearchState { error?: Error; documentSearchResults?: DocumentSearchResult; repositorySearchResults?: any; - searchOptions?: SearchOptions; + searchOptions: SearchOptions; } const initialState: SearchState = { query: '', isLoading: false, scope: SearchScope.DEFAULT, + searchOptions: { repoScope: [] }, }; export const search = handleActions( diff --git a/x-pack/plugins/code/public/sagas/search.ts b/x-pack/plugins/code/public/sagas/search.ts index a74338e716e78..c6b4fccc54eaa 100644 --- a/x-pack/plugins/code/public/sagas/search.ts +++ b/x-pack/plugins/code/public/sagas/search.ts @@ -26,7 +26,7 @@ import { import { searchRoutePattern } from './patterns'; function requestDocumentSearch(payload: DocumentSearchPayload) { - const { query, page, languages, repositories } = payload; + const { query, page, languages, repositories, repoScope } = payload; const queryParams: { [key: string]: string | number | boolean } = { q: query, }; @@ -43,6 +43,11 @@ function requestDocumentSearch(payload: DocumentSearchPayload) { queryParams.repos = repositories; } + if (repoScope) { + const qs = repoScope.split(',').join('&repoScope='); + queryParams.repoScope = qs; + } + if (query && query.length > 0) { return kfetch({ pathname: `../api/code/search/doc`, @@ -99,7 +104,7 @@ function* handleSearchRouteChange(action: Action) { const { location } = action.payload!; const rawSearchStr = location.search.length > 0 ? location.search.substring(1) : ''; const queryParams = queryString.parse(rawSearchStr); - const { q, p, langs, repos, scope } = queryParams; + const { q, p, langs, repos, scope, repoScope } = queryParams; yield put(changeSearchScope(scope as SearchScope)); if (scope === SearchScope.REPOSITORY) { yield put(repositorySearch({ query: q as string })); @@ -110,6 +115,7 @@ function* handleSearchRouteChange(action: Action) { page: p as string, languages: langs as string, repositories: repos as string, + repoScope: repoScope as string, }) ); }