diff --git a/src/plugins/vis_type_timeseries/common/index_patterns_utils.test.ts b/src/plugins/vis_type_timeseries/common/index_patterns_utils.test.ts index 515fadffb6b32..0428e6e80ae78 100644 --- a/src/plugins/vis_type_timeseries/common/index_patterns_utils.test.ts +++ b/src/plugins/vis_type_timeseries/common/index_patterns_utils.test.ts @@ -44,7 +44,7 @@ describe('extractIndexPatterns', () => { }); test('should return index patterns', () => { - expect(extractIndexPatternValues(panel, '')).toEqual([ + expect(extractIndexPatternValues(panel, null)).toEqual([ '*', 'example-1-*', 'example-2-*', diff --git a/src/plugins/vis_type_timeseries/common/index_patterns_utils.ts b/src/plugins/vis_type_timeseries/common/index_patterns_utils.ts index 398d1c30ed5a7..af9f0750b2604 100644 --- a/src/plugins/vis_type_timeseries/common/index_patterns_utils.ts +++ b/src/plugins/vis_type_timeseries/common/index_patterns_utils.ts @@ -8,7 +8,7 @@ import { uniq } from 'lodash'; import { PanelSchema, IndexPatternValue, FetchedIndexPattern } from '../common/types'; -import { IndexPatternsService } from '../../data/common'; +import { IIndexPattern, IndexPatternsService } from '../../data/common'; export const isStringTypeIndexPattern = ( indexPatternValue: IndexPatternValue @@ -19,7 +19,7 @@ export const getIndexPatternKey = (indexPatternValue: IndexPatternValue) => export const extractIndexPatternValues = ( panel: PanelSchema, - defaultIndex?: PanelSchema['default_index_pattern'] + defaultIndex: IIndexPattern | null ) => { const patterns: IndexPatternValue[] = []; @@ -43,8 +43,8 @@ export const extractIndexPatternValues = ( }); } - if (patterns.length === 0 && defaultIndex) { - patterns.push(defaultIndex); + if (patterns.length === 0 && defaultIndex?.id) { + patterns.push({ id: defaultIndex.id }); } return uniq(patterns).sort(); diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index 383b089593565..9fb7644b0fd16 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -213,8 +213,6 @@ export const panel = schema.object({ bar_color_rules: schema.maybe(arrayNullable), background_color: stringOptionalNullable, background_color_rules: schema.maybe(schema.arrayOf(backgroundColorRulesItems)), - default_index_pattern: stringOptionalNullable, - default_timefield: stringOptionalNullable, drilldown_url: stringOptional, drop_last_bucket: numberIntegerOptional, filter: schema.maybe(queryObject), diff --git a/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js b/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js index 0ad6344ac51b7..5a991238d10f8 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js +++ b/src/plugins/vis_type_timeseries/public/application/components/index_pattern.js @@ -29,6 +29,7 @@ import { YesNo } from './yes_no'; import { LastValueModePopover } from './last_value_mode_popover'; import { KBN_FIELD_TYPES } from '../../../../data/public'; import { FormValidationContext } from '../contexts/form_validation_context'; +import { DefaultIndexPatternContext } from '../contexts/default_index_context'; import { isGteInterval, validateReInterval, isAutoInterval } from './lib/get_interval'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -76,6 +77,7 @@ export const IndexPattern = ({ const intervalName = `${prefix}interval`; const maxBarsName = `${prefix}max_bars`; const dropBucketName = `${prefix}drop_last_bucket`; + const defaultIndex = useContext(DefaultIndexPatternContext); const updateControlValidity = useContext(FormValidationContext); const uiRestrictions = get(useContext(VisDataContext), 'uiRestrictions'); const maxBarsUiSettings = config.get(UI_SETTINGS.HISTOGRAM_MAX_BARS); @@ -110,7 +112,6 @@ export const IndexPattern = ({ ]; const defaults = { - default_index_pattern: '', [indexPatternName]: '', [intervalName]: AUTO_INTERVAL, [dropBucketName]: 1, @@ -120,7 +121,6 @@ export const IndexPattern = ({ const model = { ...defaults, ..._model }; - const isDefaultIndexPatternUsed = model.default_index_pattern && !model[indexPatternName]; const intervalValidation = validateIntervalValue(model[intervalName]); const selectedTimeRangeOption = timeRangeOptions.find( ({ value }) => model[TIME_RANGE_MODE_KEY] === value @@ -205,7 +205,7 @@ export const IndexPattern = ({ onChange={handleSelectChange(timeFieldName)} indexPattern={model[indexPatternName]} fields={fields} - placeholder={isDefaultIndexPatternUsed ? model.default_timefield : undefined} + placeholder={defaultIndex?.timeFieldName} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/index_pattern_select/index_pattern_select.tsx b/src/plugins/vis_type_timeseries/public/application/components/lib/index_pattern_select/index_pattern_select.tsx index 28b9c173a2b1b..ac86a299dfa1c 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/index_pattern_select/index_pattern_select.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/index_pattern_select/index_pattern_select.tsx @@ -23,6 +23,7 @@ import { FieldTextSelect } from './field_text_select'; import { ComboBoxSelect } from './combo_box_select'; import type { IndexPatternValue, FetchedIndexPattern } from '../../../../../common/types'; +import { DefaultIndexPatternContext } from '../../../contexts/default_index_context'; const USE_KIBANA_INDEXES_KEY = 'use_kibana_indexes'; @@ -61,6 +62,8 @@ export const IndexPatternSelect = ({ }: IndexPatternSelectProps) => { const htmlId = htmlIdGenerator(); const panelModel = useContext(PanelModelContext); + const defaultIndex = useContext(DefaultIndexPatternContext); + const [fetchedIndex, setFetchedIndex] = useState(); const useKibanaIndices = Boolean(panelModel?.[USE_KIBANA_INDEXES_KEY]); const Component = useKibanaIndices ? ComboBoxSelect : FieldTextSelect; @@ -146,7 +149,7 @@ export const IndexPatternSelect = ({ allowSwitchMode={allowIndexSwitchingMode} onIndexChange={onIndexChange} onModeChange={onModeChange} - placeholder={panelModel?.default_index_pattern ?? ''} + placeholder={defaultIndex?.title ?? ''} data-test-subj="metricsIndexPatternInput" /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.tsx b/src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.tsx index f39ff6923f5ce..99c3fa8ea9673 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/gauge.tsx @@ -152,7 +152,7 @@ export class GaugePanelConfig extends Component< onChange={(filter) => { this.props.onChange({ filter }); }} - indexPatterns={[model.index_pattern || model.default_index_pattern || '']} + indexPatterns={[model.index_pattern]} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx b/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx index a9d9d01376608..c3f0f00125769 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/markdown.tsx @@ -167,7 +167,7 @@ export class MarkdownPanelConfig extends Component< onChange={(filter) => { this.props.onChange({ filter }); }} - indexPatterns={[model.index_pattern || model.default_index_pattern || '']} + indexPatterns={[model.index_pattern]} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/metric.tsx b/src/plugins/vis_type_timeseries/public/application/components/panel_config/metric.tsx index 3ab49c1bef873..f38d0ec83e957 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/metric.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/metric.tsx @@ -116,7 +116,7 @@ export class MetricPanelConfig extends Component< onChange={(filter) => { this.props.onChange({ filter }); }} - indexPatterns={[model.index_pattern || model.default_index_pattern || '']} + indexPatterns={[model.index_pattern]} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.tsx b/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.tsx index f3d01df19666a..1a78585de433a 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/table.tsx @@ -244,7 +244,7 @@ export class TablePanelConfig extends Component< onChange={(filter) => { this.props.onChange({ filter }); }} - indexPatterns={[model.index_pattern || model.default_index_pattern || '']} + indexPatterns={[model.index_pattern]} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.tsx b/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.tsx index 2e714b8db480b..ae36408a08b46 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/timeseries.tsx @@ -207,7 +207,7 @@ export class TimeseriesPanelConfig extends Component< onChange={(filter) => { this.props.onChange({ filter }); }} - indexPatterns={[model.index_pattern || model.default_index_pattern || '']} + indexPatterns={[model.index_pattern]} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/panel_config/top_n.tsx b/src/plugins/vis_type_timeseries/public/application/components/panel_config/top_n.tsx index 78ac11eb39744..a537a769cac11 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/panel_config/top_n.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/panel_config/top_n.tsx @@ -144,7 +144,7 @@ export class TopNPanelConfig extends Component< onChange={(filter: PanelConfigProps['model']['filter']) => { this.props.onChange({ filter }); }} - indexPatterns={[model.index_pattern || model.default_index_pattern || '']} + indexPatterns={[model.index_pattern]} /> diff --git a/src/plugins/vis_type_timeseries/public/application/components/query_bar_wrapper.tsx b/src/plugins/vis_type_timeseries/public/application/components/query_bar_wrapper.tsx index f9a5de313521a..ccbfebe84bc51 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/query_bar_wrapper.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/query_bar_wrapper.tsx @@ -9,6 +9,7 @@ import React, { useContext, useEffect, useState } from 'react'; import { CoreStartContext } from '../contexts/query_input_bar_context'; +import { DefaultIndexPatternContext } from '../contexts/default_index_context'; import { IndexPatternValue } from '../../../common/types'; import { QueryStringInput, QueryStringInputProps } from '../../../../../plugins/data/public'; @@ -24,27 +25,32 @@ export function QueryBarWrapper({ query, onChange, indexPatterns }: QueryBarWrap const [indexes, setIndexes] = useState([]); const coreStartContext = useContext(CoreStartContext); + const defaultIndex = useContext(DefaultIndexPatternContext); useEffect(() => { async function fetchIndexes() { const i: QueryStringInputProps['indexPatterns'] = []; for (const index of indexPatterns ?? []) { - if (isStringTypeIndexPattern(index)) { - i.push(index); - } else if (index?.id) { - const fetchedIndex = await fetchIndexPattern(index, indexPatternsService); - - if (fetchedIndex.indexPattern) { - i.push(fetchedIndex.indexPattern); + if (index) { + if (isStringTypeIndexPattern(index)) { + i.push(index); + } else if (index?.id) { + const { indexPattern } = await fetchIndexPattern(index, indexPatternsService); + + if (indexPattern) { + i.push(indexPattern); + } } + } else if (defaultIndex) { + i.push(defaultIndex); } } setIndexes(i); } fetchIndexes(); - }, [indexPatterns, indexPatternsService]); + }, [indexPatterns, indexPatternsService, defaultIndex]); return ( ); }} diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.tsx b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.tsx index 887075e9e4e48..90b7ccaa14d86 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.tsx @@ -12,17 +12,19 @@ import { share } from 'rxjs/operators'; import { isEqual, isEmpty, debounce } from 'lodash'; import { EventEmitter } from 'events'; -import { IUiSettingsClient } from 'kibana/public'; -import { TimeRange } from 'src/plugins/data/public'; +import type { IUiSettingsClient } from 'kibana/public'; import { Vis, PersistedState, VisualizeEmbeddableContract, -} from 'src/plugins/visualizations/public'; -import { IndexPatternValue, TimeseriesVisData } from 'src/plugins/vis_type_timeseries/common/types'; +} from '../../../../../plugins/visualizations/public'; import { KibanaContextProvider } from '../../../../../plugins/kibana_react/public'; +import { DefaultIndexPatternContext } from '../contexts/default_index_context'; import { Storage } from '../../../../../plugins/kibana_utils/public'; +import type { IIndexPattern, TimeRange } from '../../../../../plugins/data/public'; +import type { IndexPatternValue, TimeseriesVisData } from '../../../common/types'; + // @ts-expect-error import { VisEditorVisualization } from './vis_editor_visualization'; import { PanelConfig } from './panel_config'; @@ -48,6 +50,7 @@ export interface TimeseriesEditorProps { interface TimeseriesEditorState { autoApply: boolean; dirty: boolean; + defaultIndex: IIndexPattern | null; extractedIndexPatterns: IndexPatternValue[]; model: TimeseriesVisParams; visFields?: VisFields; @@ -65,6 +68,7 @@ export class VisEditor extends Component { @@ -175,35 +179,37 @@ export class VisEditor extends Component -
-
- -
- -
- +
+
+ +
+ +
+ +
-
+ ); } @@ -212,24 +218,13 @@ export class VisEditor extends Component { - const defaultIndexTitle = index?.title ?? ''; - const indexPatterns = extractIndexPatternValues(this.props.vis.params, defaultIndexTitle); + const indexPatterns = extractIndexPatternValues(this.props.vis.params, index); const visFields = await fetchFields(indexPatterns); - this.setState((state) => ({ - model: { - ...state.model, - /** @legacy - * please use IndexPatterns service instead - * **/ - default_index_pattern: defaultIndexTitle, - /** @legacy - * please use IndexPatterns service instead - * **/ - default_timefield: index?.timeFieldName ?? '', - }, + this.setState({ + defaultIndex: index, visFields, - })); + }); }); this.props.eventEmitter.on('updateEditor', this.updateModel); diff --git a/src/plugins/vis_type_timeseries/public/application/contexts/default_index_context.ts b/src/plugins/vis_type_timeseries/public/application/contexts/default_index_context.ts new file mode 100644 index 0000000000000..a8770d86fba9b --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/application/contexts/default_index_context.ts @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import React from 'react'; +import { IIndexPattern } from '../../../../data/public'; + +export const DefaultIndexPatternContext = React.createContext(null); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts index e7410c7a97343..b082737cce288 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.test.ts @@ -1953,4 +1953,28 @@ describe('migration visualization', () => { expect(hideLastValueIndicator).toBeUndefined(); }); }); + + describe('7.13.0 tsvb - remove default_index_pattern and default_timefield from Model', () => { + const migrate = (doc: any) => + visualizationSavedObjectTypeMigrations['7.13.0']( + doc as Parameters[0], + savedObjectMigrationContext + ); + + const createTestDocWithType = () => ({ + attributes: { + title: 'My Vis', + description: 'This is my super cool vis.', + visState: `{"type":"metrics","params":{"default_index_pattern":"test", "default_timefield":"test"}}`, + }, + }); + + it('should remove default_index_pattern and default_timefield', () => { + const migratedTestDoc = migrate(createTestDocWithType()); + const { params } = JSON.parse(migratedTestDoc.attributes.visState); + + expect(params).not.toHaveProperty('default_index_pattern'); + expect(params).not.toHaveProperty('default_timefield'); + }); + }); }); diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index 633442ec55d69..093255d65a7a8 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -951,6 +951,36 @@ const hideTSVBLastValueIndicator: SavedObjectMigrationFn = (doc) => { return doc; }; +const removeDefaultIndexPatternAndTimeFieldFromTSVBModel: SavedObjectMigrationFn = ( + doc +) => { + const visStateJSON = get(doc, 'attributes.visState'); + let visState; + + if (visStateJSON) { + try { + visState = JSON.parse(visStateJSON); + } catch (e) { + // Let it go, the data is invalid and we'll leave it as is + } + if (visState && visState.type === 'metrics') { + const { params } = visState; + + delete params.default_index_pattern; + delete params.default_timefield; + + return { + ...doc, + attributes: { + ...doc.attributes, + visState: JSON.stringify(visState), + }, + }; + } + } + return doc; +}; + export const visualizationSavedObjectTypeMigrations = { /** * We need to have this migration twice, once with a version prior to 7.0.0 once with a version @@ -986,5 +1016,9 @@ export const visualizationSavedObjectTypeMigrations = { '7.10.0': flow(migrateFilterRatioQuery, removeTSVBSearchSource), '7.11.0': flow(enableDataTableVisToolbar), '7.12.0': flow(migrateVislibAreaLineBarTypes, migrateSchema), - '7.13.0': flow(addSupportOfDualIndexSelectionModeInTSVB, hideTSVBLastValueIndicator), + '7.13.0': flow( + addSupportOfDualIndexSelectionModeInTSVB, + hideTSVBLastValueIndicator, + removeDefaultIndexPatternAndTimeFieldFromTSVBModel + ), };