mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Translate Input Control component (#22400)
* Translate Input Control component * Remove export from variables that get wrapped by a helper * Refactoring * Update message ids * Fix unit tests
This commit is contained in:
parent
cd5eb594a3
commit
1a2e8970b2
29 changed files with 388 additions and 142 deletions
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"paths": {
|
||||
"common.ui": "src/ui",
|
||||
"inputControl":"src/core_plugins/input_control_vis",
|
||||
"kbn": "src/core_plugins/kibana",
|
||||
"statusPage": "src/core_plugins/status_page",
|
||||
"xpack.idxMgmt": "x-pack/plugins/index_management"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
exports[`renders ControlsTab 1`] = `
|
||||
<div>
|
||||
<ControlEditor
|
||||
<InjectIntl(ControlEditorUi)
|
||||
controlIndex={0}
|
||||
controlParams={
|
||||
Object {
|
||||
|
@ -39,7 +39,7 @@ exports[`renders ControlsTab 1`] = `
|
|||
]
|
||||
}
|
||||
/>
|
||||
<ControlEditor
|
||||
<InjectIntl(ControlEditorUi)
|
||||
controlIndex={1}
|
||||
controlParams={
|
||||
Object {
|
||||
|
@ -140,7 +140,11 @@ exports[`renders ControlsTab 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Add
|
||||
<FormattedMessage
|
||||
defaultMessage="Add"
|
||||
id="inputControl.editor.controlsTab.addButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
exports[`renders dynamic options should display disabled dynamic options with tooltip for non-string fields 1`] = `
|
||||
<div>
|
||||
<IndexPatternSelect
|
||||
<InjectIntl(IndexPatternSelectUi)
|
||||
controlIndex={0}
|
||||
getIndexPattern={[Function]}
|
||||
getIndexPatterns={[Function]}
|
||||
indexPatternId="mockIndexPattern"
|
||||
onChange={[Function]}
|
||||
/>
|
||||
<FieldSelect
|
||||
<InjectIntl(FieldSelectUi)
|
||||
controlIndex={0}
|
||||
fieldName="numberField"
|
||||
filterField={[Function]}
|
||||
|
@ -72,14 +72,14 @@ exports[`renders dynamic options should display disabled dynamic options with to
|
|||
|
||||
exports[`renders dynamic options should display dynamic options for string fields 1`] = `
|
||||
<div>
|
||||
<IndexPatternSelect
|
||||
<InjectIntl(IndexPatternSelectUi)
|
||||
controlIndex={0}
|
||||
getIndexPattern={[Function]}
|
||||
getIndexPatterns={[Function]}
|
||||
indexPatternId="mockIndexPattern"
|
||||
onChange={[Function]}
|
||||
/>
|
||||
<FieldSelect
|
||||
<InjectIntl(FieldSelectUi)
|
||||
controlIndex={0}
|
||||
fieldName="keywordField"
|
||||
filterField={[Function]}
|
||||
|
@ -123,14 +123,14 @@ exports[`renders dynamic options should display dynamic options for string field
|
|||
|
||||
exports[`renders dynamic options should display size field when dynamic options is disabled 1`] = `
|
||||
<div>
|
||||
<IndexPatternSelect
|
||||
<InjectIntl(IndexPatternSelectUi)
|
||||
controlIndex={0}
|
||||
getIndexPattern={[Function]}
|
||||
getIndexPatterns={[Function]}
|
||||
indexPatternId="mockIndexPattern"
|
||||
onChange={[Function]}
|
||||
/>
|
||||
<FieldSelect
|
||||
<InjectIntl(FieldSelectUi)
|
||||
controlIndex={0}
|
||||
fieldName="keywordField"
|
||||
filterField={[Function]}
|
||||
|
@ -193,14 +193,14 @@ exports[`renders dynamic options should display size field when dynamic options
|
|||
|
||||
exports[`renders should display chaining input when parents are provided 1`] = `
|
||||
<div>
|
||||
<IndexPatternSelect
|
||||
<InjectIntl(IndexPatternSelectUi)
|
||||
controlIndex={0}
|
||||
getIndexPattern={[Function]}
|
||||
getIndexPatterns={[Function]}
|
||||
indexPatternId="indexPattern1"
|
||||
onChange={[Function]}
|
||||
/>
|
||||
<FieldSelect
|
||||
<InjectIntl(FieldSelectUi)
|
||||
controlIndex={0}
|
||||
fieldName="keywordField"
|
||||
filterField={[Function]}
|
||||
|
@ -296,14 +296,14 @@ exports[`renders should display chaining input when parents are provided 1`] = `
|
|||
|
||||
exports[`renders should not display any options until field is selected 1`] = `
|
||||
<div>
|
||||
<IndexPatternSelect
|
||||
<InjectIntl(IndexPatternSelectUi)
|
||||
controlIndex={0}
|
||||
getIndexPattern={[Function]}
|
||||
getIndexPatterns={[Function]}
|
||||
indexPatternId="mockIndexPattern"
|
||||
onChange={[Function]}
|
||||
/>
|
||||
<FieldSelect
|
||||
<InjectIntl(FieldSelectUi)
|
||||
controlIndex={0}
|
||||
fieldName=""
|
||||
filterField={[Function]}
|
||||
|
|
|
@ -11,7 +11,13 @@ exports[`renders OptionsTab 1`] = `
|
|||
<EuiSwitch
|
||||
checked={false}
|
||||
data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"
|
||||
label="Update Kibana filters on each change"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Update Kibana filters on each change"
|
||||
id="inputControl.editor.optionsTab.updateFilterLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
@ -24,7 +30,13 @@ exports[`renders OptionsTab 1`] = `
|
|||
<EuiSwitch
|
||||
checked={false}
|
||||
data-test-subj="inputControlEditorUseTimeFilterCheckbox"
|
||||
label="Use time filter"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Use time filter"
|
||||
id="inputControl.editor.optionsTab.useTimeFielterLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
@ -36,7 +48,13 @@ exports[`renders OptionsTab 1`] = `
|
|||
>
|
||||
<EuiSwitch
|
||||
data-test-subj="inputControlEditorPinFiltersCheckbox"
|
||||
label="Pin filters to global state"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Pin filters to global state"
|
||||
id="inputControl.editor.optionsTab.pinFieltersLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
onChange={[Function]}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
exports[`renders RangeControlEditor 1`] = `
|
||||
<div>
|
||||
<IndexPatternSelect
|
||||
<InjectIntl(IndexPatternSelectUi)
|
||||
controlIndex={0}
|
||||
getIndexPattern={[Function]}
|
||||
getIndexPatterns={[Function]}
|
||||
indexPatternId="indexPattern1"
|
||||
onChange={[Function]}
|
||||
/>
|
||||
<FieldSelect
|
||||
<InjectIntl(FieldSelectUi)
|
||||
controlIndex={0}
|
||||
fieldName="numberField"
|
||||
filterField={[Function]}
|
||||
|
@ -22,7 +22,13 @@ exports[`renders RangeControlEditor 1`] = `
|
|||
fullWidth={false}
|
||||
hasEmptyLabelSpace={false}
|
||||
id="stepSize-0"
|
||||
label="Step Size"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Step Size"
|
||||
id="inputControl.editor.rangeControl.stepSizeLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
compressed={false}
|
||||
|
@ -38,7 +44,13 @@ exports[`renders RangeControlEditor 1`] = `
|
|||
fullWidth={false}
|
||||
hasEmptyLabelSpace={false}
|
||||
id="decimalPlaces-0"
|
||||
label="Decimal Places"
|
||||
label={
|
||||
<FormattedMessage
|
||||
defaultMessage="Decimal Places"
|
||||
id="inputControl.editor.rangeControl.decimalPlacesLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
compressed={false}
|
||||
|
|
|
@ -23,6 +23,7 @@ import React, { Component } from 'react';
|
|||
import { RangeControlEditor } from './range_control_editor';
|
||||
import { ListControlEditor } from './list_control_editor';
|
||||
import { getTitle } from '../../editor_utils';
|
||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiAccordion,
|
||||
|
@ -34,7 +35,7 @@ import {
|
|||
EuiSpacer,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export class ControlEditor extends Component {
|
||||
class ControlEditorUi extends Component {
|
||||
|
||||
changeLabel = (evt) => {
|
||||
this.props.handleLabelChange(this.props.controlIndex, evt);
|
||||
|
@ -101,7 +102,7 @@ export class ControlEditor extends Component {
|
|||
<EuiForm>
|
||||
<EuiFormRow
|
||||
id={labelId}
|
||||
label="Control Label"
|
||||
label={<FormattedMessage id="inputControl.editor.controlEditor.controlLabel" defaultMessage="Control Label"/>}
|
||||
>
|
||||
<EuiFieldText
|
||||
value={this.props.controlParams.label}
|
||||
|
@ -118,21 +119,30 @@ export class ControlEditor extends Component {
|
|||
return (
|
||||
<div>
|
||||
<EuiButtonIcon
|
||||
aria-label="Move control up"
|
||||
aria-label={this.props.intl.formatMessage({
|
||||
id: 'inputControl.editor.controlEditor.moveControlUpAriaLabel',
|
||||
defaultMessage: 'Move control up'
|
||||
})}
|
||||
color="primary"
|
||||
onClick={this.moveUpControl}
|
||||
iconType="sortUp"
|
||||
data-test-subj={`inputControlEditorMoveUpControl${this.props.controlIndex}`}
|
||||
/>
|
||||
<EuiButtonIcon
|
||||
aria-label="Move control down"
|
||||
aria-label={this.props.intl.formatMessage({
|
||||
id: 'inputControl.editor.controlEditor.moveControlDownAriaLabel',
|
||||
defaultMessage: 'Move control down'
|
||||
})}
|
||||
color="primary"
|
||||
onClick={this.moveDownControl}
|
||||
iconType="sortDown"
|
||||
data-test-subj={`inputControlEditorMoveDownControl${this.props.controlIndex}`}
|
||||
/>
|
||||
<EuiButtonIcon
|
||||
aria-label="Remove control"
|
||||
aria-label={this.props.intl.formatMessage({
|
||||
id: 'inputControl.editor.controlEditor.removeControlAriaLabel',
|
||||
defaultMessage: 'Remove control'
|
||||
})}
|
||||
color="danger"
|
||||
onClick={this.removeControl}
|
||||
iconType="cross"
|
||||
|
@ -161,7 +171,7 @@ export class ControlEditor extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
ControlEditor.propTypes = {
|
||||
ControlEditorUi.propTypes = {
|
||||
controlIndex: PropTypes.number.isRequired,
|
||||
controlParams: PropTypes.object.isRequired,
|
||||
handleLabelChange: PropTypes.func.isRequired,
|
||||
|
@ -179,3 +189,5 @@ ControlEditor.propTypes = {
|
|||
})).isRequired,
|
||||
handleParentChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export const ControlEditor = injectI18n(ControlEditorUi);
|
||||
|
|
|
@ -23,6 +23,7 @@ import React, { Component } from 'react';
|
|||
import { ControlEditor } from './control_editor';
|
||||
import { addControl, moveControl, newControl, removeControl, setControl } from '../../editor_utils';
|
||||
import { getLineageMap, getParentCandidates } from '../../lineage';
|
||||
import { injectI18n, FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
|
@ -33,7 +34,7 @@ import {
|
|||
EuiSelect,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export class ControlsTab extends Component {
|
||||
class ControlsTabUi extends Component {
|
||||
|
||||
state = {
|
||||
type: 'list'
|
||||
|
@ -138,6 +139,8 @@ export class ControlsTab extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
|
||||
|
@ -151,12 +154,21 @@ export class ControlsTab extends Component {
|
|||
>
|
||||
<EuiSelect
|
||||
options={[
|
||||
{ value: 'range', text: 'Range slider' },
|
||||
{ value: 'list', text: 'Options list' },
|
||||
{ value: 'range', text: intl.formatMessage({
|
||||
id: 'inputControl.editor.controlsTab.select.rangeDropDownOptionLabel',
|
||||
defaultMessage: 'Range slider' })
|
||||
},
|
||||
{ value: 'list', text: intl.formatMessage({
|
||||
id: 'inputControl.editor.controlsTab.select.listDropDownOptionLabel',
|
||||
defaultMessage: 'Options list' })
|
||||
},
|
||||
]}
|
||||
value={this.state.type}
|
||||
onChange={evt => this.setState({ type: evt.target.value })}
|
||||
aria-label="Select control type"
|
||||
aria-label={intl.formatMessage({
|
||||
id: 'inputControl.editor.controlsTab.select.controlTypeAriaLabel',
|
||||
defaultMessage: 'Select control type'
|
||||
})}
|
||||
/>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -169,9 +181,12 @@ export class ControlsTab extends Component {
|
|||
onClick={this.handleAddControl}
|
||||
iconType="plusInCircle"
|
||||
data-test-subj="inputControlEditorAddBtn"
|
||||
aria-label="Add control"
|
||||
aria-label={intl.formatMessage({
|
||||
id: 'inputControl.editor.controlsTab.select.addControlAriaLabel',
|
||||
defaultMessage: 'Add control'
|
||||
})}
|
||||
>
|
||||
Add
|
||||
<FormattedMessage id="inputControl.editor.controlsTab.addButtonLabel" defaultMessage="Add"/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -183,7 +198,9 @@ export class ControlsTab extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
ControlsTab.propTypes = {
|
||||
ControlsTabUi.propTypes = {
|
||||
scope: PropTypes.object.isRequired,
|
||||
stageEditorParams: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export const ControlsTab = injectI18n(ControlsTabUi);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { getIndexPatternMock } from './__tests__/get_index_pattern_mock';
|
||||
import {
|
||||
|
@ -87,7 +87,7 @@ beforeEach(() => {
|
|||
});
|
||||
|
||||
test('renders ControlsTab', () => {
|
||||
const component = shallow(<ControlsTab
|
||||
const component = shallowWithIntl(<ControlsTab.WrappedComponent
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
@ -98,7 +98,7 @@ test('renders ControlsTab', () => {
|
|||
describe('behavior', () => {
|
||||
|
||||
test('add control button', () => {
|
||||
const component = mount(<ControlsTab
|
||||
const component = mountWithIntl(<ControlsTab.WrappedComponent
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
@ -114,7 +114,7 @@ describe('behavior', () => {
|
|||
});
|
||||
|
||||
test('remove control button', () => {
|
||||
const component = mount(<ControlsTab
|
||||
const component = mountWithIntl(<ControlsTab.WrappedComponent
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
@ -139,7 +139,7 @@ describe('behavior', () => {
|
|||
|
||||
|
||||
test('move down control button', () => {
|
||||
const component = mount(<ControlsTab
|
||||
const component = mountWithIntl(<ControlsTab.WrappedComponent
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
@ -176,7 +176,7 @@ describe('behavior', () => {
|
|||
});
|
||||
|
||||
test('move up control button', () => {
|
||||
const component = mount(<ControlsTab
|
||||
const component = mountWithIntl(<ControlsTab.WrappedComponent
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
|
|
@ -20,13 +20,14 @@
|
|||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiFormRow,
|
||||
EuiComboBox,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export class FieldSelect extends Component {
|
||||
class FieldSelectUi extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -132,6 +133,7 @@ export class FieldSelect extends Component {
|
|||
const selectId = `fieldSelect-${this.props.controlIndex}`;
|
||||
|
||||
const selectedOptions = [];
|
||||
const { intl } = this.props;
|
||||
if (this.props.fieldName) {
|
||||
selectedOptions.push({ value: this.props.fieldName, label: this.props.fieldName });
|
||||
}
|
||||
|
@ -139,10 +141,16 @@ export class FieldSelect extends Component {
|
|||
return (
|
||||
<EuiFormRow
|
||||
id={selectId}
|
||||
label="Field"
|
||||
label={intl.formatMessage({
|
||||
id: 'inputControl.editor.fieldSelect.fieldLabel',
|
||||
defaultMessage: 'Field'
|
||||
})}
|
||||
>
|
||||
<EuiComboBox
|
||||
placeholder="Select field..."
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'inputControl.editor.fieldSelect.selectFieldPlaceholder',
|
||||
defaultMessage: 'Select field...'
|
||||
})}
|
||||
singleSelection={true}
|
||||
isLoading={this.state.isLoading}
|
||||
options={this.state.fields}
|
||||
|
@ -155,7 +163,7 @@ export class FieldSelect extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
FieldSelect.propTypes = {
|
||||
FieldSelectUi.propTypes = {
|
||||
getIndexPattern: PropTypes.func.isRequired,
|
||||
indexPatternId: PropTypes.string,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
|
@ -163,3 +171,5 @@ FieldSelect.propTypes = {
|
|||
filterField: PropTypes.func,
|
||||
controlIndex: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export const FieldSelect = injectI18n(FieldSelectUi);
|
||||
|
|
|
@ -20,13 +20,14 @@
|
|||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiFormRow,
|
||||
EuiComboBox,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export class IndexPatternSelect extends Component {
|
||||
class IndexPatternSelectUi extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -122,16 +123,24 @@ export class IndexPatternSelect extends Component {
|
|||
render() {
|
||||
const selectId = `indexPatternSelect-${this.props.controlIndex}`;
|
||||
const selectedOptions = [];
|
||||
const { intl } = this.props;
|
||||
if (this.state.selectedIndexPattern) {
|
||||
selectedOptions.push(this.state.selectedIndexPattern);
|
||||
}
|
||||
|
||||
return (
|
||||
<EuiFormRow
|
||||
id={selectId}
|
||||
label="Index Pattern"
|
||||
label={intl.formatMessage({
|
||||
id: 'inputControl.editor.indexPatternSelect.patternLabel',
|
||||
defaultMessage: 'Index Pattern'
|
||||
})}
|
||||
>
|
||||
<EuiComboBox
|
||||
placeholder="Select index pattern..."
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'inputControl.editor.indexPatternSelect.patternPlaceholder',
|
||||
defaultMessage: 'Select index pattern...'
|
||||
})}
|
||||
singleSelection={true}
|
||||
isLoading={this.state.isLoading}
|
||||
onSearchChange={this.fetchOptions}
|
||||
|
@ -145,10 +154,12 @@ export class IndexPatternSelect extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
IndexPatternSelect.propTypes = {
|
||||
IndexPatternSelectUi.propTypes = {
|
||||
getIndexPatterns: PropTypes.func.isRequired,
|
||||
getIndexPattern: PropTypes.func.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
indexPatternId: PropTypes.string,
|
||||
controlIndex: PropTypes.number.isRequired,
|
||||
};
|
||||
|
||||
export const IndexPatternSelect = injectI18n(IndexPatternSelectUi);
|
||||
|
|
|
@ -21,6 +21,7 @@ import PropTypes from 'prop-types';
|
|||
import React, { Component } from 'react';
|
||||
import { IndexPatternSelect } from './index_pattern_select';
|
||||
import { FieldSelect } from './field_select';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiFormRow,
|
||||
|
@ -33,7 +34,7 @@ function filterField(field) {
|
|||
return field.aggregatable && ['number', 'boolean', 'date', 'ip', 'string'].includes(field.type);
|
||||
}
|
||||
|
||||
export class ListControlEditor extends Component {
|
||||
class ListControlEditorUi extends Component {
|
||||
state = {
|
||||
isLoadingFieldType: true,
|
||||
isStringField: false,
|
||||
|
@ -102,6 +103,7 @@ export class ListControlEditor extends Component {
|
|||
}
|
||||
|
||||
const options = [];
|
||||
const { intl } = this.props;
|
||||
if (this.props.parentCandidates && this.props.parentCandidates.length > 0) {
|
||||
const parentCandidatesOptions = [
|
||||
{ value: '', text: '' },
|
||||
|
@ -110,8 +112,14 @@ export class ListControlEditor extends Component {
|
|||
options.push(
|
||||
<EuiFormRow
|
||||
id={`parentSelect-${this.props.controlIndex}`}
|
||||
label="Parent control"
|
||||
helpText="Options are based on the value of parent control. Disabled if parent is not set."
|
||||
label={intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.parentLabel',
|
||||
defaultMessage: 'Parent control'
|
||||
})}
|
||||
helpText={intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.parentDescription',
|
||||
defaultMessage: 'Options are based on the value of parent control. Disabled if parent is not set.'
|
||||
})}
|
||||
key="parentSelect"
|
||||
>
|
||||
<EuiSelect
|
||||
|
@ -129,10 +137,16 @@ export class ListControlEditor extends Component {
|
|||
<EuiFormRow
|
||||
id={`multiselect-${this.props.controlIndex}`}
|
||||
key="multiselect"
|
||||
helpText="Allow multiple selection"
|
||||
helpText={intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.multiselectDescription',
|
||||
defaultMessage: 'Allow multiple selection'
|
||||
})}
|
||||
>
|
||||
<EuiSwitch
|
||||
label="Multiselect"
|
||||
label={intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.multiselectLabel',
|
||||
defaultMessage: 'Multiselect'
|
||||
})}
|
||||
checked={this.props.controlParams.options.multiselect}
|
||||
onChange={(evt) => {
|
||||
this.props.handleCheckboxOptionChange(this.props.controlIndex, 'multiselect', evt);
|
||||
|
@ -143,8 +157,14 @@ export class ListControlEditor extends Component {
|
|||
);
|
||||
|
||||
const dynamicOptionsHelpText = this.state.isStringField
|
||||
? 'Update options in response to user input'
|
||||
: 'Only available for "string" fields';
|
||||
? intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.dynamicOptions.updateDescription',
|
||||
defaultMessage: 'Update options in response to user input'
|
||||
})
|
||||
: intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.dynamicOptions.stringFieldDescription',
|
||||
defaultMessage: 'Only available for "string" fields'
|
||||
});
|
||||
options.push(
|
||||
<EuiFormRow
|
||||
id={`dynamicOptions-${this.props.controlIndex}`}
|
||||
|
@ -152,7 +172,10 @@ export class ListControlEditor extends Component {
|
|||
helpText={dynamicOptionsHelpText}
|
||||
>
|
||||
<EuiSwitch
|
||||
label="Dynamic Options"
|
||||
label={intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.dynamicOptionsLabel',
|
||||
defaultMessage: 'Dynamic Options'
|
||||
})}
|
||||
checked={this.props.controlParams.options.dynamicOptions}
|
||||
onChange={(evt) => {
|
||||
this.props.handleCheckboxOptionChange(this.props.controlIndex, 'dynamicOptions', evt);
|
||||
|
@ -168,9 +191,15 @@ export class ListControlEditor extends Component {
|
|||
options.push(
|
||||
<EuiFormRow
|
||||
id={`size-${this.props.controlIndex}`}
|
||||
label="Size"
|
||||
label={intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.sizeLabel',
|
||||
defaultMessage: 'Size'
|
||||
})}
|
||||
key="size"
|
||||
helpText="Number of options"
|
||||
helpText={intl.formatMessage({
|
||||
id: 'inputControl.editor.listControl.sizeDescription',
|
||||
defaultMessage: 'Number of options'
|
||||
})}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
min={1}
|
||||
|
@ -215,7 +244,7 @@ export class ListControlEditor extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
ListControlEditor.propTypes = {
|
||||
ListControlEditorUi.propTypes = {
|
||||
getIndexPatterns: PropTypes.func.isRequired,
|
||||
getIndexPattern: PropTypes.func.isRequired,
|
||||
controlIndex: PropTypes.number.isRequired,
|
||||
|
@ -230,3 +259,5 @@ ListControlEditor.propTypes = {
|
|||
})).isRequired,
|
||||
handleParentChange: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export const ListControlEditor = injectI18n(ListControlEditorUi);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { getIndexPatternMock } from './__tests__/get_index_pattern_mock';
|
||||
import { getIndexPatternsMock } from './__tests__/get_index_patterns_mock';
|
||||
|
@ -67,7 +67,7 @@ describe('renders', () => {
|
|||
size: 5,
|
||||
}
|
||||
};
|
||||
const component = shallow(<ListControlEditor
|
||||
const component = shallowWithIntl(<ListControlEditor.WrappedComponent
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
@ -93,7 +93,7 @@ describe('renders', () => {
|
|||
{ value: '1', text: 'fieldA' },
|
||||
{ value: '2', text: 'fieldB' }
|
||||
];
|
||||
const component = shallow(<ListControlEditor
|
||||
const component = shallowWithIntl(<ListControlEditor.WrappedComponent
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
@ -128,7 +128,7 @@ describe('renders', () => {
|
|||
size: 5,
|
||||
}
|
||||
};
|
||||
const component = shallow(<ListControlEditor
|
||||
const component = shallowWithIntl(<ListControlEditor.WrappedComponent
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
@ -162,7 +162,7 @@ describe('renders', () => {
|
|||
size: 5,
|
||||
}
|
||||
};
|
||||
const component = shallow(<ListControlEditor
|
||||
const component = shallowWithIntl(<ListControlEditor.WrappedComponent
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
@ -196,7 +196,7 @@ describe('renders', () => {
|
|||
size: 5,
|
||||
}
|
||||
};
|
||||
const component = shallow(<ListControlEditor
|
||||
const component = shallowWithIntl(<ListControlEditor.WrappedComponent
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
@ -220,7 +220,7 @@ describe('renders', () => {
|
|||
});
|
||||
|
||||
test('handleCheckboxOptionChange - multiselect', async () => {
|
||||
const component = mount(<ListControlEditor
|
||||
const component = mountWithIntl(<ListControlEditor.WrappedComponent
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
@ -258,7 +258,7 @@ test('handleCheckboxOptionChange - multiselect', async () => {
|
|||
});
|
||||
|
||||
test('handleNumberOptionChange - size', async () => {
|
||||
const component = mount(<ListControlEditor
|
||||
const component = mountWithIntl(<ListControlEditor.WrappedComponent
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
|
|
@ -27,6 +27,8 @@ import {
|
|||
EuiSwitch,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export class OptionsTab extends Component {
|
||||
|
||||
setVisParam = (paramName, paramValue) => {
|
||||
|
@ -54,7 +56,10 @@ export class OptionsTab extends Component {
|
|||
id="updateFiltersOnChange"
|
||||
>
|
||||
<EuiSwitch
|
||||
label="Update Kibana filters on each change"
|
||||
label={<FormattedMessage
|
||||
id="inputControl.editor.optionsTab.updateFilterLabel"
|
||||
defaultMessage="Update Kibana filters on each change"
|
||||
/>}
|
||||
checked={this.props.editorState.params.updateFiltersOnChange}
|
||||
onChange={this.handleUpdateFiltersChange}
|
||||
data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"
|
||||
|
@ -65,7 +70,10 @@ export class OptionsTab extends Component {
|
|||
id="useTimeFilter"
|
||||
>
|
||||
<EuiSwitch
|
||||
label="Use time filter"
|
||||
label={<FormattedMessage
|
||||
id="inputControl.editor.optionsTab.useTimeFielterLabel"
|
||||
defaultMessage="Use time filter"
|
||||
/>}
|
||||
checked={this.props.editorState.params.useTimeFilter}
|
||||
onChange={this.handleUseTimeFilter}
|
||||
data-test-subj="inputControlEditorUseTimeFilterCheckbox"
|
||||
|
@ -76,7 +84,10 @@ export class OptionsTab extends Component {
|
|||
id="pinFilters"
|
||||
>
|
||||
<EuiSwitch
|
||||
label="Pin filters to global state"
|
||||
label={<FormattedMessage
|
||||
id="inputControl.editor.optionsTab.pinFieltersLabel"
|
||||
defaultMessage="Pin filters to global state"
|
||||
/>}
|
||||
checked={this.props.editorState.params.pinFilters}
|
||||
onChange={this.handlePinFilters}
|
||||
data-test-subj="inputControlEditorPinFiltersCheckbox"
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
import {
|
||||
OptionsTab,
|
||||
|
@ -49,7 +50,7 @@ test('renders OptionsTab', () => {
|
|||
});
|
||||
|
||||
test('updateFiltersOnChange', () => {
|
||||
const component = mount(<OptionsTab
|
||||
const component = mountWithIntl(<OptionsTab
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
@ -64,7 +65,7 @@ test('updateFiltersOnChange', () => {
|
|||
});
|
||||
|
||||
test('useTimeFilter', () => {
|
||||
const component = mount(<OptionsTab
|
||||
const component = mountWithIntl(<OptionsTab
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
@ -79,7 +80,7 @@ test('useTimeFilter', () => {
|
|||
});
|
||||
|
||||
test('pinFilters', () => {
|
||||
const component = mount(<OptionsTab
|
||||
const component = mountWithIntl(<OptionsTab
|
||||
scope={scopeMock}
|
||||
editorState={scopeMock.editorState}
|
||||
stageEditorParams={stageEditorParams}
|
||||
|
|
|
@ -27,6 +27,8 @@ import {
|
|||
EuiFieldNumber,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
function filterField(field) {
|
||||
return field.type === 'number';
|
||||
}
|
||||
|
@ -62,7 +64,10 @@ export function RangeControlEditor(props) {
|
|||
|
||||
<EuiFormRow
|
||||
id={stepSizeId}
|
||||
label="Step Size"
|
||||
label={<FormattedMessage
|
||||
id="inputControl.editor.rangeControl.stepSizeLabel"
|
||||
defaultMessage="Step Size"
|
||||
/>}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
value={props.controlParams.options.step}
|
||||
|
@ -73,7 +78,10 @@ export function RangeControlEditor(props) {
|
|||
|
||||
<EuiFormRow
|
||||
id={decimalPlacesId}
|
||||
label="Decimal Places"
|
||||
label={<FormattedMessage
|
||||
id="inputControl.editor.rangeControl.decimalPlacesLabel"
|
||||
defaultMessage="Decimal Places"
|
||||
/>}
|
||||
>
|
||||
<EuiFieldNumber
|
||||
min={0}
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { getIndexPatternMock } from './__tests__/get_index_pattern_mock';
|
||||
import { getIndexPatternsMock } from './__tests__/get_index_patterns_mock';
|
||||
|
@ -63,7 +64,7 @@ test('renders RangeControlEditor', () => {
|
|||
});
|
||||
|
||||
test('handleNumberOptionChange - step', () => {
|
||||
const component = mount(<RangeControlEditor
|
||||
const component = mountWithIntl(<RangeControlEditor
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
@ -90,7 +91,7 @@ test('handleNumberOptionChange - step', () => {
|
|||
});
|
||||
|
||||
test('handleNumberOptionChange - decimalPlaces', () => {
|
||||
const component = mount(<RangeControlEditor
|
||||
const component = mountWithIntl(<RangeControlEditor
|
||||
getIndexPatterns={getIndexPatternsMock}
|
||||
getIndexPattern={getIndexPatternMock}
|
||||
controlIndex={0}
|
||||
|
|
|
@ -24,7 +24,7 @@ exports[`Apply and Cancel change btns enabled when there are changes 1`] = `
|
|||
}
|
||||
}
|
||||
>
|
||||
<ListControl
|
||||
<InjectIntl(ListControlUi)
|
||||
controlIndex={0}
|
||||
disableMsg={null}
|
||||
fetchOptions={[Function]}
|
||||
|
@ -75,7 +75,11 @@ exports[`Apply and Cancel change btns enabled when there are changes 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Clear form
|
||||
<FormattedMessage
|
||||
defaultMessage="Clear form"
|
||||
id="inputControl.vis.inputControlVis.clearFormButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -97,7 +101,11 @@ exports[`Apply and Cancel change btns enabled when there are changes 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Cancel changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel changes"
|
||||
id="inputControl.vis.inputControlVis.cancelChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -119,7 +127,11 @@ exports[`Apply and Cancel change btns enabled when there are changes 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Apply changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Apply changes"
|
||||
id="inputControl.vis.inputControlVis.applyChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -151,7 +163,7 @@ exports[`Clear btns enabled when there are values 1`] = `
|
|||
}
|
||||
}
|
||||
>
|
||||
<ListControl
|
||||
<InjectIntl(ListControlUi)
|
||||
controlIndex={0}
|
||||
disableMsg={null}
|
||||
fetchOptions={[Function]}
|
||||
|
@ -202,7 +214,11 @@ exports[`Clear btns enabled when there are values 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Clear form
|
||||
<FormattedMessage
|
||||
defaultMessage="Clear form"
|
||||
id="inputControl.vis.inputControlVis.clearFormButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -224,7 +240,11 @@ exports[`Clear btns enabled when there are values 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Cancel changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel changes"
|
||||
id="inputControl.vis.inputControlVis.cancelChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -246,7 +266,11 @@ exports[`Clear btns enabled when there are values 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Apply changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Apply changes"
|
||||
id="inputControl.vis.inputControlVis.applyChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -278,7 +302,7 @@ exports[`Renders list control 1`] = `
|
|||
}
|
||||
}
|
||||
>
|
||||
<ListControl
|
||||
<InjectIntl(ListControlUi)
|
||||
controlIndex={0}
|
||||
disableMsg={null}
|
||||
fetchOptions={[Function]}
|
||||
|
@ -329,7 +353,11 @@ exports[`Renders list control 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Clear form
|
||||
<FormattedMessage
|
||||
defaultMessage="Clear form"
|
||||
id="inputControl.vis.inputControlVis.clearFormButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -351,7 +379,11 @@ exports[`Renders list control 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Cancel changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel changes"
|
||||
id="inputControl.vis.inputControlVis.cancelChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -373,7 +405,11 @@ exports[`Renders list control 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Apply changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Apply changes"
|
||||
id="inputControl.vis.inputControlVis.applyChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -405,7 +441,7 @@ exports[`Renders range control 1`] = `
|
|||
}
|
||||
}
|
||||
>
|
||||
<RangeControl
|
||||
<InjectIntl(RangeControlUi)
|
||||
control={
|
||||
Object {
|
||||
"id": "mock-range-control",
|
||||
|
@ -456,7 +492,11 @@ exports[`Renders range control 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Clear form
|
||||
<FormattedMessage
|
||||
defaultMessage="Clear form"
|
||||
id="inputControl.vis.inputControlVis.clearFormButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -478,7 +518,11 @@ exports[`Renders range control 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Cancel changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Cancel changes"
|
||||
id="inputControl.vis.inputControlVis.cancelChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -500,7 +544,11 @@ exports[`Renders range control 1`] = `
|
|||
onClick={[Function]}
|
||||
type="button"
|
||||
>
|
||||
Apply changes
|
||||
<FormattedMessage
|
||||
defaultMessage="Apply changes"
|
||||
id="inputControl.vis.inputControlVis.applyChangesButtonLabel"
|
||||
values={Object {}}
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -28,6 +28,8 @@ import {
|
|||
EuiFormRow,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
|
||||
export class InputControlVis extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
@ -104,7 +106,7 @@ export class InputControlVis extends Component {
|
|||
disabled={!this.props.hasValues()}
|
||||
data-test-subj="inputControlClearBtn"
|
||||
>
|
||||
Clear form
|
||||
<FormattedMessage id="inputControl.vis.inputControlVis.clearFormButtonLabel" defaultMessage="Clear form"/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -115,7 +117,7 @@ export class InputControlVis extends Component {
|
|||
disabled={!this.props.hasChanges()}
|
||||
data-test-subj="inputControlCancelBtn"
|
||||
>
|
||||
Cancel changes
|
||||
<FormattedMessage id="inputControl.vis.inputControlVis.cancelChangesButtonLabel" defaultMessage="Cancel changes"/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
@ -127,7 +129,7 @@ export class InputControlVis extends Component {
|
|||
disabled={!this.props.hasChanges()}
|
||||
data-test-subj="inputControlSubmitBtn"
|
||||
>
|
||||
Apply changes
|
||||
<FormattedMessage id="inputControl.vis.inputControlVis.applyChangesButtonLabel" defaultMessage="Apply changes"/>
|
||||
</EuiButton>
|
||||
</EuiFormRow>
|
||||
</EuiFlexItem>
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { shallow } from 'enzyme';
|
||||
import { mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
|
||||
import {
|
||||
|
@ -129,7 +130,7 @@ test('Clear btns enabled when there are values', () => {
|
|||
});
|
||||
|
||||
test('clearControls', () => {
|
||||
const component = mount(<InputControlVis
|
||||
const component = mountWithIntl(<InputControlVis
|
||||
stageFilter={stageFilter}
|
||||
submitFilters={submitFilters}
|
||||
resetControls={resetControls}
|
||||
|
@ -148,7 +149,7 @@ test('clearControls', () => {
|
|||
});
|
||||
|
||||
test('submitFilters', () => {
|
||||
const component = mount(<InputControlVis
|
||||
const component = mountWithIntl(<InputControlVis
|
||||
stageFilter={stageFilter}
|
||||
submitFilters={submitFilters}
|
||||
resetControls={resetControls}
|
||||
|
@ -167,7 +168,7 @@ test('submitFilters', () => {
|
|||
});
|
||||
|
||||
test('resetControls', () => {
|
||||
const component = mount(<InputControlVis
|
||||
const component = mountWithIntl(<InputControlVis
|
||||
stageFilter={stageFilter}
|
||||
submitFilters={submitFilters}
|
||||
resetControls={resetControls}
|
||||
|
|
|
@ -21,13 +21,14 @@ import PropTypes from 'prop-types';
|
|||
import React, { Component } from 'react';
|
||||
import _ from 'lodash';
|
||||
import { FormRow } from './form_row';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiFieldText,
|
||||
EuiComboBox,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export class ListControl extends Component {
|
||||
class ListControlUi extends Component {
|
||||
|
||||
state = {
|
||||
isLoading: false
|
||||
|
@ -62,10 +63,15 @@ export class ListControl extends Component {
|
|||
}
|
||||
|
||||
renderControl() {
|
||||
const { intl } = this.props;
|
||||
|
||||
if (this.props.disableMsg) {
|
||||
return (
|
||||
<EuiFieldText
|
||||
placeholder="Select..."
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'inputControl.vis.listControl.selectTextPlaceholder',
|
||||
defaultMessage: 'Select...'
|
||||
})}
|
||||
disabled={true}
|
||||
/>
|
||||
);
|
||||
|
@ -81,7 +87,10 @@ export class ListControl extends Component {
|
|||
|
||||
return (
|
||||
<EuiComboBox
|
||||
placeholder="Select..."
|
||||
placeholder={intl.formatMessage({
|
||||
id: 'inputControl.vis.listControl.selectPlaceholder',
|
||||
defaultMessage: 'Select...'
|
||||
})}
|
||||
options={options}
|
||||
isLoading={this.state.isLoading}
|
||||
async={this.props.dynamicOptions}
|
||||
|
@ -113,7 +122,7 @@ const comboBoxOptionShape = PropTypes.shape({
|
|||
value: PropTypes.string.isRequired,
|
||||
});
|
||||
|
||||
ListControl.propTypes = {
|
||||
ListControlUi.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
label: PropTypes.string.isRequired,
|
||||
selectedOptions: PropTypes.arrayOf(comboBoxOptionShape).isRequired,
|
||||
|
@ -126,12 +135,14 @@ ListControl.propTypes = {
|
|||
fetchOptions: PropTypes.func,
|
||||
};
|
||||
|
||||
ListControl.defaultProps = {
|
||||
ListControlUi.defaultProps = {
|
||||
dynamicOptions: false,
|
||||
multiselect: true,
|
||||
};
|
||||
|
||||
ListControl.defaultProps = {
|
||||
ListControlUi.defaultProps = {
|
||||
selectedOptions: [],
|
||||
options: [],
|
||||
};
|
||||
|
||||
export const ListControl = injectI18n(ListControlUi);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import sinon from 'sinon';
|
||||
import { shallow } from 'enzyme';
|
||||
import { shallowWithIntl } from 'test_utils/enzyme_helpers';
|
||||
|
||||
import {
|
||||
ListControl,
|
||||
|
@ -37,7 +37,7 @@ beforeEach(() => {
|
|||
});
|
||||
|
||||
test('renders ListControl', () => {
|
||||
const component = shallow(<ListControl
|
||||
const component = shallowWithIntl(<ListControl.WrappedComponent
|
||||
id="mock-list-control"
|
||||
label="list control"
|
||||
options={options}
|
||||
|
@ -50,7 +50,7 @@ test('renders ListControl', () => {
|
|||
});
|
||||
|
||||
test('disableMsg', () => {
|
||||
const component = shallow(<ListControl
|
||||
const component = shallowWithIntl(<ListControl.WrappedComponent
|
||||
id="mock-list-control"
|
||||
label="list control"
|
||||
multiselect={true}
|
||||
|
|
|
@ -22,6 +22,7 @@ import PropTypes from 'prop-types';
|
|||
import React, { Component } from 'react';
|
||||
import InputRange from 'react-input-range';
|
||||
import { FormRow } from './form_row';
|
||||
import { injectI18n } from '@kbn/i18n/react';
|
||||
|
||||
import {
|
||||
EuiFormRow,
|
||||
|
@ -49,7 +50,7 @@ const toState = ({ control }) => {
|
|||
return state;
|
||||
};
|
||||
|
||||
export class RangeControl extends Component {
|
||||
class RangeControlUi extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -93,12 +94,18 @@ export class RangeControl extends Component {
|
|||
|
||||
if ((!isMinValid && isMaxValid) || (isMinValid && !isMaxValid)) {
|
||||
isRangeValid = false;
|
||||
errorMessage = 'both min and max must be set';
|
||||
errorMessage = this.props.intl.formatMessage({
|
||||
id: 'inputControl.vis.rangeControl.minMaxValidErrorMessage',
|
||||
defaultMessage: 'both min and max must be set'
|
||||
});
|
||||
}
|
||||
|
||||
if (isMinValid && isMaxValid && max < min) {
|
||||
isRangeValid = false;
|
||||
errorMessage = 'max must be greater or equal to min';
|
||||
errorMessage = this.props.intl.formatMessage({
|
||||
id: 'inputControl.vis.rangeControl.maxValidErrorMessage',
|
||||
defaultMessage: 'max must be greater or equal to min'
|
||||
});
|
||||
}
|
||||
|
||||
this.setState({
|
||||
|
@ -196,8 +203,10 @@ export class RangeControl extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
RangeControl.propTypes = {
|
||||
RangeControlUi.propTypes = {
|
||||
control: PropTypes.object.isRequired,
|
||||
controlIndex: PropTypes.number.isRequired,
|
||||
stageFilter: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export const RangeControl = injectI18n(RangeControlUi);
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { shallow, mount } from 'enzyme';
|
||||
import { shallowWithIntl, mountWithIntl } from 'test_utils/enzyme_helpers';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
|
||||
import {
|
||||
|
@ -43,7 +43,7 @@ const control = {
|
|||
};
|
||||
|
||||
test('renders RangeControl', () => {
|
||||
const component = shallow(<RangeControl
|
||||
const component = shallowWithIntl(<RangeControl.WrappedComponent
|
||||
control={control}
|
||||
controlIndex={0}
|
||||
stageFilter={() => {}}
|
||||
|
@ -66,7 +66,7 @@ test('disabled', () => {
|
|||
return false;
|
||||
}
|
||||
};
|
||||
const component = shallow(<RangeControl
|
||||
const component = shallowWithIntl(<RangeControl.WrappedComponent
|
||||
control={disabledRangeControl}
|
||||
controlIndex={0}
|
||||
stageFilter={() => {}}
|
||||
|
@ -75,7 +75,7 @@ test('disabled', () => {
|
|||
});
|
||||
|
||||
describe('min and max input values', () => {
|
||||
const component = mount(<RangeControl
|
||||
const component = mountWithIntl(<RangeControl.WrappedComponent
|
||||
control={control}
|
||||
controlIndex={0}
|
||||
stageFilter={() => {}}
|
||||
|
|
|
@ -17,16 +17,24 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
/* eslint-disable no-multi-str*/
|
||||
|
||||
import _ from 'lodash';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export function noValuesDisableMsg(fieldName, indexPatternName) {
|
||||
return `Filtering occurs on the "${fieldName}" field,
|
||||
which doesn't exist on any documents in the "${indexPatternName}" index pattern.
|
||||
Choose a different field or index documents that contain values for this field.`;
|
||||
return i18n.translate('inputControl.control.noValuesDisableTootip', {
|
||||
defaultMessage: 'Filtering occurs on the "{fieldName}" field, which doesn\'t exist on any documents in the "{indexPatternName}" \
|
||||
index pattern. Choose a different field or index documents that contain values for this field.',
|
||||
values: { fieldName: fieldName, indexPatternName: indexPatternName }
|
||||
});
|
||||
}
|
||||
|
||||
export function noIndexPatternMsg(indexPatternId) {
|
||||
return `Could not locate index-pattern id: ${indexPatternId}.`;
|
||||
return i18n.translate('inputControl.control.noIndexPatternTootip', {
|
||||
defaultMessage: 'Could not locate index-pattern id: {indexPatternId}.',
|
||||
values: { indexPatternId }
|
||||
});
|
||||
}
|
||||
|
||||
export class Control {
|
||||
|
@ -43,7 +51,9 @@ export class Control {
|
|||
// restore state from kibana filter context
|
||||
this.reset();
|
||||
// disable until initialized
|
||||
this.disable('Control has not been initialized');
|
||||
this.disable(i18n.translate('inputControl.control.notInitializedTootip', {
|
||||
defaultMessage: 'Control has not been initialized'
|
||||
}));
|
||||
}
|
||||
|
||||
async fetch() {
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
} from './control';
|
||||
import { PhraseFilterManager } from './filter_manager/phrase_filter_manager';
|
||||
import { createSearchSource } from './create_search_source';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
function getEscapedQuery(query = '') {
|
||||
// https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-regexp-query.html#_standard_operators
|
||||
|
@ -75,7 +76,10 @@ class ListControl extends Control {
|
|||
let ancestorFilters;
|
||||
if (this.hasAncestors()) {
|
||||
if (this.hasUnsetAncestor()) {
|
||||
this.disable(`Disabled until '${this.ancestors[0].label}' is set.`);
|
||||
this.disable(i18n.translate('inputControl.listControl.disableTootip', {
|
||||
defaultMessage: 'Disabled until \'{label}\' is set.',
|
||||
values: { label: this.ancestors[0].label }
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -113,7 +117,10 @@ class ListControl extends Control {
|
|||
try {
|
||||
resp = await searchSource.fetch();
|
||||
} catch(error) {
|
||||
this.disable(`Unable to fetch terms, error: ${error.message}`);
|
||||
this.disable(i18n.translate('inputControl.listControl.unableToFetchTootip', {
|
||||
defaultMessage: 'Unable to fetch terms, error: {errorMessage}',
|
||||
values: { errorMessage: error.message }
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ import {
|
|||
} from './control';
|
||||
import { RangeFilterManager } from './filter_manager/range_filter_manager';
|
||||
import { createSearchSource } from './create_search_source';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
const minMaxAgg = (field) => {
|
||||
const aggBody = {};
|
||||
|
@ -64,7 +65,10 @@ class RangeControl extends Control {
|
|||
try {
|
||||
resp = await searchSource.fetch();
|
||||
} catch(error) {
|
||||
this.disable(`Unable to fetch range min and max, error: ${error.message}`);
|
||||
this.disable(i18n.translate('inputControl.rangeControl.unableToFetchTootip', {
|
||||
defaultMessage: 'Unable to fetch range min and max, error: {errorMessage}',
|
||||
values: { errorMessage: error.message }
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import { OptionsTab } from './components/editor/options_tab';
|
|||
import { defaultFeedbackMessage } from 'ui/vis/default_feedback_message';
|
||||
import image from './images/icon-input-control.svg';
|
||||
import { Status } from 'ui/vis/update_status';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
function InputControlVisProvider(Private) {
|
||||
const VisFactory = Private(VisFactoryProvider);
|
||||
|
@ -34,9 +35,13 @@ function InputControlVisProvider(Private) {
|
|||
// return the visType object, which kibana will use to display and configure new Vis object of this type.
|
||||
return VisFactory.createBaseVisualization({
|
||||
name: 'input_control_vis',
|
||||
title: 'Controls',
|
||||
title: i18n.translate('inputControl.register.controlsTitle', {
|
||||
defaultMessage: 'Controls'
|
||||
}),
|
||||
image,
|
||||
description: 'Create interactive controls for easy dashboard manipulation.',
|
||||
description: i18n.translate('inputControl.register.controlsDescription', {
|
||||
defaultMessage: 'Create interactive controls for easy dashboard manipulation.'
|
||||
}),
|
||||
category: CATEGORY.OTHER,
|
||||
stage: 'lab',
|
||||
requiresUpdateStatus: [Status.PARAMS, Status.TIME],
|
||||
|
@ -55,12 +60,16 @@ function InputControlVisProvider(Private) {
|
|||
optionTabs: [
|
||||
{
|
||||
name: 'controls',
|
||||
title: 'Controls',
|
||||
title: i18n.translate('inputControl.register.tabs.controlsTitle', {
|
||||
defaultMessage: 'Controls'
|
||||
}),
|
||||
editor: ControlsTab
|
||||
},
|
||||
{
|
||||
name: 'options',
|
||||
title: 'Options',
|
||||
title: i18n.translate('inputControl.register.tabs.optionsTitle', {
|
||||
defaultMessage: 'Options'
|
||||
}),
|
||||
editor: OptionsTab
|
||||
}
|
||||
]
|
||||
|
|
|
@ -23,6 +23,8 @@ import { InputControlVis } from './components/vis/input_control_vis';
|
|||
import { controlFactory } from './control/control_factory';
|
||||
import { getLineageMap } from './lineage';
|
||||
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
|
||||
class VisController {
|
||||
constructor(el, vis) {
|
||||
this.el = el;
|
||||
|
@ -50,17 +52,19 @@ class VisController {
|
|||
|
||||
drawVis = () => {
|
||||
render(
|
||||
<InputControlVis
|
||||
updateFiltersOnChange={this.vis.params.updateFiltersOnChange}
|
||||
controls={this.controls}
|
||||
stageFilter={this.stageFilter}
|
||||
submitFilters={this.submitFilters}
|
||||
resetControls={this.updateControlsFromKbn}
|
||||
clearControls={this.clearControls}
|
||||
hasChanges={this.hasChanges}
|
||||
hasValues={this.hasValues}
|
||||
refreshControl={this.refreshControl}
|
||||
/>,
|
||||
<I18nProvider>
|
||||
<InputControlVis
|
||||
updateFiltersOnChange={this.vis.params.updateFiltersOnChange}
|
||||
controls={this.controls}
|
||||
stageFilter={this.stageFilter}
|
||||
submitFilters={this.submitFilters}
|
||||
resetControls={this.updateControlsFromKbn}
|
||||
clearControls={this.clearControls}
|
||||
hasChanges={this.hasChanges}
|
||||
hasValues={this.hasValues}
|
||||
refreshControl={this.refreshControl}
|
||||
/>
|
||||
</I18nProvider>,
|
||||
this.el);
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import React from 'react';
|
|||
import { render, unmountComponentAtNode } from 'react-dom';
|
||||
import { uiModules } from '../../../modules';
|
||||
import visOptionsTemplate from './vis_options.html';
|
||||
import { I18nProvider } from '@kbn/i18n/react';
|
||||
|
||||
/**
|
||||
* This directive sort of "transcludes" in whatever template you pass in via the `editor` attribute.
|
||||
|
@ -53,7 +54,10 @@ uiModules
|
|||
};
|
||||
const renderReactComponent = () => {
|
||||
const Component = $scope.editor;
|
||||
render(<Component scope={$scope} editorState={$scope.editorState} stageEditorParams={stageEditorParams} />, $el[0]);
|
||||
render(
|
||||
<I18nProvider>
|
||||
<Component scope={$scope} editorState={$scope.editorState} stageEditorParams={stageEditorParams} />
|
||||
</I18nProvider>, $el[0]);
|
||||
};
|
||||
// Bind the `editor` template with the scope.
|
||||
if (reactOptionsComponent) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue