Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/core_plugins/metrics/public/components/index_pattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export const IndexPattern = props => {
disabled={props.disabled}
onChange={handleTextChange(indexPatternName, '*')}
value={model[indexPatternName]}
data-test-subj="metricsIndexPatternInput"
/>
<label className="vis_editor__label" htmlFor={htmlId('timeField')}>
Time Field
Expand All @@ -67,6 +68,7 @@ export const IndexPattern = props => {
onChange={handleSelectChange(timeFieldName)}
indexPattern={model[indexPatternName]}
fields={fields}
data-test-subj="metricsIndexPatternFieldsSelect"
/>
</div>
<label className="vis_editor__label" htmlFor={htmlId('interval')}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class MetricPanelConfig extends Component {
aria-selected={selectedTab === 'options'}
className={`kbnTabs__tab${selectedTab === 'options' && '-active' || ''}`}
onClick={() => this.switchTab('options')}
data-test-subj="metricEditorPanelOptionsBtn"
>Panel Options
</button>
</div>
Expand Down
88 changes: 63 additions & 25 deletions src/core_plugins/metrics/public/components/vis_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,23 @@ import VisPicker from './vis_picker';
import PanelConfig from './panel_config';
import brushHandler from '../lib/create_brush_handler';
import { get } from 'lodash';
import { extractIndexPatterns } from '../lib/extract_index_patterns';
import { fetchFields } from '../lib/fetch_fields';
import chrome from 'ui/chrome';

class VisEditor extends Component {
constructor(props) {
super(props);
const { vis } = props;
this.appState = vis.API.getAppState();
const reversed = get(this.appState, 'options.darkTheme', false);
this.state = { model: props.vis.params, dirty: false, autoApply: true, reversed };
this.state = {
model: props.vis.params,
dirty: false,
autoApply: true,
reversed,
visFields: {},
};
this.onBrush = brushHandler(props.vis.API.timeFilter);
this.handleUiState = this.handleUiState.bind(this, props.vis);
this.handleAppStateChange = this.handleAppStateChange.bind(this);
Expand Down Expand Up @@ -60,27 +69,54 @@ class VisEditor extends Component {
}
}

render() {
const handleChange = (part) => {
const nextModel = { ...this.state.model, ...part };
fetchIndexPatternFields = async () => {
const { params } = this.props.vis;
const { visFields } = this.state;
const indexPatterns = extractIndexPatterns(params, visFields);
const fields = await fetchFields(indexPatterns);
this.setState((previousState) => {
return {
visFields: {
...previousState.visFields,
...fields,
}
};
});
}

this.props.vis.params = nextModel;
if (this.state.autoApply) {
this.props.vis.updateState();
}
setDefaultIndexPattern = async () => {
if (this.props.vis.params.index_pattern === '') {
// set the default index pattern if none is defined.
const savedObjectsClient = chrome.getSavedObjectsClient();
const indexPattern = await savedObjectsClient.get('index-pattern', this.getConfig('defaultIndex'));
const defaultIndexPattern = indexPattern.attributes.title;
this.props.vis.params.index_pattern = defaultIndexPattern;
}
}

this.setState({ model: nextModel, dirty: !this.state.autoApply });
};
handleChange = async (partialModel) => {
const nextModel = { ...this.state.model, ...partialModel };
this.props.vis.params = nextModel;
if (this.state.autoApply) {
this.props.vis.updateState();
}
this.setState({
model: nextModel,
dirty: !this.state.autoApply,
});
this.fetchIndexPatternFields();
}

const handleAutoApplyToggle = (part) => {
this.setState({ autoApply: part.target.checked });
};
handleCommit = () => {
this.props.vis.updateState();
this.setState({ dirty: false });
}

const handleCommit = () => {
this.props.vis.updateState();
this.setState({ dirty: false });
};
handleAutoApplyToggle = (event) => {
this.setState({ autoApply: event.target.checked });
}

render() {
if (!this.props.isEditorMode) {
if (!this.props.vis.params || !this.props.visData) return null;
const reversed = this.state.reversed;
Expand All @@ -91,7 +127,7 @@ class VisEditor extends Component {
onBrush={this.onBrush}
onUiState={this.handleUiState}
uiState={this.props.vis.getUiState()}
fields={this.props.vis.fields}
fields={this.state.visFields}
model={this.props.vis.params}
visData={this.props.visData}
getConfig={this.getConfig}
Expand All @@ -105,7 +141,7 @@ class VisEditor extends Component {
return (
<div className="vis_editor">
<div className="vis-editor-hide-for-reporting">
<VisPicker model={model} onChange={handleChange} />
<VisPicker model={model} onChange={this.handleChange} />
</div>
<VisEditorVisualization
dirty={this.state.dirty}
Expand All @@ -117,20 +153,20 @@ class VisEditor extends Component {
onUiState={this.handleUiState}
uiState={this.props.vis.getUiState()}
onBrush={this.onBrush}
onCommit={handleCommit}
onToggleAutoApply={handleAutoApplyToggle}
onChange={handleChange}
onCommit={this.handleCommit}
onToggleAutoApply={this.handleAutoApplyToggle}
onChange={this.handleChange}
title={this.props.vis.title}
description={this.props.vis.description}
dateFormat={this.props.config.get('dateFormat')}
/>
<div className="vis-editor-hide-for-reporting">
<PanelConfig
fields={this.props.vis.fields}
fields={this.state.visFields}
model={model}
visData={this.props.visData}
dateFormat={this.props.config.get('dateFormat')}
onChange={handleChange}
onChange={this.handleChange}
getConfig={this.getConfig}
/>
</div>
Expand All @@ -141,7 +177,9 @@ class VisEditor extends Component {
return null;
}

componentDidMount() {
async componentDidMount() {
await this.setDefaultIndexPattern();
await this.fetchIndexPatternFields();
this.props.renderComplete();
}

Expand Down
43 changes: 11 additions & 32 deletions src/core_plugins/metrics/public/kbn_vis_types/editor_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,48 +18,27 @@
*/

import React from 'react';
import chrome from 'ui/chrome';
import { render, unmountComponentAtNode } from 'react-dom';
import { FetchFieldsProvider } from '../lib/fetch_fields';
import { extractIndexPatterns } from '../lib/extract_index_patterns';

function ReactEditorControllerProvider(Private, config) {
const fetchFields = Private(FetchFieldsProvider);
const savedObjectsClient = chrome.getSavedObjectsClient();

class ReactEditorController {
constructor(el, savedObj) {
this.el = el;
this.savedObj = savedObj;
this.vis = savedObj.vis;
this.vis.fields = {};
}

render(params) {
return new Promise((resolve) => {
Promise.resolve().then(() => {
if (this.vis.params.index_pattern === '') {
return savedObjectsClient.get('index-pattern', config.get('defaultIndex')).then((indexPattern) => {
this.vis.params.index_pattern = indexPattern.attributes.title;
});
}
}).then(() => {
const indexPatterns = extractIndexPatterns(this.vis);
fetchFields(indexPatterns).then(fields => {
this.vis.fields = { ...fields, ...this.vis.fields };
const Component = this.vis.type.editorConfig.component;
render(<Component
config={config}
vis={this.vis}
savedObj={this.savedObj}
timeRange={params.timeRange}
renderComplete={resolve}
isEditorMode={true}
appState={params.appState}
/>, this.el);
});
});
});
async render(params) {
const Component = this.vis.type.editorConfig.component;
render(<Component
config={config}
vis={this.vis}
savedObj={this.savedObj}
timeRange={params.timeRange}
renderComplete={() => {}}
isEditorMode={true}
appState={params.appState}
/>, this.el);
}

resize() {
Expand Down
2 changes: 2 additions & 0 deletions src/core_plugins/metrics/public/less/error.less
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
color: #c00;
justify-content: center;
padding: 20px;
height: 100%;
width: 100%;
}

.metrics_error__title {
Expand Down
4 changes: 4 additions & 0 deletions src/core_plugins/metrics/public/less/misc.less
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.thor__visualization {
width: 100%;
height: 100%;
}
.thor__input {
padding: 7px 10px;
border-radius: 4px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,44 +20,43 @@
import { extractIndexPatterns } from '../extract_index_patterns';
import { expect } from 'chai';
describe('extractIndexPatterns(vis)', () => {
let vis;
let visParams;
let visFields;
beforeEach(() => {
vis = {
fields: {
'*': []
},
params: {
index_pattern: '*',
series: [
{
override_index_pattern: 1,
series_index_pattern: 'example-1-*'
},
{
override_index_pattern: 1,
series_index_pattern: 'example-2-*'
}
],
annotations: [
{ index_pattern: 'notes-*' },
{ index_pattern: 'example-1-*' }
]
}
visFields = {
'*': []
};
visParams = {
index_pattern: '*',
series: [
{
override_index_pattern: 1,
series_index_pattern: 'example-1-*'
},
{
override_index_pattern: 1,
series_index_pattern: 'example-2-*'
}
],
annotations: [
{ index_pattern: 'notes-*' },
{ index_pattern: 'example-1-*' }
]
};
});

it('should return index patterns', () => {
vis.fields = {};
expect(extractIndexPatterns(vis)).to.eql([
visFields = {};
expect(extractIndexPatterns(visParams, visFields)).to.eql([
'*',
'example-1-*',
'example-2-*',
'notes-*'
]);
});

it('should return index patterns that do not exist in vis.fields', () => {
expect(extractIndexPatterns(vis)).to.eql([
it('should return index patterns that do not exist in visFields', () => {
expect(extractIndexPatterns(visParams, visFields)).to.eql([
'example-1-*',
'example-2-*',
'notes-*'
Expand Down
16 changes: 8 additions & 8 deletions src/core_plugins/metrics/public/lib/extract_index_patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,24 @@
*/

import { uniq } from 'lodash';
export function extractIndexPatterns(vis) {
export function extractIndexPatterns(params, fetchedFields) {
const patternsToFetch = [];

if (!vis.fields[vis.params.index_pattern]) {
patternsToFetch.push(vis.params.index_pattern);
if (!fetchedFields[params.index_pattern]) {
patternsToFetch.push(params.index_pattern);
}

vis.params.series.forEach(series => {
params.series.forEach(series => {
const indexPattern = series.series_index_pattern;
if (series.override_index_pattern && !vis.fields[indexPattern]) {
if (series.override_index_pattern && !fetchedFields[indexPattern]) {
patternsToFetch.push(indexPattern);
}
});

if (vis.params.annotations) {
vis.params.annotations.forEach(item => {
if (params.annotations) {
params.annotations.forEach(item => {
const indexPattern = item.index_pattern;
if (indexPattern && !vis.fields[indexPattern]) {
if (indexPattern && !fetchedFields[indexPattern]) {
patternsToFetch.push(indexPattern);
}
});
Expand Down
Loading