mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Lens] fix FieldPicker passes the prop to the DOM when it shouldn't (#159930)
## Summary When opening the field picker, the error in the console appears: <img width="837" alt="Screenshot 2023-06-19 at 15 45 39" src="10fbc0e6
-ae59-4c3b-ab94-80dd86805ca6"> That's because we pass `exists` props to the `styledOptions` which are passed to the dom. The thing is we don't need to pass this prop. We assign the classname based on `exists` value at the same level and then do the styling but then don't use it in any level deeper, so no need to pass it. So I removed it to fix this error. fixes errors that show in tests too: <img width="605" alt="Screenshot 2023-06-19 at 20 54 58" src="1583070f
-8e18-4494-9892-585bef584588"> <img width="761" alt="Screenshot 2023-06-19 at 20 55 39" src="23aab03b
-0204-478b-aa01-fab801d02e78"> <img width="730" alt="Screenshot 2023-06-19 at 20 56 49" src="cae606f5
-54a8-4da9-99cf-e5151302acae">
This commit is contained in:
parent
58ec0a486f
commit
2fd8f04abe
4 changed files with 102 additions and 82 deletions
|
@ -44,13 +44,11 @@ export function FieldPicker<T extends FieldOptionValue = FieldOptionValue>({
|
|||
if (otherAttr.options) {
|
||||
return {
|
||||
...otherAttr,
|
||||
compatible,
|
||||
exists,
|
||||
options: otherAttr.options.map((fieldOption) => ({
|
||||
options: otherAttr.options.map(({ exists: fieldOptionExists, ...fieldOption }) => ({
|
||||
...fieldOption,
|
||||
className: classNames({
|
||||
'lnFieldPicker__option--incompatible': !fieldOption.compatible,
|
||||
'lnFieldPicker__option--nonExistant': !fieldOption.exists,
|
||||
'lnFieldPicker__option--nonExistant': !fieldOptionExists,
|
||||
}),
|
||||
})),
|
||||
};
|
||||
|
@ -58,7 +56,6 @@ export function FieldPicker<T extends FieldOptionValue = FieldOptionValue>({
|
|||
return {
|
||||
...otherAttr,
|
||||
compatible,
|
||||
exists,
|
||||
className: classNames({
|
||||
'lnFieldPicker__option--incompatible': !compatible,
|
||||
'lnFieldPicker__option--nonExistant': !exists,
|
||||
|
|
|
@ -547,7 +547,7 @@ describe('FormBasedDimensionEditor', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('should keep the operation when switching to another field compatible with this operation', () => {
|
||||
it('should keep the operation when switching to another field compatible with this operation', async () => {
|
||||
const initialState: FormBasedPrivateState = getStateWithColumns({ col1: bytesColumn });
|
||||
|
||||
wrapper = mountWithServices(
|
||||
|
@ -559,8 +559,8 @@ describe('FormBasedDimensionEditor', () => {
|
|||
.filter('[data-test-subj="indexPattern-dimension-field"]')!;
|
||||
const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'memory')!;
|
||||
|
||||
act(() => {
|
||||
comboBox.prop('onChange')!([option]);
|
||||
await act(async () => {
|
||||
await comboBox.prop('onChange')!([option]);
|
||||
});
|
||||
|
||||
expect(setState.mock.calls[0]).toEqual([
|
||||
|
@ -586,7 +586,7 @@ describe('FormBasedDimensionEditor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should switch operations when selecting a field that requires another operation', () => {
|
||||
it('should switch operations when selecting a field that requires another operation', async () => {
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...defaultProps} />);
|
||||
|
||||
const comboBox = wrapper
|
||||
|
@ -594,8 +594,8 @@ describe('FormBasedDimensionEditor', () => {
|
|||
.filter('[data-test-subj="indexPattern-dimension-field"]')!;
|
||||
const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'source')!;
|
||||
|
||||
act(() => {
|
||||
comboBox.prop('onChange')!([option]);
|
||||
await act(async () => {
|
||||
await comboBox.prop('onChange')!([option]);
|
||||
});
|
||||
|
||||
expect(setState.mock.calls[0]).toEqual([
|
||||
|
@ -797,11 +797,11 @@ describe('FormBasedDimensionEditor', () => {
|
|||
});
|
||||
|
||||
describe('transient invalid state', () => {
|
||||
it('should set the state if selecting an operation incompatible with the current field', () => {
|
||||
it('should set the state if selecting an operation incompatible with the current field', async () => {
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
@ -873,19 +873,16 @@ describe('FormBasedDimensionEditor', () => {
|
|||
expect(wrapper.find('[data-test-subj="indexPattern-invalid-operation"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should leave error state when switching from incomplete state to fieldless operation', () => {
|
||||
it('should leave error state when switching from incomplete state to fieldless operation', async () => {
|
||||
// @ts-expect-error
|
||||
window['__react-beautiful-dnd-disable-dev-warnings'] = true; // issue with enzyme & react-beautiful-dnd throwing errors: https://github.com/atlassian/react-beautiful-dnd/issues/1593
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-filters"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
@ -925,11 +922,11 @@ describe('FormBasedDimensionEditor', () => {
|
|||
expect(wrapper.find('[data-test-subj="indexPattern-invalid-operation"]')).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('should indicate fields compatible with selected operation', () => {
|
||||
it('should indicate fields compatible with selected operation', async () => {
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
@ -949,13 +946,13 @@ describe('FormBasedDimensionEditor', () => {
|
|||
).not.toContain('Incompatible');
|
||||
});
|
||||
|
||||
it('should select compatible operation if field not compatible with selected operation', () => {
|
||||
it('should select compatible operation if field not compatible with selected operation', async () => {
|
||||
wrapper = mountWithServices(
|
||||
<FormBasedDimensionEditorComponent {...defaultProps} columnId={'col2'} />
|
||||
);
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-average"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
@ -964,7 +961,11 @@ describe('FormBasedDimensionEditor', () => {
|
|||
expect.any(Function),
|
||||
{ isDimensionComplete: false },
|
||||
]);
|
||||
expect(setState.mock.calls[0][0](state)).toEqual({
|
||||
let returnedState: FormBasedPrivateState = {} as FormBasedPrivateState;
|
||||
act(() => {
|
||||
returnedState = setState.mock.calls[0][0](state);
|
||||
});
|
||||
expect(returnedState).toEqual({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
|
@ -982,8 +983,8 @@ describe('FormBasedDimensionEditor', () => {
|
|||
const options = comboBox.prop('options');
|
||||
|
||||
// options[1][2] is a `source` field of type `string` which doesn't support `average` operation
|
||||
act(() => {
|
||||
comboBox.prop('onChange')!([options![1].options![2]]);
|
||||
await act(async () => {
|
||||
await comboBox.prop('onChange')!([options![1].options![2]]);
|
||||
});
|
||||
|
||||
expect(setState.mock.calls[1][0](state)).toEqual({
|
||||
|
@ -1042,7 +1043,7 @@ describe('FormBasedDimensionEditor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should select the Records field when count is selected on non-existing column', () => {
|
||||
it('should select the Records field when count is selected on non-existing column', async () => {
|
||||
wrapper = mountWithServices(
|
||||
<FormBasedDimensionEditorComponent
|
||||
{...defaultProps}
|
||||
|
@ -1051,8 +1052,10 @@ describe('FormBasedDimensionEditor', () => {
|
|||
/>
|
||||
);
|
||||
|
||||
act(() => {
|
||||
wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click');
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-count"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
||||
const newColumnState = setState.mock.calls[0][0](state).layers.first.columns.col2;
|
||||
|
@ -1060,7 +1063,7 @@ describe('FormBasedDimensionEditor', () => {
|
|||
expect(newColumnState.sourceField).toEqual('___records___');
|
||||
});
|
||||
|
||||
it('should indicate document and field compatibility with selected document operation', () => {
|
||||
it('should indicate document and field compatibility with selected document operation', async () => {
|
||||
wrapper = mountWithServices(
|
||||
<FormBasedDimensionEditorComponent
|
||||
{...defaultProps}
|
||||
|
@ -1076,20 +1079,17 @@ describe('FormBasedDimensionEditor', () => {
|
|||
columnId="col2"
|
||||
/>
|
||||
);
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]')
|
||||
.simulate('click');
|
||||
const terms = wrapper.find(
|
||||
'button[data-test-subj="lns-indexPatternDimension-terms incompatible"]'
|
||||
);
|
||||
await act(async () => {
|
||||
await terms.simulate('click');
|
||||
});
|
||||
|
||||
const options = wrapper
|
||||
.find(EuiComboBox)
|
||||
.filter('[data-test-subj="indexPattern-dimension-field"]')
|
||||
.prop('options');
|
||||
|
||||
expect(options![0]['data-test-subj']).toContain('Incompatible');
|
||||
|
||||
expect(
|
||||
options![1].options!.filter(({ label }) => label === 'timestampLabel')[0]['data-test-subj']
|
||||
).toContain('Incompatible');
|
||||
|
@ -1098,24 +1098,20 @@ describe('FormBasedDimensionEditor', () => {
|
|||
).not.toContain('Incompatible');
|
||||
});
|
||||
|
||||
it('should set datasource state if compatible field is selected for operation', () => {
|
||||
it('should set datasource state if compatible field is selected for operation', async () => {
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...defaultProps} />);
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-terms incompatible"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
||||
const comboBox = wrapper
|
||||
.find(EuiComboBox)
|
||||
.filter('[data-test-subj="indexPattern-dimension-field"]')!;
|
||||
const option = comboBox.prop('options')![1].options!.find(({ label }) => label === 'source')!;
|
||||
|
||||
act(() => {
|
||||
comboBox.prop('onChange')!([option]);
|
||||
await act(async () => {
|
||||
await comboBox.prop('onChange')!([option]);
|
||||
});
|
||||
|
||||
expect(setState.mock.calls.length).toEqual(2);
|
||||
expect(setState.mock.calls[1]).toEqual([
|
||||
expect.any(Function),
|
||||
|
@ -1471,7 +1467,9 @@ describe('FormBasedDimensionEditor', () => {
|
|||
timeShift: '1d',
|
||||
});
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...props} />);
|
||||
wrapper.find(ReducedTimeRange).find(EuiComboBox).prop('onCreateOption')!('7m', []);
|
||||
act(() => {
|
||||
wrapper.find(ReducedTimeRange).find(EuiComboBox).prop('onCreateOption')!('7m', []);
|
||||
});
|
||||
expect((props.setState as jest.Mock).mock.calls[0][0](props.state)).toEqual({
|
||||
...props.state,
|
||||
layers: {
|
||||
|
@ -1643,7 +1641,9 @@ describe('FormBasedDimensionEditor', () => {
|
|||
timeShift: '1d',
|
||||
});
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...props} />);
|
||||
wrapper.find(TimeShift).find(EuiComboBox).prop('onCreateOption')!('1h', []);
|
||||
act(() => {
|
||||
wrapper.find(TimeShift).find(EuiComboBox).prop('onCreateOption')!('1h', []);
|
||||
});
|
||||
expect((props.setState as jest.Mock).mock.calls[0][0](props.state)).toEqual({
|
||||
...props.state,
|
||||
layers: {
|
||||
|
@ -1856,15 +1856,21 @@ describe('FormBasedDimensionEditor', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it('should support selecting the operation before the field', () => {
|
||||
it('should support selecting the operation before the field', async () => {
|
||||
wrapper = mountWithServices(
|
||||
<FormBasedDimensionEditorComponent {...defaultProps} columnId={'col2'} />
|
||||
);
|
||||
act(() => {
|
||||
wrapper.find('button[data-test-subj="lns-indexPatternDimension-average"]').simulate('click');
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-average"]')
|
||||
.simulate('click');
|
||||
});
|
||||
expect(setState.mock.calls[0]).toEqual([expect.any(Function), { isDimensionComplete: false }]);
|
||||
expect(setState.mock.calls[0][0](defaultProps.state)).toEqual({
|
||||
let returnedState: FormBasedPrivateState = {} as FormBasedPrivateState;
|
||||
act(() => {
|
||||
returnedState = setState.mock.calls[0][0](defaultProps.state);
|
||||
});
|
||||
expect(returnedState).toEqual({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
|
@ -1883,8 +1889,8 @@ describe('FormBasedDimensionEditor', () => {
|
|||
.filter('[data-test-subj="indexPattern-dimension-field"]');
|
||||
const options = comboBox.prop('options');
|
||||
|
||||
act(() => {
|
||||
comboBox.prop('onChange')!([options![1].options![0]]);
|
||||
await act(async () => {
|
||||
await comboBox.prop('onChange')!([options![1].options![0]]);
|
||||
});
|
||||
|
||||
expect(setState.mock.calls[1][0](defaultProps.state)).toEqual({
|
||||
|
@ -1906,7 +1912,7 @@ describe('FormBasedDimensionEditor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should select operation directly if only one field is possible', () => {
|
||||
it('should select operation directly if only one field is possible', async () => {
|
||||
wrapper = mountWithServices(
|
||||
<FormBasedDimensionEditorComponent
|
||||
{...defaultProps}
|
||||
|
@ -1921,11 +1927,17 @@ describe('FormBasedDimensionEditor', () => {
|
|||
}}
|
||||
/>
|
||||
);
|
||||
act(() => {
|
||||
wrapper.find('button[data-test-subj="lns-indexPatternDimension-average"]').simulate('click');
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-average"]')
|
||||
.simulate('click');
|
||||
});
|
||||
expect(setState.mock.calls[0]).toEqual([expect.any(Function), { isDimensionComplete: true }]);
|
||||
expect(setState.mock.calls[0][0](state)).toEqual({
|
||||
let returnedState: FormBasedPrivateState = {} as FormBasedPrivateState;
|
||||
act(() => {
|
||||
returnedState = setState.mock.calls[0][0](state);
|
||||
});
|
||||
expect(returnedState).toEqual({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
|
@ -1944,15 +1956,21 @@ describe('FormBasedDimensionEditor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should select operation directly if only document is possible', () => {
|
||||
it('should select operation directly if only document is possible', async () => {
|
||||
wrapper = mountWithServices(
|
||||
<FormBasedDimensionEditorComponent {...defaultProps} columnId={'col2'} />
|
||||
);
|
||||
act(() => {
|
||||
wrapper.find('button[data-test-subj="lns-indexPatternDimension-count"]').simulate('click');
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-count"]')
|
||||
.simulate('click');
|
||||
});
|
||||
expect(setState.mock.calls[0]).toEqual([expect.any(Function), { isDimensionComplete: true }]);
|
||||
expect(setState.mock.calls[0][0](state)).toEqual({
|
||||
let returnedState: FormBasedPrivateState = {} as FormBasedPrivateState;
|
||||
act(() => {
|
||||
returnedState = setState.mock.calls[0][0](state);
|
||||
});
|
||||
expect(returnedState).toEqual({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
|
@ -2022,7 +2040,7 @@ describe('FormBasedDimensionEditor', () => {
|
|||
expect(options![0]['data-test-subj']).not.toContain('Incompatible');
|
||||
});
|
||||
|
||||
it('should not update when selecting the current field again', () => {
|
||||
it('should not update when selecting the current field again', async () => {
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...defaultProps} />);
|
||||
|
||||
const comboBox = wrapper
|
||||
|
@ -2033,8 +2051,8 @@ describe('FormBasedDimensionEditor', () => {
|
|||
.prop('options')![1]
|
||||
.options!.find(({ label }) => label === 'timestampLabel')!;
|
||||
|
||||
act(() => {
|
||||
comboBox.prop('onChange')!([option]);
|
||||
await act(async () => {
|
||||
await comboBox.prop('onChange')!([option]);
|
||||
});
|
||||
|
||||
expect(setState).not.toHaveBeenCalled();
|
||||
|
@ -2070,7 +2088,7 @@ describe('FormBasedDimensionEditor', () => {
|
|||
]);
|
||||
});
|
||||
|
||||
it('should add a column on selection of a field', () => {
|
||||
it('should add a column on selection of a field', async () => {
|
||||
// Prevents field format from being loaded
|
||||
setState.mockImplementation(() => {});
|
||||
|
||||
|
@ -2083,15 +2101,20 @@ describe('FormBasedDimensionEditor', () => {
|
|||
.filter('[data-test-subj="indexPattern-dimension-field"]')!;
|
||||
const option = comboBox.prop('options')![1].options![0];
|
||||
|
||||
act(() => {
|
||||
comboBox.prop('onChange')!([option]);
|
||||
await act(async () => {
|
||||
await comboBox.prop('onChange')!([option]);
|
||||
});
|
||||
|
||||
expect(setState.mock.calls[0]).toEqual([
|
||||
expect.any(Function),
|
||||
{ isDimensionComplete: true, forceRender: false },
|
||||
]);
|
||||
expect(setState.mock.calls[0][0](defaultProps.state)).toEqual({
|
||||
let returnedState: FormBasedPrivateState | null = null;
|
||||
act(() => {
|
||||
returnedState = setState.mock.calls[0][0](defaultProps.state);
|
||||
});
|
||||
|
||||
expect(returnedState).toEqual({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
|
@ -2273,14 +2296,14 @@ describe('FormBasedDimensionEditor', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should hide the top level field selector when switching from non-reference to reference', () => {
|
||||
it('should hide the top level field selector when switching from non-reference to reference', async () => {
|
||||
(generateId as jest.Mock).mockReturnValue(`second`);
|
||||
wrapper = mountWithServices(<FormBasedDimensionEditorComponent {...defaultProps} />);
|
||||
|
||||
expect(wrapper.find('ReferenceEditor')).toHaveLength(0);
|
||||
|
||||
act(() => {
|
||||
wrapper
|
||||
await act(async () => {
|
||||
await wrapper
|
||||
.find('button[data-test-subj="lns-indexPatternDimension-differences incompatible"]')
|
||||
.simulate('click');
|
||||
});
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import React, { Fragment } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import type { IndexPattern, IndexPatternField } from '../../../../types';
|
||||
import {
|
||||
|
@ -103,10 +103,10 @@ export const generateMissingFieldMessage = (
|
|||
missingFields: (
|
||||
<>
|
||||
{missingFields.map((field, index) => (
|
||||
<>
|
||||
<Fragment key={field}>
|
||||
<strong>{field}</strong>
|
||||
{index + 1 === missingFields.length ? '' : ', '}
|
||||
</>
|
||||
</Fragment>
|
||||
))}
|
||||
</>
|
||||
),
|
||||
|
|
|
@ -267,8 +267,8 @@ describe('LayerPanel', () => {
|
|||
dimensionsTooMany: 1,
|
||||
},
|
||||
{
|
||||
groupLabel: 'A',
|
||||
groupId: 'a',
|
||||
groupLabel: 'C',
|
||||
groupId: 'c',
|
||||
accessors: [{ columnId: 'x' }],
|
||||
filterOperations: () => true,
|
||||
supportsMoreColumns: false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue