Skip to content

Commit

Permalink
[ML] Data Visualizer: Replace KqlFilterBar with QueryStringInput (#6…
Browse files Browse the repository at this point in the history
…0544)

* data visualizer:replace kqlFilterBar

* remove unused translation

* show syntax error toast
  • Loading branch information
alvarezmelissa87 authored Mar 19, 2020
1 parent bafd45f commit f5355a9
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 54 deletions.
5 changes: 5 additions & 0 deletions x-pack/plugins/ml/public/application/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import ReactDOM from 'react-dom';

import { AppMountParameters, CoreStart } from 'kibana/public';

import { Storage } from '../../../../../src/plugins/kibana_utils/public';

import { KibanaContextProvider } from '../../../../../src/plugins/kibana_react/public';
import { setDependencyCache, clearCache } from './util/dependency_cache';
import { setLicenseCache } from './license';
Expand All @@ -24,6 +26,8 @@ interface AppProps {
appMountParams: AppMountParameters;
}

const localStorage = new Storage(window.localStorage);

const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
setDependencyCache({
indexPatterns: deps.data.indexPatterns,
Expand Down Expand Up @@ -62,6 +66,7 @@ const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
appName: 'ML',
data: deps.data,
security: deps.security,
storage: localStorage,
...coreStart,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export const NumberContent: FC<FieldDataCardProps> = ({ config }) => {
buttonSize="compressed"
/>
<EuiSpacer size="m" />
{detailsMode === DETAILS_MODE.DISTRIBUTION && (
{distribution && detailsMode === DETAILS_MODE.DISTRIBUTION && (
<Fragment>
<EuiFlexGroup justifyContent="spaceAround" gutterSize="xs">
<EuiFlexItem grow={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,37 +4,34 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { FC } from 'react';
import React, { FC, useState } from 'react';

import {
EuiFieldSearch,
EuiFlexItem,
EuiFlexGroup,
EuiForm,
EuiFormRow,
EuiIconTip,
EuiSuperSelect,
EuiText,
} from '@elastic/eui';
import { EuiFlexItem, EuiFlexGroup, EuiIconTip, EuiSuperSelect, EuiText } from '@elastic/eui';

import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';

import { IndexPattern } from '../../../../../../../../../src/plugins/data/public';

import { SEARCH_QUERY_LANGUAGE } from '../../../../../../common/constants/search';
import { SavedSearchQuery } from '../../../../contexts/ml';

// @ts-ignore
import { KqlFilterBar } from '../../../../components/kql_filter_bar/index';
import {
esKuery,
esQuery,
Query,
QueryStringInput,
} from '../../../../../../../../../src/plugins/data/public';

import { getToastNotifications } from '../../../../util/dependency_cache';

interface Props {
indexPattern: IndexPattern;
searchString: string | SavedSearchQuery;
setSearchString(s: string): void;
searchQuery: string | SavedSearchQuery;
setSearchQuery(q: string | SavedSearchQuery): void;
searchString: Query['query'];
setSearchString(s: Query['query']): void;
searchQuery: Query['query'];
setSearchQuery(q: Query['query']): void;
searchQueryLanguage: SEARCH_QUERY_LANGUAGE;
setSearchQueryLanguage(q: any): void;
samplerShardSize: number;
setSamplerShardSize(s: number): void;
totalCount: number;
Expand All @@ -59,51 +56,86 @@ const searchSizeOptions = [1000, 5000, 10000, 100000, -1].map(v => {
};
});

const kqlSyntaxErrorMessage = i18n.translate(
'xpack.ml.datavisualizer.invalidKqlSyntaxErrorMessage',
{
defaultMessage:
'Invalid syntax in search bar. The input must be valid Kibana Query Language (KQL)',
}
);
const luceneSyntaxErrorMessage = i18n.translate(
'xpack.ml.datavisualizer.invalidLuceneSyntaxErrorMessage',
{
defaultMessage: 'Invalid syntax in search bar. The input must be valid Lucene',
}
);

export const SearchPanel: FC<Props> = ({
indexPattern,
searchString,
setSearchString,
searchQuery,
setSearchQuery,
searchQueryLanguage,
setSearchQueryLanguage,
samplerShardSize,
setSamplerShardSize,
totalCount,
}) => {
const searchHandler = (d: Record<string, any>) => {
setSearchQuery(d.filterQuery);
// The internal state of the input query bar updated on every key stroke.
const [searchInput, setSearchInput] = useState<Query>({
query: searchString || '',
language: searchQueryLanguage,
});

const searchHandler = (query: Query) => {
let filterQuery;
try {
if (query.language === SEARCH_QUERY_LANGUAGE.KUERY) {
filterQuery = esKuery.toElasticsearchQuery(
esKuery.fromKueryExpression(query.query),
indexPattern
);
} else if (query.language === SEARCH_QUERY_LANGUAGE.LUCENE) {
filterQuery = esQuery.luceneStringToDsl(query.query);
} else {
filterQuery = {};
}

setSearchQuery(filterQuery);
setSearchString(query.query);
setSearchQueryLanguage(query.language);
} catch (e) {
console.log('Invalid syntax', e); // eslint-disable-line no-console
const toastNotifications = getToastNotifications();
const notification =
query.language === SEARCH_QUERY_LANGUAGE.KUERY
? kqlSyntaxErrorMessage
: luceneSyntaxErrorMessage;
toastNotifications.addDanger(notification);
}
};
const searchChangeHandler = (query: Query) => setSearchInput(query);

return (
<EuiFlexGroup gutterSize="m" alignItems="center" data-test-subj="mlDataVisualizerSearchPanel">
<EuiFlexItem>
{searchQueryLanguage === SEARCH_QUERY_LANGUAGE.KUERY ? (
<KqlFilterBar
indexPattern={indexPattern}
onSubmit={searchHandler}
initialValue={searchString}
placeholder={i18n.translate(
'xpack.ml.datavisualizer.searchPanel.queryBarPlaceholderText',
{
defaultMessage: 'Search… (e.g. status:200 AND extension:"PHP")',
}
)}
/>
) : (
<EuiForm>
<EuiFormRow
helpText={i18n.translate('xpack.ml.datavisualizer.searchPanel.kqlEditOnlyLabel', {
defaultMessage: 'Currently only KQL saved searches can be edited',
})}
>
<EuiFieldSearch
value={`${searchString}`}
readOnly
data-test-subj="mlDataVisualizerLuceneSearchBarl"
/>
</EuiFormRow>
</EuiForm>
)}
<QueryStringInput
bubbleSubmitEvent={true}
query={searchInput}
indexPatterns={[indexPattern]}
onChange={searchChangeHandler}
onSubmit={searchHandler}
placeholder={i18n.translate(
'xpack.ml.datavisualizer.searchPanel.queryBarPlaceholderText',
{
defaultMessage: 'Search… (e.g. status:200 AND extension:"PHP")',
}
)}
disableAutoFocus={true}
dataTestSubj="transformQueryInput"
languageSwitcherPopoverAnchorPosition="rightDown"
/>
</EuiFlexItem>

<EuiFlexItem grow={false}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import {
IFieldType,
KBN_FIELD_TYPES,
Query,
esQuery,
esKuery,
} from '../../../../../../../src/plugins/data/public';
Expand All @@ -36,7 +37,7 @@ import { checkPermission } from '../../privilege/check_privilege';
import { mlNodesAvailable } from '../../ml_nodes_check/check_ml_nodes';
import { FullTimeRangeSelector } from '../../components/full_time_range_selector';
import { mlTimefilterRefresh$ } from '../../services/timefilter_refresh_service';
import { useMlContext, SavedSearchQuery } from '../../contexts/ml';
import { useMlContext } from '../../contexts/ml';
import { kbnTypeToMLJobType } from '../../util/field_types_utils';
import { useTimefilter } from '../../contexts/kibana';
import { timeBasedIndexCheck, getQueryFromSavedSearch } from '../../util/index_utils';
Expand All @@ -49,8 +50,8 @@ import { SearchPanel } from './components/search_panel';
import { DataLoader } from './data_loader';

interface DataVisualizerPageState {
searchQuery: string | SavedSearchQuery;
searchString: string | SavedSearchQuery;
searchQuery: Query['query'];
searchString: Query['query'];
searchQueryLanguage: SEARCH_QUERY_LANGUAGE;
samplerShardSize: number;
overallStats: any;
Expand Down Expand Up @@ -160,7 +161,7 @@ export const Page: FC = () => {

const [searchString, setSearchString] = useState(initSearchString);
const [searchQuery, setSearchQuery] = useState(initSearchQuery);
const [searchQueryLanguage] = useState(initQueryLanguage);
const [searchQueryLanguage, setSearchQueryLanguage] = useState(initQueryLanguage);
const [samplerShardSize, setSamplerShardSize] = useState(defaults.samplerShardSize);

// TODO - type overallStats and stats
Expand Down Expand Up @@ -676,6 +677,7 @@ export const Page: FC = () => {
searchQuery={searchQuery}
setSearchQuery={setSearchQuery}
searchQueryLanguage={searchQueryLanguage}
setSearchQueryLanguage={setSearchQueryLanguage}
samplerShardSize={samplerShardSize}
setSamplerShardSize={setSamplerShardSize}
totalCount={overallStats.totalCount}
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -7677,7 +7677,6 @@
"xpack.ml.datavisualizer.page.fieldsPanelTitle": "フィールド",
"xpack.ml.datavisualizer.page.metricsPanelTitle": "メトリック",
"xpack.ml.datavisualizer.searchPanel.allOptionLabel": "すべて",
"xpack.ml.datavisualizer.searchPanel.kqlEditOnlyLabel": "現在 KQAL で保存された検索のみ編集できます。",
"xpack.ml.datavisualizer.searchPanel.queryBarPlaceholder": "小さいサンプルサイズを選択することで、クエリの実行時間を短縮しクラスターへの負荷を軽減できます。",
"xpack.ml.datavisualizer.searchPanel.queryBarPlaceholderText": "検索… (例: status:200 AND extension:\"PHP\")",
"xpack.ml.datavisualizer.searchPanel.sampleSizeAriaLabel": "サンプリングするドキュメント数を選択してください",
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/translations/translations/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -7677,7 +7677,6 @@
"xpack.ml.datavisualizer.page.fieldsPanelTitle": "字段",
"xpack.ml.datavisualizer.page.metricsPanelTitle": "指标",
"xpack.ml.datavisualizer.searchPanel.allOptionLabel": "全部",
"xpack.ml.datavisualizer.searchPanel.kqlEditOnlyLabel": "当前仅可以编辑 KQL 已保存搜索",
"xpack.ml.datavisualizer.searchPanel.queryBarPlaceholder": "选择较小的样例大小将减少查询运行时间和集群上的负载。",
"xpack.ml.datavisualizer.searchPanel.queryBarPlaceholderText": "搜索……(例如,status:200 AND extension:\"PHP\")",
"xpack.ml.datavisualizer.searchPanel.sampleSizeAriaLabel": "选择要采样的文档数目",
Expand Down

0 comments on commit f5355a9

Please sign in to comment.