Skip to content

Commit

Permalink
Decouple datasources (elastic#370)
Browse files Browse the repository at this point in the history
* Added conditional rendering to datasource to check if datasource is a React component

* Added isReact: true prop to datasources

* Added wrapper component for conditional rendering of React vs non-React datasource components

* Removed isReact prop from all datasources

* Added templateFromReactComponent wrapper around datasource templates

* Stored reference to domNode in datasource instead of spec.

* Removed domNode static variable in datasource. Instead, ref to domNode is passed into callRenderFn.
  • Loading branch information
cqliu1 authored Apr 11, 2018
1 parent 123827f commit 4890cb9
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 26 deletions.
44 changes: 42 additions & 2 deletions public/expression_types/datasource.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import React, { createElement } from 'react';
import React from 'react';
import PropTypes from 'prop-types';
import { Registry } from '../../common/lib/registry';
import { RenderToDom } from '../components/render_to_dom';
import { ExpressionFormHandlers } from '../../common/lib/expression_form_handlers';
import { BaseForm } from './base_form';

const defaultTemplate = () => (
Expand All @@ -8,6 +11,38 @@ const defaultTemplate = () => (
</div>
);

class DatasourceWrapper extends React.PureComponent {
static propTypes = {
spec: PropTypes.object.isRequired,
datasourceProps: PropTypes.object.isRequired,
handlers: PropTypes.object.isRequired,
};

componentDidUpdate() {
this.callRenderFn();
}

componentWillUnmount() {
this.props.handlers.destroy();
}

callRenderFn = domNode => {
const { spec, datasourceProps, handlers } = this.props;
const { template } = spec;
template(domNode, datasourceProps, handlers);
};

render() {
return (
<RenderToDom
render={domNode => {
this.callRenderFn(domNode);
}}
/>
);
}
}

export class Datasource extends BaseForm {
constructor(props) {
super(props);
Expand All @@ -16,8 +51,13 @@ export class Datasource extends BaseForm {
this.image = props.image;
}

static domNode = null;

render(props = {}) {
return createElement(this.template, props);
const expressionFormHandlers = new ExpressionFormHandlers();
return (
<DatasourceWrapper spec={this} handlers={expressionFormHandlers} datasourceProps={props} />
);
}
}

Expand Down
27 changes: 14 additions & 13 deletions public/expression_types/datasources/demodata/index.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
import React from 'react';
import { templateFromReactComponent } from '../../../lib/template_from_react_component';
import header from './header.png';

const DemodataDatasource = () => (
<div>
<h3>The demodata source</h3>
<p>
This data source is connected to every Canvas element by default. Its purpose is to give you
lightweight data to use in getting to know an element. The demo data set contains 4 strings, 3
numbers and a date. Feel free to experiment and, when you're ready, click the
<i>Change Datasource</i> link below to connect to your own data.
</p>
</div>
);

export const demodata = () => ({
name: 'demodata',
displayName: 'Demo Data',
help: 'Mock data set with with usernames, prices, projects, countries and phases.',
image: header,
template() {
return (
<div>
<h3>The demodata source</h3>
<p>
This data source is connected to every Canvas element by default. Its purpose is to give
you lightweight data to use in getting to know an element. The demo data set contains 4
strings, 3 numbers and a date. Feel free to experiment and, when you're ready, click the
<i>Change Datasource</i> link below to connect to your own data.
</p>
</div>
);
},
template: templateFromReactComponent(DemodataDatasource),
});
9 changes: 5 additions & 4 deletions public/expression_types/datasources/demoprices/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FormGroup, ControlLabel, FormControl } from 'react-bootstrap';
import { get } from 'lodash';
import { templateFromReactComponent } from '../../../lib/template_from_react_component';
import header from './header.png';

const template = ({ args, updateArgs }) => {
const DemopricesDatasource = ({ args, updateArgs }) => {
const updateBucket = ({ target }) => {
updateArgs &&
updateArgs({
Expand All @@ -20,7 +21,7 @@ const template = ({ args, updateArgs }) => {
<FormControl
componentClass="select"
placeholder="select"
value={get(args, 'bucket.0')}
value={get(args, 'bucket.0.value')}
onChange={updateBucket}
>
<option value="second">Seconds</option>
Expand All @@ -33,7 +34,7 @@ const template = ({ args, updateArgs }) => {
);
};

template.propTypes = {
DemopricesDatasource.propTypes = {
args: PropTypes.object.isRequired,
updateArgs: PropTypes.func,
};
Expand All @@ -43,5 +44,5 @@ export const demoprices = () => ({
displayName: 'Demo Prices',
help: 'Product pricing data in a variety of intervals',
image: header,
template,
template: templateFromReactComponent(DemopricesDatasource),
});
7 changes: 4 additions & 3 deletions public/expression_types/datasources/esdocs/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ import { ESFieldsSelect } from '../../../components/es_fields_select';
import { ESFieldSelect } from '../../../components/es_field_select';
import { ESIndexSelect } from '../../../components/es_index_select';
import { TooltipIcon } from '../../../components/tooltip_icon';
import { templateFromReactComponent } from '../../../lib/template_from_react_component';
import header from './header.png';
import './esdocs.less';

const template = ({ args, updateArgs }) => {
const EsdocsDatasource = ({ args, updateArgs }) => {
const setArg = (name, value) => {
updateArgs &&
updateArgs({
Expand Down Expand Up @@ -120,7 +121,7 @@ const template = ({ args, updateArgs }) => {
);
};

template.propTypes = {
EsdocsDatasource.propTypes = {
args: PropTypes.object.isRequired,
updateArgs: PropTypes.func,
};
Expand All @@ -130,5 +131,5 @@ export const esdocs = () => ({
displayName: 'Elasticsearch Raw Documents',
help: 'Pull back raw documents from elasticsearch',
image: header,
template,
template: templateFromReactComponent(EsdocsDatasource),
});
9 changes: 5 additions & 4 deletions public/expression_types/datasources/timelion/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import PropTypes from 'prop-types';
import { ControlLabel, FormControl } from 'react-bootstrap';
import { getSimpleArg, setSimpleArg } from '../../../lib/arg_helpers';
import { TooltipIcon } from '../../../components/tooltip_icon';
import header from './header.png';
import './timelion.less';
import { templateFromReactComponent } from '../../../lib/template_from_react_component';
import header from './header.png';

const template = ({ args, updateArgs }) => {
const TimelionDatasource = ({ args, updateArgs }) => {
const setArg = (name, value) => {
updateArgs &&
updateArgs({
Expand Down Expand Up @@ -76,7 +77,7 @@ const template = ({ args, updateArgs }) => {
);
};

template.propTypes = {
TimelionDatasource.propTypes = {
args: PropTypes.object.isRequired,
updateArgs: PropTypes.func,
};
Expand All @@ -86,5 +87,5 @@ export const timelion = () => ({
displayName: 'Timelion',
help: 'Use timelion syntax to retrieve a timeseries',
image: header,
template,
template: templateFromReactComponent(TimelionDatasource),
});

0 comments on commit 4890cb9

Please sign in to comment.