Skip to content

Commit

Permalink
[TSVB] Fix panel config updates on history changes (#75896)
Browse files Browse the repository at this point in the history
* Apply history changes to panel config

* Add functional tests

* Update jest snapshot

* Add waiters for stabilizing vis chart

* Fix comments

* Remove unused method isValidKueryQuery

* Add a waiter for component render

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
sulemanof and elasticmachine authored Sep 1, 2020
1 parent d802bf0 commit b8c7945
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ export function PanelConfig(props) {
return (
<FormValidationContext.Provider value={updateControlValidity}>
<VisDataContext.Provider value={visData}>
<Component {...props} />
<div data-test-subj={`tvbPanelConfig__${model.type}`}>
<Component {...props} />
</div>
</VisDataContext.Provider>
</FormValidationContext.Provider>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ class GaugePanelConfigUi extends Component {
);
}
return (
<div>
<>
<EuiTabs size="s">
<EuiTab isSelected={selectedTab === 'data'} onClick={() => this.switchTab('data')}>
<FormattedMessage
Expand All @@ -346,7 +346,7 @@ class GaugePanelConfigUi extends Component {
</EuiTab>
</EuiTabs>
{view}
</div>
</>
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ class MarkdownPanelConfigUi extends Component {
);
}
return (
<div>
<>
<EuiTabs size="s">
<EuiTab
isSelected={selectedTab === 'markdown'}
Expand Down Expand Up @@ -325,7 +325,7 @@ class MarkdownPanelConfigUi extends Component {
</EuiTab>
</EuiTabs>
{view}
</div>
</>
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export class MetricPanelConfig extends Component {
);
}
return (
<div>
<>
<EuiTabs size="s">
<EuiTab isSelected={selectedTab === 'data'} onClick={() => this.switchTab('data')}>
<FormattedMessage
Expand All @@ -187,7 +187,7 @@ export class MetricPanelConfig extends Component {
</EuiTab>
</EuiTabs>
{view}
</div>
</>
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ export class TablePanelConfig extends Component {
);
}
return (
<div>
<>
<EuiTabs size="s">
<EuiTab isSelected={selectedTab === 'data'} onClick={() => this.switchTab('data')}>
<FormattedMessage
Expand All @@ -285,7 +285,7 @@ export class TablePanelConfig extends Component {
</EuiTab>
</EuiTabs>
{view}
</div>
</>
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
import { getDefaultQueryLanguage } from '../lib/get_default_query_language';
import { QueryBarWrapper } from '../query_bar_wrapper';

class TimeseriesPanelConfigUi extends Component {
constructor(props) {
super(props);
Expand Down Expand Up @@ -401,7 +402,7 @@ class TimeseriesPanelConfigUi extends Component {
);
}
return (
<div>
<>
<EuiTabs size="s">
<EuiTab isSelected={selectedTab === 'data'} onClick={() => this.switchTab('data')}>
<FormattedMessage
Expand Down Expand Up @@ -430,7 +431,7 @@ class TimeseriesPanelConfigUi extends Component {
</EuiTab>
</EuiTabs>
{view}
</div>
</>
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export class TopNPanelConfig extends Component {
);
}
return (
<div>
<>
<EuiTabs size="s">
<EuiTab isSelected={selectedTab === 'data'} onClick={() => this.switchTab('data')}>
<FormattedMessage
Expand All @@ -243,7 +243,7 @@ export class TopNPanelConfig extends Component {
</EuiTab>
</EuiTabs>
{view}
</div>
</>
);
}
}
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ export const SplitByTermsUI = ({
}
>
<FieldSelect
data-test-subj="groupByField"
indexPattern={indexPattern}
onChange={handleSelectChange('terms_field')}
value={model.terms_field}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { PanelConfig } from './panel_config';
import { createBrushHandler } from '../lib/create_brush_handler';
import { fetchFields } from '../lib/fetch_fields';
import { extractIndexPatterns } from '../../../../../plugins/vis_type_timeseries/common/extract_index_patterns';
import { esKuery, UI_SETTINGS } from '../../../../../plugins/data/public';
import { getSavedObjectsClient, getUISettings, getDataStart, getCoreStart } from '../../services';

import { CoreStartContextProvider } from '../contexts/query_input_bar_context';
Expand Down Expand Up @@ -86,20 +85,6 @@ export class VisEditor extends Component {
});
}, VIS_STATE_DEBOUNCE_DELAY);

isValidKueryQuery = (filterQuery) => {
if (filterQuery && filterQuery.language === 'kuery') {
try {
const queryOptions = this.coreContext.uiSettings.get(
UI_SETTINGS.QUERY_ALLOW_LEADING_WILDCARDS
);
esKuery.fromKueryExpression(filterQuery.query, { allowLeadingWildcards: queryOptions });
} catch (error) {
return false;
}
}
return true;
};

handleChange = (partialModel) => {
if (isEmpty(partialModel)) {
return;
Expand Down Expand Up @@ -134,6 +119,14 @@ export class VisEditor extends Component {
});
};

updateModel = () => {
const { params } = this.props.vis.clone();

this.setState({
model: params,
});
};

handleCommit = () => {
this.updateVisState();
this.setState({ dirty: false });
Expand Down Expand Up @@ -219,6 +212,10 @@ export class VisEditor extends Component {

componentDidMount() {
this.props.renderComplete();

if (this.props.isEditorMode && this.props.eventEmitter) {
this.props.eventEmitter.on('updateEditor', this.updateModel);
}
}

componentDidUpdate() {
Expand All @@ -227,6 +224,10 @@ export class VisEditor extends Component {

componentWillUnmount() {
this.updateVisState.cancel();

if (this.props.isEditorMode && this.props.eventEmitter) {
this.props.eventEmitter.off('updateEditor', this.updateModel);
}
}
}

Expand Down
75 changes: 75 additions & 0 deletions test/functional/apps/visualize/_tsvb_chart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import expect from '@kbn/expect';
import { FtrProviderContext } from '../../ftr_provider_context';

export default function ({ getService, getPageObjects }: FtrProviderContext) {
const browser = getService('browser');
const esArchiver = getService('esArchiver');
const log = getService('log');
const inspector = getService('inspector');
Expand Down Expand Up @@ -146,5 +147,79 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
expect(newValue).to.eql('10');
});
});

describe('browser history changes', () => {
it('should activate previous/next chart tab and panel config', async () => {
await PageObjects.visualBuilder.resetPage();

log.debug('Click metric chart');
await PageObjects.visualBuilder.clickMetric();
await PageObjects.visualBuilder.checkMetricTabIsPresent();
await PageObjects.visualBuilder.checkTabIsSelected('metric');

log.debug('Click Top N chart');
await PageObjects.visualBuilder.clickTopN();
await PageObjects.visualBuilder.checkTopNTabIsPresent();
await PageObjects.visualBuilder.checkTabIsSelected('top_n');

log.debug('Go back in browser history');
await browser.goBack();

log.debug('Check metric chart and panel config is rendered');
await PageObjects.visualBuilder.checkMetricTabIsPresent();
await PageObjects.visualBuilder.checkTabIsSelected('metric');
await PageObjects.visualBuilder.checkPanelConfigIsPresent('metric');

log.debug('Go back in browser history');
await browser.goBack();

log.debug('Check timeseries chart and panel config is rendered');
await PageObjects.visualBuilder.checkTimeSeriesChartIsPresent();
await PageObjects.visualBuilder.checkTabIsSelected('timeseries');
await PageObjects.visualBuilder.checkPanelConfigIsPresent('timeseries');

log.debug('Go forward in browser history');
await browser.goForward();

log.debug('Check metric chart and panel config is rendered');
await PageObjects.visualBuilder.checkMetricTabIsPresent();
await PageObjects.visualBuilder.checkTabIsSelected('metric');
await PageObjects.visualBuilder.checkPanelConfigIsPresent('metric');
});

it('should update panel config', async () => {
await PageObjects.visualBuilder.resetPage();

const initialLegendItems = ['Count: 156'];
const finalLegendItems = ['jpg: 106', 'css: 22', 'png: 14', 'gif: 8', 'php: 6'];

log.debug('Group metrics by terms: extension.raw');
await PageObjects.visualBuilder.setMetricsGroupByTerms('extension.raw');
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
const legendItems1 = await PageObjects.visualBuilder.getLegendItemsContent();
expect(legendItems1).to.eql(finalLegendItems);

log.debug('Go back in browser history');
await browser.goBack();
const isTermsSelected = await PageObjects.visualBuilder.checkSelectedMetricsGroupByValue(
'Terms'
);
expect(isTermsSelected).to.be(true);

log.debug('Go back in browser history');
await browser.goBack();
await PageObjects.visualBuilder.checkSelectedMetricsGroupByValue('Everything');
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
const legendItems2 = await PageObjects.visualBuilder.getLegendItemsContent();
expect(legendItems2).to.eql(initialLegendItems);

log.debug('Go forward twice in browser history');
await browser.goForward();
await browser.goForward();
await PageObjects.visChart.waitForVisualizationRenderingStabilized();
const legendItems3 = await PageObjects.visualBuilder.getLegendItemsContent();
expect(legendItems3).to.eql(finalLegendItems);
});
});
});
}
44 changes: 44 additions & 0 deletions test/functional/page_objects/visual_builder_page.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,19 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro
}
}

public async checkTabIsSelected(chartType: string) {
const chartTypeBtn = await testSubjects.find(`${chartType}TsvbTypeBtn`);
const isSelected = await chartTypeBtn.getAttribute('aria-selected');

if (isSelected !== 'true') {
throw new Error(`TSVB ${chartType} tab is not selected`);
}
}

public async checkPanelConfigIsPresent(chartType: string) {
await testSubjects.existOrFail(`tvbPanelConfig__${chartType}`);
}

public async checkVisualBuilderIsPresent() {
await this.checkTabIsLoaded('tvbVisEditor', 'Time Series');
}
Expand Down Expand Up @@ -558,9 +571,40 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro
return await find.allByCssSelector('.echLegendItem');
}

public async getLegendItemsContent(): Promise<string[]> {
const legendList = await find.byCssSelector('.echLegendList');
const $ = await legendList.parseDomContent();

return $('li')
.toArray()
.map((li) => {
const label = $(li).find('.echLegendItem__label').text();
const value = $(li).find('.echLegendItem__extra').text();

return `${label}: ${value}`;
});
}

public async getSeries(): Promise<WebElementWrapper[]> {
return await find.allByCssSelector('.tvbSeriesEditor');
}

public async setMetricsGroupByTerms(field: string) {
const groupBy = await find.byCssSelector(
'.tvbAggRow--split [data-test-subj="comboBoxInput"]'
);
await comboBox.setElement(groupBy, 'Terms', { clickWithMouse: true });
await PageObjects.common.sleep(1000);
const byField = await testSubjects.find('groupByField');
await comboBox.setElement(byField, field, { clickWithMouse: true });
}

public async checkSelectedMetricsGroupByValue(value: string) {
const groupBy = await find.byCssSelector(
'.tvbAggRow--split [data-test-subj="comboBoxInput"]'
);
return await comboBox.isOptionSelected(groupBy, value);
}
}

return new VisualBuilderPage();
Expand Down

0 comments on commit b8c7945

Please sign in to comment.