From 35e61520e052438098baab399c95de7b7dee3aac Mon Sep 17 00:00:00 2001 From: Marco Vettorello <1421091+markov00@users.noreply.github.com> Date: Wed, 7 Nov 2018 10:48:33 +0100 Subject: [PATCH] Fix missing TSVB markdown variables (#25132) (#25231) * Move fieldsFetch logic into the vis editor * Add annotations index pattern change detection * Fix async update of state. Add functional test * Add missing data archive * Force fetch when component mount the first time * Fix parameters naming * Refactoring indexPatterns to fetch * Add observables and pipe data updates to markdown panel config * Fix jest test --- .../public/components/markdown_editor.js | 35 ++++++++++++++----- .../metrics/public/components/panel_config.js | 4 +-- .../public/components/panel_config/gauge.js | 1 - .../components/panel_config/markdown.js | 1 - .../public/components/panel_config/metric.js | 1 - .../public/components/panel_config/table.js | 1 - .../components/panel_config/timeseries.js | 1 - .../public/components/panel_config/top_n.js | 1 - .../metrics/public/components/vis_editor.js | 17 +++++++-- .../components/vis_editor_visualization.js | 8 +++++ .../vis_editor_visualization.test.js | 5 ++- .../loader/embedded_visualize_handler.ts | 21 +++++++++-- 12 files changed, 73 insertions(+), 23 deletions(-) diff --git a/src/core_plugins/metrics/public/components/markdown_editor.js b/src/core_plugins/metrics/public/components/markdown_editor.js index 706548b32af3..a1a74e57e802 100644 --- a/src/core_plugins/metrics/public/components/markdown_editor.js +++ b/src/core_plugins/metrics/public/components/markdown_editor.js @@ -37,17 +37,30 @@ import { } from '@elastic/eui'; class MarkdownEditor extends Component { - constructor(props) { - super(props); - this.handleChange = this.handleChange.bind(this); - this.handleOnLoad = this.handleOnLoad.bind(this); + state = { + visData: null, + }; + subscription = null; + + componentDidMount() { + if(this.props.visData$) { + this.subscription = this.props.visData$.subscribe((data) => { + this.setState({ visData: data }); + }); + } } - handleChange(value) { + componentWillUnmount() { + if(this.subscription) { + this.subscription.unsubscribe(); + } + } + + handleChange = (value) => { this.props.onChange({ markdown: value }); } - handleOnLoad(ace) { + handleOnLoad = (ace) => { this.ace = ace; } @@ -58,7 +71,11 @@ class MarkdownEditor extends Component { } render() { - const { model, visData, dateFormat } = this.props; + const { visData } = this.state; + if (!visData) { + return null; + } + const { model, dateFormat } = this.props; const series = _.get(visData, `${model.id}.series`, []); const variables = convertSeriesToVars(series, model, dateFormat, this.props.getConfig); const rows = []; @@ -174,8 +191,8 @@ class MarkdownEditor extends Component { MarkdownEditor.propTypes = { onChange: PropTypes.func, model: PropTypes.object, - visData: PropTypes.object, - dateFormat: PropTypes.string + dateFormat: PropTypes.string, + visData$: PropTypes.object, }; export default MarkdownEditor; diff --git a/src/core_plugins/metrics/public/components/panel_config.js b/src/core_plugins/metrics/public/components/panel_config.js index 59e3fb381b2d..91c944927608 100644 --- a/src/core_plugins/metrics/public/components/panel_config.js +++ b/src/core_plugins/metrics/public/components/panel_config.js @@ -48,8 +48,8 @@ PanelConfig.propTypes = { fields: PropTypes.object, model: PropTypes.object, onChange: PropTypes.func, - visData: PropTypes.object, - dateFormat: PropTypes.string + dateFormat: PropTypes.string, + visData$: PropTypes.object, }; export default PanelConfig; diff --git a/src/core_plugins/metrics/public/components/panel_config/gauge.js b/src/core_plugins/metrics/public/components/panel_config/gauge.js index 043133992663..37c5e1c09666 100644 --- a/src/core_plugins/metrics/public/components/panel_config/gauge.js +++ b/src/core_plugins/metrics/public/components/panel_config/gauge.js @@ -218,7 +218,6 @@ GaugePanelConfig.propTypes = { fields: PropTypes.object, model: PropTypes.object, onChange: PropTypes.func, - visData: PropTypes.object, }; export default GaugePanelConfig; diff --git a/src/core_plugins/metrics/public/components/panel_config/markdown.js b/src/core_plugins/metrics/public/components/panel_config/markdown.js index 29d419b59669..79c59763f754 100644 --- a/src/core_plugins/metrics/public/components/panel_config/markdown.js +++ b/src/core_plugins/metrics/public/components/panel_config/markdown.js @@ -197,7 +197,6 @@ MarkdownPanelConfig.propTypes = { fields: PropTypes.object, model: PropTypes.object, onChange: PropTypes.func, - visData: PropTypes.object, dateFormat: PropTypes.string }; diff --git a/src/core_plugins/metrics/public/components/panel_config/metric.js b/src/core_plugins/metrics/public/components/panel_config/metric.js index 173cfc404a2a..092a913766f0 100644 --- a/src/core_plugins/metrics/public/components/panel_config/metric.js +++ b/src/core_plugins/metrics/public/components/panel_config/metric.js @@ -134,7 +134,6 @@ MetricPanelConfig.propTypes = { fields: PropTypes.object, model: PropTypes.object, onChange: PropTypes.func, - visData: PropTypes.object, }; export default MetricPanelConfig; diff --git a/src/core_plugins/metrics/public/components/panel_config/table.js b/src/core_plugins/metrics/public/components/panel_config/table.js index 58fcf43c7aaa..efd84af39c06 100644 --- a/src/core_plugins/metrics/public/components/panel_config/table.js +++ b/src/core_plugins/metrics/public/components/panel_config/table.js @@ -172,7 +172,6 @@ TablePanelConfig.propTypes = { fields: PropTypes.object, model: PropTypes.object, onChange: PropTypes.func, - visData: PropTypes.object, }; export default TablePanelConfig; diff --git a/src/core_plugins/metrics/public/components/panel_config/timeseries.js b/src/core_plugins/metrics/public/components/panel_config/timeseries.js index 85b09047b7d9..b52967caa7be 100644 --- a/src/core_plugins/metrics/public/components/panel_config/timeseries.js +++ b/src/core_plugins/metrics/public/components/panel_config/timeseries.js @@ -232,7 +232,6 @@ TimeseriesPanelConfig.propTypes = { fields: PropTypes.object, model: PropTypes.object, onChange: PropTypes.func, - visData: PropTypes.object, }; export default TimeseriesPanelConfig; diff --git a/src/core_plugins/metrics/public/components/panel_config/top_n.js b/src/core_plugins/metrics/public/components/panel_config/top_n.js index 98b5155e2c0b..f3e0979052a7 100644 --- a/src/core_plugins/metrics/public/components/panel_config/top_n.js +++ b/src/core_plugins/metrics/public/components/panel_config/top_n.js @@ -154,7 +154,6 @@ TopNPanelConfig.propTypes = { fields: PropTypes.object, model: PropTypes.object, onChange: PropTypes.func, - visData: PropTypes.object, }; export default TopNPanelConfig; diff --git a/src/core_plugins/metrics/public/components/vis_editor.js b/src/core_plugins/metrics/public/components/vis_editor.js index 057a4fb07102..94d8119c94cb 100644 --- a/src/core_plugins/metrics/public/components/vis_editor.js +++ b/src/core_plugins/metrics/public/components/vis_editor.js @@ -19,6 +19,8 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; +import * as Rx from 'rxjs'; +import { share } from 'rxjs/operators'; import VisEditorVisualization from './vis_editor_visualization'; import Visualization from './visualization'; import VisPicker from './vis_picker'; @@ -46,6 +48,8 @@ class VisEditor extends Component { this.handleUiState = this.handleUiState.bind(this, props.vis); this.handleAppStateChange = this.handleAppStateChange.bind(this); this.getConfig = (...args) => props.config.get(...args); + this.visDataSubject = new Rx.Subject(); + this.visData$ = this.visDataSubject.asObservable().pipe(share()); } handleUiState(vis, ...args) { @@ -116,9 +120,15 @@ class VisEditor extends Component { this.setState({ autoApply: event.target.checked }); } + onDataChange = (data) => { + this.visDataSubject.next(data); + } + render() { if (!this.props.isEditorMode) { - if (!this.props.vis.params || !this.props.visData) return null; + if (!this.props.vis.params || !this.props.visData) { + return null; + } const reversed = this.state.reversed; return (
@@ -159,12 +169,13 @@ class VisEditor extends Component { title={this.props.vis.title} description={this.props.vis.description} dateFormat={this.props.config.get('dateFormat')} + onDataChange={this.onDataChange} />
{ @@ -90,6 +94,10 @@ class VisEditorVisualization extends Component { appState: this.props.appState, }); + this._subscription = this._handler.data$.subscribe((data) => { + this.props.onDataChange(data); + }); + if (this._handlerUpdateHasAlreadyBeenTriggered) { this.onUpdate(); } diff --git a/src/core_plugins/metrics/public/components/vis_editor_visualization.test.js b/src/core_plugins/metrics/public/components/vis_editor_visualization.test.js index 6329a1cc95bd..15b6666207f7 100644 --- a/src/core_plugins/metrics/public/components/vis_editor_visualization.test.js +++ b/src/core_plugins/metrics/public/components/vis_editor_visualization.test.js @@ -29,7 +29,10 @@ describe('getVisualizeLoader', () => { beforeEach(() => { updateStub = jest.fn(); const handlerMock = { - update: updateStub + update: updateStub, + data$: { + subscribe: () => {} + } }; const loaderMock = { embedVisualizationWithSavedObject: () => { diff --git a/src/ui/public/visualize/loader/embedded_visualize_handler.ts b/src/ui/public/visualize/loader/embedded_visualize_handler.ts index f5310e5a61de..35784982d96b 100644 --- a/src/ui/public/visualize/loader/embedded_visualize_handler.ts +++ b/src/ui/public/visualize/loader/embedded_visualize_handler.ts @@ -19,6 +19,9 @@ import { EventEmitter } from 'events'; import { debounce } from 'lodash'; +import * as Rx from 'rxjs'; +import { share } from 'rxjs/operators'; +import { Inspector } from '../../inspector'; import { Adapters } from '../../inspector/types'; import { PersistedState } from '../../persisted_state'; import { IPrivate } from '../../private'; @@ -29,7 +32,6 @@ import { RequestHandlerParams, Vis } from '../../vis'; import { visualizationLoader } from './visualization_loader'; import { VisualizeDataLoader } from './visualize_data_loader'; -import { Inspector } from '../../inspector'; import { DataAdapter, RequestAdapter } from '../../inspector/adapters'; import { VisSavedObject, VisualizeLoaderParams, VisualizeUpdateParams } from './types'; @@ -47,6 +49,14 @@ const LOADING_ATTRIBUTE = 'data-loading'; * with the visualization. */ export class EmbeddedVisualizeHandler { + /** + * This observable will emit every time new data is loaded for the + * visualization. The emitted value is the loaded data after it has + * been transformed by the visualization's response handler. + * This should not be used by any plugin. + * @ignore + */ + public readonly data$: Rx.Observable; private vis: Vis; private loaded: boolean = false; private destroyed: boolean = false; @@ -69,6 +79,7 @@ export class EmbeddedVisualizeHandler { private readonly appState?: AppState; private uiState: PersistedState; private dataLoader: VisualizeDataLoader; + private dataSubject: Rx.Subject; private inspectorAdapters: Adapters = {}; constructor( @@ -117,6 +128,9 @@ export class EmbeddedVisualizeHandler { this.vis.openInspector = this.openInspector; this.vis.hasInspector = this.hasInspector; + this.dataSubject = new Rx.Subject(); + this.data$ = this.dataSubject.asObservable().pipe(share()); + this.render(); } @@ -313,7 +327,10 @@ export class EmbeddedVisualizeHandler { this.dataLoaderParams.forceFetch = forceFetch; this.dataLoaderParams.inspectorAdapters = this.inspectorAdapters; - return this.dataLoader.fetch(this.dataLoaderParams); + return this.dataLoader.fetch(this.dataLoaderParams).then(data => { + this.dataSubject.next(data); + return data; + }); }; private render = (visData: any = null) => {