diff --git a/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx b/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx index cd3982afd9afd5..0cd2a2b3319801 100644 --- a/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx +++ b/src/legacy/core_plugins/input_control_vis/public/components/vis/range_control.tsx @@ -19,8 +19,7 @@ import _ from 'lodash'; import React, { PureComponent } from 'react'; - -import { ValidatedDualRange } from '../../legacy_imports'; +import { ValidatedDualRange } from '../../../../../../../src/plugins/kibana_react/public'; import { FormRow } from './form_row'; import { RangeControl as RangeControlClass } from '../../control/range_control_factory'; diff --git a/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts b/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts index b6c4eb28e974f2..8c58ac2386da43 100644 --- a/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts +++ b/src/legacy/core_plugins/input_control_vis/public/legacy_imports.ts @@ -22,7 +22,5 @@ import { SearchSource as SearchSourceClass, ISearchSource } from '../../../../pl export { SearchSourceFields } from '../../../../plugins/data/public'; -export { ValidatedDualRange } from 'ui/validated_range'; - export type SearchSource = Class; export const SearchSource = SearchSourceClass; diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx index ab7c2cd980c424..a9e816f70cf531 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/tag_cloud_options.tsx @@ -20,11 +20,10 @@ import React from 'react'; import { EuiPanel } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; - +import { ValidatedDualRange } from '../../../../../../src/plugins/kibana_react/public'; import { VisOptionsProps } from '../../../vis_default_editor/public'; import { SelectOption, SwitchOption } from '../../../vis_type_vislib/public'; import { TagCloudVisParams } from '../types'; -import { ValidatedDualRange } from '../legacy_imports'; function TagCloudOptions({ stateParams, setValue, vis }: VisOptionsProps) { const handleFontSizeChange = ([minFontSize, maxFontSize]: [string | number, string | number]) => { diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/legacy_imports.ts b/src/legacy/core_plugins/vis_type_tagcloud/public/legacy_imports.ts index d5b442bc5b3468..0d76bc5d8b68b0 100644 --- a/src/legacy/core_plugins/vis_type_tagcloud/public/legacy_imports.ts +++ b/src/legacy/core_plugins/vis_type_tagcloud/public/legacy_imports.ts @@ -18,5 +18,4 @@ */ export { Schemas } from 'ui/agg_types'; -export { ValidatedDualRange } from 'ui/validated_range'; export { getFormat } from 'ui/visualize/loader/pipeline_helpers/utilities'; diff --git a/src/legacy/ui/public/validated_range/index.d.ts b/src/legacy/ui/public/validated_range/index.d.ts deleted file mode 100644 index 50cacbc517be8b..00000000000000 --- a/src/legacy/ui/public/validated_range/index.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import React from 'react'; -import { EuiRangeProps } from '@elastic/eui'; - -export class ValidatedDualRange extends React.Component { - allowEmptyRange?: boolean; -} diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts index f04c6f1f19c338..e88ca7178cde39 100644 --- a/src/plugins/kibana_react/public/index.ts +++ b/src/plugins/kibana_react/public/index.ts @@ -25,6 +25,7 @@ export * from './ui_settings'; export * from './field_icon'; export * from './table_list_view'; export * from './split_panel'; +export { ValidatedDualRange } from './validated_range'; export { Markdown, MarkdownSimple } from './markdown'; export { reactToUiComponent, uiToReactComponent } from './adapters'; export { useUrlTracker } from './use_url_tracker'; diff --git a/src/legacy/ui/public/validated_range/index.js b/src/plugins/kibana_react/public/validated_range/index.ts similarity index 100% rename from src/legacy/ui/public/validated_range/index.js rename to src/plugins/kibana_react/public/validated_range/index.ts diff --git a/src/legacy/ui/public/validated_range/is_range_valid.test.js b/src/plugins/kibana_react/public/validated_range/is_range_valid.test.ts similarity index 100% rename from src/legacy/ui/public/validated_range/is_range_valid.test.js rename to src/plugins/kibana_react/public/validated_range/is_range_valid.test.ts diff --git a/src/legacy/ui/public/validated_range/is_range_valid.js b/src/plugins/kibana_react/public/validated_range/is_range_valid.ts similarity index 74% rename from src/legacy/ui/public/validated_range/is_range_valid.js rename to src/plugins/kibana_react/public/validated_range/is_range_valid.ts index 9b733815a66ba8..1f822c0cb94b96 100644 --- a/src/legacy/ui/public/validated_range/is_range_valid.js +++ b/src/plugins/kibana_react/public/validated_range/is_range_valid.ts @@ -18,14 +18,24 @@ */ import { i18n } from '@kbn/i18n'; +import { ValueMember, Value } from './validated_dual_range'; const LOWER_VALUE_INDEX = 0; const UPPER_VALUE_INDEX = 1; -export function isRangeValid(value, min, max, allowEmptyRange) { - allowEmptyRange = typeof allowEmptyRange === 'boolean' ? allowEmptyRange : true; //cannot use default props since that uses falsy check - let lowerValue = isNaN(value[LOWER_VALUE_INDEX]) ? '' : value[LOWER_VALUE_INDEX]; - let upperValue = isNaN(value[UPPER_VALUE_INDEX]) ? '' : value[UPPER_VALUE_INDEX]; +export function isRangeValid( + value: Value = [0, 0], + min: ValueMember = 0, + max: ValueMember = 0, + allowEmptyRange?: boolean +) { + allowEmptyRange = typeof allowEmptyRange === 'boolean' ? allowEmptyRange : true; // cannot use default props since that uses falsy check + let lowerValue: ValueMember = isNaN(value[LOWER_VALUE_INDEX] as number) + ? '' + : `${value[LOWER_VALUE_INDEX]}`; + let upperValue: ValueMember = isNaN(value[UPPER_VALUE_INDEX] as number) + ? '' + : `${value[UPPER_VALUE_INDEX]}`; const isLowerValueValid = lowerValue.toString() !== ''; const isUpperValueValid = upperValue.toString() !== ''; @@ -39,7 +49,7 @@ export function isRangeValid(value, min, max, allowEmptyRange) { let errorMessage = ''; const bothMustBeSetErrorMessage = i18n.translate( - 'common.ui.dualRangeControl.mustSetBothErrorMessage', + 'kibana-react.dualRangeControl.mustSetBothErrorMessage', { defaultMessage: 'Both lower and upper values must be set', } @@ -55,13 +65,13 @@ export function isRangeValid(value, min, max, allowEmptyRange) { errorMessage = bothMustBeSetErrorMessage; } else if ((isLowerValueValid && lowerValue < min) || (isUpperValueValid && upperValue > max)) { isValid = false; - errorMessage = i18n.translate('common.ui.dualRangeControl.outsideOfRangeErrorMessage', { + errorMessage = i18n.translate('kibana-react.dualRangeControl.outsideOfRangeErrorMessage', { defaultMessage: 'Values must be on or between {min} and {max}', values: { min, max }, }); } else if (isLowerValueValid && isUpperValueValid && upperValue < lowerValue) { isValid = false; - errorMessage = i18n.translate('common.ui.dualRangeControl.upperValidErrorMessage', { + errorMessage = i18n.translate('kibana-react.dualRangeControl.upperValidErrorMessage', { defaultMessage: 'Upper value must be greater or equal to lower value', }); } diff --git a/src/legacy/ui/public/validated_range/validated_dual_range.js b/src/plugins/kibana_react/public/validated_range/validated_dual_range.tsx similarity index 67% rename from src/legacy/ui/public/validated_range/validated_dual_range.js rename to src/plugins/kibana_react/public/validated_range/validated_dual_range.tsx index 3b0efba11afccc..e7392eeba3830f 100644 --- a/src/legacy/ui/public/validated_range/validated_dual_range.js +++ b/src/plugins/kibana_react/public/validated_range/validated_dual_range.tsx @@ -18,17 +18,38 @@ */ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; -import { isRangeValid } from './is_range_valid'; - import { EuiFormRow, EuiDualRange } from '@elastic/eui'; +import { EuiFormRowDisplayKeys } from '@elastic/eui/src/components/form/form_row/form_row'; +import { EuiDualRangeProps } from '@elastic/eui/src/components/form/range/dual_range'; +import { isRangeValid } from './is_range_valid'; // Wrapper around EuiDualRange that ensures onChange callback is only called when range value // is valid and within min/max -export class ValidatedDualRange extends Component { - state = {}; - static getDerivedStateFromProps(nextProps, prevState) { +export type Value = EuiDualRangeProps['value']; +export type ValueMember = EuiDualRangeProps['value'][0]; + +interface Props extends Omit { + value?: Value; + allowEmptyRange?: boolean; + label?: string; + formRowDisplay?: EuiFormRowDisplayKeys; + onChange?: (val: [string, string]) => void; + min?: ValueMember; + max?: ValueMember; +} + +interface State { + isValid?: boolean; + errorMessage?: string; + value: [ValueMember, ValueMember]; + prevValue?: Value; +} + +export class ValidatedDualRange extends Component { + static defaultProps: { fullWidth: boolean; allowEmptyRange: boolean; compressed: boolean }; + + static getDerivedStateFromProps(nextProps: Props, prevState: State) { if (nextProps.value !== prevState.prevValue) { const { isValid, errorMessage } = isRangeValid( nextProps.value, @@ -47,7 +68,10 @@ export class ValidatedDualRange extends Component { return null; } - _onChange = value => { + // @ts-ignore state populated by getDerivedStateFromProps + state: State = {}; + + _onChange = (value: Value) => { const { isValid, errorMessage } = isRangeValid( value, this.props.min, @@ -61,8 +85,8 @@ export class ValidatedDualRange extends Component { errorMessage, }); - if (isValid) { - this.props.onChange(value); + if (this.props.onChange && isValid) { + this.props.onChange([value[0] as string, value[1] as string]); } }; @@ -75,7 +99,8 @@ export class ValidatedDualRange extends Component { value, // eslint-disable-line no-unused-vars onChange, // eslint-disable-line no-unused-vars allowEmptyRange, // eslint-disable-line no-unused-vars - ...rest + // @ts-ignore + ...rest // TODO: Consider alternatives for spread operator in component } = this.props; return ( @@ -92,6 +117,7 @@ export class ValidatedDualRange extends Component { fullWidth={fullWidth} value={this.state.value} onChange={this._onChange} + // @ts-ignore focusable={false} // remove when #59039 is fixed {...rest} /> @@ -100,14 +126,6 @@ export class ValidatedDualRange extends Component { } } -ValidatedDualRange.propTypes = { - allowEmptyRange: PropTypes.bool, - fullWidth: PropTypes.bool, - compressed: PropTypes.bool, - label: PropTypes.node, - formRowDisplay: PropTypes.string, -}; - ValidatedDualRange.defaultProps = { allowEmptyRange: true, fullWidth: false, diff --git a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js index ac17915b5f2776..eb23607aa2150c 100644 --- a/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js +++ b/x-pack/legacy/plugins/maps/public/connected_components/layer_panel/layer_settings/layer_settings.js @@ -11,7 +11,7 @@ import { EuiTitle, EuiPanel, EuiFormRow, EuiFieldText, EuiSpacer } from '@elasti import { ValidatedRange } from '../../../components/validated_range'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ValidatedDualRange } from 'ui/validated_range'; +import { ValidatedDualRange } from '../../../../../../../../src/plugins/kibana_react/public'; import { MAX_ZOOM, MIN_ZOOM } from '../../../../common/constants'; export function LayerSettings(props) { diff --git a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js index 1d5815a84920cb..5de7b462136e16 100644 --- a/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js +++ b/x-pack/legacy/plugins/maps/public/layers/styles/vector/components/size/size_range_selector.js @@ -6,7 +6,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { ValidatedDualRange } from 'ui/validated_range'; +import { ValidatedDualRange } from '../../../../../../../../../../src/plugins/kibana_react/public'; import { MIN_SIZE, MAX_SIZE } from '../../vector_style_defaults'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index fb0eb6e4bf8046..2601298145d9ca 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -78,9 +78,6 @@ "messages": { "common.ui.aggResponse.allDocsTitle": "すべてのドキュメント", "common.ui.directives.paginate.size.allDropDownOptionLabel": "すべて", - "common.ui.dualRangeControl.mustSetBothErrorMessage": "下と上の値の両方を設定する必要があります", - "common.ui.dualRangeControl.outsideOfRangeErrorMessage": "値は {min} と {max} の間でなければなりません", - "common.ui.dualRangeControl.upperValidErrorMessage": "上の値は下の値以上でなければなりません", "common.ui.errorAutoCreateIndex.breadcrumbs.errorText": "エラー", "common.ui.errorAutoCreateIndex.errorDescription": "Elasticsearch クラスターの {autoCreateIndexActionConfig} 設定が原因で、Kibana が保存されたオブジェクトを格納するインデックスを自動的に作成できないようです。Kibana は、保存されたオブジェクトインデックスが適切なマッピング/スキーマを使用し Kibana から Elasticsearch へのポーリングの回数を減らすための最適な手段であるため、この Elasticsearch の機能を使用します。", "common.ui.errorAutoCreateIndex.errorDisclaimer": "申し訳ございませんが、この問題が解決されるまで Kibana で何も保存することができません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 0a9c82afaec1d4..27e0ced424b991 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -78,9 +78,6 @@ "messages": { "common.ui.aggResponse.allDocsTitle": "所有文档", "common.ui.directives.paginate.size.allDropDownOptionLabel": "全部", - "common.ui.dualRangeControl.mustSetBothErrorMessage": "下限值和上限值都须设置", - "common.ui.dualRangeControl.outsideOfRangeErrorMessage": "值必须是在 {min} 到 {max} 的范围内", - "common.ui.dualRangeControl.upperValidErrorMessage": "上限值必须大于或等于下限值", "common.ui.errorAutoCreateIndex.breadcrumbs.errorText": "错误", "common.ui.errorAutoCreateIndex.errorDescription": "似乎 Elasticsearch 集群的 {autoCreateIndexActionConfig} 设置使 Kibana 无法自动创建用于存储已保存对象的索引。Kibana 将使用此 Elasticsearch 功能,因为这是确保已保存对象索引使用正确映射/架构的最好方式,而且其允许 Kibana 较少地轮询 Elasticsearch。", "common.ui.errorAutoCreateIndex.errorDisclaimer": "但是,只有解决了此问题后,您才能在 Kibana 保存内容。",