* 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:
parent
b2e62cd9a4
commit
35e61520e0
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -218,7 +218,6 @@ GaugePanelConfig.propTypes = {
|
|||
fields: PropTypes.object,
|
||||
model: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
visData: PropTypes.object,
|
||||
};
|
||||
|
||||
export default GaugePanelConfig;
|
||||
|
|
|
@ -197,7 +197,6 @@ MarkdownPanelConfig.propTypes = {
|
|||
fields: PropTypes.object,
|
||||
model: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
visData: PropTypes.object,
|
||||
dateFormat: PropTypes.string
|
||||
};
|
||||
|
||||
|
|
|
@ -134,7 +134,6 @@ MetricPanelConfig.propTypes = {
|
|||
fields: PropTypes.object,
|
||||
model: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
visData: PropTypes.object,
|
||||
};
|
||||
|
||||
export default MetricPanelConfig;
|
||||
|
|
|
@ -172,7 +172,6 @@ TablePanelConfig.propTypes = {
|
|||
fields: PropTypes.object,
|
||||
model: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
visData: PropTypes.object,
|
||||
};
|
||||
|
||||
export default TablePanelConfig;
|
||||
|
|
|
@ -232,7 +232,6 @@ TimeseriesPanelConfig.propTypes = {
|
|||
fields: PropTypes.object,
|
||||
model: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
visData: PropTypes.object,
|
||||
};
|
||||
|
||||
export default TimeseriesPanelConfig;
|
||||
|
|
|
@ -154,7 +154,6 @@ TopNPanelConfig.propTypes = {
|
|||
fields: PropTypes.object,
|
||||
model: PropTypes.object,
|
||||
onChange: PropTypes.func,
|
||||
visData: PropTypes.object,
|
||||
};
|
||||
|
||||
export default TopNPanelConfig;
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,10 @@ describe('getVisualizeLoader', () => {
|
|||
beforeEach(() => {
|
||||
updateStub = jest.fn();
|
||||
const handlerMock = {
|
||||
update: updateStub
|
||||
update: updateStub,
|
||||
data$: {
|
||||
subscribe: () => {}
|
||||
}
|
||||
};
|
||||
const loaderMock = {
|
||||
embedVisualizationWithSavedObject: () => {
|
||||
|
|
|
@ -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) => {
|
||||
|
|
Loading…
Reference in a new issue