Skip to content

Commit

Permalink
[Vis: Default editor] Euification of heatmap options tab (#45766)
Browse files Browse the repository at this point in the history
* EUIficate heatmap options

* Move collections

* Split labels in a panel

* Remove angular templates

* Remove unused translations

* Fix functional tests

* Fix validation

* Fix UI details

* Compress color picker

* Improve types

* Replace headings h2 with h3

* Add functional tests

* Create setCustomRangeByIndex
  • Loading branch information
sulemanof authored Sep 27, 2019
1 parent f7b95ec commit b322b60
Show file tree
Hide file tree
Showing 31 changed files with 772 additions and 827 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* 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, { useCallback } from 'react';
import { last } from 'lodash';
import { i18n } from '@kbn/i18n';

import { RangeValues, RangesParamEditor } from 'ui/vis/editors/default/controls/ranges';

interface ColorRangesProps {
'data-test-subj'?: string;
colorsRange: RangeValues[];
setValue(paramName: string, value: RangeValues[]): void;
setValidity?(isValid: boolean): void;
setTouched?(isTouched: boolean): void;
}

function ColorRanges({
'data-test-subj': dataTestSubj,
colorsRange,
setValue,
setValidity,
setTouched,
}: ColorRangesProps) {
const addRangeValues = useCallback(() => {
const previousRange = last(colorsRange) || {};
const from = previousRange.to ? previousRange.to : 0;
const to = previousRange.to ? from + (previousRange.to - (previousRange.from || 0)) : 100;

return { from, to };
}, [colorsRange]);

const validateRange = useCallback(
({ from, to }, index) => {
const leftBound = index === 0 ? -Infinity : colorsRange[index - 1].to || 0;
const isFromValid = from >= leftBound;
const isToValid = to >= from;

return [isFromValid, isToValid];
},
[colorsRange]
);

const setColorRanges = useCallback((value: RangeValues[]) => setValue('colorsRange', value), [
setValue,
]);

return (
<RangesParamEditor
data-test-subj={dataTestSubj}
error={i18n.translate('kbnVislibVisTypes.controls.colorRanges.errorText', {
defaultMessage: 'Each range should be greater than previous.',
})}
hidePlaceholders={true}
value={colorsRange}
setValue={setColorRanges}
setValidity={setValidity}
setTouched={setTouched}
addRangeValues={addRangeValues}
validateRange={validateRange}
/>
);
}

export { ColorRanges };
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* 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, { useEffect, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiLink, EuiText } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';

import { VisOptionsProps } from 'ui/vis/editors/default';
import { ColorSchema } from 'ui/vislib/components/color/colormaps';
import { SelectOption } from './select';
import { SwitchOption } from './switch';
import { ColorSchemaVislibParams } from '../../types';

export type SetColorSchemaOptionsValue = <T extends keyof ColorSchemaVislibParams>(
paramName: T,
value: ColorSchemaVislibParams[T]
) => void;

interface ColorSchemaOptionsProps extends ColorSchemaVislibParams {
disabled?: boolean;
colorSchemas: ColorSchema[];
uiState: VisOptionsProps['uiState'];
setValue: SetColorSchemaOptionsValue;
}

function ColorSchemaOptions({
disabled,
colorSchema,
colorSchemas,
invertColors,
uiState,
setValue,
}: ColorSchemaOptionsProps) {
const [isCustomColors, setIsCustomColors] = useState(() => !!uiState.get('vis.colors'));

useEffect(() => {
uiState.on('colorChanged', () => {
setIsCustomColors(true);
});
}, [uiState]);

const resetColorsButton = (
<EuiText size="xs">
<EuiLink
onClick={() => {
uiState.set('vis.colors', null);
setIsCustomColors(false);
}}
>
<FormattedMessage
id="kbnVislibVisTypes.controls.colorSchema.resetColorsButtonLabel"
defaultMessage="Reset colors"
/>
</EuiLink>
</EuiText>
);

return (
<>
<SelectOption
disabled={disabled}
helpText={i18n.translate(
'kbnVislibVisTypes.controls.colorSchema.howToChangeColorsDescription',
{
defaultMessage: 'Individual colors can be changed in the legend.',
}
)}
label={i18n.translate('kbnVislibVisTypes.controls.colorSchema.colorSchemaLabel', {
defaultMessage: 'Color schema',
})}
labelAppend={isCustomColors && resetColorsButton}
options={colorSchemas}
paramName="colorSchema"
value={colorSchema}
setValue={setValue}
/>

<SwitchOption
disabled={disabled}
label={i18n.translate('kbnVislibVisTypes.controls.colorSchema.reverseColorSchemaLabel', {
defaultMessage: 'Reverse schema',
})}
paramName="invertColors"
value={invertColors}
setValue={setValue}
/>
</>
);
}

export { ColorSchemaOptions };
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
*/

export { BasicOptions } from './basic_options';
export { ColorRanges } from './color_ranges';
export { ColorSchemaOptions } from './color_schema';
export { NumberInputOption } from './number_input';
export { RangeOption } from './range';
export { SelectOption } from './select';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import React from 'react';
import React, { useMemo } from 'react';
import { EuiFormRow, EuiSelect } from '@elastic/eui';

interface SelectOptionProps<ParamName extends string, ValidParamValues extends string | number> {
Expand Down Expand Up @@ -45,6 +45,8 @@ function SelectOption<ParamName extends string, ValidParamValues extends string
value,
setValue,
}: SelectOptionProps<ParamName, ValidParamValues>) {
const availableOptions = useMemo(() => [emptyValue, ...options], [options]);

return (
<EuiFormRow
compressed
Expand All @@ -57,7 +59,7 @@ function SelectOption<ParamName extends string, ValidParamValues extends string
<EuiSelect
compressed
disabled={disabled}
options={[emptyValue, ...options]}
options={availableOptions}
value={value === undefined ? emptyValue.value : value}
onChange={ev => setValue(paramName, ev.target.value as ValidParamValues)}
fullWidth={true}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@
* under the License.
*/

import React, { useCallback, useEffect, useState } from 'react';
import { last } from 'lodash';
import { EuiLink, EuiPanel, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui';
import React from 'react';
import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

import { RangesParamEditor } from 'ui/vis/editors/default/controls/ranges';
import { SelectOption, SwitchOption } from '../../common';
import { ColorRanges, ColorSchemaOptions, SwitchOption } from '../../common';
import { SetColorSchemaOptionsValue } from '../../common/color_schema';
import { GaugeOptionsInternalProps } from '.';

function RangesPanel({
Expand All @@ -36,49 +35,6 @@ function RangesPanel({
uiState,
vis,
}: GaugeOptionsInternalProps) {
const [isCustomColors, setIsCustomColors] = useState(false);

useEffect(() => {
uiState.on('colorChanged', () => {
setIsCustomColors(true);
});
}, [uiState]);

const addRangeValues = useCallback(() => {
const previousRange = last(stateParams.gauge.colorsRange);
const from = previousRange.to ? previousRange.to : 0;
const to = previousRange.to ? from + (previousRange.to - (previousRange.from || 0)) : 100;

return { from, to };
}, [stateParams.gauge.colorsRange]);

const validateRange = useCallback(
({ from, to }, index) => {
const leftBound = index === 0 ? -Infinity : stateParams.gauge.colorsRange[index - 1].to || 0;
const isFromValid = from >= leftBound;
const isToValid = to >= from;

return [isFromValid, isToValid];
},
[stateParams.gauge.colorsRange]
);

const resetColorsButton = (
<EuiText size="xs">
<EuiLink
onClick={() => {
uiState.set('vis.colors', null);
setIsCustomColors(false);
}}
>
<FormattedMessage
id="kbnVislibVisTypes.controls.gaugeOptions.resetColorsButtonLabel"
defaultMessage="Reset colors"
/>
</EuiLink>
</EuiText>
);

return (
<EuiPanel paddingSize="s">
<EuiTitle size="xs">
Expand All @@ -91,18 +47,12 @@ function RangesPanel({
</EuiTitle>
<EuiSpacer size="s" />

<RangesParamEditor
dataTestSubj="gaugeColorRange"
error={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.errorText', {
defaultMessage: 'Each range should be greater than previous.',
})}
hidePlaceholders={true}
value={stateParams.gauge.colorsRange}
setValue={value => setGaugeValue('colorsRange', value)}
<ColorRanges
data-test-subj="gaugeColorRange"
colorsRange={stateParams.gauge.colorsRange}
setValue={setGaugeValue}
setTouched={setTouched}
setValidity={setValidity}
addRangeValues={addRangeValues}
validateRange={validateRange}
/>

<SwitchOption
Expand All @@ -128,32 +78,13 @@ function RangesPanel({
setValue={setGaugeValue}
/>

<SelectOption
<ColorSchemaOptions
disabled={stateParams.gauge.colorsRange.length < 2}
helpText={i18n.translate(
'kbnVislibVisTypes.controls.gaugeOptions.howToChangeColorsDescription',
{
defaultMessage: 'Note: colors can be changed in the legend.',
}
)}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.colorSchemaLabel', {
defaultMessage: 'Color schema',
})}
labelAppend={isCustomColors && resetColorsButton}
options={vis.type.editorConfig.collections.colorSchemas}
paramName="colorSchema"
value={stateParams.gauge.colorSchema}
setValue={setGaugeValue}
/>

<SwitchOption
disabled={stateParams.gauge.colorsRange.length < 2}
label={i18n.translate('kbnVislibVisTypes.controls.gaugeOptions.reverseColorSchemaLabel', {
defaultMessage: 'Reverse schema',
})}
paramName="invertColors"
value={stateParams.gauge.invertColors}
setValue={setGaugeValue}
colorSchema={stateParams.gauge.colorSchema}
colorSchemas={vis.type.editorConfig.collections.colorSchemas}
invertColors={stateParams.gauge.invertColors}
uiState={uiState}
setValue={setGaugeValue as SetColorSchemaOptionsValue}
/>

<SwitchOption
Expand Down
Loading

0 comments on commit b322b60

Please sign in to comment.