* 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';
|
} from '@elastic/eui';
|
||||||
|
|
||||||
class MarkdownEditor extends Component {
|
class MarkdownEditor extends Component {
|
||||||
constructor(props) {
|
state = {
|
||||||
super(props);
|
visData: null,
|
||||||
this.handleChange = this.handleChange.bind(this);
|
};
|
||||||
this.handleOnLoad = this.handleOnLoad.bind(this);
|
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 });
|
this.props.onChange({ markdown: value });
|
||||||
}
|
}
|
||||||
|
|
||||||
handleOnLoad(ace) {
|
handleOnLoad = (ace) => {
|
||||||
this.ace = ace;
|
this.ace = ace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +71,11 @@ class MarkdownEditor extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
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 series = _.get(visData, `${model.id}.series`, []);
|
||||||
const variables = convertSeriesToVars(series, model, dateFormat, this.props.getConfig);
|
const variables = convertSeriesToVars(series, model, dateFormat, this.props.getConfig);
|
||||||
const rows = [];
|
const rows = [];
|
||||||
|
@ -174,8 +191,8 @@ class MarkdownEditor extends Component {
|
||||||
MarkdownEditor.propTypes = {
|
MarkdownEditor.propTypes = {
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
visData: PropTypes.object,
|
dateFormat: PropTypes.string,
|
||||||
dateFormat: PropTypes.string
|
visData$: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MarkdownEditor;
|
export default MarkdownEditor;
|
||||||
|
|
|
@ -48,8 +48,8 @@ PanelConfig.propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visData: PropTypes.object,
|
dateFormat: PropTypes.string,
|
||||||
dateFormat: PropTypes.string
|
visData$: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default PanelConfig;
|
export default PanelConfig;
|
||||||
|
|
|
@ -218,7 +218,6 @@ GaugePanelConfig.propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visData: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default GaugePanelConfig;
|
export default GaugePanelConfig;
|
||||||
|
|
|
@ -197,7 +197,6 @@ MarkdownPanelConfig.propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visData: PropTypes.object,
|
|
||||||
dateFormat: PropTypes.string
|
dateFormat: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -134,7 +134,6 @@ MetricPanelConfig.propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visData: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MetricPanelConfig;
|
export default MetricPanelConfig;
|
||||||
|
|
|
@ -172,7 +172,6 @@ TablePanelConfig.propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visData: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TablePanelConfig;
|
export default TablePanelConfig;
|
||||||
|
|
|
@ -232,7 +232,6 @@ TimeseriesPanelConfig.propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visData: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TimeseriesPanelConfig;
|
export default TimeseriesPanelConfig;
|
||||||
|
|
|
@ -154,7 +154,6 @@ TopNPanelConfig.propTypes = {
|
||||||
fields: PropTypes.object,
|
fields: PropTypes.object,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
onChange: PropTypes.func,
|
onChange: PropTypes.func,
|
||||||
visData: PropTypes.object,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default TopNPanelConfig;
|
export default TopNPanelConfig;
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
|
import * as Rx from 'rxjs';
|
||||||
|
import { share } from 'rxjs/operators';
|
||||||
import VisEditorVisualization from './vis_editor_visualization';
|
import VisEditorVisualization from './vis_editor_visualization';
|
||||||
import Visualization from './visualization';
|
import Visualization from './visualization';
|
||||||
import VisPicker from './vis_picker';
|
import VisPicker from './vis_picker';
|
||||||
|
@ -46,6 +48,8 @@ class VisEditor extends Component {
|
||||||
this.handleUiState = this.handleUiState.bind(this, props.vis);
|
this.handleUiState = this.handleUiState.bind(this, props.vis);
|
||||||
this.handleAppStateChange = this.handleAppStateChange.bind(this);
|
this.handleAppStateChange = this.handleAppStateChange.bind(this);
|
||||||
this.getConfig = (...args) => props.config.get(...args);
|
this.getConfig = (...args) => props.config.get(...args);
|
||||||
|
this.visDataSubject = new Rx.Subject();
|
||||||
|
this.visData$ = this.visDataSubject.asObservable().pipe(share());
|
||||||
}
|
}
|
||||||
|
|
||||||
handleUiState(vis, ...args) {
|
handleUiState(vis, ...args) {
|
||||||
|
@ -116,9 +120,15 @@ class VisEditor extends Component {
|
||||||
this.setState({ autoApply: event.target.checked });
|
this.setState({ autoApply: event.target.checked });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onDataChange = (data) => {
|
||||||
|
this.visDataSubject.next(data);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (!this.props.isEditorMode) {
|
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;
|
const reversed = this.state.reversed;
|
||||||
return (
|
return (
|
||||||
<Visualization
|
<Visualization
|
||||||
|
@ -137,7 +147,7 @@ class VisEditor extends Component {
|
||||||
|
|
||||||
const { model } = this.state;
|
const { model } = this.state;
|
||||||
|
|
||||||
if (model && this.props.visData) {
|
if (model) {
|
||||||
return (
|
return (
|
||||||
<div className="vis_editor">
|
<div className="vis_editor">
|
||||||
<div className="vis-editor-hide-for-reporting">
|
<div className="vis-editor-hide-for-reporting">
|
||||||
|
@ -159,12 +169,13 @@ class VisEditor extends Component {
|
||||||
title={this.props.vis.title}
|
title={this.props.vis.title}
|
||||||
description={this.props.vis.description}
|
description={this.props.vis.description}
|
||||||
dateFormat={this.props.config.get('dateFormat')}
|
dateFormat={this.props.config.get('dateFormat')}
|
||||||
|
onDataChange={this.onDataChange}
|
||||||
/>
|
/>
|
||||||
<div className="vis-editor-hide-for-reporting">
|
<div className="vis-editor-hide-for-reporting">
|
||||||
<PanelConfig
|
<PanelConfig
|
||||||
fields={this.state.visFields}
|
fields={this.state.visFields}
|
||||||
model={model}
|
model={model}
|
||||||
visData={this.props.visData}
|
visData$={this.visData$}
|
||||||
dateFormat={this.props.config.get('dateFormat')}
|
dateFormat={this.props.config.get('dateFormat')}
|
||||||
onChange={this.handleChange}
|
onChange={this.handleChange}
|
||||||
getConfig={this.getConfig}
|
getConfig={this.getConfig}
|
||||||
|
|
|
@ -39,6 +39,7 @@ class VisEditorVisualization extends Component {
|
||||||
this.onSizeHandleKeyDown = this.onSizeHandleKeyDown.bind(this);
|
this.onSizeHandleKeyDown = this.onSizeHandleKeyDown.bind(this);
|
||||||
|
|
||||||
this._visEl = React.createRef();
|
this._visEl = React.createRef();
|
||||||
|
this._subscription = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMouseDown() {
|
handleMouseDown() {
|
||||||
|
@ -67,6 +68,9 @@ class VisEditorVisualization extends Component {
|
||||||
if (this._handler) {
|
if (this._handler) {
|
||||||
this._handler.destroy();
|
this._handler.destroy();
|
||||||
}
|
}
|
||||||
|
if(this._subscription) {
|
||||||
|
this._subscription.unsubscribe();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onUpdate = () => {
|
onUpdate = () => {
|
||||||
|
@ -90,6 +94,10 @@ class VisEditorVisualization extends Component {
|
||||||
appState: this.props.appState,
|
appState: this.props.appState,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this._subscription = this._handler.data$.subscribe((data) => {
|
||||||
|
this.props.onDataChange(data);
|
||||||
|
});
|
||||||
|
|
||||||
if (this._handlerUpdateHasAlreadyBeenTriggered) {
|
if (this._handlerUpdateHasAlreadyBeenTriggered) {
|
||||||
this.onUpdate();
|
this.onUpdate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,10 @@ describe('getVisualizeLoader', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
updateStub = jest.fn();
|
updateStub = jest.fn();
|
||||||
const handlerMock = {
|
const handlerMock = {
|
||||||
update: updateStub
|
update: updateStub,
|
||||||
|
data$: {
|
||||||
|
subscribe: () => {}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
const loaderMock = {
|
const loaderMock = {
|
||||||
embedVisualizationWithSavedObject: () => {
|
embedVisualizationWithSavedObject: () => {
|
||||||
|
|
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
import * as Rx from 'rxjs';
|
||||||
|
import { share } from 'rxjs/operators';
|
||||||
|
import { Inspector } from '../../inspector';
|
||||||
import { Adapters } from '../../inspector/types';
|
import { Adapters } from '../../inspector/types';
|
||||||
import { PersistedState } from '../../persisted_state';
|
import { PersistedState } from '../../persisted_state';
|
||||||
import { IPrivate } from '../../private';
|
import { IPrivate } from '../../private';
|
||||||
|
@ -29,7 +32,6 @@ import { RequestHandlerParams, Vis } from '../../vis';
|
||||||
import { visualizationLoader } from './visualization_loader';
|
import { visualizationLoader } from './visualization_loader';
|
||||||
import { VisualizeDataLoader } from './visualize_data_loader';
|
import { VisualizeDataLoader } from './visualize_data_loader';
|
||||||
|
|
||||||
import { Inspector } from '../../inspector';
|
|
||||||
import { DataAdapter, RequestAdapter } from '../../inspector/adapters';
|
import { DataAdapter, RequestAdapter } from '../../inspector/adapters';
|
||||||
|
|
||||||
import { VisSavedObject, VisualizeLoaderParams, VisualizeUpdateParams } from './types';
|
import { VisSavedObject, VisualizeLoaderParams, VisualizeUpdateParams } from './types';
|
||||||
|
@ -47,6 +49,14 @@ const LOADING_ATTRIBUTE = 'data-loading';
|
||||||
* with the visualization.
|
* with the visualization.
|
||||||
*/
|
*/
|
||||||
export class EmbeddedVisualizeHandler {
|
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 vis: Vis;
|
||||||
private loaded: boolean = false;
|
private loaded: boolean = false;
|
||||||
private destroyed: boolean = false;
|
private destroyed: boolean = false;
|
||||||
|
@ -69,6 +79,7 @@ export class EmbeddedVisualizeHandler {
|
||||||
private readonly appState?: AppState;
|
private readonly appState?: AppState;
|
||||||
private uiState: PersistedState;
|
private uiState: PersistedState;
|
||||||
private dataLoader: VisualizeDataLoader;
|
private dataLoader: VisualizeDataLoader;
|
||||||
|
private dataSubject: Rx.Subject<any>;
|
||||||
private inspectorAdapters: Adapters = {};
|
private inspectorAdapters: Adapters = {};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -117,6 +128,9 @@ export class EmbeddedVisualizeHandler {
|
||||||
this.vis.openInspector = this.openInspector;
|
this.vis.openInspector = this.openInspector;
|
||||||
this.vis.hasInspector = this.hasInspector;
|
this.vis.hasInspector = this.hasInspector;
|
||||||
|
|
||||||
|
this.dataSubject = new Rx.Subject();
|
||||||
|
this.data$ = this.dataSubject.asObservable().pipe(share());
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +327,10 @@ export class EmbeddedVisualizeHandler {
|
||||||
this.dataLoaderParams.forceFetch = forceFetch;
|
this.dataLoaderParams.forceFetch = forceFetch;
|
||||||
this.dataLoaderParams.inspectorAdapters = this.inspectorAdapters;
|
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) => {
|
private render = (visData: any = null) => {
|
||||||
|
|
Loading…
Reference in a new issue