Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
220eefa
[lens] WIP add support for layers
wylieconlon Jul 12, 2019
26601aa
[lens] WIP switch to nested tables
wylieconlon Jul 15, 2019
152bee3
Merge remote-tracking branch 'origin/feature/lens' into lens/layers-t…
wylieconlon Jul 15, 2019
84bf126
Get basic layering to work
wylieconlon Jul 16, 2019
63fb14b
Load multiple tables and render in one chart
wylieconlon Jul 16, 2019
5e60930
Merge remote-tracking branch 'origin/feature/lens' into lens/layers-t…
wylieconlon Jul 16, 2019
4aa80f2
Fix priority ordering
wylieconlon Jul 16, 2019
8be851e
Merge remote-tracking branch 'origin/feature/lens' into lens/layers-t…
wylieconlon Jul 17, 2019
f78ce1a
Reduce quantity of linting errors
wylieconlon Jul 17, 2019
3c56d84
Merge branch 'lens/layers-toplevel' of https://github.com/wylieconlon…
chrisdavies Jul 18, 2019
6b2454b
Ensure that new xy layer state has a split column
chrisdavies Jul 18, 2019
94c97d7
Make the "add" y / split the trailing accessor
chrisdavies Jul 18, 2019
cbea4e8
Various fixes for datasource public API and implementation
wylieconlon Jul 18, 2019
762bd44
Unify datasource deletion and accessor removal
chrisdavies Jul 18, 2019
6229db6
Merge branch 'lens/layers-toplevel' of https://github.com/wylieconlon…
chrisdavies Jul 18, 2019
5001bf2
Fix broken scss
chrisdavies Jul 18, 2019
e111fdc
Fix xy visualization TypeScript errors?
chrisdavies Jul 18, 2019
dcc243f
Build basic suggestions
wylieconlon Jul 18, 2019
d9e101a
Restore save/load and fix typescript bugs
flash1293 Jul 19, 2019
5d533c0
Merge branch 'lens/layers-toplevel' of github.com:wylieconlon/kibana …
flash1293 Jul 19, 2019
e35bc9f
simplify init routine
flash1293 Jul 19, 2019
cd90a9d
fix save tests
flash1293 Jul 19, 2019
9fac490
fix persistence tests
flash1293 Jul 19, 2019
5b997af
fix state management tests
flash1293 Jul 19, 2019
26bc89c
Ensure the data table is aligned to the top
chrisdavies Jul 19, 2019
cbcb341
Add layer support to Lens datatable
chrisdavies Jul 19, 2019
91c6881
Give xy chart a default layer initially
chrisdavies Jul 19, 2019
e263e4c
Allow deletion of layers in xy charts
chrisdavies Jul 19, 2019
a642a11
xy: Make split accessor singular
chrisdavies Jul 19, 2019
844be81
Change expression type for lens_merge_tables
wylieconlon Jul 19, 2019
142bca2
Fix XY chart rendering expression
wylieconlon Jul 19, 2019
c10b6a1
Fix type errors relating to `layerId` in table suggestions
wylieconlon Jul 19, 2019
542557c
Pass around tables for suggestions with associated layerIds
wylieconlon Jul 19, 2019
c659084
fix tests in workspace panel
flash1293 Jul 22, 2019
42302d6
fix editor_frame tests
flash1293 Jul 22, 2019
64b2f58
Fix xy tests, skip inapplicable tests
chrisdavies Jul 22, 2019
f634f51
add some tests for multiple datasources and layers
flash1293 Jul 22, 2019
aaa320d
Merge branch 'lens/layers-toplevel' of github.com:wylieconlon/kibana …
chrisdavies Jul 22, 2019
9fb5e9d
Suggest that split series comes before X axis in XY chart
wylieconlon Jul 22, 2019
19d9a50
Get datatable suggestion working
chrisdavies Jul 22, 2019
ddab6e4
Adjust how xy axis labels are computed
chrisdavies Jul 22, 2019
c368a28
Merge branch 'lens/layers-toplevel' of github.com:wylieconlon/kibana …
chrisdavies Jul 22, 2019
3f25c93
Datasource suggestions should handle layers and have tests
wylieconlon Jul 22, 2019
0ac2c31
Fix linting in XY chart and remove commented code
wylieconlon Jul 22, 2019
61f232b
Update snapshots from earlier change
wylieconlon Jul 22, 2019
f15228a
Merge branch 'feature/lens' into lens/layers-toplevel
wylieconlon Jul 22, 2019
5decb43
started not materializing columns until necessary
flash1293 Jul 23, 2019
6610049
continued performance improvement
flash1293 Jul 23, 2019
0134bb9
continued performance improvement #2
flash1293 Jul 23, 2019
68603f6
fix linting errors and make dimension panel work again
flash1293 Jul 23, 2019
9f59ecc
improve performance by not re-rendering everything
flash1293 Jul 23, 2019
e7d50f5
Merge remote-tracking branch 'upstream/feature/lens' into lens/potent…
flash1293 Jul 25, 2019
d6eec66
Merge branch 'lens/potential-columns-improvements' of github.com:flas…
flash1293 Jul 25, 2019
57ab321
resolve conflicts
flash1293 Jul 25, 2019
ebb2485
fix tests and improve implementation
flash1293 Jul 25, 2019
2e4513f
fix bug with document showing as incompatible
flash1293 Jul 25, 2019
af76488
fix tests
flash1293 Jul 25, 2019
146297b
rename stuff
flash1293 Jul 25, 2019
bcf1f43
fix types
flash1293 Jul 25, 2019
a89e854
shortened code
flash1293 Jul 25, 2019
c60b3c6
Merge remote-tracking branch 'upstream/feature/lens' into lens/potent…
flash1293 Jul 25, 2019
365f98c
fix type bugs and clean up
flash1293 Jul 26, 2019
986bce4
Merge branch 'feature/lens' into lens/potential-columns-improvements
flash1293 Jul 26, 2019
84ff252
Merge branch 'feature/lens' into lens/potential-columns-improvements
flash1293 Jul 26, 2019
1aec574
make filterOperations function memoizable in datatable vis
flash1293 Jul 26, 2019
0de364e
Merge branch 'feature/lens' into lens/potential-columns-improvements
flash1293 Jul 29, 2019
01a955a
code style
flash1293 Jul 29, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,6 @@ describe('Datatable Visualization', () => {
dataType: 'string',
isBucketed: true,
label: '',
id: '',
};
expect(filterOperations({ ...baseOperation })).toEqual(true);
expect(filterOperations({ ...baseOperation, dataType: 'number' })).toEqual(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ function updateColumns(
return { ...state, layers };
}

const allOperations = () => true;

export function DataTableLayer({
layer,
frame,
Expand All @@ -68,7 +70,7 @@ export function DataTableLayer({
accessors={layer.columns}
datasource={datasource}
dragDropContext={dragDropContext}
filterOperations={() => true}
filterOperations={allOperations}
layerId={layer.layerId}
onAdd={() =>
setState(updateColumns(state, layer, columns => [...columns, generateId()]))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,12 @@

const actual = jest.requireActual('../operations');

jest.spyOn(actual, 'getPotentialColumns');
jest.spyOn(actual.operationDefinitionMap.date_histogram, 'paramEditor');
jest.spyOn(actual.operationDefinitionMap.terms, 'onOtherColumnChanged');

export const {
getPotentialColumns,
getColumnOrder,
getAvailableOperationsByMetadata,
buildColumn,
getOperations,
getOperationDisplay,
getOperationTypesForField,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ import { shallow } from 'enzyme';
import React, { ChangeEvent, ReactElement } from 'react';
import { EuiComboBox, EuiFieldSearch, EuiContextMenuPanel } from '@elastic/eui';
import { IndexPatternPrivateState } from './indexpattern';
import { DatasourceDataPanelProps } from '../types';
import { createMockedDragDropContext } from './mocks';
import { IndexPatternDataPanel } from './datapanel';
import { InnerIndexPatternDataPanel } from './datapanel';
import { FieldItem } from './field_item';
import { act } from 'react-dom/test-utils';

Expand All @@ -24,7 +23,6 @@ const initialState: IndexPatternPrivateState = {
columnOrder: ['col1'],
columns: {
col1: {
operationId: 'op1',
label: 'My Op',
dataType: 'string',
isBucketed: true,
Expand Down Expand Up @@ -139,31 +137,35 @@ const initialState: IndexPatternPrivateState = {
},
};
describe('IndexPattern Data Panel', () => {
let defaultProps: DatasourceDataPanelProps<IndexPatternPrivateState>;
let defaultProps: Parameters<typeof InnerIndexPatternDataPanel>[0];

beforeEach(() => {
defaultProps = {
state: initialState,
setState: jest.fn(),
dragDropContext: createMockedDragDropContext(),
currentIndexPatternId: '1',
indexPatterns: initialState.indexPatterns,
showIndexPatternSwitcher: false,
setShowIndexPatternSwitcher: jest.fn(),
onChangeIndexPattern: jest.fn(),
};
});

it('should render a warning if there are no index patterns', () => {
const wrapper = shallow(
<IndexPatternDataPanel
{...defaultProps}
state={{ ...initialState, currentIndexPatternId: '', indexPatterns: {} }}
/>
<InnerIndexPatternDataPanel {...defaultProps} currentIndexPatternId="" indexPatterns={{}} />
);
expect(wrapper.find('[data-test-subj="indexPattern-no-indexpatterns"]')).toHaveLength(1);
});

it('should call setState when the index pattern is switched', async () => {
const wrapper = shallow(<IndexPatternDataPanel {...defaultProps} />);
const wrapper = shallow(<InnerIndexPatternDataPanel {...defaultProps} />);

wrapper.find('[data-test-subj="indexPattern-switch-link"]').simulate('click');

expect(defaultProps.setShowIndexPatternSwitcher).toHaveBeenCalledWith(true);

wrapper.setProps({ showIndexPatternSwitcher: true });

const comboBox = wrapper.find(EuiComboBox);

comboBox.prop('onChange')!([
Expand All @@ -173,14 +175,11 @@ describe('IndexPattern Data Panel', () => {
},
]);

expect(defaultProps.setState).toHaveBeenCalledWith({
...initialState,
currentIndexPatternId: '2',
});
expect(defaultProps.onChangeIndexPattern).toHaveBeenCalledWith('2');
});

it('should list all supported fields in the pattern sorted alphabetically', async () => {
const wrapper = shallow(<IndexPatternDataPanel {...defaultProps} />);
const wrapper = shallow(<InnerIndexPatternDataPanel {...defaultProps} />);

expect(wrapper.find(FieldItem).map(fieldItem => fieldItem.prop('field').name)).toEqual([
'bytes',
Expand All @@ -191,7 +190,7 @@ describe('IndexPattern Data Panel', () => {
});

it('should filter down by name', async () => {
const wrapper = shallow(<IndexPatternDataPanel {...defaultProps} />);
const wrapper = shallow(<InnerIndexPatternDataPanel {...defaultProps} />);

act(() => {
wrapper.find(EuiFieldSearch).prop('onChange')!({ target: { value: 'mem' } } as ChangeEvent<
Expand All @@ -205,7 +204,7 @@ describe('IndexPattern Data Panel', () => {
});

it('should filter down by type', async () => {
const wrapper = shallow(<IndexPatternDataPanel {...defaultProps} />);
const wrapper = shallow(<InnerIndexPatternDataPanel {...defaultProps} />);

act(() => {
(wrapper
Expand All @@ -223,7 +222,7 @@ describe('IndexPattern Data Panel', () => {
});

it('should toggle type if clicked again', async () => {
const wrapper = shallow(<IndexPatternDataPanel {...defaultProps} />);
const wrapper = shallow(<InnerIndexPatternDataPanel {...defaultProps} />);

act(() => {
(wrapper
Expand Down Expand Up @@ -252,7 +251,7 @@ describe('IndexPattern Data Panel', () => {
});

it('should filter down by type and by name', async () => {
const wrapper = shallow(<IndexPatternDataPanel {...defaultProps} />);
const wrapper = shallow(<InnerIndexPatternDataPanel {...defaultProps} />);

act(() => {
wrapper.find(EuiFieldSearch).prop('onChange')!({ target: { value: 'mem' } } as ChangeEvent<
Expand Down
92 changes: 68 additions & 24 deletions x-pack/legacy/plugins/lens/public/indexpattern_plugin/datapanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

import _ from 'lodash';
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, memo, useCallback } from 'react';
import {
EuiComboBox,
EuiFieldSearch,
Expand All @@ -26,8 +26,8 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { DatasourceDataPanelProps, DataType } from '../types';
import { IndexPatternPrivateState, IndexPatternField } from './indexpattern';
import { ChildDragDropProvider } from '../drag_drop';
import { IndexPatternPrivateState, IndexPatternField, IndexPattern } from './indexpattern';
import { ChildDragDropProvider, DragContextState } from '../drag_drop';
import { FieldItem } from './field_item';
import { FieldIcon } from './field_icon';

Expand All @@ -50,11 +50,55 @@ const fieldTypeNames: Record<DataType, string> = {
date: i18n.translate('xpack.lens.datatypes.date', { defaultMessage: 'date' }),
};

export function IndexPatternDataPanel(props: DatasourceDataPanelProps<IndexPatternPrivateState>) {
export function IndexPatternDataPanel({
setState,
state,
dragDropContext,
}: DatasourceDataPanelProps<IndexPatternPrivateState>) {
const { indexPatterns, currentIndexPatternId } = state;
const [showIndexPatternSwitcher, setShowIndexPatternSwitcher] = useState(false);

const onChangeIndexPattern = useCallback(
(newIndexPattern: string) => {
setState({
...state,
currentIndexPatternId: newIndexPattern,
});
},
[state, setState]
);

return (
<MemoizedDataPanel
showIndexPatternSwitcher={showIndexPatternSwitcher}
setShowIndexPatternSwitcher={setShowIndexPatternSwitcher}
currentIndexPatternId={currentIndexPatternId}
indexPatterns={indexPatterns}
dragDropContext={dragDropContext}
// only pass in the state change callback if it's actually needed to avoid re-renders
onChangeIndexPattern={showIndexPatternSwitcher ? onChangeIndexPattern : undefined}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine, but I wonder if we should move from a setState kind of approach to a dispatch kind of approach, for this reason. dispatch-helpers can be easily memoized as they don't need to close over the state object.

/>
);
}

export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({
currentIndexPatternId,
indexPatterns,
dragDropContext,
showIndexPatternSwitcher,
setShowIndexPatternSwitcher,
onChangeIndexPattern,
}: {
currentIndexPatternId: string;
indexPatterns: Record<string, IndexPattern>;
dragDropContext: DragContextState;
showIndexPatternSwitcher: boolean;
setShowIndexPatternSwitcher: (show: boolean) => void;
onChangeIndexPattern?: (newId: string) => void;
}) {
const [state, setState] = useState({
nameFilter: '',
typeFilter: [] as DataType[],
showIndexPatternSwitcher: false,
isTypeFilterOpen: false,
});
const [pageSize, setPageSize] = useState(PAGINATION_SIZE);
Expand All @@ -76,9 +120,9 @@ export function IndexPatternDataPanel(props: DatasourceDataPanelProps<IndexPatte
setPageSize(PAGINATION_SIZE);
lazyScroll();
}
}, [state.nameFilter, state.typeFilter, props.state.currentIndexPatternId]);
}, [state.nameFilter, state.typeFilter, currentIndexPatternId]);

if (Object.keys(props.state.indexPatterns).length === 0) {
if (Object.keys(indexPatterns).length === 0) {
return (
<EuiFlexGroup gutterSize="s" className="lnsIndexPatternDataPanel" direction="column">
<EuiFlexItem grow={null}>
Expand All @@ -102,7 +146,7 @@ export function IndexPatternDataPanel(props: DatasourceDataPanelProps<IndexPatte
);
}

const allFields = props.state.indexPatterns[props.state.currentIndexPatternId].fields;
const allFields = indexPatterns[currentIndexPatternId].fields;
const filteredFields = allFields
.filter(
(field: IndexPatternField) =>
Expand All @@ -117,24 +161,24 @@ export function IndexPatternDataPanel(props: DatasourceDataPanelProps<IndexPatte
);

return (
<ChildDragDropProvider {...props.dragDropContext}>
<ChildDragDropProvider {...dragDropContext}>
<EuiFlexGroup gutterSize="s" className="lnsIndexPatternDataPanel" direction="column">
<EuiFlexItem grow={null}>
<div className="lnsIndexPatternDataPanel__header">
{!state.showIndexPatternSwitcher ? (
{!showIndexPatternSwitcher ? (
<>
<EuiTitle size="xxs">
<h4
className="lnsIndexPatternDataPanel__header"
title={props.state.indexPatterns[props.state.currentIndexPatternId].title}
title={indexPatterns[currentIndexPatternId].title}
>
{props.state.indexPatterns[props.state.currentIndexPatternId].title}{' '}
{indexPatterns[currentIndexPatternId].title}{' '}
</h4>
</EuiTitle>
<EuiButtonEmpty
data-test-subj="indexPattern-switch-link"
className="lnsIndexPatternDataPanel__changeLink"
onClick={() => setState({ ...state, showIndexPatternSwitcher: true })}
onClick={() => setShowIndexPatternSwitcher(true)}
size="xs"
>
(
Expand All @@ -148,7 +192,7 @@ export function IndexPatternDataPanel(props: DatasourceDataPanelProps<IndexPatte
) : (
<EuiComboBox
data-test-subj="indexPattern-switcher"
options={Object.values(props.state.indexPatterns).map(({ title, id }) => ({
options={Object.values(indexPatterns).map(({ title, id }) => ({
label: title,
value: id,
}))}
Expand All @@ -158,32 +202,30 @@ export function IndexPatternDataPanel(props: DatasourceDataPanelProps<IndexPatte
}
}}
selectedOptions={
props.state.currentIndexPatternId
currentIndexPatternId
? [
{
label: props.state.indexPatterns[props.state.currentIndexPatternId].title,
value: props.state.indexPatterns[props.state.currentIndexPatternId].id,
label: indexPatterns[currentIndexPatternId].title,
value: indexPatterns[currentIndexPatternId].id,
},
]
: undefined
}
singleSelection={{ asPlainText: true }}
isClearable={false}
onBlur={() => {
setState({ ...state, showIndexPatternSwitcher: false });
setShowIndexPatternSwitcher(false);
}}
onChange={choices => {
props.setState({
...props.state,
currentIndexPatternId: choices[0].value as string,
});
onChangeIndexPattern!(choices[0].value as string);

setState({
...state,
showIndexPatternSwitcher: false,
nameFilter: '',
typeFilter: [],
});

setShowIndexPatternSwitcher(false);
}}
/>
)}
Expand Down Expand Up @@ -288,4 +330,6 @@ export function IndexPatternDataPanel(props: DatasourceDataPanelProps<IndexPatte
</EuiFlexGroup>
</ChildDragDropProvider>
);
}
};

const MemoizedDataPanel = memo(InnerIndexPatternDataPanel);
Loading