From bedfc97554a5dd3bc0c4adbbfe53306c6f54f9ba Mon Sep 17 00:00:00 2001 From: Nathan Reese Date: Thu, 1 Jun 2017 13:46:55 -0600 Subject: [PATCH] editor components --- .../terms_vis/components/field_select.js | 62 ++++++++++ .../components/index_pattern_select.js | 46 +++++++ .../public/terms_vis/components/terms_vis.js | 36 ++++++ .../terms_vis/components/terms_vis_editor.js | 113 ++++++++++++++++++ .../public/terms_vis/editor_controller.js | 36 +++++- .../public/terms_vis/lib/editor_utils.js | 20 ++++ .../public/terms_vis/terms_vis.js | 5 +- 7 files changed, 311 insertions(+), 7 deletions(-) create mode 100644 src/core_plugins/control_visualizations/public/terms_vis/components/field_select.js create mode 100644 src/core_plugins/control_visualizations/public/terms_vis/components/index_pattern_select.js create mode 100644 src/core_plugins/control_visualizations/public/terms_vis/components/terms_vis.js create mode 100644 src/core_plugins/control_visualizations/public/terms_vis/components/terms_vis_editor.js create mode 100644 src/core_plugins/control_visualizations/public/terms_vis/lib/editor_utils.js diff --git a/src/core_plugins/control_visualizations/public/terms_vis/components/field_select.js b/src/core_plugins/control_visualizations/public/terms_vis/components/field_select.js new file mode 100644 index 000000000000000..f0a1a2ac8d744d7 --- /dev/null +++ b/src/core_plugins/control_visualizations/public/terms_vis/components/field_select.js @@ -0,0 +1,62 @@ +import React, { Component, PropTypes } from 'react'; +import Select from 'react-select'; + +export class FieldSelect extends Component { + constructor(props) { + super(props); + + this.loadFields = this.loadFields.bind(this); + } + + loadFields(input, callback) { + if (!this.props.indexPatternId || this.props.indexPatternId.length === 0) { + callback(null, { options: [] }); + return; + } + + this.props.getIndexPattern(this.props.indexPatternId).then(index => { + const fields = index.fields.filter(function (field) { + return field.aggregatable && ['number', 'boolean', 'date', 'ip', 'string'].includes(field.type); + }).sort((a, b) => { + if (a.name < b.name) return -1; + if (a.name > b.name) return 1; + return 0; + }).map(function (field) { + return { label: field.name, value: field.name }; + }); + //Setting complete=true means loadOptions will never be called again. + callback(null, { options: fields, complete: true }); + }); + } + + render() { + if (!this.props.indexPatternId || this.props.indexPatternId.trim().length === 0) { + return null; + } + + return ( +
+
+ +
+
+ +
+
+ ); + } +} + +FieldSelect.propTypes = { + getIndexPattern: PropTypes.func.isRequired, + indexPatternId: PropTypes.string, + onChange: PropTypes.func.isRequired, + value: PropTypes.string +}; diff --git a/src/core_plugins/control_visualizations/public/terms_vis/components/index_pattern_select.js b/src/core_plugins/control_visualizations/public/terms_vis/components/index_pattern_select.js new file mode 100644 index 000000000000000..3c5a02e0cad8873 --- /dev/null +++ b/src/core_plugins/control_visualizations/public/terms_vis/components/index_pattern_select.js @@ -0,0 +1,46 @@ +import React, { Component, PropTypes } from 'react'; +import Select from 'react-select'; + +export class IndexPatternSelect extends Component { + constructor(props) { + super(props); + + this.loadOptions = this.loadOptions.bind(this); + } + + loadOptions(input, callback) { + this.props.getIndexPatternIds().then(ids => { + const options = ids.map(id => { + return { label: id, value: id }; + }); + //Setting complete=true means loadOptions will never be called again. + callback(null, { options: options, complete: true }); + }); + } + + render() { + return ( +
+
+ +
+
+ +
+
+ ); + } +} + +IndexPatternSelect.propTypes = { + getIndexPatternIds: PropTypes.func.isRequired, + onChange: PropTypes.func.isRequired, + value: PropTypes.string +}; diff --git a/src/core_plugins/control_visualizations/public/terms_vis/components/terms_vis.js b/src/core_plugins/control_visualizations/public/terms_vis/components/terms_vis.js new file mode 100644 index 000000000000000..c54a2cdd012a9fe --- /dev/null +++ b/src/core_plugins/control_visualizations/public/terms_vis/components/terms_vis.js @@ -0,0 +1,36 @@ +import React, { Component } from 'react'; +import Select from 'react-select'; + +export class TermsVis extends Component { + constructor(props) { + super(props); + + this.handleOnChange = this.handleOnChange.bind(this); + } + + handleOnChange(control, evt) { + if (evt) { + this.props.setFilter(control.field, evt.value, control.indexPattern); + } else { + this.props.removeFilter(control.field, control.indexPattern); + } + } + + render() { + return ( +
+ {this.props.controls.map((control, index) => +
+ {control.label} + +
+ +
+ + + + + + ); + }); + } + + render() { + return ( +
+
+ {this.props.count} +
+ {this.renderFields()} + + } + onClick={this.handleAddField} + > + Add + +
+ ); + } +} diff --git a/src/core_plugins/control_visualizations/public/terms_vis/editor_controller.js b/src/core_plugins/control_visualizations/public/terms_vis/editor_controller.js index 3a2cf63a9693f6f..85b703c921dd44a 100644 --- a/src/core_plugins/control_visualizations/public/terms_vis/editor_controller.js +++ b/src/core_plugins/control_visualizations/public/terms_vis/editor_controller.js @@ -1,8 +1,12 @@ +import React from 'react'; +import { render, unmountComponentAtNode } from 'react-dom'; import { VisController } from './vis_controller'; +import { TermsVisEditor } from './components/terms_vis_editor'; class EditorController { - constructor(el) { + constructor(el, vis) { this.el = el; + this.vis = vis; this.editorDiv = document.createElement('div'); this.visDiv = document.createElement('div'); this.el.appendChild(this.editorDiv); @@ -10,12 +14,33 @@ class EditorController { this.visualization = new VisController(this.visDiv); } - render(vis, visData) { + render(visData) { + let count = 0; + const setVisParam = (paramName, paramValue) => { + this.vis.params[paramName] = paramValue; + //this.vis.updateState(); + count++; + console.log('count', count); + }; + const getIndexPatternIds = () => { + return this.vis.API.indexPatterns.getIds(); + }; + const getIndexPattern = (indexPatternId) => { + return this.vis.API.indexPatterns.get(indexPatternId); + }; return new Promise(resolve => { - console.log('rendering editor'); - this.editorDiv.innerHTML = 'my editor'; + render( + , + this.el + ); // we probably want to render the visualization as well ? - this.visualization.render(vis, visData).then(() => { + this.visualization.render(this.vis, visData).then(() => { resolve('when done rendering'); }); }); @@ -26,6 +51,7 @@ class EditorController { } destroy() { + unmountComponentAtNode(this.el); this.visualization.destroy(); } } diff --git a/src/core_plugins/control_visualizations/public/terms_vis/lib/editor_utils.js b/src/core_plugins/control_visualizations/public/terms_vis/lib/editor_utils.js new file mode 100644 index 000000000000000..faee186e521d1df --- /dev/null +++ b/src/core_plugins/control_visualizations/public/terms_vis/lib/editor_utils.js @@ -0,0 +1,20 @@ +export const setField = (fields, fieldIndex, field) => [ + ...fields.slice(0, fieldIndex), + field, + ...fields.slice(fieldIndex + 1) +]; + +export const addField = (fields, field) => [...fields, field]; + +export const removeField = (fields, fieldIndex) => [ + ...fields.slice(0, fieldIndex), + ...fields.slice(fieldIndex + 1) +]; + +export const newField = () => ({ + indexPattern: '', + fieldName: '', + label: '', + size: 5, + order: 'desc' +}); diff --git a/src/core_plugins/control_visualizations/public/terms_vis/terms_vis.js b/src/core_plugins/control_visualizations/public/terms_vis/terms_vis.js index b3665b66db042ab..df6e933148ea410 100644 --- a/src/core_plugins/control_visualizations/public/terms_vis/terms_vis.js +++ b/src/core_plugins/control_visualizations/public/terms_vis/terms_vis.js @@ -1,9 +1,11 @@ import './terms_vis.less'; +import 'react-select/dist/react-select.css'; import { CATEGORY } from 'ui/vis/vis_category'; import { VisFactoryProvider } from 'ui/vis/vis_factory'; import { VisTypesRegistryProvider } from 'ui/registry/vis_types'; import { VisController } from './vis_controller'; import { EditorController } from './editor_controller'; +import { newField } from './lib/editor_utils'; function TermsVisProvider(Private) { const VisFactory = Private(VisFactoryProvider); @@ -18,8 +20,7 @@ function TermsVisProvider(Private) { visualization: VisController, visConfig: { defaults: { - // add default parameters - fontSize: '50' + fields: [newField()] }, }, editor: EditorController,