[TSVB] Disables the input string mode (#110571)

* [TSVB] Remove the input string mode

* Fix some tests

* Add some functional tests and fix failing CI

* Update telemetry mappings

* Rename useStringIndices to allowStringIndices, move it from TSVB to Data constants and refactor test

* Apply text suggestions from code review

Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>

* Apply formatting and remove unused translations

* Fix labels

* Remove unused import

* Move popover toggling  to checkIndexPatternSelectionModeSwitchIsEnabled function to prevent flakiness

* Update some visual_builder_page functions

* Remove accidentally added newlines

* Move TSVB ui settings to constants, remove tooltip and update popover text

* Handle the case of editing advanced settings is restricted

* Add requiresPageReload to UI setting and condition for the case the setting is already enabled

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Kaarina Tungseth <kaarina.tungseth@elastic.co>
This commit is contained in:
Diana Derevyankina 2021-09-22 11:13:53 +03:00 committed by GitHub
parent da1ae4923a
commit abdb7a4c49
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 158 additions and 22 deletions

View file

@ -276,6 +276,10 @@ export const stackManagementSchema: MakeSchemaFrom<UsageStats> = {
type: 'long',
_meta: { description: 'Non-default value of setting.' },
},
'metrics:allowStringIndices': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },
},
'query:allowLeadingWildcards': {
type: 'boolean',
_meta: { description: 'Non-default value of setting.' },

View file

@ -91,6 +91,7 @@ export interface UsageStats {
'savedObjects:listingLimit': number;
'query:queryString:options': string;
'metrics:max_buckets': number;
'metrics:allowStringIndices': boolean;
'query:allowLeadingWildcards': boolean;
metaFields: string[];
'indexPattern:placeholder': string;

View file

@ -7428,6 +7428,12 @@
"description": "Non-default value of setting."
}
},
"metrics:allowStringIndices": {
"type": "boolean",
"_meta": {
"description": "Non-default value of setting."
}
},
"query:allowLeadingWildcards": {
"type": "boolean",
"_meta": {

View file

@ -6,7 +6,10 @@
* Side Public License, v 1.
*/
export const MAX_BUCKETS_SETTING = 'metrics:max_buckets';
export const UI_SETTINGS = {
MAX_BUCKETS_SETTING: 'metrics:max_buckets',
ALLOW_STRING_INDICES: 'metrics:allowStringIndices',
};
export const INDEXES_SEPARATOR = ',';
export const AUTO_INTERVAL = 'auto';
export const ROUTES = {

View file

@ -17,9 +17,17 @@ import {
EuiSpacer,
EuiSwitch,
EuiText,
EuiLink,
} from '@elastic/eui';
import type { PopoverProps } from './types';
import { getCoreStart, getUISettings } from '../../../../services';
import { UI_SETTINGS } from '../../../../../common/constants';
const allowStringIndicesMessage = i18n.translate(
'visTypeTimeseries.indexPatternSelect.switchModePopover.allowStringIndices',
{ defaultMessage: 'Allow string indices in TSVB' }
);
export const SwitchModePopover = ({ onModeChange, useKibanaIndices }: PopoverProps) => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
@ -30,6 +38,39 @@ export const SwitchModePopover = ({ onModeChange, useKibanaIndices }: PopoverPro
onModeChange(!useKibanaIndices);
}, [onModeChange, useKibanaIndices]);
const { application } = getCoreStart();
const canEditAdvancedSettings = application.capabilities.advancedSettings.save;
const handleAllowStringIndicesLinkClick = useCallback(
() =>
application.navigateToApp('management', {
path: `/kibana/settings?query=${UI_SETTINGS.ALLOW_STRING_INDICES}`,
}),
[application]
);
const stringIndicesAllowed = getUISettings().get(UI_SETTINGS.ALLOW_STRING_INDICES);
const isSwitchDisabled = useKibanaIndices && !stringIndicesAllowed;
let allowStringIndicesLabel;
if (!stringIndicesAllowed) {
allowStringIndicesLabel = (
<FormattedMessage
id="visTypeTimeseries.indexPatternSelect.switchModePopover.enableAllowStringIndices"
defaultMessage="To search by Elasticsearch indices enable {allowStringIndices} setting."
values={{
allowStringIndices: canEditAdvancedSettings ? (
<EuiLink color="accent" onClick={handleAllowStringIndicesLinkClick}>
{allowStringIndicesMessage}
</EuiLink>
) : (
<strong>{allowStringIndicesMessage}</strong>
),
}}
/>
);
}
return (
<EuiPopover
button={
@ -42,14 +83,18 @@ export const SwitchModePopover = ({ onModeChange, useKibanaIndices }: PopoverPro
}
)}
onClick={onButtonClick}
data-test-subj="switchIndexPatternSelectionModePopover"
data-test-subj="switchIndexPatternSelectionModePopoverButton"
/>
}
isOpen={isPopoverOpen}
closePopover={closePopover}
style={{ height: 'auto' }}
initialFocus={false}
>
<div style={{ width: '360px' }}>
<div
style={{ width: '360px' }}
data-test-subj="switchIndexPatternSelectionModePopoverContent"
>
<EuiPopoverTitle>
{i18n.translate('visTypeTimeseries.indexPatternSelect.switchModePopover.title', {
defaultMessage: 'Index pattern selection mode',
@ -59,7 +104,10 @@ export const SwitchModePopover = ({ onModeChange, useKibanaIndices }: PopoverPro
<FormattedMessage
id="visTypeTimeseries.indexPatternSelect.switchModePopover.text"
defaultMessage="An index pattern identifies one or more Elasticsearch indices that you want to explore.
You can use Elasticsearch indices or Kibana index patterns (recommended)."
Kibana index patterns are used by default. {allowStringIndicesLabel}"
values={{
allowStringIndicesLabel,
}}
/>
</EuiText>
<EuiSpacer />
@ -68,10 +116,11 @@ export const SwitchModePopover = ({ onModeChange, useKibanaIndices }: PopoverPro
label={i18n.translate(
'visTypeTimeseries.indexPatternSelect.switchModePopover.useKibanaIndices',
{
defaultMessage: 'Use only Kibana index patterns',
defaultMessage: 'Use only index patterns',
}
)}
onChange={switchMode}
disabled={isSwitchDisabled}
data-test-subj="switchIndexPatternSelectionMode"
/>
</div>

View file

@ -43,7 +43,7 @@ export const UseIndexPatternModeCallout = () => {
<p>
<FormattedMessage
id="visTypeTimeseries.visEditorVisualization.indexPatternMode.notificationMessage"
defaultMessage="Great news! You can now visualize the data from Elasticsearch indices or Kibana index patterns. {indexPatternModeLink}."
defaultMessage="Great news! You can now visualize the data from Kibana index patterns (recommended) or Elasticsearch indices. {indexPatternModeLink}."
values={{
indexPatternModeLink: (
<EuiLink href={indexPatternModeLink} target="_blank" external>

View file

@ -20,8 +20,8 @@ import { getSeriesData } from './vis_data/get_series_data';
import { getTableData } from './vis_data/get_table_data';
import { getEsQueryConfig } from './vis_data/helpers/get_es_query_uisettings';
import { getCachedIndexPatternFetcher } from './search_strategies/lib/cached_index_pattern_fetcher';
import { MAX_BUCKETS_SETTING } from '../../common/constants';
import { getIntervalAndTimefield } from './vis_data/get_interval_and_timefield';
import { UI_SETTINGS } from '../../common/constants';
export async function getVisData(
requestContext: VisTypeTimeseriesRequestHandlerContext,
@ -57,7 +57,7 @@ export async function getVisData(
index = await cachedIndexPatternFetcher(index.indexPatternString, true);
}
const maxBuckets = await uiSettings.get<number>(MAX_BUCKETS_SETTING);
const maxBuckets = await uiSettings.get<number>(UI_SETTINGS.MAX_BUCKETS_SETTING);
const { min, max } = request.body.timerange;
return getIntervalAndTimefield(

View file

@ -15,7 +15,7 @@ import type {
VisTypeTimeseriesRequestHandlerContext,
VisTypeTimeseriesRequest,
} from '../../../types';
import { MAX_BUCKETS_SETTING } from '../../../../common/constants';
import { UI_SETTINGS } from '../../../../common/constants';
export class DefaultSearchStrategy extends AbstractSearchStrategy {
async checkForViability(
@ -29,7 +29,7 @@ export class DefaultSearchStrategy extends AbstractSearchStrategy {
capabilities: new DefaultSearchCapabilities({
panel: req.body.panels ? req.body.panels[0] : null,
timezone: req.body.timerange?.timezone,
maxBucketsLimit: await uiSettings.get(MAX_BUCKETS_SETTING),
maxBucketsLimit: await uiSettings.get(UI_SETTINGS.MAX_BUCKETS_SETTING),
}),
};
}

View file

@ -20,7 +20,7 @@ import type {
VisTypeTimeseriesRequestHandlerContext,
VisTypeTimeseriesVisDataRequest,
} from '../../../types';
import { MAX_BUCKETS_SETTING } from '../../../../common/constants';
import { UI_SETTINGS } from '../../../../common/constants';
const getRollupIndices = (rollupData: { [key: string]: any }) => Object.keys(rollupData);
const isIndexPatternContainsWildcard = (indexPattern: string) => indexPattern.includes('*');
@ -75,7 +75,7 @@ export class RollupSearchStrategy extends AbstractSearchStrategy {
capabilities = new RollupSearchCapabilities(
{
maxBucketsLimit: await uiSettings.get(MAX_BUCKETS_SETTING),
maxBucketsLimit: await uiSettings.get(UI_SETTINGS.MAX_BUCKETS_SETTING),
panel: req.body.panels ? req.body.panels[0] : null,
},
fieldsCapabilities,

View file

@ -10,11 +10,10 @@ import { i18n } from '@kbn/i18n';
import { schema } from '@kbn/config-schema';
import { UiSettingsParams } from 'kibana/server';
import { MAX_BUCKETS_SETTING } from '../common/constants';
import { UI_SETTINGS } from '../common/constants';
export const getUiSettings: () => Record<string, UiSettingsParams> = () => ({
[MAX_BUCKETS_SETTING]: {
[UI_SETTINGS.MAX_BUCKETS_SETTING]: {
name: i18n.translate('visTypeTimeseries.advancedSettings.maxBucketsTitle', {
defaultMessage: 'TSVB buckets limit',
}),
@ -25,4 +24,16 @@ export const getUiSettings: () => Record<string, UiSettingsParams> = () => ({
}),
schema: schema.number(),
},
[UI_SETTINGS.ALLOW_STRING_INDICES]: {
name: i18n.translate('visTypeTimeseries.advancedSettings.allowStringIndicesTitle', {
defaultMessage: 'Allow string indices in TSVB',
}),
value: false,
requiresPageReload: true,
description: i18n.translate('visTypeTimeseries.advancedSettings.allowStringIndicesText', {
defaultMessage:
'Enables you to use index patterns and Elasticsearch indices in <strong>TSVB</strong> visualizations.',
}),
schema: schema.boolean(),
},
});

View file

@ -16,6 +16,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
const inspector = getService('inspector');
const retry = getService('retry');
const security = getService('security');
const kibanaServer = getService('kibanaServer');
const { timePicker, visChart, visualBuilder, visualize, settings } = getPageObjects([
'timePicker',
@ -95,6 +96,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await visualBuilder.setFieldForAggregation('machine.ram');
const kibanaIndexPatternModeValue = await visualBuilder.getMetricValue();
await kibanaServer.uiSettings.update({ 'metrics:allowStringIndices': true });
await browser.refresh();
await visualBuilder.clickPanelOptions('metric');
await visualBuilder.switchIndexPatternSelectionMode(false);
const stringIndexPatternModeValue = await visualBuilder.getMetricValue();

View file

@ -433,6 +433,49 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
after(async () => await visualBuilder.toggleNewChartsLibraryWithDebug(false));
});
describe('index pattern selection mode', () => {
it('should disable switch for Kibana index patterns mode by default', async () => {
await visualBuilder.clickPanelOptions('timeSeries');
const isEnabled = await visualBuilder.checkIndexPatternSelectionModeSwitchIsEnabled();
expect(isEnabled).to.be(false);
});
describe('metrics:allowStringIndices = true', () => {
before(async () => {
await kibanaServer.uiSettings.update({ 'metrics:allowStringIndices': true });
await browser.refresh();
});
beforeEach(async () => await visualBuilder.clickPanelOptions('timeSeries'));
it('should not disable switch for Kibana index patterns mode', async () => {
await visualBuilder.switchIndexPatternSelectionMode(true);
const isEnabled = await visualBuilder.checkIndexPatternSelectionModeSwitchIsEnabled();
expect(isEnabled).to.be(true);
});
it('should disable switch after selecting Kibana index patterns mode and metrics:allowStringIndices = false', async () => {
await visualBuilder.switchIndexPatternSelectionMode(false);
await kibanaServer.uiSettings.update({ 'metrics:allowStringIndices': false });
await browser.refresh();
await visualBuilder.clickPanelOptions('timeSeries');
let isEnabled = await visualBuilder.checkIndexPatternSelectionModeSwitchIsEnabled();
expect(isEnabled).to.be(true);
await visualBuilder.switchIndexPatternSelectionMode(true);
isEnabled = await visualBuilder.checkIndexPatternSelectionModeSwitchIsEnabled();
expect(isEnabled).to.be(false);
});
after(
async () =>
await kibanaServer.uiSettings.update({ 'metrics:allowStringIndices': false })
);
});
});
});
});
}

View file

@ -502,12 +502,32 @@ export class VisualBuilderPageObject extends FtrService {
return await annotationTooltipDetails.getVisibleText();
}
public async toggleIndexPatternSelectionModePopover(shouldOpen: boolean) {
const isPopoverOpened = await this.testSubjects.exists(
'switchIndexPatternSelectionModePopoverContent'
);
if ((shouldOpen && !isPopoverOpened) || (!shouldOpen && isPopoverOpened)) {
await this.testSubjects.click('switchIndexPatternSelectionModePopoverButton');
}
}
public async switchIndexPatternSelectionMode(useKibanaIndices: boolean) {
await this.testSubjects.click('switchIndexPatternSelectionModePopover');
await this.toggleIndexPatternSelectionModePopover(true);
await this.testSubjects.setEuiSwitch(
'switchIndexPatternSelectionMode',
useKibanaIndices ? 'check' : 'uncheck'
);
await this.toggleIndexPatternSelectionModePopover(false);
}
public async checkIndexPatternSelectionModeSwitchIsEnabled() {
await this.toggleIndexPatternSelectionModePopover(true);
let isEnabled;
await this.testSubjects.retry.tryForTime(2000, async () => {
isEnabled = await this.testSubjects.isEnabled('switchIndexPatternSelectionMode');
});
await this.toggleIndexPatternSelectionModePopover(false);
return isEnabled;
}
public async setIndexPatternValue(value: string, useKibanaIndices?: boolean) {

View file

@ -5227,9 +5227,7 @@
"visTypeTimeseries.indexPatternSelect.label": "インデックスパターン",
"visTypeTimeseries.indexPatternSelect.queryAllIndexesText": "すべてのインデックスにクエリを実行するには * を使用します",
"visTypeTimeseries.indexPatternSelect.switchModePopover.areaLabel": "インデックスパターン選択モードを構成",
"visTypeTimeseries.indexPatternSelect.switchModePopover.text": "インデックスパターンは、データ探索で対象とする1つ以上のElasticsearchインデックスを定義します。ElasticsearchインデックスまたはKibanaインデックスパターン推奨を使用できます。",
"visTypeTimeseries.indexPatternSelect.switchModePopover.title": "インデックスパターン選択モード",
"visTypeTimeseries.indexPatternSelect.switchModePopover.useKibanaIndices": "Kibanaインデックスパターンのみを使用",
"visTypeTimeseries.kbnVisTypes.metricsDescription": "時系列データの高度な分析を実行します。",
"visTypeTimeseries.kbnVisTypes.metricsTitle": "TSVB",
"visTypeTimeseries.lastValueModeIndicator.lastBucketDate": "バケット:{lastBucketDate}",
@ -5556,7 +5554,6 @@
"visTypeTimeseries.visEditorVisualization.changesWillBeAutomaticallyAppliedMessage": "変更が自動的に適用されます。",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.dismissNoticeButtonText": "閉じる",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.link": "確認してください。",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.notificationMessage": "お知らせElasticsearchインデックスまたはKibanaインデックスパターンからデータを可視化できるようになりました。{indexPatternModeLink}。",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.notificationTitle": "TSVBはインデックスパターンをサポートします",
"visTypeTimeseries.visPicker.gaugeLabel": "ゲージ",
"visTypeTimeseries.visPicker.metricLabel": "メトリック",

View file

@ -5272,9 +5272,7 @@
"visTypeTimeseries.indexPatternSelect.label": "索引模式",
"visTypeTimeseries.indexPatternSelect.queryAllIndexesText": "要查询所有索引,请使用 *",
"visTypeTimeseries.indexPatternSelect.switchModePopover.areaLabel": "配置索引模式选择模式",
"visTypeTimeseries.indexPatternSelect.switchModePopover.text": "索引模式可识别一个或多个您希望浏览的 Elasticsearch 索引。可用使用 Elasticsearch 索引或 Kibana 索引模式(推荐)。",
"visTypeTimeseries.indexPatternSelect.switchModePopover.title": "索引模式选择模式",
"visTypeTimeseries.indexPatternSelect.switchModePopover.useKibanaIndices": "仅使用 Kibana 索引模式",
"visTypeTimeseries.kbnVisTypes.metricsDescription": "对时间序列数据执行高级分析。",
"visTypeTimeseries.kbnVisTypes.metricsTitle": "TSVB",
"visTypeTimeseries.lastValueModeIndicator.lastBucketDate": "存储桶:{lastBucketDate}",
@ -5602,7 +5600,6 @@
"visTypeTimeseries.visEditorVisualization.changesWillBeAutomaticallyAppliedMessage": "将自动应用更改。",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.dismissNoticeButtonText": "关闭",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.link": "请查看。",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.notificationMessage": "好消息!现在可以可视化 Elasticsearch 索引或 Kibana 索引模式的数据。{indexPatternModeLink}。",
"visTypeTimeseries.visEditorVisualization.indexPatternMode.notificationTitle": "TSVB 现在支持索引模式",
"visTypeTimeseries.visPicker.gaugeLabel": "仪表盘",
"visTypeTimeseries.visPicker.metricLabel": "指标",

View file

@ -43,6 +43,7 @@ export default function ({ getService, getPageObjects }) {
await kibanaServer.uiSettings.replace({
defaultIndex: 'rollup',
});
await kibanaServer.uiSettings.update({ 'metrics:allowStringIndices': true });
});
it('create rollup tsvb', async () => {
@ -110,6 +111,7 @@ export default function ({ getService, getPageObjects }) {
await kibanaServer.importExport.unload(
'x-pack/test/functional/fixtures/kbn_archiver/rollup/rollup.json'
);
await kibanaServer.uiSettings.update({ 'metrics:allowStringIndices': false });
await security.testUser.restoreDefaults();
});
});