Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Lens] Revisit flyout fields style from column to row compressed #120103

Merged
merged 11 commits into from
Dec 14, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

@include euiBreakpoint('xs', 's', 'm') {
@include euiFlyout;
left: 10vw;
ryankeairns marked this conversation as resolved.
Show resolved Hide resolved
z-index: $euiZContentMenu;
}

.lnsFrameLayout__sidebar-isFullscreen & {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export function AdvancedOptions(props: {
<>
{popoverOptions.length > 0 && (
<EuiText textAlign="right">
<EuiSpacer size="s" />
<EuiPopover
ownFocus
button={
Expand Down Expand Up @@ -69,17 +68,12 @@ export function AdvancedOptions(props: {
</EuiPopover>
</EuiText>
)}
{inlineOptions.length > 0 && (
<>
{inlineOptions.map((option) => (
<React.Fragment key={option.dataTestSubj}>
<EuiSpacer size="s" />
{inlineOptions.map((option, index) => (
<React.Fragment key={option.dataTestSubj}>
{option.inlineElement}
{index !== inlineOptions.length - 1 && <EuiSpacer size="s" />}
</React.Fragment>
))}
</>
)}
{option.inlineElement}
</React.Fragment>
))}
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
<div className="lnsIndexPatternDimensionEditor__section lnsIndexPatternDimensionEditor__section--padded lnsIndexPatternDimensionEditor__section--shaded">
<EuiFormLabel>
{i18n.translate('xpack.lens.indexPattern.functionsLabel', {
defaultMessage: 'Select a function',
defaultMessage: 'Functions',
})}
</EuiFormLabel>
<EuiSpacer size="s" />
Expand Down Expand Up @@ -485,7 +485,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
/>
);
})}
<EuiSpacer size="s" />
{selectedOperationDefinition.selectionStyle !== 'field' ? <EuiSpacer size="s" /> : null}
</>
) : null}

Expand All @@ -496,7 +496,7 @@ export function DimensionEditor(props: DimensionEditorProps) {
<EuiFormRow
data-test-subj="indexPattern-field-selection-row"
label={i18n.translate('xpack.lens.indexPattern.chooseField', {
defaultMessage: 'Select a field',
defaultMessage: 'Field',
})}
fullWidth
isInvalid={Boolean(incompleteOperation || currentFieldIsInvalid)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ export function Filtering({

return (
<EuiFormRow
display="columnCompressed"
display="rowCompressed"
label={filterByLabel}
fullWidth
isInvalid={!isInputFilterValid}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ export function ReferenceEditor(props: ReferenceEditorProps) {
<EuiFormRow
data-test-subj="indexPattern-reference-field-selection-row"
label={i18n.translate('xpack.lens.indexPattern.chooseField', {
defaultMessage: 'Select a field',
defaultMessage: 'Field',
})}
fullWidth
isInvalid={showFieldInvalid || showFieldMissingInvalid}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function TimeScaling({

return (
<EuiFormRow
display="columnCompressed"
display="rowCompressed"
fullWidth
label={
<EuiToolTip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export function TimeShift({
}}
>
<EuiFormRow
display="columnCompressed"
display="rowCompressed"
fullWidth
data-test-subj="indexPattern-dimension-time-shift-row"
label={i18n.translate('xpack.lens.indexPattern.timeShift.label', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ function MovingAverageParamEditor({
label={i18n.translate('xpack.lens.indexPattern.movingAverage.window', {
defaultMessage: 'Window size',
})}
display="columnCompressed"
display="rowCompressed"
fullWidth
isInvalid={!isValidNumber(inputValue)}
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ export const lastValueOperation: OperationDefinition<LastValueIndexPatternColumn
label={i18n.translate('xpack.lens.indexPattern.lastValue.sortField', {
defaultMessage: 'Sort by date field',
})}
display="columnCompressed"
display="rowCompressed"
fullWidth
error={i18n.translate('xpack.lens.indexPattern.sortField.invalid', {
defaultMessage: 'Invalid field. Check your data view or pick another field.',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import React from 'react';
import React, { ChangeEvent } from 'react';
import { shallow, mount } from 'enzyme';
import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
Expand All @@ -14,11 +14,20 @@ import { createMockedIndexPattern } from '../../mocks';
import { percentileOperation } from './index';
import { IndexPattern, IndexPatternLayer } from '../../types';
import { PercentileIndexPatternColumn } from './percentile';
import { EuiFieldNumber } from '@elastic/eui';
import { EuiRange } from '@elastic/eui';
import { act } from 'react-dom/test-utils';
import { EuiFormRow } from '@elastic/eui';
import { TermsIndexPatternColumn } from './terms';

jest.mock('lodash', () => {
const original = jest.requireActual('lodash');

return {
...original,
debounce: (fn: unknown) => fn,
};
});

const uiSettingsMock = {} as IUiSettingsClient;

const defaultProps = {
Expand Down Expand Up @@ -272,8 +281,7 @@ describe('percentile', () => {
expect(input.prop('value')).toEqual('23');
});

it('should update state on change', async () => {
jest.useFakeTimers();
it('should update state on change', () => {
const updateLayerSpy = jest.fn();
const instance = mount(
<InlineOptions
Expand All @@ -285,20 +293,19 @@ describe('percentile', () => {
/>
);

jest.runAllTimers();

const input = instance.find(
'[data-test-subj="lns-indexPattern-percentile-input"] input[type="number"]'
);
const input = instance
.find('[data-test-subj="lns-indexPattern-percentile-input"]')
.find(EuiRange);

await act(async () => {
input.simulate('change', { target: { value: '27' } });
act(() => {
input.prop('onChange')!(
{ currentTarget: { value: '27' } } as ChangeEvent<HTMLInputElement>,
true
);
});

instance.update();

jest.runAllTimers();

expect(updateLayerSpy).toHaveBeenCalledWith({
...layer,
columns: {
Expand All @@ -314,7 +321,7 @@ describe('percentile', () => {
});
});

it('should not update on invalid input, but show invalid value locally', async () => {
it('should not update on invalid input, but show invalid value locally', () => {
const updateLayerSpy = jest.fn();
const instance = mount(
<InlineOptions
Expand All @@ -326,20 +333,19 @@ describe('percentile', () => {
/>
);

jest.runAllTimers();

const input = instance.find(
'[data-test-subj="lns-indexPattern-percentile-input"] input[type="number"]'
);
const input = instance
.find('[data-test-subj="lns-indexPattern-percentile-input"]')
.find(EuiRange);

await act(async () => {
input.simulate('change', { target: { value: '12.12' } });
act(() => {
input.prop('onChange')!(
{ currentTarget: { value: '12.12' } } as ChangeEvent<HTMLInputElement>,
true
);
});

instance.update();

jest.runAllTimers();

expect(updateLayerSpy).not.toHaveBeenCalled();

expect(
Expand All @@ -351,7 +357,7 @@ describe('percentile', () => {
expect(
instance
.find('[data-test-subj="lns-indexPattern-percentile-input"]')
.find(EuiFieldNumber)
.find(EuiRange)
.prop('value')
).toEqual('12.12');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
* 2.0.
*/

import { EuiFieldNumber, EuiFormRow } from '@elastic/eui';
import React, { useCallback, useState } from 'react';
import { EuiFormRow, EuiRange, EuiRangeProps } from '@elastic/eui';
import React, { useCallback } from 'react';
import { i18n } from '@kbn/i18n';
import { AggFunctionsMapping } from 'src/plugins/data/public';
import { buildExpressionFunction } from '../../../../../../../src/plugins/expressions/public';
Expand All @@ -21,7 +21,7 @@ import {
} from './helpers';
import { FieldBasedIndexPatternColumn } from './column_types';
import { adjustTimeScaleLabelSuffix } from '../time_scale_utils';
import { useDebounceWithOptions } from '../../../shared_components';
import { useDebouncedValue } from '../../../shared_components';

export interface PercentileIndexPatternColumn extends FieldBasedIndexPatternColumn {
operationType: 'percentile';
Expand Down Expand Up @@ -150,16 +150,14 @@ export const percentileOperation: OperationDefinition<
columnId,
indexPattern,
}) {
const [inputValue, setInputValue] = useState(String(currentColumn.params.percentile));

const inputValueAsNumber = Number(inputValue);
// an input is value if it's not an empty string, parses to a valid number, is between 0 and 100 (exclusive)
// and is an integer
const inputValueIsValid = isValidNumber(inputValue, true, 99, 1);

useDebounceWithOptions(
() => {
if (!inputValueIsValid) return;
const onChange = useCallback(
(value) => {
if (
!isValidNumber(value, true, 99, 1) ||
Number(value) === currentColumn.params.percentile
) {
return;
}
updateLayer({
...layer,
columns: {
Expand All @@ -171,33 +169,39 @@ export const percentileOperation: OperationDefinition<
: ofName(
indexPattern.getFieldByName(currentColumn.sourceField)?.displayName ||
currentColumn.sourceField,
inputValueAsNumber,
Number(value),
currentColumn.timeShift
),
params: {
...currentColumn.params,
percentile: inputValueAsNumber,
percentile: Number(value),
},
} as PercentileIndexPatternColumn,
},
});
},
{ skipFirstRender: true },
256,
[inputValue]
[updateLayer, layer, columnId, currentColumn, indexPattern]
);
const { inputValue, handleInputChange: handleInputChangeWithoutValidation } = useDebouncedValue<
string | undefined
>({
onChange,
value: String(currentColumn.params.percentile),
});
const inputValueIsValid = isValidNumber(inputValue, true, 99, 1);

const handleInputChange: EuiRangeProps['onChange'] = useCallback(
(e) => handleInputChangeWithoutValidation(String(e.currentTarget.value)),
[handleInputChangeWithoutValidation]
);

const handleInputChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
const val = String(e.target.value);
setInputValue(val);
}, []);
return (
<EuiFormRow
label={i18n.translate('xpack.lens.indexPattern.percentile.percentileValue', {
defaultMessage: 'Percentile',
})}
data-test-subj="lns-indexPattern-percentile-form"
display="columnCompressed"
display="rowCompressed"
fullWidth
isInvalid={!inputValueIsValid}
error={
Expand All @@ -207,14 +211,18 @@ export const percentileOperation: OperationDefinition<
})
}
>
<EuiFieldNumber
<EuiRange
data-test-subj="lns-indexPattern-percentile-input"
compressed
value={inputValue}
value={inputValue ?? ''}
min={1}
max={99}
step={1}
onChange={handleInputChange}
showInput
aria-label={i18n.translate('xpack.lens.indexPattern.percentile.percentileValue', {
defaultMessage: 'Percentile',
})}
/>
</EuiFormRow>
);
Expand Down
Loading