From c2bfdffee241ae5803a2709a6b284ddde4f129a6 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Mon, 16 Nov 2020 17:59:26 +0300 Subject: [PATCH 01/18] Implement custom renderer --- .../components/timeseries_visualization.tsx | 116 ++++++++++++++++++ .../application/components/vis_types/index.ts | 61 +++++++++ .../vis_type_timeseries/public/metrics_fn.ts | 6 +- .../public/metrics_type.ts | 2 - .../vis_type_timeseries/public/plugin.ts | 8 +- .../public/timeseries_vis_renderer.tsx | 63 ++++++++++ 6 files changed, 250 insertions(+), 6 deletions(-) create mode 100644 src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx create mode 100644 src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts create mode 100644 src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx diff --git a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx new file mode 100644 index 0000000000000..aa965d555a5f9 --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx @@ -0,0 +1,116 @@ +/* + * 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, { useCallback, useEffect } from 'react'; + +import { IUiSettingsClient } from 'src/core/public'; +import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import { PersistedState } from 'src/plugins/visualizations/public'; + +// @ts-expect-error +import { ErrorComponent } from './error'; +import { TimeseriesVisTypes } from './vis_types'; + +interface TimeseriesVisualizationProps { + className?: string; + dateFormat: string; + getConfig: IUiSettingsClient['get']; + handlers: IInterpreterRenderHandlers; + model: { + id: string; + type: keyof typeof TimeseriesVisTypes; + }; + visData: any; + uiState: PersistedState; +} + +function TimeseriesVisualization({ + className = 'tvbVis', + visData, + model, + handlers, + uiState, + ...visProps +}: TimeseriesVisualizationProps) { + const onBrush = useCallback( + (gte: string, lte: string) => { + handlers.event({ + name: 'applyFilter', + data: { + timeFieldName: '*', + filters: [ + { + range: { + '*': { + gte, + lte, + }, + }, + }, + ], + }, + }); + }, + [handlers] + ); + + const handleUiState = useCallback( + (field: string, value: { column: string; order: string }) => { + uiState.set(field, value); + // reload visualization because data might need to be re-fetched + uiState.emit('reload'); + }, + [uiState] + ); + + useEffect(() => { + handlers.done(); + }); + + // Show the error panel + const error = visData[model.id]?.error; + if (error) { + return ( +
+ +
+ ); + } + + const VisComponent = TimeseriesVisTypes[model.type]; + + if (VisComponent) { + return ( + + ); + } + + return
; +} + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TimeseriesVisualization as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts new file mode 100644 index 0000000000000..cee56af9bfe9d --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts @@ -0,0 +1,61 @@ +/* + * 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 { IUiSettingsClient } from 'src/core/public'; +import { PersistedState } from 'src/plugins/visualizations/public'; + +// @ts-expect-error +import { TimeseriesVisualization as timeseries } from './timeseries/vis'; +// @ts-expect-error +import { metric } from './metric/vis'; +// @ts-expect-error +import { TopNVisualization as topN } from './top_n/vis'; +// @ts-expect-error +import { TableVis as table } from './table/vis'; +// @ts-expect-error +import { gauge } from './gauge/vis'; +// @ts-expect-error +import { MarkdownVisualization as markdown } from './markdown/vis'; + +export const TimeseriesVisTypes: Record> = { + timeseries, + metric, + top_n: topN, + table, + gauge, + markdown, +}; + +export interface TimeseriesVisProps { + model: any; + onBrush: (gte: string, lte: string) => void; + onUiState: ( + field: string, + value: { + column: string; + order: string; + } + ) => void; + uiState: PersistedState; + visData: any; + dateFormat: string; + getConfig: IUiSettingsClient['get']; +} diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index 8652d703f963e..5c42db92af1c3 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -26,7 +26,7 @@ import { ExpressionFunctionDefinition, Render } from '../../expressions/public'; import { metricsRequestHandler } from './request_handler'; type Input = KibanaContext | null; -type Output = Promise>; +type Output = Promise>; interface Arguments { params: string; @@ -36,7 +36,7 @@ interface Arguments { type VisParams = Required; -interface RenderValue { +export interface TimeseriesRenderValue { visType: 'metrics'; visData: Input; visConfig: VisParams; @@ -92,7 +92,7 @@ export const createMetricsFn = (): ExpressionFunctionDefinition< return { type: 'render', - as: 'visualization', + as: 'timeseries_vis', value: { uiState, visType: 'metrics', diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index 682517ab1a996..017955240ddf8 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -24,7 +24,6 @@ import { metricsRequestHandler } from './request_handler'; import { EditorController } from './application'; // @ts-ignore import { PANEL_TYPES } from '../common/panel_types'; -import { VisEditor } from './application/components/vis_editor_lazy'; import { VIS_EVENT_TO_TRIGGER, VisGroups } from '../../visualizations/public'; export const metricsVisDefinition = { @@ -71,7 +70,6 @@ export const metricsVisDefinition = { show_grid: 1, tooltip_mode: 'show_all', }, - component: VisEditor, }, editor: EditorController, options: { diff --git a/src/plugins/vis_type_timeseries/public/plugin.ts b/src/plugins/vis_type_timeseries/public/plugin.ts index d98e55bdb340c..d36b3611680af 100644 --- a/src/plugins/vis_type_timeseries/public/plugin.ts +++ b/src/plugins/vis_type_timeseries/public/plugin.ts @@ -36,6 +36,7 @@ import { } from './services'; import { DataPublicPluginStart } from '../../data/public'; import { ChartsPluginSetup } from '../../charts/public'; +import { getTimeseriesVisRenderer } from './timeseries_vis_renderer'; /** @internal */ export interface MetricsPluginSetupDependencies { @@ -62,9 +63,14 @@ export class MetricsPlugin implements Plugin, void> { { expressions, visualizations, charts }: MetricsPluginSetupDependencies ) { expressions.registerFunction(createMetricsFn); + expressions.registerRenderer( + getTimeseriesVisRenderer({ + uiSettings: core.uiSettings, + }) + ); setUISettings(core.uiSettings); setChartsSetup(charts); - visualizations.createReactVisualization(metricsVisDefinition); + visualizations.createBaseVisualization(metricsVisDefinition); } public start(core: CoreStart, { data }: MetricsPluginStartDependencies) { diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx new file mode 100644 index 0000000000000..2bb749cfc9fef --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -0,0 +1,63 @@ +/* + * 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, { lazy } from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; + +import { IUiSettingsClient } from 'kibana/public'; +import { VisualizationContainer } from '../../visualizations/public'; +import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers'; +import { TimeseriesRenderValue } from './metrics_fn'; + +const TimeseriesVisualization = lazy( + () => import('./application/components/timeseries_visualization') +); + +const checkIfDataExists = (visData: any, model: any) => { + const data = visData.type === 'table' ? visData.series : visData[model.id].series; + return data.length > 0; +}; + +export const getTimeseriesVisRenderer: (deps: { + uiSettings: IUiSettingsClient; +}) => ExpressionRenderDefinition = ({ uiSettings }) => ({ + name: 'timeseries_vis', + reuseDomNode: true, + render: async (domNode, config, handlers) => { + handlers.onDestroy(() => { + unmountComponentAtNode(domNode); + }); + + const showNoResult = !checkIfDataExists(config.visData, config.visConfig); + + render( + + + , + domNode + ); + }, +}); From bcebcdb828eb9bf1dea8fc42a6720b65efbe958b Mon Sep 17 00:00:00 2001 From: sulemanof Date: Mon, 16 Nov 2020 18:05:49 +0300 Subject: [PATCH 02/18] Remove legacy code --- .../public/application/components/no_data.js | 41 -------- .../application/components/vis_editor.js | 60 ++---------- .../application/components/visualization.js | 96 ------------------- .../public/application/editor_controller.js | 1 - .../lib/create_brush_handler.test.ts | 48 ---------- .../application/lib/create_brush_handler.ts | 39 -------- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 8 files changed, 10 insertions(+), 277 deletions(-) delete mode 100644 src/plugins/vis_type_timeseries/public/application/components/no_data.js delete mode 100644 src/plugins/vis_type_timeseries/public/application/components/visualization.js delete mode 100644 src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.test.ts delete mode 100644 src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.ts diff --git a/src/plugins/vis_type_timeseries/public/application/components/no_data.js b/src/plugins/vis_type_timeseries/public/application/components/no_data.js deleted file mode 100644 index 1968f1858a46c..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/components/no_data.js +++ /dev/null @@ -1,41 +0,0 @@ -/* - * 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 { FormattedMessage } from '@kbn/i18n/react'; -import { EuiIcon, EuiSpacer, EuiText } from '@elastic/eui'; - -export function NoDataComponent() { - return ( -
- - -
- ); -} diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js index 47b30f9ab2711..1f9d17b2b251c 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_editor.js @@ -23,10 +23,8 @@ import * as Rx from 'rxjs'; import { share } from 'rxjs/operators'; import { isEqual, isEmpty, debounce } from 'lodash'; import { VisEditorVisualization } from './vis_editor_visualization'; -import { Visualization } from './visualization'; import { VisPicker } from './vis_picker'; import { PanelConfig } from './panel_config'; -import { createBrushHandler } from '../lib/create_brush_handler'; import { fetchFields } from '../lib/fetch_fields'; import { extractIndexPatterns } from '../../../../../plugins/vis_type_timeseries/common/extract_index_patterns'; import { getSavedObjectsClient, getUISettings, getDataStart, getCoreStart } from '../../services'; @@ -49,7 +47,6 @@ export class VisEditor extends Component { visFields: props.visFields, extractedIndexPatterns: [''], }; - this.onBrush = createBrushHandler((data) => props.vis.API.events.applyFilter(data)); this.visDataSubject = new Rx.BehaviorSubject(this.props.visData); this.visData$ = this.visDataSubject.asObservable().pipe(share()); @@ -71,12 +68,6 @@ export class VisEditor extends Component { return this.props.config.get(...args); }; - handleUiState = (field, value) => { - this.props.vis.uiState.set(field, value); - // reload visualization because data might need to be re-fetched - this.props.vis.uiState.emit('reload'); - }; - updateVisState = debounce(() => { this.props.vis.params = this.state.model; this.props.embeddableHandler.reload(); @@ -101,16 +92,14 @@ export class VisEditor extends Component { dirty = false; } - if (this.props.isEditorMode) { - const extractedIndexPatterns = extractIndexPatterns(nextModel); - if (!isEqual(this.state.extractedIndexPatterns, extractedIndexPatterns)) { - fetchFields(extractedIndexPatterns).then((visFields) => - this.setState({ - visFields, - extractedIndexPatterns, - }) - ); - } + const extractedIndexPatterns = extractIndexPatterns(nextModel); + if (!isEqual(this.state.extractedIndexPatterns, extractedIndexPatterns)) { + fetchFields(extractedIndexPatterns).then((visFields) => + this.setState({ + visFields, + extractedIndexPatterns, + }) + ); } this.setState({ @@ -141,23 +130,6 @@ export class VisEditor extends Component { }; render() { - if (!this.props.isEditorMode) { - if (!this.props.visParams || !this.props.visData) { - return null; - } - return ( - - ); - } - const { model } = this.state; if (model) { @@ -211,23 +183,12 @@ export class VisEditor extends Component { } componentDidMount() { - this.props.renderComplete(); - - if (this.props.isEditorMode && this.props.eventEmitter) { - this.props.eventEmitter.on('updateEditor', this.updateModel); - } - } - - componentDidUpdate() { - this.props.renderComplete(); + this.props.eventEmitter.on('updateEditor', this.updateModel); } componentWillUnmount() { this.updateVisState.cancel(); - - if (this.props.isEditorMode && this.props.eventEmitter) { - this.props.eventEmitter.off('updateEditor', this.updateModel); - } + this.props.eventEmitter.off('updateEditor', this.updateModel); } } @@ -241,7 +202,6 @@ VisEditor.propTypes = { visFields: PropTypes.object, renderComplete: PropTypes.func, config: PropTypes.object, - isEditorMode: PropTypes.bool, savedObj: PropTypes.object, timeRange: PropTypes.object, appState: PropTypes.object, diff --git a/src/plugins/vis_type_timeseries/public/application/components/visualization.js b/src/plugins/vis_type_timeseries/public/application/components/visualization.js deleted file mode 100644 index 8b8218653f97c..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/components/visualization.js +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 PropTypes from 'prop-types'; -import React from 'react'; -import _ from 'lodash'; - -import { TimeseriesVisualization } from './vis_types/timeseries/vis'; -import { metric } from './vis_types/metric/vis'; -import { TopNVisualization as topN } from './vis_types/top_n/vis'; -import { TableVis as table } from './vis_types/table/vis'; -import { gauge } from './vis_types/gauge/vis'; -import { MarkdownVisualization as markdown } from './vis_types/markdown/vis'; -import { ErrorComponent } from './error'; -import { NoDataComponent } from './no_data'; - -const types = { - timeseries: TimeseriesVisualization, - metric, - top_n: topN, - table, - gauge, - markdown, -}; - -export function Visualization(props) { - const { visData, model } = props; - // Show the error panel - const error = _.get(visData, `${model.id}.error`); - if (error) { - return ( -
- -
- ); - } - - const path = visData.type === 'table' ? 'series' : `${model.id}.series`; - const noData = _.get(visData, path, []).length === 0; - if (noData) { - return ( -
- -
- ); - } - - const component = types[model.type]; - if (component) { - return React.createElement(component, { - dateFormat: props.dateFormat, - backgroundColor: props.backgroundColor, - model: props.model, - onBrush: props.onBrush, - onChange: props.onChange, - onUiState: props.onUiState, - uiState: props.uiState, - visData: visData.type === model.type ? visData : {}, - getConfig: props.getConfig, - }); - } - return
; -} - -Visualization.propTypes = { - backgroundColor: PropTypes.string, - className: PropTypes.string, - model: PropTypes.object, - onBrush: PropTypes.func, - onChange: PropTypes.func, - onUiState: PropTypes.func, - uiState: PropTypes.object, - visData: PropTypes.object, - dateFormat: PropTypes.string, - getConfig: PropTypes.func, -}; - -Visualization.defaultProps = { - className: 'tvbVis', -}; diff --git a/src/plugins/vis_type_timeseries/public/application/editor_controller.js b/src/plugins/vis_type_timeseries/public/application/editor_controller.js index f21b5f947bca7..548bf2623fc1a 100644 --- a/src/plugins/vis_type_timeseries/public/application/editor_controller.js +++ b/src/plugins/vis_type_timeseries/public/application/editor_controller.js @@ -70,7 +70,6 @@ export class EditorController { visParams={this.state.vis.params} timeRange={params.timeRange} renderComplete={() => {}} - isEditorMode={true} appState={params.appState} embeddableHandler={this.embeddableHandler} eventEmitter={this.eventEmitter} diff --git a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.test.ts b/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.test.ts deleted file mode 100644 index a9568b5be9d3f..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.test.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 { createBrushHandler } from './create_brush_handler'; -import { ExprVisAPIEvents } from '../../../../visualizations/public'; - -describe('brushHandler', () => { - let onBrush: ReturnType; - let applyFilter: ExprVisAPIEvents['applyFilter']; - - beforeEach(() => { - applyFilter = jest.fn(); - - onBrush = createBrushHandler(applyFilter); - }); - - test('returns brushHandler() should updates timefilter through vis.API.events.applyFilter', () => { - const gte = '2017-01-01T00:00:00Z'; - const lte = '2017-01-01T00:10:00Z'; - - onBrush(gte, lte); - - expect(applyFilter).toHaveBeenCalledWith({ - timeFieldName: '*', - filters: [ - { - range: { '*': { gte: '2017-01-01T00:00:00Z', lte: '2017-01-01T00:10:00Z' } }, - }, - ], - }); - }); -}); diff --git a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.ts b/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.ts deleted file mode 100644 index 38002c7552952..0000000000000 --- a/src/plugins/vis_type_timeseries/public/application/lib/create_brush_handler.ts +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 { ExprVisAPIEvents } from '../../../../visualizations/public'; - -export const createBrushHandler = (applyFilter: ExprVisAPIEvents['applyFilter']) => ( - gte: string, - lte: string -) => { - return applyFilter({ - timeFieldName: '*', - filters: [ - { - range: { - '*': { - gte, - lte, - }, - }, - }, - ], - }); -}; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index ba6ac32f2e3d0..f0adb27f4c34e 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -4035,7 +4035,6 @@ "visTypeTimeseries.movingAverage.windowSizeHint": "ウィンドウは、必ず、期間のサイズの 2 倍以上でなければなりません", "visTypeTimeseries.movingAverage.windowSizeLabel": "ウィンドウサイズ", "visTypeTimeseries.noButtonLabel": "いいえ", - "visTypeTimeseries.noDataDescription": "選択されたメトリックに表示するデータがありません", "visTypeTimeseries.percentile.aggregationLabel": "集約", "visTypeTimeseries.percentile.fieldLabel": "フィールド", "visTypeTimeseries.percentile.fillToLabel": "次の基準に合わせる:", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 822ccf5cc8409..ee3c66f63b948 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -4036,7 +4036,6 @@ "visTypeTimeseries.movingAverage.windowSizeHint": "窗口必须始终至少是期间大小的两倍", "visTypeTimeseries.movingAverage.windowSizeLabel": "窗口大小", "visTypeTimeseries.noButtonLabel": "否", - "visTypeTimeseries.noDataDescription": "所选指标没有可显示的数据", "visTypeTimeseries.percentile.aggregationLabel": "聚合", "visTypeTimeseries.percentile.fieldLabel": "字段", "visTypeTimeseries.percentile.fillToLabel": "填充到:", From ce016d5f676f5515e2ac8251564facef1d9da851 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 17 Nov 2020 14:09:31 +0300 Subject: [PATCH 03/18] Use custom expression --- .../public/metrics_type.ts | 4 +- .../public/timeseries_vis_renderer.tsx | 4 +- .../vis_type_timeseries/public/to_ast.ts | 39 +++++++++++++++++++ .../public/legacy/build_pipeline.ts | 7 ---- 4 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 src/plugins/vis_type_timeseries/public/to_ast.ts diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index 017955240ddf8..0aa25794a1c1d 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -25,6 +25,7 @@ import { EditorController } from './application'; // @ts-ignore import { PANEL_TYPES } from '../common/panel_types'; import { VIS_EVENT_TO_TRIGGER, VisGroups } from '../../visualizations/public'; +import { toExpressionAst } from './to_ast'; export const metricsVisDefinition = { name: 'metrics', @@ -77,10 +78,9 @@ export const metricsVisDefinition = { showFilterBar: false, showIndexSelection: false, }, - requestHandler: metricsRequestHandler, + toExpressionAst, getSupportedTriggers: () => { return [VIS_EVENT_TO_TRIGGER.applyFilter]; }, inspectorAdapters: {}, - responseHandler: 'none', }; diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx index 2bb749cfc9fef..a5ecd4de21919 100644 --- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -30,8 +30,8 @@ const TimeseriesVisualization = lazy( ); const checkIfDataExists = (visData: any, model: any) => { - const data = visData.type === 'table' ? visData.series : visData[model.id].series; - return data.length > 0; + const data = visData.type === 'table' ? visData.series : visData[model.id]?.series; + return data?.length > 0; }; export const getTimeseriesVisRenderer: (deps: { diff --git a/src/plugins/vis_type_timeseries/public/to_ast.ts b/src/plugins/vis_type_timeseries/public/to_ast.ts new file mode 100644 index 0000000000000..bf1c7074b76b0 --- /dev/null +++ b/src/plugins/vis_type_timeseries/public/to_ast.ts @@ -0,0 +1,39 @@ +/* + * 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 { buildExpression, buildExpressionFunction } from '../../expressions/public'; +import { Vis } from '../../visualizations/public'; + +// const fun = ({ title, ...params }, schemas, uiState = {}) => { +// const paramsJson = prepareJson('params', params); +// const uiStateJson = prepareJson('uiState', uiState); + +// const paramsArray = [paramsJson, uiStateJson].filter((param) => Boolean(param)); +// return `tsvb ${paramsArray.join(' ')}`; +// }; + +export const toExpressionAst = (vis: Vis) => { + const timeseries = buildExpressionFunction('tsvb', { + params: JSON.stringify(vis.params).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`), + }); + + const ast = buildExpression([timeseries]); + + return ast.toAst(); +}; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.ts b/src/plugins/visualizations/public/legacy/build_pipeline.ts index 3593d62b9d2e6..d412ec918a71a 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.ts @@ -222,13 +222,6 @@ export const buildPipelineVisFunction: BuildPipelineVisFunction = { input_control_vis: (params) => { return `input_control_vis ${prepareJson('visConfig', params)}`; }, - metrics: ({ title, ...params }, schemas, uiState = {}) => { - const paramsJson = prepareJson('params', params); - const uiStateJson = prepareJson('uiState', uiState); - - const paramsArray = [paramsJson, uiStateJson].filter((param) => Boolean(param)); - return `tsvb ${paramsArray.join(' ')}`; - }, region_map: (params, schemas) => { const visConfig = { ...params, From ce34e0d288ef843bf0d16eb4a39236a0873b2bc3 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 17 Nov 2020 14:22:02 +0300 Subject: [PATCH 04/18] Convert to typescript --- .../vis_type_timeseries/common/constants.ts | 4 ++ .../vis_type_timeseries/public/metrics_fn.ts | 7 +-- .../public/metrics_type.ts | 2 - ...{request_handler.js => request_handler.ts} | 52 +++++++++---------- .../vis_type_timeseries/public/to_ast.ts | 18 +++---- .../vis_type_timeseries/server/routes/vis.ts | 3 +- 6 files changed, 43 insertions(+), 43 deletions(-) rename src/plugins/vis_type_timeseries/public/{request_handler.js => request_handler.ts} (64%) diff --git a/src/plugins/vis_type_timeseries/common/constants.ts b/src/plugins/vis_type_timeseries/common/constants.ts index fc402d6ab7db5..280c297ce7c1b 100644 --- a/src/plugins/vis_type_timeseries/common/constants.ts +++ b/src/plugins/vis_type_timeseries/common/constants.ts @@ -18,3 +18,7 @@ */ export const MAX_BUCKETS_SETTING = 'metrics:max_buckets'; + +export const ROUTES = { + VIS_DATA: '/api/metrics/vis/data', +}; diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index 5c42db92af1c3..f9d17ca40c96a 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -22,7 +22,6 @@ import { i18n } from '@kbn/i18n'; import { KibanaContext } from '../../data/public'; import { ExpressionFunctionDefinition, Render } from '../../expressions/public'; -// @ts-ignore import { metricsRequestHandler } from './request_handler'; type Input = KibanaContext | null; @@ -43,12 +42,14 @@ export interface TimeseriesRenderValue { uiState: any; } -export const createMetricsFn = (): ExpressionFunctionDefinition< +export type TimeseriesExpressionFunctionDefinition = ExpressionFunctionDefinition< 'tsvb', Input, Arguments, Output -> => ({ +>; + +export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ name: 'tsvb', type: 'render', inputTypes: ['kibana_context', 'null'], diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index 0aa25794a1c1d..7a5535c22a2fa 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -19,8 +19,6 @@ import { i18n } from '@kbn/i18n'; -// @ts-ignore -import { metricsRequestHandler } from './request_handler'; import { EditorController } from './application'; // @ts-ignore import { PANEL_TYPES } from '../common/panel_types'; diff --git a/src/plugins/vis_type_timeseries/public/request_handler.js b/src/plugins/vis_type_timeseries/public/request_handler.ts similarity index 64% rename from src/plugins/vis_type_timeseries/public/request_handler.js rename to src/plugins/vis_type_timeseries/public/request_handler.ts index 12b7f3d417ef6..e4e796a9ba11a 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.js +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -19,7 +19,7 @@ import { getTimezone, validateInterval } from './application'; import { getUISettings, getDataStart, getCoreStart } from './services'; -import { MAX_BUCKETS_SETTING } from '../common/constants'; +import { MAX_BUCKETS_SETTING, ROUTES } from '../common/constants'; export const metricsRequestHandler = async ({ uiState, @@ -38,36 +38,32 @@ export const metricsRequestHandler = async ({ const dateFormat = config.get('dateFormat'); if (visParams && visParams.id && !visParams.isModelInvalid) { - try { - const maxBuckets = config.get(MAX_BUCKETS_SETTING); + const maxBuckets = config.get(MAX_BUCKETS_SETTING); - validateInterval(parsedTimeRange, visParams, maxBuckets); + validateInterval(parsedTimeRange, visParams, maxBuckets); - const resp = await getCoreStart().http.post('/api/metrics/vis/data', { - body: JSON.stringify({ - timerange: { - timezone, - ...parsedTimeRange, - }, - query, - filters, - panels: [visParams], - state: uiStateObj, - savedObjectId: savedObjectId || 'unsaved', - sessionId: dataSearch.search.session.getSessionId(), - }), - }); + const resp = await getCoreStart().http.post(ROUTES.VIS_DATA, { + body: JSON.stringify({ + timerange: { + timezone, + ...parsedTimeRange, + }, + query, + filters, + panels: [visParams], + state: uiStateObj, + savedObjectId: savedObjectId || 'unsaved', + sessionId: dataSearch.search.session.getSessionId(), + }), + }); - return { - dateFormat, - scaledDataFormat, - timezone, - ...resp, - }; - } catch (error) { - return Promise.reject(error); - } + return { + dateFormat, + scaledDataFormat, + timezone, + ...resp, + }; } - return Promise.resolve({}); + return {}; }; diff --git a/src/plugins/vis_type_timeseries/public/to_ast.ts b/src/plugins/vis_type_timeseries/public/to_ast.ts index bf1c7074b76b0..2b73b1d9b822c 100644 --- a/src/plugins/vis_type_timeseries/public/to_ast.ts +++ b/src/plugins/vis_type_timeseries/public/to_ast.ts @@ -19,18 +19,18 @@ import { buildExpression, buildExpressionFunction } from '../../expressions/public'; import { Vis } from '../../visualizations/public'; +import { TimeseriesExpressionFunctionDefinition } from './metrics_fn'; -// const fun = ({ title, ...params }, schemas, uiState = {}) => { -// const paramsJson = prepareJson('params', params); -// const uiStateJson = prepareJson('uiState', uiState); - -// const paramsArray = [paramsJson, uiStateJson].filter((param) => Boolean(param)); -// return `tsvb ${paramsArray.join(' ')}`; -// }; +const prepareJson = (data: unknown) => + JSON.stringify(data).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`); export const toExpressionAst = (vis: Vis) => { - const timeseries = buildExpressionFunction('tsvb', { - params: JSON.stringify(vis.params).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`), + const params = prepareJson(vis.params); + const uiState = prepareJson(vis.uiState); + + const timeseries = buildExpressionFunction('tsvb', { + params, + uiState, }); const ast = buildExpression([timeseries]); diff --git a/src/plugins/vis_type_timeseries/server/routes/vis.ts b/src/plugins/vis_type_timeseries/server/routes/vis.ts index 1ca8b57ab230f..ba6a115248348 100644 --- a/src/plugins/vis_type_timeseries/server/routes/vis.ts +++ b/src/plugins/vis_type_timeseries/server/routes/vis.ts @@ -21,6 +21,7 @@ import { IRouter, KibanaRequest } from 'kibana/server'; import { schema } from '@kbn/config-schema'; import { getVisData, GetVisDataOptions } from '../lib/get_vis_data'; import { visPayloadSchema } from '../../common/vis_schema'; +import { ROUTES } from '../../common/constants'; import { ValidationTelemetryServiceSetup } from '../index'; import { Framework } from '../plugin'; @@ -33,7 +34,7 @@ export const visDataRoutes = ( ) => { router.post( { - path: '/api/metrics/vis/data', + path: ROUTES.VIS_DATA, validate: { body: escapeHatch, }, From 20eb91802e5ea44509341386e6c59cdb454136f3 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 17 Nov 2020 15:37:19 +0300 Subject: [PATCH 05/18] Remove savedObjectId extra param --- src/plugins/vis_type_timeseries/public/metrics_fn.ts | 8 -------- .../vis_type_timeseries/public/request_handler.ts | 11 ++--------- src/plugins/vis_type_timeseries/server/routes/vis.ts | 6 ------ 3 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index f9d17ca40c96a..c1a25bc590378 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -30,7 +30,6 @@ type Output = Promise>; interface Arguments { params: string; uiState: string; - savedObjectId: string | null; } type VisParams = Required; @@ -67,16 +66,10 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ default: '"{}"', help: '', }, - savedObjectId: { - types: ['null', 'string'], - default: null, - help: '', - }, }, async fn(input, args) { const params = JSON.parse(args.params); const uiStateParams = JSON.parse(args.uiState); - const savedObjectId = args.savedObjectId; const { PersistedState } = await import('../../visualizations/public'); const uiState = new PersistedState(uiStateParams); @@ -86,7 +79,6 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ filters: get(input, 'filters', null), visParams: params, uiState, - savedObjectId, }); response.visType = 'metrics'; diff --git a/src/plugins/vis_type_timeseries/public/request_handler.ts b/src/plugins/vis_type_timeseries/public/request_handler.ts index e4e796a9ba11a..d131f3df5c234 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.ts +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -21,14 +21,7 @@ import { getTimezone, validateInterval } from './application'; import { getUISettings, getDataStart, getCoreStart } from './services'; import { MAX_BUCKETS_SETTING, ROUTES } from '../common/constants'; -export const metricsRequestHandler = async ({ - uiState, - timeRange, - filters, - query, - visParams, - savedObjectId, -}) => { +export const metricsRequestHandler = async ({ uiState, timeRange, filters, query, visParams }) => { const config = getUISettings(); const timezone = getTimezone(config); const uiStateObj = uiState.get(visParams.type, {}); @@ -52,7 +45,7 @@ export const metricsRequestHandler = async ({ filters, panels: [visParams], state: uiStateObj, - savedObjectId: savedObjectId || 'unsaved', + savedObjectId: 'unsaved', sessionId: dataSearch.search.session.getSessionId(), }), }); diff --git a/src/plugins/vis_type_timeseries/server/routes/vis.ts b/src/plugins/vis_type_timeseries/server/routes/vis.ts index ba6a115248348..bd38d6a4ed1ee 100644 --- a/src/plugins/vis_type_timeseries/server/routes/vis.ts +++ b/src/plugins/vis_type_timeseries/server/routes/vis.ts @@ -44,12 +44,6 @@ export const visDataRoutes = ( visPayloadSchema.validate(request.body); } catch (error) { logFailedValidation(); - const savedObjectId = - (typeof request.body === 'object' && (request.body as any).savedObjectId) || - 'unavailable'; - framework.logger.warn( - `Request validation error: ${error.message} (saved object id: ${savedObjectId}). This most likely means your TSVB visualization contains outdated configuration. You can report this problem under https://github.com/elastic/kibana/issues/new?template=Bug_report.md` - ); } try { From 2cbd5451ef95c3cc266ea3b32d18d234c877bac0 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 17 Nov 2020 16:52:56 +0300 Subject: [PATCH 06/18] Other updates --- .../vis_type_timeseries/common/vis_schema.ts | 1 - .../vis_type_timeseries/public/metrics_fn.ts | 20 ++++++---------- .../public/metrics_type.ts | 1 - .../public/request_handler.ts | 24 ++++++++++++++----- .../vis_type_timeseries/public/to_ast.ts | 10 ++------ 5 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index 9ec5ae1424ae3..372e7e01e0539 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -267,7 +267,6 @@ export const visPayloadSchema = schema.object({ }) ), }), - savedObjectId: schema.maybe(schema.string()), timerange: schema.object({ timezone: stringRequired, min: stringRequired, diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index c1a25bc590378..99f7e7f290a7a 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -17,11 +17,11 @@ * under the License. */ -import { get } from 'lodash'; import { i18n } from '@kbn/i18n'; import { KibanaContext } from '../../data/public'; import { ExpressionFunctionDefinition, Render } from '../../expressions/public'; +import { PanelSchema } from '../common/types'; import { metricsRequestHandler } from './request_handler'; type Input = KibanaContext | null; @@ -32,12 +32,10 @@ interface Arguments { uiState: string; } -type VisParams = Required; - export interface TimeseriesRenderValue { visType: 'metrics'; visData: Input; - visConfig: VisParams; + visConfig: PanelSchema; uiState: any; } @@ -68,16 +66,12 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ }, }, async fn(input, args) { - const params = JSON.parse(args.params); - const uiStateParams = JSON.parse(args.uiState); - const { PersistedState } = await import('../../visualizations/public'); - const uiState = new PersistedState(uiStateParams); + const visParams: PanelSchema = JSON.parse(args.params); + const uiState = JSON.parse(args.uiState); const response = await metricsRequestHandler({ - timeRange: get(input, 'timeRange', null), - query: get(input, 'query', null), - filters: get(input, 'filters', null), - visParams: params, + input, + visParams, uiState, }); @@ -89,7 +83,7 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ value: { uiState, visType: 'metrics', - visConfig: params, + visConfig: visParams, visData: response, }, }; diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index 7a5535c22a2fa..680366973c602 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -20,7 +20,6 @@ import { i18n } from '@kbn/i18n'; import { EditorController } from './application'; -// @ts-ignore import { PANEL_TYPES } from '../common/panel_types'; import { VIS_EVENT_TO_TRIGGER, VisGroups } from '../../visualizations/public'; import { toExpressionAst } from './to_ast'; diff --git a/src/plugins/vis_type_timeseries/public/request_handler.ts b/src/plugins/vis_type_timeseries/public/request_handler.ts index d131f3df5c234..9ecb2f4ca2928 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.ts +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -17,16 +17,29 @@ * under the License. */ +import { KibanaContext } from '../../data/public'; + import { getTimezone, validateInterval } from './application'; import { getUISettings, getDataStart, getCoreStart } from './services'; import { MAX_BUCKETS_SETTING, ROUTES } from '../common/constants'; +import { PanelSchema } from '../common/types'; + +interface MetricsRequestHandlerParams { + input: KibanaContext | null; + uiState: Record; + visParams: PanelSchema; +} -export const metricsRequestHandler = async ({ uiState, timeRange, filters, query, visParams }) => { +export const metricsRequestHandler = async ({ + input, + uiState, + visParams, +}: MetricsRequestHandlerParams) => { const config = getUISettings(); const timezone = getTimezone(config); - const uiStateObj = uiState.get(visParams.type, {}); + const uiStateObj = uiState[visParams.type] ?? {}; const dataSearch = getDataStart(); - const parsedTimeRange = dataSearch.query.timefilter.timefilter.calculateBounds(timeRange); + const parsedTimeRange = dataSearch.query.timefilter.timefilter.calculateBounds(input?.timeRange!); const scaledDataFormat = config.get('dateFormat:scaled'); const dateFormat = config.get('dateFormat'); @@ -41,11 +54,10 @@ export const metricsRequestHandler = async ({ uiState, timeRange, filters, query timezone, ...parsedTimeRange, }, - query, - filters, + query: input?.query, + filters: input?.filters, panels: [visParams], state: uiStateObj, - savedObjectId: 'unsaved', sessionId: dataSearch.search.session.getSessionId(), }), }); diff --git a/src/plugins/vis_type_timeseries/public/to_ast.ts b/src/plugins/vis_type_timeseries/public/to_ast.ts index 2b73b1d9b822c..f6eb727072eb4 100644 --- a/src/plugins/vis_type_timeseries/public/to_ast.ts +++ b/src/plugins/vis_type_timeseries/public/to_ast.ts @@ -21,16 +21,10 @@ import { buildExpression, buildExpressionFunction } from '../../expressions/publ import { Vis } from '../../visualizations/public'; import { TimeseriesExpressionFunctionDefinition } from './metrics_fn'; -const prepareJson = (data: unknown) => - JSON.stringify(data).replace(/\\/g, `\\\\`).replace(/'/g, `\\'`); - export const toExpressionAst = (vis: Vis) => { - const params = prepareJson(vis.params); - const uiState = prepareJson(vis.uiState); - const timeseries = buildExpressionFunction('tsvb', { - params, - uiState, + params: JSON.stringify(vis.params), + uiState: JSON.stringify(vis.uiState), }); const ast = buildExpression([timeseries]); From c23834a74b70c0b5a1f252eed040f1986be516aa Mon Sep 17 00:00:00 2001 From: sulemanof Date: Tue, 17 Nov 2020 18:48:30 +0300 Subject: [PATCH 07/18] Fix types --- src/plugins/vis_type_timeseries/public/metrics_fn.ts | 6 ++++-- .../vis_type_timeseries/public/timeseries_vis_renderer.tsx | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index 99f7e7f290a7a..994b3b0577ed3 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -32,10 +32,12 @@ interface Arguments { uiState: string; } +export type TimeseriesVisParams = PanelSchema; + export interface TimeseriesRenderValue { visType: 'metrics'; visData: Input; - visConfig: PanelSchema; + visParams: TimeseriesVisParams; uiState: any; } @@ -83,7 +85,7 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ value: { uiState, visType: 'metrics', - visConfig: visParams, + visParams, visData: response, }, }; diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx index a5ecd4de21919..a7ba2ebce7e2a 100644 --- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -44,7 +44,7 @@ export const getTimeseriesVisRenderer: (deps: { unmountComponentAtNode(domNode); }); - const showNoResult = !checkIfDataExists(config.visData, config.visConfig); + const showNoResult = !checkIfDataExists(config.visData, config.visParams); render( @@ -52,7 +52,7 @@ export const getTimeseriesVisRenderer: (deps: { dateFormat={uiSettings.get('dateFormat')} getConfig={uiSettings.get} handlers={handlers} - model={config.visConfig} + model={config.visParams} visData={config.visData} uiState={handlers.uiState!} /> From 99163c59395765d2b477814e98658271f5b9c7e3 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Wed, 18 Nov 2020 12:49:41 +0300 Subject: [PATCH 08/18] Cleanup --- src/plugins/vis_type_timeseries/common/constants.ts | 2 +- src/plugins/vis_type_timeseries/public/metrics_type.ts | 1 - .../public/legacy/__snapshots__/build_pipeline.test.ts.snap | 2 -- .../visualizations/public/legacy/build_pipeline.test.ts | 6 ------ 4 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/plugins/vis_type_timeseries/common/constants.ts b/src/plugins/vis_type_timeseries/common/constants.ts index 578b4ba442266..4f24bc273e265 100644 --- a/src/plugins/vis_type_timeseries/common/constants.ts +++ b/src/plugins/vis_type_timeseries/common/constants.ts @@ -22,4 +22,4 @@ export const INDEXES_SEPARATOR = ','; export const ROUTES = { VIS_DATA: '/api/metrics/vis/data', -}; \ No newline at end of file +}; diff --git a/src/plugins/vis_type_timeseries/public/metrics_type.ts b/src/plugins/vis_type_timeseries/public/metrics_type.ts index b371e69b83fd9..2b75f69620629 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_type.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_type.ts @@ -21,7 +21,6 @@ import { i18n } from '@kbn/i18n'; import { EditorController } from './application'; import { PANEL_TYPES } from '../common/panel_types'; -import { VisEditor } from './application/components/vis_editor_lazy'; import { toExpressionAst } from './to_ast'; import { VIS_EVENT_TO_TRIGGER, VisGroups, VisParams } from '../../visualizations/public'; import { getDataStart } from './services'; diff --git a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap index 2c6cfc6fb7462..03a355c604c4d 100644 --- a/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap +++ b/src/plugins/visualizations/public/legacy/__snapshots__/build_pipeline.test.ts.snap @@ -4,8 +4,6 @@ exports[`visualize loader pipeline helpers: build pipeline buildPipeline calls t exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles input_control_vis function 1`] = `"input_control_vis visConfig='{\\"some\\":\\"nested\\",\\"data\\":{\\"here\\":true}}' "`; -exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles metrics/tsvb function 1`] = `"tsvb params='{\\"foo\\":\\"bar\\"}' uiState='{}' "`; - exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function with buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"},\\"bucket\\":1}' "`; exports[`visualize loader pipeline helpers: build pipeline buildPipelineVisFunction handles region_map function without buckets 1`] = `"regionmap visConfig='{\\"metric\\":{\\"accessor\\":0,\\"label\\":\\"\\",\\"format\\":{},\\"params\\":{},\\"aggType\\":\\"\\"}}' "`; diff --git a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts index 0c210a04d2007..653542bd8837d 100644 --- a/src/plugins/visualizations/public/legacy/build_pipeline.test.ts +++ b/src/plugins/visualizations/public/legacy/build_pipeline.test.ts @@ -101,12 +101,6 @@ describe('visualize loader pipeline helpers: build pipeline', () => { expect(actual).toMatchSnapshot(); }); - it('handles metrics/tsvb function', () => { - const params = { foo: 'bar' }; - const actual = buildPipelineVisFunction.metrics(params, schemasDef, uiState); - expect(actual).toMatchSnapshot(); - }); - describe('handles region_map function', () => { it('without buckets', () => { const params = { metric: {} }; From c7b55bd5677a84127e572fa2bab84949c53dfd65 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Wed, 18 Nov 2020 14:07:03 +0300 Subject: [PATCH 09/18] Fix functional tests --- .../vis_type_timeseries/public/timeseries_vis_renderer.tsx | 6 +++++- .../public/components/visualization_container.tsx | 4 +++- .../public/components/visualization_noresults.tsx | 2 +- test/functional/apps/dashboard/dashboard_filtering.js | 2 +- test/functional/page_objects/visual_builder_page.ts | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx index a7ba2ebce7e2a..337b2451d6095 100644 --- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -47,7 +47,11 @@ export const getTimeseriesVisRenderer: (deps: { const showNoResult = !checkIfDataExists(config.visData, config.visParams); render( - + +
{showNoResult ? handlers.done()} /> : children} diff --git a/src/plugins/visualizations/public/components/visualization_noresults.tsx b/src/plugins/visualizations/public/components/visualization_noresults.tsx index c77ef4490a4b3..90d5353185229 100644 --- a/src/plugins/visualizations/public/components/visualization_noresults.tsx +++ b/src/plugins/visualizations/public/components/visualization_noresults.tsx @@ -30,7 +30,7 @@ export class VisualizationNoResults extends React.Component +
diff --git a/test/functional/apps/dashboard/dashboard_filtering.js b/test/functional/apps/dashboard/dashboard_filtering.js index 0be4fbbebe7c5..b3812af38c348 100644 --- a/test/functional/apps/dashboard/dashboard_filtering.js +++ b/test/functional/apps/dashboard/dashboard_filtering.js @@ -92,7 +92,7 @@ export default function ({ getService, getPageObjects }) { }); it('tsvb time series shows no data message', async () => { - expect(await testSubjects.exists('noTSVBDataMessage')).to.be(true); + expect(await testSubjects.exists('timeseriesVis > visNoResult')).to.be(true); }); it('metric value shows no data', async () => { diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts index 37634d0248b04..0e305eaafc82f 100644 --- a/test/functional/page_objects/visual_builder_page.ts +++ b/test/functional/page_objects/visual_builder_page.ts @@ -549,7 +549,7 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro public async checkPreviewIsDisabled(): Promise { log.debug(`Check no data message is present`); - await testSubjects.existOrFail('noTSVBDataMessage', { timeout: 5000 }); + await testSubjects.existOrFail('timeseriesVis > visNoResult', { timeout: 5000 }); } public async cloneSeries(nth: number = 0): Promise { From 01cf48531130a0b944edc0393cdda6a7204fc0f7 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Wed, 18 Nov 2020 14:46:39 +0300 Subject: [PATCH 10/18] Bind uiSettings --- .../vis_type_timeseries/public/timeseries_vis_renderer.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx index 337b2451d6095..2793bcdc9a4ff 100644 --- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -54,7 +54,8 @@ export const getTimeseriesVisRenderer: (deps: { > Date: Wed, 18 Nov 2020 16:30:57 +0300 Subject: [PATCH 11/18] Update snapshot --- .../__snapshots__/visualization_noresults.test.js.snap | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap b/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap index 978c67fb71721..94c5da872b1cb 100644 --- a/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap +++ b/src/plugins/visualizations/public/components/__snapshots__/visualization_noresults.test.js.snap @@ -3,6 +3,7 @@ exports[`VisualizationNoResults should render according to snapshot 1`] = `
Date: Wed, 18 Nov 2020 17:45:43 +0300 Subject: [PATCH 12/18] Update types --- .../vis_type_timeseries/common/panel_types.ts | 4 +++ .../components/timeseries_visualization.tsx | 9 +++--- .../application/components/vis_types/index.ts | 10 +++++-- .../vis_type_timeseries/public/metrics_fn.ts | 11 ++----- .../public/request_handler.ts | 7 +++-- .../public/timeseries_vis_renderer.tsx | 15 ++++++---- .../vis_type_timeseries/public/to_ast.ts | 4 +-- .../vis_type_timeseries/public/types.ts | 30 +++++++++++++++++++ 8 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/plugins/vis_type_timeseries/common/panel_types.ts b/src/plugins/vis_type_timeseries/common/panel_types.ts index 6a9420ab6e4c1..96b649bd88571 100644 --- a/src/plugins/vis_type_timeseries/common/panel_types.ts +++ b/src/plugins/vis_type_timeseries/common/panel_types.ts @@ -17,6 +17,8 @@ * under the License. */ +import { $Values } from '@kbn/utility-types'; + export const PANEL_TYPES = { TABLE: 'table', GAUGE: 'gauge', @@ -25,3 +27,5 @@ export const PANEL_TYPES = { TIMESERIES: 'timeseries', METRIC: 'metric', }; + +export type PANEL_TYPES = $Values; diff --git a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx index aa965d555a5f9..6c9bd5126c871 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx @@ -26,17 +26,16 @@ import { PersistedState } from 'src/plugins/visualizations/public'; // @ts-expect-error import { ErrorComponent } from './error'; import { TimeseriesVisTypes } from './vis_types'; +import { TimeseriesVisParams } from '../../metrics_fn'; +import { TimeseriesVisData } from '../../types'; interface TimeseriesVisualizationProps { className?: string; dateFormat: string; getConfig: IUiSettingsClient['get']; handlers: IInterpreterRenderHandlers; - model: { - id: string; - type: keyof typeof TimeseriesVisTypes; - }; - visData: any; + model: TimeseriesVisParams; + visData: TimeseriesVisData; uiState: PersistedState; } diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts index cee56af9bfe9d..e6e10a2a45467 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts @@ -22,6 +22,10 @@ import React from 'react'; import { IUiSettingsClient } from 'src/core/public'; import { PersistedState } from 'src/plugins/visualizations/public'; +/** + * TSVB visualizations are not typed yet. + */ + // @ts-expect-error import { TimeseriesVisualization as timeseries } from './timeseries/vis'; // @ts-expect-error @@ -34,6 +38,8 @@ import { TableVis as table } from './table/vis'; import { gauge } from './gauge/vis'; // @ts-expect-error import { MarkdownVisualization as markdown } from './markdown/vis'; +import { TimeseriesVisParams } from '../../../metrics_fn'; +import { TimeseriesVisData } from '../../../types'; export const TimeseriesVisTypes: Record> = { timeseries, @@ -45,7 +51,7 @@ export const TimeseriesVisTypes: Record void; onUiState: ( field: string, @@ -55,7 +61,7 @@ export interface TimeseriesVisProps { } ) => void; uiState: PersistedState; - visData: any; + visData: TimeseriesVisData; dateFormat: string; getConfig: IUiSettingsClient['get']; } diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index 994b3b0577ed3..a6aa1b41cae1d 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -23,6 +23,7 @@ import { ExpressionFunctionDefinition, Render } from '../../expressions/public'; import { PanelSchema } from '../common/types'; import { metricsRequestHandler } from './request_handler'; +import { TimeseriesVisData } from './types'; type Input = KibanaContext | null; type Output = Promise>; @@ -35,10 +36,8 @@ interface Arguments { export type TimeseriesVisParams = PanelSchema; export interface TimeseriesRenderValue { - visType: 'metrics'; - visData: Input; + visData: TimeseriesVisData | {}; visParams: TimeseriesVisParams; - uiState: any; } export type TimeseriesExpressionFunctionDefinition = ExpressionFunctionDefinition< @@ -68,7 +67,7 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ }, }, async fn(input, args) { - const visParams: PanelSchema = JSON.parse(args.params); + const visParams: TimeseriesVisParams = JSON.parse(args.params); const uiState = JSON.parse(args.uiState); const response = await metricsRequestHandler({ @@ -77,14 +76,10 @@ export const createMetricsFn = (): TimeseriesExpressionFunctionDefinition => ({ uiState, }); - response.visType = 'metrics'; - return { type: 'render', as: 'timeseries_vis', value: { - uiState, - visType: 'metrics', visParams, visData: response, }, diff --git a/src/plugins/vis_type_timeseries/public/request_handler.ts b/src/plugins/vis_type_timeseries/public/request_handler.ts index 9ecb2f4ca2928..326dbd8a5abb4 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.ts +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -22,19 +22,20 @@ import { KibanaContext } from '../../data/public'; import { getTimezone, validateInterval } from './application'; import { getUISettings, getDataStart, getCoreStart } from './services'; import { MAX_BUCKETS_SETTING, ROUTES } from '../common/constants'; -import { PanelSchema } from '../common/types'; +import { TimeseriesVisParams } from './metrics_fn'; +import { TimeseriesVisData } from './types'; interface MetricsRequestHandlerParams { input: KibanaContext | null; uiState: Record; - visParams: PanelSchema; + visParams: TimeseriesVisParams; } export const metricsRequestHandler = async ({ input, uiState, visParams, -}: MetricsRequestHandlerParams) => { +}: MetricsRequestHandlerParams): Promise => { const config = getUISettings(); const timezone = getTimezone(config); const uiStateObj = uiState[visParams.type] ?? {}; diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx index 2793bcdc9a4ff..97de5518b3ff1 100644 --- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -23,15 +23,20 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { IUiSettingsClient } from 'kibana/public'; import { VisualizationContainer } from '../../visualizations/public'; import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers'; -import { TimeseriesRenderValue } from './metrics_fn'; +import { TimeseriesRenderValue, TimeseriesVisParams } from './metrics_fn'; +import { TimeseriesVisData } from './types'; const TimeseriesVisualization = lazy( () => import('./application/components/timeseries_visualization') ); -const checkIfDataExists = (visData: any, model: any) => { - const data = visData.type === 'table' ? visData.series : visData[model.id]?.series; - return data?.length > 0; +const checkIfDataExists = (visData: TimeseriesVisData | {}, model: TimeseriesVisParams) => { + if ('type' in visData) { + const data = visData.type === 'table' ? visData.series : visData?.[model.id]?.series; + return Boolean(data?.length); + } + + return false; }; export const getTimeseriesVisRenderer: (deps: { @@ -58,7 +63,7 @@ export const getTimeseriesVisRenderer: (deps: { getConfig={uiSettings.get.bind(uiSettings)} handlers={handlers} model={config.visParams} - visData={config.visData} + visData={config.visData as TimeseriesVisData} uiState={handlers.uiState!} /> , diff --git a/src/plugins/vis_type_timeseries/public/to_ast.ts b/src/plugins/vis_type_timeseries/public/to_ast.ts index f6eb727072eb4..58de0269fd27f 100644 --- a/src/plugins/vis_type_timeseries/public/to_ast.ts +++ b/src/plugins/vis_type_timeseries/public/to_ast.ts @@ -19,9 +19,9 @@ import { buildExpression, buildExpressionFunction } from '../../expressions/public'; import { Vis } from '../../visualizations/public'; -import { TimeseriesExpressionFunctionDefinition } from './metrics_fn'; +import { TimeseriesExpressionFunctionDefinition, TimeseriesVisParams } from './metrics_fn'; -export const toExpressionAst = (vis: Vis) => { +export const toExpressionAst = (vis: Vis) => { const timeseries = buildExpressionFunction('tsvb', { params: JSON.stringify(vis.params), uiState: JSON.stringify(vis.uiState), diff --git a/src/plugins/vis_type_timeseries/public/types.ts b/src/plugins/vis_type_timeseries/public/types.ts index 338118dcdc5aa..e3d9d7a4df2c0 100644 --- a/src/plugins/vis_type_timeseries/public/types.ts +++ b/src/plugins/vis_type_timeseries/public/types.ts @@ -20,6 +20,9 @@ import React from 'react'; import { EuiDraggable } from '@elastic/eui'; +import type { PANEL_TYPES } from '../common/panel_types'; +import { TimeseriesUIRestrictions } from '../common/ui_restrictions'; + type PropsOf = T extends React.ComponentType ? ComponentProps : never; type FirstArgumentOf = Func extends (arg1: infer FirstArgument, ...rest: any[]) => any ? FirstArgument @@ -27,3 +30,30 @@ type FirstArgumentOf = Func extends (arg1: infer FirstArgument, ...rest: a export type DragHandleProps = FirstArgumentOf< Exclude['children'], React.ReactElement> >['dragHandleProps']; + +/** + * series data is not typed yet. + * Should be in sync with returned data from server [GetVisDataPanel] in src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts + */ +interface SeriesData { + [key: string]: { + annotations: { + [key: string]: unknown[]; + }; + id: string; + series: unknown[]; + error?: unknown; + }; +} + +export type TimeseriesVisData = SeriesData & { + dateFormat: string; + scaledDataFormat: Array<[string, string]>; + timezone: string; + type: PANEL_TYPES; + uiRestrictions: TimeseriesUIRestrictions; + /** + * series array is responsible only for "table" vis type + */ + series?: unknown[]; +}; From dd02f429d3c6a49b3b2517d39ff241299fc4f523 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Thu, 19 Nov 2020 16:48:49 +0300 Subject: [PATCH 13/18] Remove extra params --- .../application/components/timeseries_visualization.tsx | 6 +++--- .../application/components/vis_types/timeseries/vis.js | 3 ++- .../vis_type_timeseries/public/request_handler.ts | 9 +-------- .../public/timeseries_vis_renderer.tsx | 1 - src/plugins/vis_type_timeseries/public/types.ts | 3 --- 5 files changed, 6 insertions(+), 16 deletions(-) diff --git a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx index 6c9bd5126c871..5e7b19e289df1 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx @@ -31,7 +31,6 @@ import { TimeseriesVisData } from '../../types'; interface TimeseriesVisualizationProps { className?: string; - dateFormat: string; getConfig: IUiSettingsClient['get']; handlers: IInterpreterRenderHandlers; model: TimeseriesVisParams; @@ -45,7 +44,7 @@ function TimeseriesVisualization({ model, handlers, uiState, - ...visProps + getConfig, }: TimeseriesVisualizationProps) { const onBrush = useCallback( (gte: string, lte: string) => { @@ -97,7 +96,8 @@ function TimeseriesVisualization({ if (VisComponent) { return ( (val) => { - const { scaledDataFormat, dateFormat } = this.props.visData; + const scaledDataFormat = this.props.getConfig('dateFormat:scaled'); + const { dateFormat } = this.props; if (!scaledDataFormat || !dateFormat) { return val; diff --git a/src/plugins/vis_type_timeseries/public/request_handler.ts b/src/plugins/vis_type_timeseries/public/request_handler.ts index 326dbd8a5abb4..f3ed3a2494f0c 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.ts +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -41,8 +41,6 @@ export const metricsRequestHandler = async ({ const uiStateObj = uiState[visParams.type] ?? {}; const dataSearch = getDataStart(); const parsedTimeRange = dataSearch.query.timefilter.timefilter.calculateBounds(input?.timeRange!); - const scaledDataFormat = config.get('dateFormat:scaled'); - const dateFormat = config.get('dateFormat'); if (visParams && visParams.id && !visParams.isModelInvalid) { const maxBuckets = config.get(MAX_BUCKETS_SETTING); @@ -63,12 +61,7 @@ export const metricsRequestHandler = async ({ }), }); - return { - dateFormat, - scaledDataFormat, - timezone, - ...resp, - }; + return resp; } return {}; diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx index 97de5518b3ff1..06130fa5e881a 100644 --- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -58,7 +58,6 @@ export const getTimeseriesVisRenderer: (deps: { showNoResult={showNoResult} > ; - timezone: string; type: PANEL_TYPES; uiRestrictions: TimeseriesUIRestrictions; /** From c25825e9d671b6a07dcc193791fde5fe0585f083 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Thu, 19 Nov 2020 17:47:17 +0300 Subject: [PATCH 14/18] Move common types --- .../vis_type_timeseries/common/types.ts | 29 +++++++++++++ .../components/timeseries_visualization.tsx | 2 +- .../application/components/vis_types/index.ts | 2 +- .../vis_type_timeseries/public/metrics_fn.ts | 3 +- .../public/request_handler.ts | 2 +- .../public/timeseries_vis_renderer.tsx | 2 +- .../vis_type_timeseries/public/types.ts | 27 ------------ .../server/lib/get_vis_data.ts | 41 +++++++------------ 8 files changed, 49 insertions(+), 59 deletions(-) diff --git a/src/plugins/vis_type_timeseries/common/types.ts b/src/plugins/vis_type_timeseries/common/types.ts index 8973060848b41..673d2916ee98d 100644 --- a/src/plugins/vis_type_timeseries/common/types.ts +++ b/src/plugins/vis_type_timeseries/common/types.ts @@ -19,8 +19,37 @@ import { TypeOf } from '@kbn/config-schema'; import { metricsItems, panel, seriesItems, visPayloadSchema } from './vis_schema'; +import type { PANEL_TYPES } from './panel_types'; +import { TimeseriesUIRestrictions } from './ui_restrictions'; export type SeriesItemsSchema = TypeOf; export type MetricsItemsSchema = TypeOf; export type PanelSchema = TypeOf; export type VisPayload = TypeOf; + +interface PanelData { + id: string; + label: string; + data: [number, number]; +} + +// series data is not fully typed yet +interface SeriesData { + [key: string]: { + annotations: { + [key: string]: unknown[]; + }; + id: string; + series: PanelData[]; + error?: unknown; + }; +} + +export type TimeseriesVisData = SeriesData & { + type: PANEL_TYPES; + uiRestrictions: TimeseriesUIRestrictions; + /** + * series array is responsible only for "table" vis type + */ + series?: unknown[]; +}; diff --git a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx index 5e7b19e289df1..5b5c99b970854 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/timeseries_visualization.tsx @@ -27,7 +27,7 @@ import { PersistedState } from 'src/plugins/visualizations/public'; import { ErrorComponent } from './error'; import { TimeseriesVisTypes } from './vis_types'; import { TimeseriesVisParams } from '../../metrics_fn'; -import { TimeseriesVisData } from '../../types'; +import { TimeseriesVisData } from '../../../common/types'; interface TimeseriesVisualizationProps { className?: string; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts index e6e10a2a45467..158350b84e25f 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts @@ -39,7 +39,7 @@ import { gauge } from './gauge/vis'; // @ts-expect-error import { MarkdownVisualization as markdown } from './markdown/vis'; import { TimeseriesVisParams } from '../../../metrics_fn'; -import { TimeseriesVisData } from '../../../types'; +import { TimeseriesVisData } from '../../../../common/types'; export const TimeseriesVisTypes: Record> = { timeseries, diff --git a/src/plugins/vis_type_timeseries/public/metrics_fn.ts b/src/plugins/vis_type_timeseries/public/metrics_fn.ts index a6aa1b41cae1d..60acd35b22402 100644 --- a/src/plugins/vis_type_timeseries/public/metrics_fn.ts +++ b/src/plugins/vis_type_timeseries/public/metrics_fn.ts @@ -21,9 +21,8 @@ import { i18n } from '@kbn/i18n'; import { KibanaContext } from '../../data/public'; import { ExpressionFunctionDefinition, Render } from '../../expressions/public'; -import { PanelSchema } from '../common/types'; +import { PanelSchema, TimeseriesVisData } from '../common/types'; import { metricsRequestHandler } from './request_handler'; -import { TimeseriesVisData } from './types'; type Input = KibanaContext | null; type Output = Promise>; diff --git a/src/plugins/vis_type_timeseries/public/request_handler.ts b/src/plugins/vis_type_timeseries/public/request_handler.ts index f3ed3a2494f0c..aa45453515277 100644 --- a/src/plugins/vis_type_timeseries/public/request_handler.ts +++ b/src/plugins/vis_type_timeseries/public/request_handler.ts @@ -23,7 +23,7 @@ import { getTimezone, validateInterval } from './application'; import { getUISettings, getDataStart, getCoreStart } from './services'; import { MAX_BUCKETS_SETTING, ROUTES } from '../common/constants'; import { TimeseriesVisParams } from './metrics_fn'; -import { TimeseriesVisData } from './types'; +import { TimeseriesVisData } from '../common/types'; interface MetricsRequestHandlerParams { input: KibanaContext | null; diff --git a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx index 06130fa5e881a..67ed487d29378 100644 --- a/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_type_timeseries/public/timeseries_vis_renderer.tsx @@ -24,7 +24,7 @@ import { IUiSettingsClient } from 'kibana/public'; import { VisualizationContainer } from '../../visualizations/public'; import { ExpressionRenderDefinition } from '../../expressions/common/expression_renderers'; import { TimeseriesRenderValue, TimeseriesVisParams } from './metrics_fn'; -import { TimeseriesVisData } from './types'; +import { TimeseriesVisData } from '../common/types'; const TimeseriesVisualization = lazy( () => import('./application/components/timeseries_visualization') diff --git a/src/plugins/vis_type_timeseries/public/types.ts b/src/plugins/vis_type_timeseries/public/types.ts index adc1666b57119..338118dcdc5aa 100644 --- a/src/plugins/vis_type_timeseries/public/types.ts +++ b/src/plugins/vis_type_timeseries/public/types.ts @@ -20,9 +20,6 @@ import React from 'react'; import { EuiDraggable } from '@elastic/eui'; -import type { PANEL_TYPES } from '../common/panel_types'; -import { TimeseriesUIRestrictions } from '../common/ui_restrictions'; - type PropsOf = T extends React.ComponentType ? ComponentProps : never; type FirstArgumentOf = Func extends (arg1: infer FirstArgument, ...rest: any[]) => any ? FirstArgument @@ -30,27 +27,3 @@ type FirstArgumentOf = Func extends (arg1: infer FirstArgument, ...rest: a export type DragHandleProps = FirstArgumentOf< Exclude['children'], React.ReactElement> >['dragHandleProps']; - -/** - * series data is not typed yet. - * Should be in sync with returned data from server [GetVisDataPanel] in src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts - */ -interface SeriesData { - [key: string]: { - annotations: { - [key: string]: unknown[]; - }; - id: string; - series: unknown[]; - error?: unknown; - }; -} - -export type TimeseriesVisData = SeriesData & { - type: PANEL_TYPES; - uiRestrictions: TimeseriesUIRestrictions; - /** - * series array is responsible only for "table" vis type - */ - series?: unknown[]; -}; diff --git a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts index fcb66d2e12fd1..4bfb1e15bcf43 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts @@ -20,46 +20,35 @@ import { FakeRequest, RequestHandlerContext } from 'kibana/server'; import _ from 'lodash'; import { first, map } from 'rxjs/operators'; + +import { Filter, TimeRangeBounds, Query } from 'src/plugins/data/common'; import { getPanelData } from './vis_data/get_panel_data'; import { Framework } from '../plugin'; import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy'; - -interface GetVisDataResponse { - [key: string]: GetVisDataPanel; -} - -interface GetVisDataPanel { - id: string; - series: GetVisDataSeries[]; -} - -interface GetVisDataSeries { - id: string; - label: string; - data: GetVisDataDataPoint[]; -} - -type GetVisDataDataPoint = [number, number]; +import { PanelSchema, TimeseriesVisData } from '../../common/types'; export interface GetVisDataOptions { - timerange?: any; - panels?: any; - filters?: any; - state?: any; - query?: any; + timerange: TimeRangeBounds & { + timezone: string; + }; + panels: PanelSchema[]; + filters?: Filter[]; + state?: Record; + query?: Query | Query[]; + sessionId?: string; } export type GetVisData = ( requestContext: RequestHandlerContext, options: GetVisDataOptions, framework: Framework -) => Promise; +) => Promise; export function getVisData( requestContext: RequestHandlerContext, request: FakeRequest & { body: GetVisDataOptions }, framework: Framework -): Promise { +): Promise { // NOTE / TODO: This facade has been put in place to make migrating to the New Platform easier. It // removes the need to refactor many layers of dependencies on "req", and instead just augments the top // level object passed from here. The layers should be refactored fully at some point, but for now @@ -81,10 +70,10 @@ export function getVisData( .toPromise(); }, }; - const promises = (reqFacade.payload as GetVisDataOptions).panels.map(getPanelData(reqFacade)); + const promises = reqFacade.payload.panels.map(getPanelData(reqFacade)); return Promise.all(promises).then((res) => { return res.reduce((acc, data) => { return _.assign(acc as any, data); }, {}); - }) as Promise; + }) as Promise; } From 9fcab2619034a75724da4f837b65610ee0258132 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Thu, 19 Nov 2020 18:13:16 +0300 Subject: [PATCH 15/18] Return back validation error message --- src/plugins/vis_type_timeseries/server/routes/vis.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/vis_type_timeseries/server/routes/vis.ts b/src/plugins/vis_type_timeseries/server/routes/vis.ts index bd38d6a4ed1ee..bba086720da0a 100644 --- a/src/plugins/vis_type_timeseries/server/routes/vis.ts +++ b/src/plugins/vis_type_timeseries/server/routes/vis.ts @@ -44,6 +44,10 @@ export const visDataRoutes = ( visPayloadSchema.validate(request.body); } catch (error) { logFailedValidation(); + + framework.logger.warn( + `Request validation error: ${error.message}. This most likely means your TSVB visualization contains outdated configuration. You can report this problem under https://github.com/elastic/kibana/issues/new?template=Bug_report.md` + ); } try { From 390968570d823fb2ee32efd915f3dec2dc921065 Mon Sep 17 00:00:00 2001 From: sulemanof Date: Thu, 19 Nov 2020 19:03:36 +0300 Subject: [PATCH 16/18] Use panel types enum --- .../vis_type_timeseries/common/panel_types.ts | 20 ++++++++----------- .../vis_type_timeseries/common/types.ts | 2 +- .../common/ui_restrictions.ts | 2 +- .../vis_type_timeseries/common/vis_schema.ts | 9 ++++++++- .../lib/vis_data/helpers/get_active_series.ts | 3 ++- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/plugins/vis_type_timeseries/common/panel_types.ts b/src/plugins/vis_type_timeseries/common/panel_types.ts index 96b649bd88571..6aed5528c23a5 100644 --- a/src/plugins/vis_type_timeseries/common/panel_types.ts +++ b/src/plugins/vis_type_timeseries/common/panel_types.ts @@ -17,15 +17,11 @@ * under the License. */ -import { $Values } from '@kbn/utility-types'; - -export const PANEL_TYPES = { - TABLE: 'table', - GAUGE: 'gauge', - MARKDOWN: 'markdown', - TOP_N: 'top_n', - TIMESERIES: 'timeseries', - METRIC: 'metric', -}; - -export type PANEL_TYPES = $Values; +export enum PANEL_TYPES { + TABLE = 'table', + GAUGE = 'gauge', + MARKDOWN = 'markdown', + TOP_N = 'top_n', + TIMESERIES = 'timeseries', + METRIC = 'metric', +} diff --git a/src/plugins/vis_type_timeseries/common/types.ts b/src/plugins/vis_type_timeseries/common/types.ts index 673d2916ee98d..e7fc4184dcef6 100644 --- a/src/plugins/vis_type_timeseries/common/types.ts +++ b/src/plugins/vis_type_timeseries/common/types.ts @@ -19,7 +19,7 @@ import { TypeOf } from '@kbn/config-schema'; import { metricsItems, panel, seriesItems, visPayloadSchema } from './vis_schema'; -import type { PANEL_TYPES } from './panel_types'; +import { PANEL_TYPES } from './panel_types'; import { TimeseriesUIRestrictions } from './ui_restrictions'; export type SeriesItemsSchema = TypeOf; diff --git a/src/plugins/vis_type_timeseries/common/ui_restrictions.ts b/src/plugins/vis_type_timeseries/common/ui_restrictions.ts index e2911eb2d70e3..1be428f1b9354 100644 --- a/src/plugins/vis_type_timeseries/common/ui_restrictions.ts +++ b/src/plugins/vis_type_timeseries/common/ui_restrictions.ts @@ -63,7 +63,7 @@ export const DEFAULT_UI_RESTRICTION: UIRestrictions = { * @constant * @public */ -export const limitOfSeries = { +export const limitOfSeries: Partial> = { [PANEL_TYPES.GAUGE]: 1, [PANEL_TYPES.METRIC]: 2, }; diff --git a/src/plugins/vis_type_timeseries/common/vis_schema.ts b/src/plugins/vis_type_timeseries/common/vis_schema.ts index 372e7e01e0539..7f17a9c44298a 100644 --- a/src/plugins/vis_type_timeseries/common/vis_schema.ts +++ b/src/plugins/vis_type_timeseries/common/vis_schema.ts @@ -251,7 +251,14 @@ export const panel = schema.object({ ), time_field: stringOptionalNullable, time_range_mode: stringOptionalNullable, - type: stringRequired, + type: schema.oneOf([ + schema.literal('table'), + schema.literal('gauge'), + schema.literal('markdown'), + schema.literal('top_n'), + schema.literal('timeseries'), + schema.literal('metric'), + ]), }); export const visPayloadSchema = schema.object({ diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts index 235235cf6a3be..b7644f6582761 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_active_series.ts @@ -29,7 +29,8 @@ export const getActiveSeries = (panel: PanelSchema) => { } // Toogle visibility functionality for 'gauge', 'markdown' is not accessible - const shouldNotApplyFilter = [PANEL_TYPES.GAUGE, PANEL_TYPES.MARKDOWN].includes(panel.type); + const shouldNotApplyFilter = + PANEL_TYPES.GAUGE === panel.type || PANEL_TYPES.MARKDOWN === panel.type; return visibleSeries.filter((series) => !series.hidden || shouldNotApplyFilter); }; From 4383a41ad80e059976f0c0aead8318689617a86f Mon Sep 17 00:00:00 2001 From: sulemanof Date: Fri, 20 Nov 2020 12:38:54 +0300 Subject: [PATCH 17/18] Fix types --- src/plugins/vis_type_timeseries/common/types.ts | 2 +- .../vis_type_timeseries/server/lib/get_vis_data.ts | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/plugins/vis_type_timeseries/common/types.ts b/src/plugins/vis_type_timeseries/common/types.ts index e7fc4184dcef6..f8e1b740fc646 100644 --- a/src/plugins/vis_type_timeseries/common/types.ts +++ b/src/plugins/vis_type_timeseries/common/types.ts @@ -30,7 +30,7 @@ export type VisPayload = TypeOf; interface PanelData { id: string; label: string; - data: [number, number]; + data: Array<[number, number]>; } // series data is not fully typed yet diff --git a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts index 4bfb1e15bcf43..aefbe0ea78d4b 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_vis_data.ts @@ -21,17 +21,19 @@ import { FakeRequest, RequestHandlerContext } from 'kibana/server'; import _ from 'lodash'; import { first, map } from 'rxjs/operators'; -import { Filter, TimeRangeBounds, Query } from 'src/plugins/data/common'; +import { Filter, Query } from 'src/plugins/data/common'; import { getPanelData } from './vis_data/get_panel_data'; import { Framework } from '../plugin'; import { ReqFacade } from './search_strategies/strategies/abstract_search_strategy'; -import { PanelSchema, TimeseriesVisData } from '../../common/types'; +import { TimeseriesVisData } from '../../common/types'; export interface GetVisDataOptions { - timerange: TimeRangeBounds & { - timezone: string; + timerange: { + min: number | string; + max: number | string; + timezone?: string; }; - panels: PanelSchema[]; + panels: unknown[]; filters?: Filter[]; state?: Record; query?: Query | Query[]; From af49c78ffddfb967cf1c16fc9fd3f3d254687d8f Mon Sep 17 00:00:00 2001 From: sulemanof Date: Mon, 23 Nov 2020 14:35:53 +0300 Subject: [PATCH 18/18] Lazy load visualizations --- .../components/vis_types/gauge/vis.js | 6 ++++- .../application/components/vis_types/index.ts | 22 ++++++++++--------- .../components/vis_types/markdown/vis.js | 6 ++++- .../components/vis_types/metric/vis.js | 6 ++++- .../components/vis_types/table/vis.js | 6 ++++- .../components/vis_types/timeseries/vis.js | 6 ++++- .../components/vis_types/top_n/vis.js | 6 ++++- 7 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js index 325e9c8372736..5a6d5f39d0c97 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/gauge/vis.js @@ -101,4 +101,8 @@ GaugeVisualization.propTypes = { getConfig: PropTypes.func, }; -export const gauge = visWithSplits(GaugeVisualization); +const gauge = visWithSplits(GaugeVisualization); + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { gauge as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts index 158350b84e25f..56e58b4da3458 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/index.ts @@ -17,29 +17,31 @@ * under the License. */ -import React from 'react'; +import React, { lazy } from 'react'; import { IUiSettingsClient } from 'src/core/public'; import { PersistedState } from 'src/plugins/visualizations/public'; +import { TimeseriesVisParams } from '../../../metrics_fn'; +import { TimeseriesVisData } from '../../../../common/types'; + /** - * TSVB visualizations are not typed yet. + * Lazy load each visualization type, since the only one is presented on the screen at the same time. + * Disable typescript errors since the components are not typed yet. */ // @ts-expect-error -import { TimeseriesVisualization as timeseries } from './timeseries/vis'; +const timeseries = lazy(() => import('./timeseries/vis')); // @ts-expect-error -import { metric } from './metric/vis'; +const metric = lazy(() => import('./metric/vis')); // @ts-expect-error -import { TopNVisualization as topN } from './top_n/vis'; +const topN = lazy(() => import('./top_n/vis')); // @ts-expect-error -import { TableVis as table } from './table/vis'; +const table = lazy(() => import('./table/vis')); // @ts-expect-error -import { gauge } from './gauge/vis'; +const gauge = lazy(() => import('./gauge/vis')); // @ts-expect-error -import { MarkdownVisualization as markdown } from './markdown/vis'; -import { TimeseriesVisParams } from '../../../metrics_fn'; -import { TimeseriesVisData } from '../../../../common/types'; +const markdown = lazy(() => import('./markdown/vis')); export const TimeseriesVisTypes: Record> = { timeseries, diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js index a4e7738e92318..e68b9e5ed8467 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/markdown/vis.js @@ -30,7 +30,7 @@ import { isBackgroundInverted } from '../../../lib/set_is_reversed'; const getMarkdownId = (id) => `markdown-${id}`; -export function MarkdownVisualization(props) { +function MarkdownVisualization(props) { const { backgroundColor, model, visData, dateFormat } = props; const series = get(visData, `${model.id}.series`, []); const variables = convertSeriesToVars(series, model, dateFormat, props.getConfig); @@ -106,3 +106,7 @@ MarkdownVisualization.propTypes = { dateFormat: PropTypes.string, getConfig: PropTypes.func, }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { MarkdownVisualization as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js index 5fe7afe47df9b..7069a32fa2b50 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/metric/vis.js @@ -95,4 +95,8 @@ MetricVisualization.propTypes = { getConfig: PropTypes.func, }; -export const metric = visWithSplits(MetricVisualization); +const metric = visWithSplits(MetricVisualization); + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { metric as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js index 92109e1a37426..a31be694cd172 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/table/vis.js @@ -46,7 +46,7 @@ function getColor(rules, colorKey, value) { return color; } -export class TableVis extends Component { +class TableVis extends Component { constructor(props) { super(props); @@ -260,3 +260,7 @@ TableVis.propTypes = { pageNumber: PropTypes.number, getConfig: PropTypes.func, }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TableVis as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js index e1eafbcffe957..b752699fa1548 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/timeseries/vis.js @@ -34,7 +34,7 @@ import { createXaxisFormatter } from '../../lib/create_xaxis_formatter'; import { STACKED_OPTIONS } from '../../../visualizations/constants'; import { getCoreStart } from '../../../../services'; -export class TimeseriesVisualization extends Component { +class TimeseriesVisualization extends Component { static propTypes = { model: PropTypes.object, onBrush: PropTypes.func, @@ -246,3 +246,7 @@ export class TimeseriesVisualization extends Component { ); } } + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TimeseriesVisualization as default }; diff --git a/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js b/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js index 1c2ebb8264ef3..92311b3f33afb 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js +++ b/src/plugins/vis_type_timeseries/public/application/components/vis_types/top_n/vis.js @@ -48,7 +48,7 @@ function sortSeries(visData, model) { }, []); } -export function TopNVisualization(props) { +function TopNVisualization(props) { const { backgroundColor, model, visData } = props; const series = sortSeries(visData, model).map((item) => { @@ -111,3 +111,7 @@ TopNVisualization.propTypes = { visData: PropTypes.object, getConfig: PropTypes.func, }; + +// default export required for React.Lazy +// eslint-disable-next-line import/no-default-export +export { TopNVisualization as default };