[Discover] Deangularize timechart header (#66532)

* Deangularize timechart header

* Add label attr to options

* Watch the interval prop change

* Tweaking the UI

Mainly moved interval notice to an `append` and copy updates

* Remove outdated i18n tokens

* fix functional test

* Change functional test due to dom changes

* fix functional test

* remove unecessary translation

* remove watcher as it is not necessary anymore

* change interval options copies

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: cchaos <caroline.horn@elastic.co>
This commit is contained in:
Stratoula Kalafateli 2020-05-20 10:28:53 +03:00 committed by GitHub
parent 3ce0b5755e
commit 42d21bcdcb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 342 additions and 97 deletions

View file

@ -52,31 +52,31 @@ export const intervalOptions = [
},
{
display: i18n.translate('data.search.aggs.buckets.intervalOptions.hourlyDisplayName', {
defaultMessage: 'Hourly',
defaultMessage: 'Hour',
}),
val: 'h',
},
{
display: i18n.translate('data.search.aggs.buckets.intervalOptions.dailyDisplayName', {
defaultMessage: 'Daily',
defaultMessage: 'Day',
}),
val: 'd',
},
{
display: i18n.translate('data.search.aggs.buckets.intervalOptions.weeklyDisplayName', {
defaultMessage: 'Weekly',
defaultMessage: 'Week',
}),
val: 'w',
},
{
display: i18n.translate('data.search.aggs.buckets.intervalOptions.monthlyDisplayName', {
defaultMessage: 'Monthly',
defaultMessage: 'Month',
}),
val: 'M',
},
{
display: i18n.translate('data.search.aggs.buckets.intervalOptions.yearlyDisplayName', {
defaultMessage: 'Yearly',
defaultMessage: 'Year',
}),
val: 'y',
},

View file

@ -101,45 +101,17 @@
class="dscTimechart"
ng-if="opts.timefield"
>
<header class="dscTimechart__header">
<div class="small">
<label
for="dscResultsIntervalSelector"
tooltip="{{::'discover.howToChangeTheTimeTooltip' | i18n: {defaultMessage: 'To change the time, click the calendar icon in the navigation bar'} }}"
>
{{toMoment(timeRange.from)}} - {{toMoment(timeRange.to)}}
</label>
&mdash;
<span class="form-inline">
<select
id="dscResultsIntervalSelector"
class="dscResults__interval form-control"
ng-model="state.interval"
ng-options="interval.val as interval.display for interval in intervalOptions | filter: intervalEnabled"
ng-blur="toggleInterval()"
data-test-subj="discoverIntervalSelect"
>
</select>
<span ng-if="bucketInterval.scaled">
<icon-tip
content="getBucketIntervalToolTipText()"
position="'top'"
></icon-tip>
<span
data-test-subj="discoverIntervalSelectScaledToDesc"
i18n-id="discover.scaledToDescription"
i18n-default-message="Scaled to {bucketIntervalDescription}"
i18n-values="{
bucketIntervalDescription: bucketInterval.description
}"
></span>
</span>
</span>
</div>
</header>
<timechart-header
from="toMoment(timeRange.from)"
to="toMoment(timeRange.to)"
options="intervalOptions"
on-change-interval="changeInterval"
state-interval="state.interval"
show-scaled-info="bucketInterval.scaled"
bucket-interval-description="bucketInterval.description"
bucket-interval-scale="bucketInterval.scale"
>
</timechart-header>
<discover-histogram
class="dscHistogram"

View file

@ -321,10 +321,6 @@ function discoverController(
}
);
$scope.intervalEnabled = function(interval) {
return interval.val !== 'custom';
};
let abortController;
$scope.$on('$destroy', () => {
if (abortController) abortController.abort();
@ -614,24 +610,6 @@ function discoverController(
$scope.state.index = $scope.indexPattern.id;
$scope.state.sort = getSortArray($scope.state.sort, $scope.indexPattern);
$scope.getBucketIntervalToolTipText = () => {
return i18n.translate('discover.bucketIntervalTooltip', {
defaultMessage:
'This interval creates {bucketsDescription} to show in the selected time range, so it has been scaled to {bucketIntervalDescription}',
values: {
bucketsDescription:
$scope.bucketInterval.scale > 1
? i18n.translate('discover.bucketIntervalTooltip.tooLargeBucketsText', {
defaultMessage: 'buckets that are too large',
})
: i18n.translate('discover.bucketIntervalTooltip.tooManyBucketsText', {
defaultMessage: 'too many buckets',
}),
bucketIntervalDescription: $scope.bucketInterval.description,
},
});
};
$scope.opts = {
// number of records to fetch, then paginate through
sampleSize: config.get(SAMPLE_SIZE_SETTING),
@ -681,12 +659,12 @@ function discoverController(
error => addFatalError(core.fatalErrors, error)
)
);
//Handling change oft the histogram interval
$scope.$watch('state.interval', function(newInterval, oldInterval) {
if (newInterval !== oldInterval) {
setAppState({ interval: newInterval });
$scope.changeInterval = interval => {
if (interval) {
setAppState({ interval });
}
});
};
$scope.$watchMulti(
['rows', 'fetchStatus'],

View file

@ -0,0 +1,21 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export { TimechartHeader } from './timechart_header';
export { createTimechartHeaderDirective } from './timechart_header_directive';

View file

@ -0,0 +1,95 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React from 'react';
import { mountWithIntl } from 'test_utils/enzyme_helpers';
import { ReactWrapper } from 'enzyme';
import { TimechartHeader, TimechartHeaderProps } from './timechart_header';
import { EuiIconTip } from '@elastic/eui';
// @ts-ignore
import { findTestSubject } from '@elastic/eui/lib/test';
describe('timechart header', function() {
let props: TimechartHeaderProps;
let component: ReactWrapper<TimechartHeaderProps>;
beforeAll(() => {
props = {
from: 'May 14, 2020 @ 11:05:13.590',
to: 'May 14, 2020 @ 11:20:13.590',
stateInterval: 's',
options: [
{
display: 'Auto',
val: 'auto',
},
{
display: 'Millisecond',
val: 'ms',
},
{
display: 'Second',
val: 's',
},
],
onChangeInterval: jest.fn(),
showScaledInfo: undefined,
bucketIntervalDescription: 'second',
bucketIntervalScale: undefined,
};
});
it('TimechartHeader not renders an info text when the showScaledInfo property is not provided', () => {
component = mountWithIntl(<TimechartHeader {...props} />);
expect(component.find(EuiIconTip).length).toBe(0);
});
it('TimechartHeader renders an info text by providing the showScaledInfo property', () => {
props.showScaledInfo = true;
component = mountWithIntl(<TimechartHeader {...props} />);
expect(component.find(EuiIconTip).length).toBe(1);
});
it('expect to render the date range', function() {
component = mountWithIntl(<TimechartHeader {...props} />);
const datetimeRangeText = findTestSubject(component, 'discoverIntervalDateRange');
expect(datetimeRangeText.text()).toBe(
'May 14, 2020 @ 11:05:13.590 - May 14, 2020 @ 11:20:13.590 per'
);
});
it('expects to render a dropdown with the interval options', () => {
component = mountWithIntl(<TimechartHeader {...props} />);
const dropdown = findTestSubject(component, 'discoverIntervalSelect');
expect(dropdown.length).toBe(1);
// @ts-ignore
const values = dropdown.find('option').map(option => option.prop('value'));
expect(values).toEqual(['auto', 'ms', 's']);
// @ts-ignore
const labels = dropdown.find('option').map(option => option.text());
expect(labels).toEqual(['Auto', 'Millisecond', 'Second']);
});
it('should change the interval', function() {
component = mountWithIntl(<TimechartHeader {...props} />);
findTestSubject(component, 'discoverIntervalSelect').simulate('change', {
target: { value: 'ms' },
});
expect(props.onChangeInterval).toHaveBeenCalled();
});
});

View file

@ -0,0 +1,159 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import React, { useState, useEffect } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
EuiToolTip,
EuiText,
EuiSelect,
EuiIconTip,
} from '@elastic/eui';
import { I18nProvider } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
export interface TimechartHeaderProps {
/**
* the query from date string
*/
from: string;
/**
* the query to date string
*/
to: string;
/**
* Interval Options
*/
options: Array<{ display: string; val: string }>;
/**
* changes the interval
*/
onChangeInterval: (interval: string) => void;
/**
* selected interval
*/
stateInterval: string;
/**
* displays the scaled info of the interval
*/
showScaledInfo: boolean | undefined;
/**
* scaled info description
*/
bucketIntervalDescription: string;
/**
* bucket interval scale
*/
bucketIntervalScale: number | undefined;
}
export function TimechartHeader({
from,
to,
options,
onChangeInterval,
stateInterval,
showScaledInfo,
bucketIntervalDescription,
bucketIntervalScale,
}: TimechartHeaderProps) {
const [interval, setInterval] = useState(stateInterval);
useEffect(() => {
setInterval(stateInterval);
}, [stateInterval]);
const handleIntervalChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
setInterval(e.target.value);
onChangeInterval(e.target.value);
};
return (
<I18nProvider>
<EuiFlexGroup gutterSize="s" responsive justifyContent="center" alignItems="center">
<EuiFlexItem grow={false}>
<EuiToolTip
content={i18n.translate('discover.howToChangeTheTimeTooltip', {
defaultMessage: 'To change the time, use the global time filter above',
})}
delay="long"
>
<EuiText data-test-subj="discoverIntervalDateRange" size="s">
{`${from} - ${to} ${
interval !== 'auto'
? i18n.translate('discover.timechartHeader.timeIntervalSelect.per', {
defaultMessage: 'per',
})
: ''
}`}
</EuiText>
</EuiToolTip>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSelect
aria-label={i18n.translate('discover.timechartHeader.timeIntervalSelect.ariaLabel', {
defaultMessage: 'Time interval',
})}
compressed
id="dscResultsIntervalSelector"
data-test-subj="discoverIntervalSelect"
options={options
.filter(({ val }) => val !== 'custom')
.map(({ display, val }) => {
return {
text: display,
value: val,
label: display,
};
})}
value={interval}
onChange={handleIntervalChange}
append={
showScaledInfo ? (
<EuiIconTip
id="discoverIntervalIconTip"
content={i18n.translate('discover.bucketIntervalTooltip', {
defaultMessage:
'This interval creates {bucketsDescription} to show in the selected time range, so it has been scaled to {bucketIntervalDescription}.',
values: {
bucketsDescription:
bucketIntervalScale && bucketIntervalScale > 1
? i18n.translate('discover.bucketIntervalTooltip.tooLargeBucketsText', {
defaultMessage: 'buckets that are too large',
})
: i18n.translate('discover.bucketIntervalTooltip.tooManyBucketsText', {
defaultMessage: 'too many buckets',
}),
bucketIntervalDescription,
},
})}
color="warning"
size="s"
type="alert"
/>
) : (
undefined
)
}
/>
</EuiFlexItem>
</EuiFlexGroup>
</I18nProvider>
);
}

View file

@ -0,0 +1,32 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { TimechartHeader } from './timechart_header';
export function createTimechartHeaderDirective(reactDirective: any) {
return reactDirective(TimechartHeader, [
['from', { watchDepth: 'reference' }],
['to', { watchDepth: 'reference' }],
['options', { watchDepth: 'reference' }],
['onChangeInterval', { watchDepth: 'reference' }],
['stateInterval', { watchDepth: 'reference' }],
['showScaledInfo', { watchDepth: 'reference' }],
['bucketIntervalDescription', { watchDepth: 'reference' }],
['bucketIntervalScale', { watchDepth: 'reference' }],
]);
}

View file

@ -59,6 +59,7 @@ import {
} from '../../kibana_legacy/public';
import { createDiscoverSidebarDirective } from './application/components/sidebar';
import { createHitsCounterDirective } from '././application/components/hits_counter';
import { createTimechartHeaderDirective } from './application/components/timechart_header';
import { DiscoverStartPlugins } from './plugin';
import { getScopedHistory } from './kibana_services';
@ -154,6 +155,7 @@ export function initializeInnerAngularModule(
.directive('renderComplete', createRenderCompleteDirective)
.directive('discoverSidebar', createDiscoverSidebarDirective)
.directive('hitsCounter', createHitsCounterDirective)
.directive('timechartHeader', createTimechartHeaderDirective)
.service('debounce', ['$timeout', DebounceProviderTimeout]);
}

View file

@ -69,7 +69,7 @@ export default function({ getService, getPageObjects }) {
const fromTime = 'Nov 01, 2017 @ 00:00:00.000';
const toTime = 'Mar 21, 2018 @ 00:00:00.000';
await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
await PageObjects.discover.setChartInterval('Monthly');
await PageObjects.discover.setChartInterval('Month');
await PageObjects.header.waitUntilLoadingHasFinished();
const chartCanvasExist = await elasticChart.canvasExists();
expect(chartCanvasExist).to.be(true);
@ -78,7 +78,7 @@ export default function({ getService, getPageObjects }) {
const fromTime = 'Mar 01, 2018 @ 00:00:00.000';
const toTime = 'May 01, 2018 @ 00:00:00.000';
await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
await PageObjects.discover.setChartInterval('Weekly');
await PageObjects.discover.setChartInterval('Week');
await PageObjects.header.waitUntilLoadingHasFinished();
const chartCanvasExist = await elasticChart.canvasExists();
expect(chartCanvasExist).to.be(true);
@ -88,12 +88,12 @@ export default function({ getService, getPageObjects }) {
const toTime = 'Mar 21, 2019 @ 00:00:00.000';
await PageObjects.timePicker.setAbsoluteRange(fromTime, toTime);
await PageObjects.discover.setChartInterval('Daily');
await PageObjects.discover.setChartInterval('Day');
await PageObjects.header.waitUntilLoadingHasFinished();
const chartCanvasExist = await elasticChart.canvasExists();
expect(chartCanvasExist).to.be(true);
const chartIntervalScaledDesc = await PageObjects.discover.getChartIntervalScaledToDesc();
expect(chartIntervalScaledDesc).to.be('Scaled to 30 days');
const chartIntervalIconTip = await PageObjects.discover.getChartIntervalWarningIcon();
expect(chartIntervalIconTip).to.be(true);
});
});
}

View file

@ -438,7 +438,7 @@ export default function({ getService, getPageObjects }) {
log.debug('Click Date Histogram');
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.setInterval('Yearly');
await PageObjects.visEditor.setInterval('Year');
await PageObjects.visEditor.clickGo();
// This svg area is composed by 7 years (2013 - 2019).
// 7 points are used to draw the upper line (usually called y1)
@ -461,7 +461,7 @@ export default function({ getService, getPageObjects }) {
log.debug('Click Date Histogram');
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.setInterval('Monthly');
await PageObjects.visEditor.setInterval('Month');
await PageObjects.visEditor.clickGo();
// This svg area is composed by 67 months 3 (2013) + 5 * 12 + 4 (2019)
// 67 points are used to draw the upper line (usually called y1)

View file

@ -174,7 +174,7 @@ export default function({ getService, getPageObjects }) {
await PageObjects.visEditor.clickBucket('Split rows');
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.setInterval('Daily');
await PageObjects.visEditor.setInterval('Day');
await PageObjects.visEditor.clickGo();
const data = await PageObjects.visChart.getTableVisData();
log.debug(data.split('\n'));
@ -196,7 +196,7 @@ export default function({ getService, getPageObjects }) {
await PageObjects.visEditor.clickBucket('Split rows');
await PageObjects.visEditor.selectAggregation('Date Histogram');
await PageObjects.visEditor.selectField('@timestamp');
await PageObjects.visEditor.setInterval('Daily');
await PageObjects.visEditor.setInterval('Day');
await PageObjects.visEditor.clickGo();
const data = await PageObjects.visChart.getTableVisData();
expect(data.trim().split('\n')).to.be.eql([

View file

@ -36,7 +36,7 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider
class DiscoverPage {
public async getChartTimespan() {
const el = await find.byCssSelector('.small > label[for="dscResultsIntervalSelector"]');
const el = await find.byCssSelector('[data-test-subj="discoverIntervalDateRange"]');
return await el.getVisibleText();
}
@ -168,9 +168,9 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider
return selectedOption.getVisibleText();
}
public async getChartIntervalScaledToDesc() {
public async getChartIntervalWarningIcon() {
await header.waitUntilLoadingHasFinished();
return await testSubjects.getVisibleText('discoverIntervalSelectScaledToDesc');
return await find.existsByCssSelector('.euiToolTipAnchor');
}
public async setChartInterval(interval: string) {

View file

@ -702,14 +702,9 @@
"data.search.aggs.buckets.geotileGridTitle": "ジオタイル",
"data.search.aggs.buckets.histogramTitle": "ヒストグラム",
"data.search.aggs.buckets.intervalOptions.autoDisplayName": "自動",
"data.search.aggs.buckets.intervalOptions.dailyDisplayName": "日ごと",
"data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "1 時間ごと",
"data.search.aggs.buckets.intervalOptions.millisecondDisplayName": "ミリ秒",
"data.search.aggs.buckets.intervalOptions.minuteDisplayName": "分",
"data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "月ごと",
"data.search.aggs.buckets.intervalOptions.secondDisplayName": "秒",
"data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "週ごと",
"data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "年ごと",
"data.search.aggs.buckets.ipRangeLabel": "{fieldName} IP 範囲",
"data.search.aggs.buckets.ipRangeTitle": "IPv4 範囲",
"data.search.aggs.buckets.rangeTitle": "範囲",
@ -967,7 +962,6 @@
"discover.histogram.partialData.bucketTooltipText": "選択された時間範囲にはこのバケット全体は含まれていませんが、一部データが含まれている可能性があります。",
"discover.histogramOfFoundDocumentsAriaLabel": "発見されたドキュメントのヒストグラム",
"discover.hitsPluralTitle": "{hits, plural, one {ヒット} other {ヒット}}",
"discover.howToChangeTheTimeTooltip": "時刻を変更するには、ナビゲーションバーのカレンダーアイコンをクリックします",
"discover.howToSeeOtherMatchingDocumentsDescription": "これらは検索条件に一致した初めの {sampleSize} 件のドキュメントです。他の結果を表示するには検索条件を絞ってください。 ",
"discover.inspectorRequestDataTitle": "データ",
"discover.inspectorRequestDescription": "このリクエストは Elasticsearch にクエリをかけ、検索データを取得します。",
@ -1003,7 +997,6 @@
"discover.reloadSavedSearchButton": "検索をリセット",
"discover.rootBreadcrumb": "ディスカバリ",
"discover.savedSearch.savedObjectName": "保存された検索",
"discover.scaledToDescription": "{bucketIntervalDescription} にスケーリング済み",
"discover.searchingTitle": "検索中",
"discover.showingDefaultIndexPatternWarningDescription": "デフォルトのインデックスパターン「{loadedIndexPatternTitle}」 ({loadedIndexPatternId}) を表示中",
"discover.showingSavedIndexPatternWarningDescription": "保存されたインデックスパターン「{ownIndexPatternTitle}」 ({ownIndexPatternId}) を表示中",

View file

@ -703,14 +703,9 @@
"data.search.aggs.buckets.geotileGridTitle": "地理磁贴",
"data.search.aggs.buckets.histogramTitle": "Histogram",
"data.search.aggs.buckets.intervalOptions.autoDisplayName": "自动",
"data.search.aggs.buckets.intervalOptions.dailyDisplayName": "每日",
"data.search.aggs.buckets.intervalOptions.hourlyDisplayName": "每小时",
"data.search.aggs.buckets.intervalOptions.millisecondDisplayName": "毫秒",
"data.search.aggs.buckets.intervalOptions.minuteDisplayName": "分钟",
"data.search.aggs.buckets.intervalOptions.monthlyDisplayName": "每月",
"data.search.aggs.buckets.intervalOptions.secondDisplayName": "秒",
"data.search.aggs.buckets.intervalOptions.weeklyDisplayName": "每周",
"data.search.aggs.buckets.intervalOptions.yearlyDisplayName": "每年",
"data.search.aggs.buckets.ipRangeLabel": "{fieldName} IP 范围",
"data.search.aggs.buckets.ipRangeTitle": "IPv4 范围",
"data.search.aggs.buckets.rangeTitle": "范围",
@ -968,7 +963,6 @@
"discover.histogram.partialData.bucketTooltipText": "选定的时间范围不包括此整个存储桶,其可能包含部分数据。",
"discover.histogramOfFoundDocumentsAriaLabel": "已找到文档的直方图",
"discover.hitsPluralTitle": "{hits, plural, one {次命中} other {次命中}}",
"discover.howToChangeTheTimeTooltip": "要更改时间,请单击导航栏中的日历图标",
"discover.howToSeeOtherMatchingDocumentsDescription": "以下是匹配您的搜索的前 {sampleSize} 个文档,请优化您的搜索以查看其他文档。 ",
"discover.inspectorRequestDataTitle": "数据",
"discover.inspectorRequestDescription": "此请求将查询 Elasticsearch 以获取搜索的数据。",
@ -1004,7 +998,6 @@
"discover.reloadSavedSearchButton": "重置搜索",
"discover.rootBreadcrumb": "Discover",
"discover.savedSearch.savedObjectName": "已保存搜索",
"discover.scaledToDescription": "已缩放至 {bucketIntervalDescription}",
"discover.searchingTitle": "正在搜索",
"discover.showingDefaultIndexPatternWarningDescription": "显示默认索引模式:“{loadedIndexPatternTitle}” ({loadedIndexPatternId})",
"discover.showingSavedIndexPatternWarningDescription": "显示保存的索引模式:“{ownIndexPatternTitle}” ({ownIndexPatternId})",