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
This commit is contained in:
Marco Vettorello 2018-11-07 10:48:33 +01:00 committed by GitHub
parent b2e62cd9a4
commit 35e61520e0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 73 additions and 23 deletions

View file

@ -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;

View file

@ -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;

View file

@ -218,7 +218,6 @@ GaugePanelConfig.propTypes = {
fields: PropTypes.object,
model: PropTypes.object,
onChange: PropTypes.func,
visData: PropTypes.object,
};
export default GaugePanelConfig;

View file

@ -197,7 +197,6 @@ MarkdownPanelConfig.propTypes = {
fields: PropTypes.object,
model: PropTypes.object,
onChange: PropTypes.func,
visData: PropTypes.object,
dateFormat: PropTypes.string
};

View file

@ -134,7 +134,6 @@ MetricPanelConfig.propTypes = {
fields: PropTypes.object,
model: PropTypes.object,
onChange: PropTypes.func,
visData: PropTypes.object,
};
export default MetricPanelConfig;

View file

@ -172,7 +172,6 @@ TablePanelConfig.propTypes = {
fields: PropTypes.object,
model: PropTypes.object,
onChange: PropTypes.func,
visData: PropTypes.object,
};
export default TablePanelConfig;

View file

@ -232,7 +232,6 @@ TimeseriesPanelConfig.propTypes = {
fields: PropTypes.object,
model: PropTypes.object,
onChange: PropTypes.func,
visData: PropTypes.object,
};
export default TimeseriesPanelConfig;

View file

@ -154,7 +154,6 @@ TopNPanelConfig.propTypes = {
fields: PropTypes.object,
model: PropTypes.object,
onChange: PropTypes.func,
visData: PropTypes.object,
};
export default TopNPanelConfig;

View file

@ -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 (
<Visualization
@ -137,7 +147,7 @@ class VisEditor extends Component {
const { model } = this.state;
if (model && this.props.visData) {
if (model) {
return (
<div className="vis_editor">
<div className="vis-editor-hide-for-reporting">
@ -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}
/>
<div className="vis-editor-hide-for-reporting">
<PanelConfig
fields={this.state.visFields}
model={model}
visData={this.props.visData}
visData$={this.visData$}
dateFormat={this.props.config.get('dateFormat')}
onChange={this.handleChange}
getConfig={this.getConfig}

View file

@ -39,6 +39,7 @@ class VisEditorVisualization extends Component {
this.onSizeHandleKeyDown = this.onSizeHandleKeyDown.bind(this);
this._visEl = React.createRef();
this._subscription = null;
}
handleMouseDown() {
@ -67,6 +68,9 @@ class VisEditorVisualization extends Component {
if (this._handler) {
this._handler.destroy();
}
if(this._subscription) {
this._subscription.unsubscribe();
}
}
onUpdate = () => {
@ -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();
}

View file

@ -29,7 +29,10 @@ describe('getVisualizeLoader', () => {
beforeEach(() => {
updateStub = jest.fn();
const handlerMock = {
update: updateStub
update: updateStub,
data$: {
subscribe: () => {}
}
};
const loaderMock = {
embedVisualizationWithSavedObject: () => {

View file

@ -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<any>;
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<any>;
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) => {