diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.test.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.test.tsx index 56163d4079f8d..9ff6297c28368 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.test.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.test.tsx @@ -7,9 +7,9 @@ import { shallow } from 'enzyme'; import React, { ChangeEvent, ReactElement } from 'react'; import { EuiComboBox, EuiFieldSearch, EuiContextMenuPanel } from '@elastic/eui'; -import { IndexPatternPrivateState } from './indexpattern'; +import { IndexPatternPrivateState, IndexPatternColumn } from './indexpattern'; import { createMockedDragDropContext } from './mocks'; -import { InnerIndexPatternDataPanel } from './datapanel'; +import { InnerIndexPatternDataPanel, IndexPatternDataPanel, MemoizedDataPanel } from './datapanel'; import { FieldItem } from './field_item'; import { act } from 'react-dom/test-utils'; @@ -205,6 +205,84 @@ describe('IndexPattern Data Panel', () => { }; }); + it('should update index pattern of layer on switch if it is a single empty one', async () => { + const setStateSpy = jest.fn(); + const wrapper = shallow( + {} }} + /> + ); + + act(() => { + wrapper.find(MemoizedDataPanel).prop('setShowIndexPatternSwitcher')!(true); + }); + wrapper.find(MemoizedDataPanel).prop('onChangeIndexPattern')!('2'); + + expect(setStateSpy).toHaveBeenCalledWith({ + ...initialState, + layers: { first: { indexPatternId: '2', columnOrder: [], columns: {} } }, + currentIndexPatternId: '2', + }); + }); + + it('should not update index pattern of layer on switch if there are more than one', async () => { + const setStateSpy = jest.fn(); + const state = { + ...initialState, + layers: { + first: { indexPatternId: '1', columnOrder: [], columns: {} }, + second: { indexPatternId: '1', columnOrder: [], columns: {} }, + }, + }; + const wrapper = shallow( + {} }} + /> + ); + + act(() => { + wrapper.find(MemoizedDataPanel).prop('setShowIndexPatternSwitcher')!(true); + }); + wrapper.find(MemoizedDataPanel).prop('onChangeIndexPattern')!('2'); + + expect(setStateSpy).toHaveBeenCalledWith({ ...state, currentIndexPatternId: '2' }); + }); + + it('should not update index pattern of layer on switch if there are columns configured', async () => { + const setStateSpy = jest.fn(); + const state = { + ...initialState, + layers: { + first: { + indexPatternId: '1', + columnOrder: ['col1'], + columns: { col1: {} as IndexPatternColumn }, + }, + }, + }; + const wrapper = shallow( + {} }} + /> + ); + + act(() => { + wrapper.find(MemoizedDataPanel).prop('setShowIndexPatternSwitcher')!(true); + }); + wrapper.find(MemoizedDataPanel).prop('onChangeIndexPattern')!('2'); + + expect(setStateSpy).toHaveBeenCalledWith({ ...state, currentIndexPatternId: '2' }); + }); + it('should render a warning if there are no index patterns', () => { const wrapper = shallow( diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx index ccc8ff6f83cec..74c19ad2cf0e3 100644 --- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx +++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; +import { mapValues, uniq } from 'lodash'; import React, { useState, useEffect, memo, useCallback } from 'react'; import { EuiComboBox, @@ -30,6 +30,7 @@ import { IndexPatternPrivateState, IndexPatternField, IndexPattern } from './ind import { ChildDragDropProvider, DragContextState } from '../drag_drop'; import { FieldItem } from './field_item'; import { FieldIcon } from './field_icon'; +import { updateLayerIndexPattern } from './state_helpers'; // TODO the typings for EuiContextMenuPanel are incorrect - watchedItemProps is missing. This can be removed when the types are adjusted const FixedEuiContextMenuPanel = (EuiContextMenuPanel as unknown) as React.FunctionComponent< @@ -50,6 +51,11 @@ const fieldTypeNames: Record = { date: i18n.translate('xpack.lens.datatypes.date', { defaultMessage: 'date' }), }; +function isSingleEmptyLayer(layerMap: IndexPatternPrivateState['layers']) { + const layers = Object.values(layerMap); + return layers.length === 1 && layers[0].columnOrder.length === 0; +} + export function IndexPatternDataPanel({ setState, state, @@ -62,6 +68,11 @@ export function IndexPatternDataPanel({ (newIndexPattern: string) => { setState({ ...state, + layers: isSingleEmptyLayer(state.layers) + ? mapValues(state.layers, layer => + updateLayerIndexPattern(layer, indexPatterns[newIndexPattern]) + ) + : state.layers, currentIndexPatternId: newIndexPattern, }); }, @@ -160,7 +171,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ ) .slice(0, pageSize); - const availableFieldTypes = _.uniq(filteredFields.map(({ type }) => type)); + const availableFieldTypes = uniq(filteredFields.map(({ type }) => type)); const availableFilteredTypes = state.typeFilter.filter(type => availableFieldTypes.includes(type) );