Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
0c872a70a3
commit
0f77d66489
15 changed files with 808 additions and 998 deletions
|
@ -107,7 +107,15 @@ export function DimensionEditor(props: DimensionEditorProps) {
|
|||
layerId,
|
||||
currentIndexPattern,
|
||||
hideGrouping,
|
||||
dateRange,
|
||||
} = props;
|
||||
const services = {
|
||||
data: props.data,
|
||||
uiSettings: props.uiSettings,
|
||||
savedObjectsClient: props.savedObjectsClient,
|
||||
http: props.http,
|
||||
storage: props.storage,
|
||||
};
|
||||
const { fieldByOperation, operationWithoutField } = operationSupportMatrix;
|
||||
|
||||
const setStateWrapper = (layer: IndexPatternLayer) => {
|
||||
|
@ -346,17 +354,13 @@ export function DimensionEditor(props: DimensionEditorProps) {
|
|||
{!currentFieldIsInvalid && !incompleteInfo && selectedColumn && ParamEditor && (
|
||||
<>
|
||||
<ParamEditor
|
||||
state={state}
|
||||
setState={setState}
|
||||
layer={state.layers[layerId]}
|
||||
updateLayer={setStateWrapper}
|
||||
columnId={columnId}
|
||||
currentColumn={state.layers[layerId].columns[columnId]}
|
||||
storage={props.storage}
|
||||
uiSettings={props.uiSettings}
|
||||
savedObjectsClient={props.savedObjectsClient}
|
||||
layerId={layerId}
|
||||
http={props.http}
|
||||
dateRange={props.dateRange}
|
||||
data={props.data}
|
||||
dateRange={dateRange}
|
||||
indexPattern={currentIndexPattern}
|
||||
{...services}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
@ -407,12 +411,15 @@ export function DimensionEditor(props: DimensionEditorProps) {
|
|||
selectedColumn={selectedColumn}
|
||||
onChange={(newFormat) => {
|
||||
setState(
|
||||
updateColumnParam({
|
||||
mergeLayer({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn: selectedColumn,
|
||||
paramName: 'format',
|
||||
value: newFormat,
|
||||
newLayer: updateColumnParam({
|
||||
layer: state.layers[layerId],
|
||||
columnId,
|
||||
paramName: 'format',
|
||||
value: newFormat,
|
||||
}),
|
||||
})
|
||||
);
|
||||
}}
|
||||
|
|
|
@ -111,10 +111,10 @@ export const movingAverageOperation: OperationDefinition<
|
|||
};
|
||||
|
||||
function MovingAverageParamEditor({
|
||||
state,
|
||||
setState,
|
||||
layer,
|
||||
updateLayer,
|
||||
currentColumn,
|
||||
layerId,
|
||||
columnId,
|
||||
}: ParamEditorProps<MovingAverageIndexPatternColumn>) {
|
||||
const [inputValue, setInputValue] = useState(String(currentColumn.params.window));
|
||||
|
||||
|
@ -124,11 +124,10 @@ function MovingAverageParamEditor({
|
|||
return;
|
||||
}
|
||||
const inputNumber = Number(inputValue);
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'window',
|
||||
value: inputNumber,
|
||||
})
|
||||
|
|
|
@ -5,19 +5,19 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { DateHistogramIndexPatternColumn } from './date_histogram';
|
||||
import type { DateHistogramIndexPatternColumn } from './date_histogram';
|
||||
import { dateHistogramOperation } from './index';
|
||||
import { shallow } from 'enzyme';
|
||||
import { EuiSwitch, EuiSwitchEvent } from '@elastic/eui';
|
||||
import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
|
||||
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
|
||||
import type { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import { UI_SETTINGS } from '../../../../../../../src/plugins/data/public';
|
||||
import {
|
||||
dataPluginMock,
|
||||
getCalculateAutoTimeExpression,
|
||||
} from '../../../../../../../src/plugins/data/public/mocks';
|
||||
import { createMockedIndexPattern } from '../../mocks';
|
||||
import { IndexPatternPrivateState } from '../../types';
|
||||
import type { IndexPatternLayer, IndexPattern } from '../../types';
|
||||
import { getFieldByNameFactory } from '../../pure_helpers';
|
||||
|
||||
const dataStart = dataPluginMock.createStartContract();
|
||||
|
@ -29,6 +29,60 @@ dataStart.search.aggs.calculateAutoTimeExpression = getCalculateAutoTimeExpressi
|
|||
}
|
||||
);
|
||||
|
||||
const indexPattern1: IndexPattern = {
|
||||
id: '1',
|
||||
title: 'Mock Indexpattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
displayName: 'timestampLabel',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
],
|
||||
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{
|
||||
name: 'timestamp',
|
||||
displayName: 'timestampLabel',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
]),
|
||||
};
|
||||
|
||||
const indexPattern2: IndexPattern = {
|
||||
id: '2',
|
||||
title: 'Mock Indexpattern 2',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'other_timestamp',
|
||||
displayName: 'other_timestamp',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
],
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{
|
||||
name: 'other_timestamp',
|
||||
displayName: 'other_timestamp',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
]),
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
storage: {} as IStorageWrapper,
|
||||
uiSettings: {} as IUiSettingsClient,
|
||||
|
@ -39,150 +93,47 @@ const defaultOptions = {
|
|||
},
|
||||
data: dataStart,
|
||||
http: {} as HttpSetup,
|
||||
indexPattern: indexPattern1,
|
||||
};
|
||||
|
||||
describe('date_histogram', () => {
|
||||
let state: IndexPatternPrivateState;
|
||||
let layer: IndexPatternLayer;
|
||||
const InlineOptions = dateHistogramOperation.paramEditor!;
|
||||
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
indexPatternRefs: [],
|
||||
existingFields: {},
|
||||
currentIndexPatternId: '1',
|
||||
isFirstExistenceFetch: false,
|
||||
indexPatterns: {
|
||||
1: {
|
||||
id: '1',
|
||||
title: 'Mock Indexpattern',
|
||||
timeFieldName: 'timestamp',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
displayName: 'timestampLabel',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
],
|
||||
layer = {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Value of timestamp',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{
|
||||
name: 'timestamp',
|
||||
displayName: 'timestampLabel',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
]),
|
||||
},
|
||||
2: {
|
||||
id: '2',
|
||||
title: 'Mock Indexpattern 2',
|
||||
hasRestrictions: false,
|
||||
fields: [
|
||||
{
|
||||
name: 'other_timestamp',
|
||||
displayName: 'other_timestamp',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
],
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{
|
||||
name: 'other_timestamp',
|
||||
displayName: 'other_timestamp',
|
||||
type: 'date',
|
||||
esTypes: ['date'],
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
layers: {
|
||||
first: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Value of timestamp',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
// Private
|
||||
operationType: 'date_histogram',
|
||||
params: {
|
||||
interval: '42w',
|
||||
},
|
||||
sourceField: 'timestamp',
|
||||
},
|
||||
},
|
||||
},
|
||||
second: {
|
||||
indexPatternId: '2',
|
||||
columnOrder: ['col2'],
|
||||
columns: {
|
||||
col2: {
|
||||
label: 'Value of timestamp',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
// Private
|
||||
operationType: 'date_histogram',
|
||||
params: {
|
||||
interval: 'd',
|
||||
},
|
||||
sourceField: 'other_timestamp',
|
||||
},
|
||||
},
|
||||
},
|
||||
third: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Value of timestamp',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
// Private
|
||||
operationType: 'date_histogram',
|
||||
params: {
|
||||
interval: 'auto',
|
||||
},
|
||||
sourceField: 'timestamp',
|
||||
},
|
||||
// Private
|
||||
operationType: 'date_histogram',
|
||||
params: {
|
||||
interval: '42w',
|
||||
},
|
||||
sourceField: 'timestamp',
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
function stateWithInterval(interval: string) {
|
||||
function layerWithInterval(interval: string) {
|
||||
return ({
|
||||
...state,
|
||||
layers: {
|
||||
...state.layers,
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
interval,
|
||||
},
|
||||
},
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
interval,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as unknown) as IndexPatternPrivateState;
|
||||
} as unknown) as IndexPatternLayer;
|
||||
}
|
||||
|
||||
describe('buildColumn', () => {
|
||||
|
@ -246,9 +197,9 @@ describe('date_histogram', () => {
|
|||
describe('toEsAggsFn', () => {
|
||||
it('should reflect params correctly', () => {
|
||||
const esAggsFn = dateHistogramOperation.toEsAggsFn(
|
||||
state.layers.first.columns.col1 as DateHistogramIndexPatternColumn,
|
||||
layer.columns.col1 as DateHistogramIndexPatternColumn,
|
||||
'col1',
|
||||
state.indexPatterns['1']
|
||||
indexPattern1
|
||||
);
|
||||
expect(esAggsFn).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -263,10 +214,10 @@ describe('date_histogram', () => {
|
|||
|
||||
it('should not use normalized es interval for rollups', () => {
|
||||
const esAggsFn = dateHistogramOperation.toEsAggsFn(
|
||||
state.layers.first.columns.col1 as DateHistogramIndexPatternColumn,
|
||||
layer.columns.col1 as DateHistogramIndexPatternColumn,
|
||||
'col1',
|
||||
{
|
||||
...state.indexPatterns['1'],
|
||||
...indexPattern1,
|
||||
fields: [
|
||||
{
|
||||
name: 'timestamp',
|
||||
|
@ -465,15 +416,14 @@ describe('date_histogram', () => {
|
|||
|
||||
describe('param editor', () => {
|
||||
it('should render current value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -482,15 +432,34 @@ describe('date_histogram', () => {
|
|||
});
|
||||
|
||||
it('should render current value for other index pattern', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const secondLayer: IndexPatternLayer = {
|
||||
indexPatternId: '2',
|
||||
columnOrder: ['col2'],
|
||||
columns: {
|
||||
col2: {
|
||||
label: 'Value of timestamp',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
// Private
|
||||
operationType: 'date_histogram',
|
||||
params: {
|
||||
interval: 'd',
|
||||
},
|
||||
sourceField: 'other_timestamp',
|
||||
},
|
||||
},
|
||||
};
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={secondLayer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col2"
|
||||
currentColumn={state.layers.second.columns.col2 as DateHistogramIndexPatternColumn}
|
||||
layerId="second"
|
||||
currentColumn={secondLayer.columns.col2 as DateHistogramIndexPatternColumn}
|
||||
indexPattern={indexPattern2}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -499,14 +468,33 @@ describe('date_histogram', () => {
|
|||
});
|
||||
|
||||
it('should render disabled switch and no time interval control for auto interval', () => {
|
||||
const thirdLayer: IndexPatternLayer = {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Value of timestamp',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
// Private
|
||||
operationType: 'date_histogram',
|
||||
params: {
|
||||
interval: 'auto',
|
||||
},
|
||||
sourceField: 'timestamp',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={jest.fn()}
|
||||
layer={thirdLayer}
|
||||
updateLayer={jest.fn()}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.third.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
layerId="third"
|
||||
currentColumn={thirdLayer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
indexPattern={indexPattern1}
|
||||
/>
|
||||
);
|
||||
expect(instance.find('[data-test-subj="lensDateHistogramValue"]').exists()).toBeFalsy();
|
||||
|
@ -515,35 +503,52 @@ describe('date_histogram', () => {
|
|||
});
|
||||
|
||||
it('should allow switching to manual interval', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const thirdLayer: IndexPatternLayer = {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Value of timestamp',
|
||||
dataType: 'date',
|
||||
isBucketed: true,
|
||||
|
||||
// Private
|
||||
operationType: 'date_histogram',
|
||||
params: {
|
||||
interval: 'auto',
|
||||
},
|
||||
sourceField: 'timestamp',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={thirdLayer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="third"
|
||||
currentColumn={state.layers.third.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={thirdLayer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
instance.find(EuiSwitch).prop('onChange')!({
|
||||
target: { checked: true },
|
||||
} as EuiSwitchEvent);
|
||||
expect(setStateSpy).toHaveBeenCalled();
|
||||
const newState = setStateSpy.mock.calls[0][0];
|
||||
expect(newState).toHaveProperty('layers.third.columns.col1.params.interval', '30d');
|
||||
expect(updateLayerSpy).toHaveBeenCalled();
|
||||
const newLayer = updateLayerSpy.mock.calls[0][0];
|
||||
expect(newLayer).toHaveProperty('columns.col1.params.interval', '30d');
|
||||
});
|
||||
|
||||
it('should force calendar values to 1', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
instance.find('[data-test-subj="lensDateHistogramValue"]').prop('onChange')!({
|
||||
|
@ -551,67 +556,63 @@ describe('date_histogram', () => {
|
|||
value: '2',
|
||||
},
|
||||
} as React.ChangeEvent<HTMLInputElement>);
|
||||
expect(setStateSpy).toHaveBeenCalledWith(stateWithInterval('1w'));
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith(layerWithInterval('1w'));
|
||||
});
|
||||
|
||||
it('should display error if an invalid interval is specified', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const testState = stateWithInterval('4quid');
|
||||
const updateLayerSpy = jest.fn();
|
||||
const testLayer = layerWithInterval('4quid');
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={testState}
|
||||
setState={setStateSpy}
|
||||
layer={testLayer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={testState.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
expect(instance.find('[data-test-subj="lensDateHistogramError"]').exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should not display error if interval value is blank', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const testState = stateWithInterval('d');
|
||||
const updateLayerSpy = jest.fn();
|
||||
const testLayer = layerWithInterval('d');
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={testState}
|
||||
setState={setStateSpy}
|
||||
layer={testLayer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={testState.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
expect(instance.find('[data-test-subj="lensDateHistogramError"]').exists()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should display error if interval value is 0', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const testState = stateWithInterval('0d');
|
||||
const updateLayerSpy = jest.fn();
|
||||
const testLayer = layerWithInterval('0d');
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={testState}
|
||||
setState={setStateSpy}
|
||||
layer={testLayer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={testState.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
expect(instance.find('[data-test-subj="lensDateHistogramError"]').exists()).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should update the unit', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
instance.find('[data-test-subj="lensDateHistogramUnit"]').prop('onChange')!({
|
||||
|
@ -619,21 +620,20 @@ describe('date_histogram', () => {
|
|||
value: 'd',
|
||||
},
|
||||
} as React.ChangeEvent<HTMLInputElement>);
|
||||
expect(setStateSpy).toHaveBeenCalledWith(stateWithInterval('42d'));
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith(layerWithInterval('42d'));
|
||||
});
|
||||
|
||||
it('should update the value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const testState = stateWithInterval('42d');
|
||||
const updateLayerSpy = jest.fn();
|
||||
const testLayer = layerWithInterval('42d');
|
||||
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={testState}
|
||||
setState={setStateSpy}
|
||||
layer={testLayer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={testState.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={testLayer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
instance.find('[data-test-subj="lensDateHistogramValue"]').prop('onChange')!({
|
||||
|
@ -641,50 +641,48 @@ describe('date_histogram', () => {
|
|||
value: '9',
|
||||
},
|
||||
} as React.ChangeEvent<HTMLInputElement>);
|
||||
expect(setStateSpy).toHaveBeenCalledWith(stateWithInterval('9d'));
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith(layerWithInterval('9d'));
|
||||
});
|
||||
|
||||
it('should not render options if they are restricted', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const indexPattern = {
|
||||
...indexPattern1,
|
||||
fields: [
|
||||
{
|
||||
...indexPattern1.fields[0],
|
||||
aggregationRestrictions: {
|
||||
date_histogram: {
|
||||
agg: 'date_histogram',
|
||||
time_zone: 'UTC',
|
||||
calendar_interval: '1h',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{
|
||||
...indexPattern1.fields[0],
|
||||
aggregationRestrictions: {
|
||||
date_histogram: {
|
||||
agg: 'date_histogram',
|
||||
time_zone: 'UTC',
|
||||
calendar_interval: '1h',
|
||||
},
|
||||
},
|
||||
},
|
||||
]),
|
||||
};
|
||||
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={{
|
||||
...state,
|
||||
indexPatterns: {
|
||||
1: {
|
||||
...state.indexPatterns[1],
|
||||
fields: [
|
||||
{
|
||||
...state.indexPatterns[1].fields[0],
|
||||
aggregationRestrictions: {
|
||||
date_histogram: {
|
||||
agg: 'date_histogram',
|
||||
time_zone: 'UTC',
|
||||
calendar_interval: '1h',
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{
|
||||
...state.indexPatterns[1].fields[0],
|
||||
aggregationRestrictions: {
|
||||
date_histogram: {
|
||||
agg: 'date_histogram',
|
||||
time_zone: 'UTC',
|
||||
calendar_interval: '1h',
|
||||
},
|
||||
},
|
||||
},
|
||||
]),
|
||||
},
|
||||
},
|
||||
}}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
indexPattern={indexPattern}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as DateHistogramIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
|
|
@ -143,12 +143,8 @@ export const dateHistogramOperation: OperationDefinition<
|
|||
extended_bounds: JSON.stringify({}),
|
||||
}).toAst();
|
||||
},
|
||||
paramEditor: ({ state, setState, currentColumn, layerId, dateRange, data }) => {
|
||||
const field =
|
||||
currentColumn &&
|
||||
state.indexPatterns[state.layers[layerId].indexPatternId].getFieldByName(
|
||||
currentColumn.sourceField
|
||||
);
|
||||
paramEditor: ({ layer, columnId, currentColumn, updateLayer, dateRange, data, indexPattern }) => {
|
||||
const field = currentColumn && indexPattern.getFieldByName(currentColumn.sourceField);
|
||||
const intervalIsRestricted =
|
||||
field!.aggregationRestrictions && field!.aggregationRestrictions.date_histogram;
|
||||
|
||||
|
@ -167,14 +163,14 @@ export const dateHistogramOperation: OperationDefinition<
|
|||
const value = ev.target.checked
|
||||
? data.search.aggs.calculateAutoTimeExpression({ from: fromDate, to: toDate }) || '1h'
|
||||
: autoInterval;
|
||||
setState(updateColumnParam({ state, layerId, currentColumn, paramName: 'interval', value }));
|
||||
updateLayer(updateColumnParam({ layer, columnId, paramName: 'interval', value }));
|
||||
}
|
||||
|
||||
const setInterval = (newInterval: typeof interval) => {
|
||||
const isCalendarInterval = calendarOnlyIntervals.has(newInterval.unit);
|
||||
const value = `${isCalendarInterval ? '1' : newInterval.value}${newInterval.unit || 'd'}`;
|
||||
|
||||
setState(updateColumnParam({ state, layerId, currentColumn, paramName: 'interval', value }));
|
||||
updateLayer(updateColumnParam({ layer, columnId, paramName: 'interval', value }));
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
@ -7,12 +7,13 @@
|
|||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
|
||||
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
|
||||
import type { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import { dataPluginMock } from '../../../../../../../../src/plugins/data/public/mocks';
|
||||
import { FiltersIndexPatternColumn } from '.';
|
||||
import type { FiltersIndexPatternColumn } from '.';
|
||||
import { filtersOperation } from '../index';
|
||||
import { IndexPatternPrivateState } from '../../../types';
|
||||
import type { IndexPatternLayer } from '../../../types';
|
||||
import { createMockedIndexPattern } from '../../../mocks';
|
||||
import { FilterPopover } from './filter_popover';
|
||||
|
||||
const defaultProps = {
|
||||
|
@ -22,6 +23,7 @@ const defaultProps = {
|
|||
dateRange: { fromDate: 'now-1d', toDate: 'now' },
|
||||
data: dataPluginMock.createStartContract(),
|
||||
http: {} as HttpSetup,
|
||||
indexPattern: createMockedIndexPattern(),
|
||||
};
|
||||
|
||||
// mocking random id generator function
|
||||
|
@ -38,49 +40,40 @@ jest.mock('@elastic/eui', () => {
|
|||
});
|
||||
|
||||
describe('filters', () => {
|
||||
let state: IndexPatternPrivateState;
|
||||
let layer: IndexPatternLayer;
|
||||
const InlineOptions = filtersOperation.paramEditor!;
|
||||
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
indexPatternRefs: [],
|
||||
indexPatterns: {},
|
||||
existingFields: {},
|
||||
currentIndexPatternId: '1',
|
||||
isFirstExistenceFetch: false,
|
||||
layers: {
|
||||
first: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'filters',
|
||||
dataType: 'document',
|
||||
operationType: 'filters',
|
||||
scale: 'ordinal',
|
||||
isBucketed: true,
|
||||
params: {
|
||||
filters: [
|
||||
{
|
||||
input: { query: 'bytes >= 1', language: 'kuery' },
|
||||
label: 'More than one',
|
||||
},
|
||||
{
|
||||
input: { query: 'src : 2', language: 'kuery' },
|
||||
label: '',
|
||||
},
|
||||
],
|
||||
layer = {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'filters',
|
||||
dataType: 'document',
|
||||
operationType: 'filters',
|
||||
scale: 'ordinal',
|
||||
isBucketed: true,
|
||||
params: {
|
||||
filters: [
|
||||
{
|
||||
input: { query: 'bytes >= 1', language: 'kuery' },
|
||||
label: 'More than one',
|
||||
},
|
||||
},
|
||||
col2: {
|
||||
label: 'Count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'Records',
|
||||
operationType: 'count',
|
||||
},
|
||||
{
|
||||
input: { query: 'src : 2', language: 'kuery' },
|
||||
label: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
col2: {
|
||||
label: 'Count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'Records',
|
||||
operationType: 'count',
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
@ -88,9 +81,9 @@ describe('filters', () => {
|
|||
describe('toEsAggsFn', () => {
|
||||
it('should reflect params correctly', () => {
|
||||
const esAggsFn = filtersOperation.toEsAggsFn(
|
||||
state.layers.first.columns.col1 as FiltersIndexPatternColumn,
|
||||
layer.columns.col1 as FiltersIndexPatternColumn,
|
||||
'col1',
|
||||
state.indexPatterns['1']
|
||||
createMockedIndexPattern()
|
||||
);
|
||||
expect(esAggsFn).toEqual(
|
||||
expect.objectContaining({
|
||||
|
@ -133,15 +126,14 @@ describe('filters', () => {
|
|||
}));
|
||||
|
||||
it('should update state when changing a filter', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as FiltersIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as FiltersIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -156,34 +148,29 @@ describe('filters', () => {
|
|||
});
|
||||
});
|
||||
instance.update();
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
filters: [
|
||||
{
|
||||
input: {
|
||||
query: 'dest : 5',
|
||||
language: 'lucene',
|
||||
},
|
||||
label: 'Dest5',
|
||||
},
|
||||
{
|
||||
input: {
|
||||
language: 'kuery',
|
||||
query: 'src : 2',
|
||||
},
|
||||
label: '',
|
||||
},
|
||||
],
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
filters: [
|
||||
{
|
||||
input: {
|
||||
query: 'dest : 5',
|
||||
language: 'lucene',
|
||||
},
|
||||
label: 'Dest5',
|
||||
},
|
||||
},
|
||||
{
|
||||
input: {
|
||||
language: 'kuery',
|
||||
query: 'src : 2',
|
||||
},
|
||||
label: '',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -192,15 +179,14 @@ describe('filters', () => {
|
|||
|
||||
describe('Modify filters', () => {
|
||||
it('should correctly show existing filters ', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as FiltersIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as FiltersIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
expect(
|
||||
|
@ -218,15 +204,14 @@ describe('filters', () => {
|
|||
});
|
||||
|
||||
it('should remove filter', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as FiltersIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as FiltersIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -234,27 +219,22 @@ describe('filters', () => {
|
|||
.find('[data-test-subj="lns-customBucketContainer-remove"]')
|
||||
.at(2)
|
||||
.simulate('click');
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
filters: [
|
||||
{
|
||||
input: {
|
||||
language: 'kuery',
|
||||
query: 'bytes >= 1',
|
||||
},
|
||||
label: 'More than one',
|
||||
},
|
||||
],
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
filters: [
|
||||
{
|
||||
input: {
|
||||
language: 'kuery',
|
||||
query: 'bytes >= 1',
|
||||
},
|
||||
label: 'More than one',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -128,16 +128,14 @@ export const filtersOperation: OperationDefinition<FiltersIndexPatternColumn, 'n
|
|||
}).toAst();
|
||||
},
|
||||
|
||||
paramEditor: ({ state, setState, currentColumn, layerId, data }) => {
|
||||
const indexPattern = state.indexPatterns[state.layers[layerId].indexPatternId];
|
||||
paramEditor: ({ layer, columnId, currentColumn, indexPattern, updateLayer, data }) => {
|
||||
const filters = currentColumn.params.filters;
|
||||
|
||||
const setFilters = (newFilters: Filter[]) =>
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'filters',
|
||||
value: newFilters,
|
||||
})
|
||||
|
|
|
@ -36,12 +36,7 @@ import { countOperation, CountIndexPatternColumn } from './count';
|
|||
import { lastValueOperation, LastValueIndexPatternColumn } from './last_value';
|
||||
import { OperationMetadata } from '../../../types';
|
||||
import type { BaseIndexPatternColumn, ReferenceBasedIndexPatternColumn } from './column_types';
|
||||
import {
|
||||
IndexPatternPrivateState,
|
||||
IndexPattern,
|
||||
IndexPatternField,
|
||||
IndexPatternLayer,
|
||||
} from '../../types';
|
||||
import { IndexPattern, IndexPatternField, IndexPatternLayer } from '../../types';
|
||||
import { DateRange } from '../../../../common';
|
||||
import { ExpressionAstFunction } from '../../../../../../../src/plugins/expressions/public';
|
||||
import { DataPublicPluginStart } from '../../../../../../../src/plugins/data/public';
|
||||
|
@ -115,10 +110,10 @@ export {
|
|||
*/
|
||||
export interface ParamEditorProps<C> {
|
||||
currentColumn: C;
|
||||
state: IndexPatternPrivateState;
|
||||
setState: (newState: IndexPatternPrivateState) => void;
|
||||
layer: IndexPatternLayer;
|
||||
updateLayer: (newLayer: IndexPatternLayer) => void;
|
||||
columnId: string;
|
||||
layerId: string;
|
||||
indexPattern: IndexPattern;
|
||||
uiSettings: IUiSettingsClient;
|
||||
storage: IStorageWrapper;
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
|
|
|
@ -13,7 +13,7 @@ import { dataPluginMock } from '../../../../../../../src/plugins/data/public/moc
|
|||
import { createMockedIndexPattern } from '../../mocks';
|
||||
import { LastValueIndexPatternColumn } from './last_value';
|
||||
import { lastValueOperation } from './index';
|
||||
import { IndexPatternPrivateState, IndexPattern, IndexPatternLayer } from '../../types';
|
||||
import type { IndexPattern, IndexPatternLayer } from '../../types';
|
||||
|
||||
const defaultProps = {
|
||||
storage: {} as IStorageWrapper,
|
||||
|
@ -22,52 +22,41 @@ const defaultProps = {
|
|||
dateRange: { fromDate: 'now-1d', toDate: 'now' },
|
||||
data: dataPluginMock.createStartContract(),
|
||||
http: {} as HttpSetup,
|
||||
indexPattern: {
|
||||
...createMockedIndexPattern(),
|
||||
hasRestrictions: false,
|
||||
} as IndexPattern,
|
||||
};
|
||||
|
||||
describe('last_value', () => {
|
||||
let state: IndexPatternPrivateState;
|
||||
let layer: IndexPatternLayer;
|
||||
const InlineOptions = lastValueOperation.paramEditor!;
|
||||
|
||||
beforeEach(() => {
|
||||
const indexPattern = createMockedIndexPattern();
|
||||
state = {
|
||||
indexPatternRefs: [],
|
||||
indexPatterns: {
|
||||
'1': {
|
||||
...indexPattern,
|
||||
hasRestrictions: false,
|
||||
} as IndexPattern,
|
||||
},
|
||||
existingFields: {},
|
||||
currentIndexPatternId: '1',
|
||||
isFirstExistenceFetch: false,
|
||||
layers: {
|
||||
first: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Top value of category',
|
||||
dataType: 'string',
|
||||
isBucketed: true,
|
||||
operationType: 'terms',
|
||||
params: {
|
||||
orderBy: { type: 'alphabetical' },
|
||||
size: 3,
|
||||
orderDirection: 'asc',
|
||||
},
|
||||
sourceField: 'category',
|
||||
},
|
||||
col2: {
|
||||
label: 'Last value of a',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'a',
|
||||
operationType: 'last_value',
|
||||
params: {
|
||||
sortField: 'datefield',
|
||||
},
|
||||
},
|
||||
layer = {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Top value of category',
|
||||
dataType: 'string',
|
||||
isBucketed: true,
|
||||
operationType: 'terms',
|
||||
params: {
|
||||
orderBy: { type: 'alphabetical' },
|
||||
size: 3,
|
||||
orderDirection: 'asc',
|
||||
},
|
||||
sourceField: 'category',
|
||||
},
|
||||
col2: {
|
||||
label: 'Last value of a',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'a',
|
||||
operationType: 'last_value',
|
||||
params: {
|
||||
sortField: 'datefield',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -76,7 +65,7 @@ describe('last_value', () => {
|
|||
|
||||
describe('toEsAggsFn', () => {
|
||||
it('should reflect params correctly', () => {
|
||||
const lastValueColumn = state.layers.first.columns.col2 as LastValueIndexPatternColumn;
|
||||
const lastValueColumn = layer.columns.col2 as LastValueIndexPatternColumn;
|
||||
const esAggsFn = lastValueOperation.toEsAggsFn(
|
||||
{ ...lastValueColumn, params: { ...lastValueColumn.params } },
|
||||
'col1',
|
||||
|
@ -345,15 +334,14 @@ describe('last_value', () => {
|
|||
|
||||
describe('param editor', () => {
|
||||
it('should render current sortField', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col2 as LastValueIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col2 as LastValueIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -363,15 +351,14 @@ describe('last_value', () => {
|
|||
});
|
||||
|
||||
it('should update state when changing sortField', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col2 as LastValueIndexPatternColumn}
|
||||
layerId="first"
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col2"
|
||||
currentColumn={layer.columns.col2 as LastValueIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -380,20 +367,15 @@ describe('last_value', () => {
|
|||
.find(EuiComboBox)
|
||||
.prop('onChange')!([{ label: 'datefield2', value: 'datefield2' }]);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col2: {
|
||||
...state.layers.first.columns.col2,
|
||||
params: {
|
||||
...(state.layers.first.columns.col2 as LastValueIndexPatternColumn).params,
|
||||
sortField: 'datefield2',
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col2: {
|
||||
...layer.columns.col2,
|
||||
params: {
|
||||
...(layer.columns.col2 as LastValueIndexPatternColumn).params,
|
||||
sortField: 'datefield2',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -403,10 +385,10 @@ describe('last_value', () => {
|
|||
|
||||
describe('getErrorMessage', () => {
|
||||
let indexPattern: IndexPattern;
|
||||
let layer: IndexPatternLayer;
|
||||
let errorLayer: IndexPatternLayer;
|
||||
beforeEach(() => {
|
||||
indexPattern = createMockedIndexPattern();
|
||||
layer = {
|
||||
errorLayer = {
|
||||
columns: {
|
||||
col1: {
|
||||
dataType: 'boolean',
|
||||
|
@ -423,53 +405,55 @@ describe('last_value', () => {
|
|||
};
|
||||
});
|
||||
it('returns undefined if sourceField exists and sortField is of type date ', () => {
|
||||
expect(lastValueOperation.getErrorMessage!(layer, 'col1', indexPattern)).toEqual(undefined);
|
||||
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern)).toEqual(
|
||||
undefined
|
||||
);
|
||||
});
|
||||
it('shows error message if the sourceField does not exist in index pattern', () => {
|
||||
layer = {
|
||||
...layer,
|
||||
errorLayer = {
|
||||
...errorLayer,
|
||||
columns: {
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
...errorLayer.columns.col1,
|
||||
sourceField: 'notExisting',
|
||||
} as LastValueIndexPatternColumn,
|
||||
},
|
||||
};
|
||||
expect(lastValueOperation.getErrorMessage!(layer, 'col1', indexPattern)).toEqual([
|
||||
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern)).toEqual([
|
||||
'Field notExisting was not found',
|
||||
]);
|
||||
});
|
||||
it('shows error message if the sortField does not exist in index pattern', () => {
|
||||
layer = {
|
||||
...layer,
|
||||
errorLayer = {
|
||||
...errorLayer,
|
||||
columns: {
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
...errorLayer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
...errorLayer.columns.col1.params,
|
||||
sortField: 'notExisting',
|
||||
},
|
||||
} as LastValueIndexPatternColumn,
|
||||
},
|
||||
};
|
||||
expect(lastValueOperation.getErrorMessage!(layer, 'col1', indexPattern)).toEqual([
|
||||
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern)).toEqual([
|
||||
'Field notExisting was not found',
|
||||
]);
|
||||
});
|
||||
it('shows error message if the sortField is not date', () => {
|
||||
layer = {
|
||||
...layer,
|
||||
errorLayer = {
|
||||
...errorLayer,
|
||||
columns: {
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
...errorLayer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
...errorLayer.columns.col1.params,
|
||||
sortField: 'bytes',
|
||||
},
|
||||
} as LastValueIndexPatternColumn,
|
||||
},
|
||||
};
|
||||
expect(lastValueOperation.getErrorMessage!(layer, 'col1', indexPattern)).toEqual([
|
||||
expect(lastValueOperation.getErrorMessage!(errorLayer, 'col1', indexPattern)).toEqual([
|
||||
'Field bytes is not a date field and cannot be used for sorting',
|
||||
]);
|
||||
});
|
||||
|
|
|
@ -186,12 +186,11 @@ export const lastValueOperation: OperationDefinition<LastValueIndexPatternColumn
|
|||
);
|
||||
},
|
||||
|
||||
paramEditor: ({ state, setState, currentColumn, layerId }) => {
|
||||
const currentIndexPattern = state.indexPatterns[state.layers[layerId].indexPatternId];
|
||||
const dateFields = getDateFields(currentIndexPattern);
|
||||
paramEditor: ({ layer, updateLayer, columnId, currentColumn, indexPattern }) => {
|
||||
const dateFields = getDateFields(indexPattern);
|
||||
const isSortFieldInvalid = !!getInvalidSortFieldMessage(
|
||||
currentColumn.params.sortField,
|
||||
currentIndexPattern
|
||||
indexPattern
|
||||
);
|
||||
return (
|
||||
<>
|
||||
|
@ -228,11 +227,10 @@ export const lastValueOperation: OperationDefinition<LastValueIndexPatternColumn
|
|||
if (choices.length === 0) {
|
||||
return;
|
||||
}
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'sortField',
|
||||
value: choices[0].value,
|
||||
})
|
||||
|
@ -243,8 +241,8 @@ export const lastValueOperation: OperationDefinition<LastValueIndexPatternColumn
|
|||
? [
|
||||
{
|
||||
label:
|
||||
currentIndexPattern.getFieldByName(currentColumn.params.sortField)
|
||||
?.displayName || currentColumn.params.sortField,
|
||||
indexPattern.getFieldByName(currentColumn.params.sortField)?.displayName ||
|
||||
currentColumn.params.sortField,
|
||||
value: currentColumn.params.sortField,
|
||||
},
|
||||
]
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
|
||||
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import { IndexPatternPrivateState, IndexPattern } from '../../../types';
|
||||
import type { IndexPatternLayer, IndexPattern } from '../../../types';
|
||||
import { dataPluginMock } from '../../../../../../../../src/plugins/data/public/mocks';
|
||||
import { rangeOperation } from '../index';
|
||||
import { RangeIndexPatternColumn } from './ranges';
|
||||
|
@ -51,6 +51,7 @@ dataPluginMockValue.fieldFormats.deserialize = jest.fn().mockImplementation(({ p
|
|||
type ReactMouseEvent = React.MouseEvent<HTMLAnchorElement, MouseEvent> &
|
||||
React.MouseEvent<HTMLButtonElement, MouseEvent>;
|
||||
|
||||
const sourceField = 'MyField';
|
||||
const defaultOptions = {
|
||||
storage: {} as IStorageWrapper,
|
||||
// need this for MAX_HISTOGRAM value
|
||||
|
@ -64,75 +65,64 @@ const defaultOptions = {
|
|||
},
|
||||
data: dataPluginMockValue,
|
||||
http: {} as HttpSetup,
|
||||
indexPattern: {
|
||||
id: '1',
|
||||
title: 'my_index_pattern',
|
||||
hasRestrictions: false,
|
||||
fields: [{ name: sourceField, type: 'number', displayName: sourceField }],
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{ name: sourceField, type: 'number', displayName: sourceField },
|
||||
]),
|
||||
},
|
||||
};
|
||||
|
||||
describe('ranges', () => {
|
||||
let state: IndexPatternPrivateState;
|
||||
let layer: IndexPatternLayer;
|
||||
const InlineOptions = rangeOperation.paramEditor!;
|
||||
const sourceField = 'MyField';
|
||||
const MAX_HISTOGRAM_VALUE = 100;
|
||||
const GRANULARITY_DEFAULT_VALUE = (MAX_HISTOGRAM_VALUE - MIN_HISTOGRAM_BARS) / 2;
|
||||
const GRANULARITY_STEP = (MAX_HISTOGRAM_VALUE - MIN_HISTOGRAM_BARS) / SLICES;
|
||||
|
||||
function setToHistogramMode() {
|
||||
const column = state.layers.first.columns.col1 as RangeIndexPatternColumn;
|
||||
const column = layer.columns.col1 as RangeIndexPatternColumn;
|
||||
column.dataType = 'number';
|
||||
column.scale = 'interval';
|
||||
column.params.type = MODES.Histogram;
|
||||
}
|
||||
|
||||
function setToRangeMode() {
|
||||
const column = state.layers.first.columns.col1 as RangeIndexPatternColumn;
|
||||
const column = layer.columns.col1 as RangeIndexPatternColumn;
|
||||
column.dataType = 'string';
|
||||
column.scale = 'ordinal';
|
||||
column.params.type = MODES.Range;
|
||||
}
|
||||
|
||||
function getDefaultState(): IndexPatternPrivateState {
|
||||
function getDefaultLayer(): IndexPatternLayer {
|
||||
return {
|
||||
indexPatternRefs: [],
|
||||
indexPatterns: {
|
||||
'1': {
|
||||
id: '1',
|
||||
title: 'my_index_pattern',
|
||||
hasRestrictions: false,
|
||||
fields: [{ name: sourceField, type: 'number', displayName: sourceField }],
|
||||
getFieldByName: getFieldByNameFactory([
|
||||
{ name: sourceField, type: 'number', displayName: sourceField },
|
||||
]),
|
||||
},
|
||||
},
|
||||
existingFields: {},
|
||||
currentIndexPatternId: '1',
|
||||
isFirstExistenceFetch: false,
|
||||
layers: {
|
||||
first: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
// Start with the histogram type
|
||||
col1: {
|
||||
label: sourceField,
|
||||
dataType: 'number',
|
||||
operationType: 'range',
|
||||
scale: 'interval',
|
||||
isBucketed: true,
|
||||
sourceField,
|
||||
params: {
|
||||
type: MODES.Histogram,
|
||||
ranges: [{ from: 0, to: DEFAULT_INTERVAL, label: '' }],
|
||||
maxBars: 'auto',
|
||||
},
|
||||
},
|
||||
col2: {
|
||||
label: 'Count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'Records',
|
||||
operationType: 'count',
|
||||
},
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
// Start with the histogram type
|
||||
col1: {
|
||||
label: sourceField,
|
||||
dataType: 'number',
|
||||
operationType: 'range',
|
||||
scale: 'interval',
|
||||
isBucketed: true,
|
||||
sourceField,
|
||||
params: {
|
||||
type: MODES.Histogram,
|
||||
ranges: [{ from: 0, to: DEFAULT_INTERVAL, label: '' }],
|
||||
maxBars: 'auto',
|
||||
},
|
||||
},
|
||||
col2: {
|
||||
label: 'Count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'Records',
|
||||
operationType: 'count',
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -142,7 +132,7 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
beforeEach(() => {
|
||||
state = getDefaultState();
|
||||
layer = getDefaultLayer();
|
||||
});
|
||||
|
||||
describe('toEsAggsFn', () => {
|
||||
|
@ -150,7 +140,7 @@ describe('ranges', () => {
|
|||
|
||||
it('should reflect params correctly', () => {
|
||||
const esAggsFn = rangeOperation.toEsAggsFn(
|
||||
state.layers.first.columns.col1 as RangeIndexPatternColumn,
|
||||
layer.columns.col1 as RangeIndexPatternColumn,
|
||||
'col1',
|
||||
{} as IndexPattern
|
||||
);
|
||||
|
@ -189,10 +179,10 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should set maxBars param if provided', () => {
|
||||
(state.layers.first.columns.col1 as RangeIndexPatternColumn).params.maxBars = 10;
|
||||
(layer.columns.col1 as RangeIndexPatternColumn).params.maxBars = 10;
|
||||
|
||||
const esAggsFn = rangeOperation.toEsAggsFn(
|
||||
state.layers.first.columns.col1 as RangeIndexPatternColumn,
|
||||
layer.columns.col1 as RangeIndexPatternColumn,
|
||||
'col1',
|
||||
{} as IndexPattern
|
||||
);
|
||||
|
@ -211,7 +201,7 @@ describe('ranges', () => {
|
|||
setToRangeMode();
|
||||
|
||||
const esAggsFn = rangeOperation.toEsAggsFn(
|
||||
state.layers.first.columns.col1 as RangeIndexPatternColumn,
|
||||
layer.columns.col1 as RangeIndexPatternColumn,
|
||||
'col1',
|
||||
{} as IndexPattern
|
||||
);
|
||||
|
@ -225,12 +215,12 @@ describe('ranges', () => {
|
|||
|
||||
it('should include custom labels', () => {
|
||||
setToRangeMode();
|
||||
(state.layers.first.columns.col1 as RangeIndexPatternColumn).params.ranges = [
|
||||
(layer.columns.col1 as RangeIndexPatternColumn).params.ranges = [
|
||||
{ from: 0, to: 100, label: 'customlabel' },
|
||||
];
|
||||
|
||||
const esAggsFn = rangeOperation.toEsAggsFn(
|
||||
state.layers.first.columns.col1 as RangeIndexPatternColumn,
|
||||
layer.columns.col1 as RangeIndexPatternColumn,
|
||||
'col1',
|
||||
{} as IndexPattern
|
||||
);
|
||||
|
@ -276,36 +266,30 @@ describe('ranges', () => {
|
|||
describe('paramEditor', () => {
|
||||
describe('Modify intervals in basic mode', () => {
|
||||
beforeEach(() => {
|
||||
state = getDefaultState();
|
||||
layer = getDefaultLayer();
|
||||
});
|
||||
|
||||
it('should start update the state with the default maxBars value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
maxBars: GRANULARITY_DEFAULT_VALUE,
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
maxBars: GRANULARITY_DEFAULT_VALUE,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -313,16 +297,15 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should update state when changing Max bars number', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -343,20 +326,15 @@ describe('ranges', () => {
|
|||
jest.advanceTimersByTime(TYPING_DEBOUNCE_TIME * 4);
|
||||
});
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
maxBars: MAX_HISTOGRAM_VALUE,
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
maxBars: MAX_HISTOGRAM_VALUE,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -364,16 +342,15 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should update the state using the plus or minus buttons by the step amount', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -389,20 +366,15 @@ describe('ranges', () => {
|
|||
jest.advanceTimersByTime(TYPING_DEBOUNCE_TIME * 4);
|
||||
});
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
maxBars: GRANULARITY_DEFAULT_VALUE - GRANULARITY_STEP,
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
maxBars: GRANULARITY_DEFAULT_VALUE - GRANULARITY_STEP,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -417,25 +389,19 @@ describe('ranges', () => {
|
|||
jest.advanceTimersByTime(TYPING_DEBOUNCE_TIME * 4);
|
||||
});
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
maxBars: GRANULARITY_DEFAULT_VALUE,
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
maxBars: GRANULARITY_DEFAULT_VALUE,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
// });
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -446,16 +412,15 @@ describe('ranges', () => {
|
|||
beforeEach(() => setToRangeMode());
|
||||
|
||||
it('should show one range interval to start with', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -463,16 +428,15 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should add a new range', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -495,23 +459,18 @@ describe('ranges', () => {
|
|||
} as React.ChangeEvent<HTMLInputElement>);
|
||||
jest.advanceTimersByTime(TYPING_DEBOUNCE_TIME * 4);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
ranges: [
|
||||
{ from: 0, to: DEFAULT_INTERVAL, label: '' },
|
||||
{ from: 50, to: Infinity, label: '' },
|
||||
],
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
ranges: [
|
||||
{ from: 0, to: DEFAULT_INTERVAL, label: '' },
|
||||
{ from: 50, to: Infinity, label: '' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -520,16 +479,15 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should add a new range with custom label', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -552,23 +510,18 @@ describe('ranges', () => {
|
|||
} as React.ChangeEvent<HTMLInputElement>);
|
||||
jest.advanceTimersByTime(TYPING_DEBOUNCE_TIME * 4);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
ranges: [
|
||||
{ from: 0, to: DEFAULT_INTERVAL, label: '' },
|
||||
{ from: DEFAULT_INTERVAL, to: Infinity, label: 'customlabel' },
|
||||
],
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
ranges: [
|
||||
{ from: 0, to: DEFAULT_INTERVAL, label: '' },
|
||||
{ from: DEFAULT_INTERVAL, to: Infinity, label: 'customlabel' },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -577,16 +530,15 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should open a popover to edit an existing range', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -607,20 +559,15 @@ describe('ranges', () => {
|
|||
} as React.ChangeEvent<HTMLInputElement>);
|
||||
jest.advanceTimersByTime(TYPING_DEBOUNCE_TIME * 4);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
ranges: [{ from: 0, to: 50, label: '' }],
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...layer.columns.col1.params,
|
||||
ranges: [{ from: 0, to: 50, label: '' }],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -629,16 +576,15 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should not accept invalid ranges', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -670,10 +616,10 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should be possible to remove a range if multiple', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
// Add an extra range
|
||||
(state.layers.first.columns.col1 as RangeIndexPatternColumn).params.ranges.push({
|
||||
(layer.columns.col1 as RangeIndexPatternColumn).params.ranges.push({
|
||||
from: DEFAULT_INTERVAL,
|
||||
to: 2 * DEFAULT_INTERVAL,
|
||||
label: '',
|
||||
|
@ -682,11 +628,10 @@ describe('ranges', () => {
|
|||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -709,10 +654,10 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should handle correctly open ranges when saved', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
// Add an extra open range:
|
||||
(state.layers.first.columns.col1 as RangeIndexPatternColumn).params.ranges.push({
|
||||
(layer.columns.col1 as RangeIndexPatternColumn).params.ranges.push({
|
||||
from: null,
|
||||
to: null,
|
||||
label: '',
|
||||
|
@ -721,11 +666,10 @@ describe('ranges', () => {
|
|||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -749,21 +693,21 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should correctly handle the default formatter for the field', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
|
||||
// set a default formatter for the sourceField used
|
||||
state.indexPatterns['1'].fieldFormatMap = {
|
||||
MyField: { id: 'custom', params: {} },
|
||||
};
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
indexPattern={{
|
||||
...defaultOptions.indexPattern,
|
||||
fieldFormatMap: {
|
||||
MyField: { id: 'custom', params: {} },
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -773,15 +717,10 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should correctly pick the dimension formatter for the field', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
|
||||
// set a default formatter for the sourceField used
|
||||
state.indexPatterns['1'].fieldFormatMap = {
|
||||
MyField: { id: 'custom', params: {} },
|
||||
};
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
// now set a format on the range operation
|
||||
(state.layers.first.columns.col1 as RangeIndexPatternColumn).params.format = {
|
||||
(layer.columns.col1 as RangeIndexPatternColumn).params.format = {
|
||||
id: 'bytes',
|
||||
params: { decimals: 0 },
|
||||
};
|
||||
|
@ -789,11 +728,16 @@ describe('ranges', () => {
|
|||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
indexPattern={{
|
||||
...defaultOptions.indexPattern,
|
||||
fieldFormatMap: {
|
||||
MyField: { id: 'custom', params: {} },
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -803,25 +747,24 @@ describe('ranges', () => {
|
|||
});
|
||||
|
||||
it('should not update the state on mount', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
|
||||
mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
expect(setStateSpy.mock.calls.length).toBe(0);
|
||||
expect(updateLayerSpy.mock.calls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should not reset formatters when switching between custom ranges and auto histogram', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
// now set a format on the range operation
|
||||
(state.layers.first.columns.col1 as RangeIndexPatternColumn).params.format = {
|
||||
(layer.columns.col1 as RangeIndexPatternColumn).params.format = {
|
||||
id: 'custom',
|
||||
params: { decimals: 3 },
|
||||
};
|
||||
|
@ -829,11 +772,10 @@ describe('ranges', () => {
|
|||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultOptions}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as RangeIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as RangeIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -842,7 +784,7 @@ describe('ranges', () => {
|
|||
instance.find(EuiLink).first().prop('onClick')!({} as ReactMouseEvent);
|
||||
});
|
||||
|
||||
expect(setStateSpy.mock.calls[1][0].layers.first.columns.col1.params.format).toEqual({
|
||||
expect(updateLayerSpy.mock.calls[1][0].columns.col1.params.format).toEqual({
|
||||
id: 'custom',
|
||||
params: { decimals: 3 },
|
||||
});
|
||||
|
|
|
@ -16,7 +16,6 @@ import { RangeEditor } from './range_editor';
|
|||
import { OperationDefinition } from '../index';
|
||||
import { FieldBasedIndexPatternColumn } from '../column_types';
|
||||
import { updateColumnParam } from '../../layer_helpers';
|
||||
import { mergeLayer } from '../../../state_helpers';
|
||||
import { supportedFormats } from '../../../format_column';
|
||||
import { MODES, AUTO_BARS, DEFAULT_INTERVAL, MIN_HISTOGRAM_BARS, SLICES } from './constants';
|
||||
import { IndexPattern, IndexPatternField } from '../../../types';
|
||||
|
@ -173,8 +172,15 @@ export const rangeOperation: OperationDefinition<RangeIndexPatternColumn, 'field
|
|||
extended_bounds: JSON.stringify({ min: '', max: '' }),
|
||||
}).toAst();
|
||||
},
|
||||
paramEditor: ({ state, setState, currentColumn, layerId, columnId, uiSettings, data }) => {
|
||||
const indexPattern = state.indexPatterns[state.layers[layerId].indexPatternId];
|
||||
paramEditor: ({
|
||||
layer,
|
||||
columnId,
|
||||
currentColumn,
|
||||
updateLayer,
|
||||
indexPattern,
|
||||
uiSettings,
|
||||
data,
|
||||
}) => {
|
||||
const currentField = indexPattern.getFieldByName(currentColumn.sourceField);
|
||||
const numberFormat = currentColumn.params.format;
|
||||
const numberFormatterPattern =
|
||||
|
@ -198,11 +204,10 @@ export const rangeOperation: OperationDefinition<RangeIndexPatternColumn, 'field
|
|||
|
||||
// Used to change one param at the time
|
||||
const setParam: UpdateParamsFnType = (paramName, value) => {
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName,
|
||||
value,
|
||||
})
|
||||
|
@ -217,29 +222,24 @@ export const rangeOperation: OperationDefinition<RangeIndexPatternColumn, 'field
|
|||
newMode === MODES.Range
|
||||
? { id: 'range', params: { template: 'arrow_right', replaceInfinity: true } }
|
||||
: undefined;
|
||||
setState(
|
||||
mergeLayer({
|
||||
state,
|
||||
layerId,
|
||||
newLayer: {
|
||||
columns: {
|
||||
...state.layers[layerId].columns,
|
||||
[columnId]: {
|
||||
...currentColumn,
|
||||
scale,
|
||||
dataType,
|
||||
params: {
|
||||
type: newMode,
|
||||
ranges: [{ from: 0, to: DEFAULT_INTERVAL, label: '' }],
|
||||
maxBars: maxBarsDefaultValue,
|
||||
format: currentColumn.params.format,
|
||||
parentFormat,
|
||||
},
|
||||
},
|
||||
updateLayer({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
[columnId]: {
|
||||
...currentColumn,
|
||||
scale,
|
||||
dataType,
|
||||
params: {
|
||||
type: newMode,
|
||||
ranges: [{ from: 0, to: DEFAULT_INTERVAL, label: '' }],
|
||||
maxBars: maxBarsDefaultValue,
|
||||
format: currentColumn.params.format,
|
||||
parentFormat,
|
||||
},
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
});
|
||||
};
|
||||
return (
|
||||
<RangeEditor
|
||||
|
|
|
@ -169,8 +169,7 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
|
|||
}
|
||||
return currentColumn;
|
||||
},
|
||||
paramEditor: function ParamEditor({ state, setState, currentColumn, layerId }) {
|
||||
const indexPattern = currentColumn && state.indexPatterns[state.layers[layerId].indexPatternId];
|
||||
paramEditor: function ParamEditor({ layer, updateLayer, currentColumn, columnId, indexPattern }) {
|
||||
const hasRestrictions = indexPattern.hasRestrictions;
|
||||
|
||||
const [popoverOpen, setPopoverOpen] = useState(false);
|
||||
|
@ -194,11 +193,11 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
|
|||
};
|
||||
}
|
||||
|
||||
const orderOptions = Object.entries(state.layers[layerId].columns)
|
||||
.filter(([_columnId, column]) => isSortableByColumn(column))
|
||||
.map(([columnId, column]) => {
|
||||
const orderOptions = Object.entries(layer.columns)
|
||||
.filter(([sortId, column]) => isSortableByColumn(column))
|
||||
.map(([sortId, column]) => {
|
||||
return {
|
||||
value: toValue({ type: 'column', columnId }),
|
||||
value: toValue({ type: 'column', columnId: sortId }),
|
||||
text: column.label,
|
||||
};
|
||||
});
|
||||
|
@ -220,11 +219,10 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
|
|||
<ValuesRangeInput
|
||||
value={currentColumn.params.size}
|
||||
onChange={(value) => {
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'size',
|
||||
value,
|
||||
})
|
||||
|
@ -263,11 +261,10 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
|
|||
data-test-subj="indexPattern-terms-other-bucket"
|
||||
checked={Boolean(currentColumn.params.otherBucket)}
|
||||
onChange={(e: EuiSwitchEvent) =>
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'otherBucket',
|
||||
value: e.target.checked,
|
||||
})
|
||||
|
@ -284,11 +281,10 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
|
|||
data-test-subj="indexPattern-terms-missing-bucket"
|
||||
checked={Boolean(currentColumn.params.missingBucket)}
|
||||
onChange={(e: EuiSwitchEvent) =>
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'missingBucket',
|
||||
value: e.target.checked,
|
||||
})
|
||||
|
@ -312,11 +308,10 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
|
|||
options={orderOptions}
|
||||
value={toValue(currentColumn.params.orderBy)}
|
||||
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'orderBy',
|
||||
value: fromValue(e.target.value),
|
||||
})
|
||||
|
@ -353,11 +348,10 @@ export const termsOperation: OperationDefinition<TermsIndexPatternColumn, 'field
|
|||
]}
|
||||
value={currentColumn.params.orderDirection}
|
||||
onChange={(e: React.ChangeEvent<HTMLSelectElement>) =>
|
||||
setState(
|
||||
updateLayer(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName: 'orderDirection',
|
||||
value: e.target.value as 'asc' | 'desc',
|
||||
})
|
||||
|
|
|
@ -8,14 +8,14 @@ import React from 'react';
|
|||
import { act } from 'react-dom/test-utils';
|
||||
import { shallow, mount } from 'enzyme';
|
||||
import { EuiRange, EuiSelect, EuiSwitch, EuiSwitchEvent } from '@elastic/eui';
|
||||
import { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
|
||||
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import type { IUiSettingsClient, SavedObjectsClientContract, HttpSetup } from 'kibana/public';
|
||||
import type { IStorageWrapper } from 'src/plugins/kibana_utils/public';
|
||||
import { dataPluginMock } from '../../../../../../../../src/plugins/data/public/mocks';
|
||||
import { createMockedIndexPattern } from '../../../mocks';
|
||||
import { ValuesRangeInput } from './values_range_input';
|
||||
import { TermsIndexPatternColumn } from '.';
|
||||
import type { TermsIndexPatternColumn } from '.';
|
||||
import { termsOperation } from '../index';
|
||||
import { IndexPatternPrivateState, IndexPattern, IndexPatternLayer } from '../../../types';
|
||||
import { IndexPattern, IndexPatternLayer } from '../../../types';
|
||||
|
||||
const defaultProps = {
|
||||
storage: {} as IStorageWrapper,
|
||||
|
@ -24,48 +24,36 @@ const defaultProps = {
|
|||
dateRange: { fromDate: 'now-1d', toDate: 'now' },
|
||||
data: dataPluginMock.createStartContract(),
|
||||
http: {} as HttpSetup,
|
||||
indexPattern: createMockedIndexPattern(),
|
||||
};
|
||||
|
||||
describe('terms', () => {
|
||||
let state: IndexPatternPrivateState;
|
||||
let layer: IndexPatternLayer;
|
||||
const InlineOptions = termsOperation.paramEditor!;
|
||||
|
||||
beforeEach(() => {
|
||||
state = {
|
||||
indexPatternRefs: [],
|
||||
indexPatterns: {
|
||||
'1': {
|
||||
hasRestrictions: false,
|
||||
} as IndexPattern,
|
||||
},
|
||||
existingFields: {},
|
||||
currentIndexPatternId: '1',
|
||||
isFirstExistenceFetch: false,
|
||||
layers: {
|
||||
first: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Top value of category',
|
||||
dataType: 'string',
|
||||
isBucketed: true,
|
||||
operationType: 'terms',
|
||||
params: {
|
||||
orderBy: { type: 'alphabetical' },
|
||||
size: 3,
|
||||
orderDirection: 'asc',
|
||||
},
|
||||
sourceField: 'category',
|
||||
},
|
||||
col2: {
|
||||
label: 'Count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'Records',
|
||||
operationType: 'count',
|
||||
},
|
||||
layer = {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1', 'col2'],
|
||||
columns: {
|
||||
col1: {
|
||||
label: 'Top value of category',
|
||||
dataType: 'string',
|
||||
isBucketed: true,
|
||||
operationType: 'terms',
|
||||
params: {
|
||||
orderBy: { type: 'alphabetical' },
|
||||
size: 3,
|
||||
orderDirection: 'asc',
|
||||
},
|
||||
sourceField: 'category',
|
||||
},
|
||||
col2: {
|
||||
label: 'Count',
|
||||
dataType: 'number',
|
||||
isBucketed: false,
|
||||
sourceField: 'Records',
|
||||
operationType: 'count',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -73,7 +61,7 @@ describe('terms', () => {
|
|||
|
||||
describe('toEsAggsFn', () => {
|
||||
it('should reflect params correctly', () => {
|
||||
const termsColumn = state.layers.first.columns.col1 as TermsIndexPatternColumn;
|
||||
const termsColumn = layer.columns.col1 as TermsIndexPatternColumn;
|
||||
const esAggsFn = termsOperation.toEsAggsFn(
|
||||
{ ...termsColumn, params: { ...termsColumn.params, otherBucket: true } },
|
||||
'col1',
|
||||
|
@ -92,7 +80,7 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should not enable missing bucket if other bucket is not set', () => {
|
||||
const termsColumn = state.layers.first.columns.col1 as TermsIndexPatternColumn;
|
||||
const termsColumn = layer.columns.col1 as TermsIndexPatternColumn;
|
||||
const esAggsFn = termsOperation.toEsAggsFn(
|
||||
{
|
||||
...termsColumn,
|
||||
|
@ -370,7 +358,7 @@ describe('terms', () => {
|
|||
it('should use the default size when there is an existing bucket', () => {
|
||||
const termsColumn = termsOperation.buildColumn({
|
||||
indexPattern: createMockedIndexPattern(),
|
||||
layer: state.layers.first,
|
||||
layer,
|
||||
field: {
|
||||
aggregatable: true,
|
||||
searchable: true,
|
||||
|
@ -526,15 +514,14 @@ describe('terms', () => {
|
|||
|
||||
describe('param editor', () => {
|
||||
it('should render current other bucket value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -546,15 +533,18 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should hide other bucket setting for rollups', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={{ ...state, indexPatterns: { '1': { hasRestrictions: true } as IndexPattern } }}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
indexPattern={{
|
||||
...createMockedIndexPattern(),
|
||||
hasRestrictions: true,
|
||||
}}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -562,15 +552,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should disable missing bucket setting as long as other bucket is not set', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -582,23 +571,22 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should enable missing bucket setting as long as other bucket is set', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={
|
||||
{
|
||||
...state.layers.first.columns.col1,
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...state.layers.first.columns.col1.params,
|
||||
...layer.columns.col1.params,
|
||||
otherBucket: true,
|
||||
},
|
||||
} as TermsIndexPatternColumn
|
||||
}
|
||||
layerId="first"
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -610,15 +598,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should update state when clicking other bucket toggle', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -631,20 +618,15 @@ describe('terms', () => {
|
|||
},
|
||||
} as EuiSwitchEvent);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...(state.layers.first.columns.col1 as TermsIndexPatternColumn).params,
|
||||
otherBucket: true,
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...(layer.columns.col1 as TermsIndexPatternColumn).params,
|
||||
otherBucket: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -652,15 +634,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should render current order by value and options', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -675,15 +656,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should update state with the order by value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
layerId="first"
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -696,22 +676,17 @@ describe('terms', () => {
|
|||
},
|
||||
} as React.ChangeEvent<HTMLSelectElement>);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...(state.layers.first.columns.col1 as TermsIndexPatternColumn).params,
|
||||
orderBy: {
|
||||
type: 'column',
|
||||
columnId: 'col2',
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...(layer.columns.col1 as TermsIndexPatternColumn).params,
|
||||
orderBy: {
|
||||
type: 'column',
|
||||
columnId: 'col2',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -720,15 +695,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should render current order direction value and options', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -741,15 +715,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should update state with the order direction value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = shallow(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -762,20 +735,15 @@ describe('terms', () => {
|
|||
},
|
||||
} as React.ChangeEvent<HTMLSelectElement>);
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...(state.layers.first.columns.col1 as TermsIndexPatternColumn).params,
|
||||
orderDirection: 'desc',
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...(layer.columns.col1 as TermsIndexPatternColumn).params,
|
||||
orderDirection: 'desc',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -783,15 +751,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should render current size value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -799,15 +766,14 @@ describe('terms', () => {
|
|||
});
|
||||
|
||||
it('should update state with the size value', () => {
|
||||
const setStateSpy = jest.fn();
|
||||
const updateLayerSpy = jest.fn();
|
||||
const instance = mount(
|
||||
<InlineOptions
|
||||
{...defaultProps}
|
||||
state={state}
|
||||
setState={setStateSpy}
|
||||
layer={layer}
|
||||
updateLayer={updateLayerSpy}
|
||||
columnId="col1"
|
||||
layerId="first"
|
||||
currentColumn={state.layers.first.columns.col1 as TermsIndexPatternColumn}
|
||||
currentColumn={layer.columns.col1 as TermsIndexPatternColumn}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -815,20 +781,15 @@ describe('terms', () => {
|
|||
instance.find(ValuesRangeInput).prop('onChange')!(7);
|
||||
});
|
||||
|
||||
expect(setStateSpy).toHaveBeenCalledWith({
|
||||
...state,
|
||||
layers: {
|
||||
first: {
|
||||
...state.layers.first,
|
||||
columns: {
|
||||
...state.layers.first.columns,
|
||||
col1: {
|
||||
...state.layers.first.columns.col1,
|
||||
params: {
|
||||
...(state.layers.first.columns.col1 as TermsIndexPatternColumn).params,
|
||||
size: 7,
|
||||
},
|
||||
},
|
||||
expect(updateLayerSpy).toHaveBeenCalledWith({
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
col1: {
|
||||
...layer.columns.col1,
|
||||
params: {
|
||||
...(layer.columns.col1 as TermsIndexPatternColumn).params,
|
||||
size: 7,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -837,7 +798,6 @@ describe('terms', () => {
|
|||
});
|
||||
describe('getErrorMessage', () => {
|
||||
let indexPattern: IndexPattern;
|
||||
let layer: IndexPatternLayer;
|
||||
beforeEach(() => {
|
||||
indexPattern = createMockedIndexPattern();
|
||||
layer = {
|
||||
|
|
|
@ -18,7 +18,7 @@ import { operationDefinitionMap, OperationType } from '../operations';
|
|||
import { TermsIndexPatternColumn } from './definitions/terms';
|
||||
import { DateHistogramIndexPatternColumn } from './definitions/date_histogram';
|
||||
import { AvgIndexPatternColumn } from './definitions/metrics';
|
||||
import type { IndexPattern, IndexPatternPrivateState, IndexPatternLayer } from '../types';
|
||||
import type { IndexPattern, IndexPatternLayer } from '../types';
|
||||
import { documentField } from '../document_field';
|
||||
import { getFieldByNameFactory } from '../pure_helpers';
|
||||
import { generateId } from '../../id_generator';
|
||||
|
@ -1266,31 +1266,19 @@ describe('state_helpers', () => {
|
|||
sourceField: 'timestamp',
|
||||
};
|
||||
|
||||
const state: IndexPatternPrivateState = {
|
||||
indexPatternRefs: [],
|
||||
existingFields: {},
|
||||
indexPatterns: {},
|
||||
currentIndexPatternId: '1',
|
||||
isFirstExistenceFetch: false,
|
||||
layers: {
|
||||
first: {
|
||||
expect(
|
||||
updateColumnParam({
|
||||
layer: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1'],
|
||||
columns: {
|
||||
col1: currentColumn,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId: 'first',
|
||||
currentColumn,
|
||||
columnId: 'col1',
|
||||
paramName: 'interval',
|
||||
value: 'M',
|
||||
}).layers.first.columns.col1
|
||||
}).columns.col1
|
||||
).toEqual({
|
||||
...currentColumn,
|
||||
params: { interval: 'M' },
|
||||
|
@ -1307,31 +1295,19 @@ describe('state_helpers', () => {
|
|||
sourceField: 'bytes',
|
||||
};
|
||||
|
||||
const state: IndexPatternPrivateState = {
|
||||
indexPatternRefs: [],
|
||||
existingFields: {},
|
||||
indexPatterns: {},
|
||||
currentIndexPatternId: '1',
|
||||
isFirstExistenceFetch: false,
|
||||
layers: {
|
||||
first: {
|
||||
expect(
|
||||
updateColumnParam({
|
||||
layer: {
|
||||
indexPatternId: '1',
|
||||
columnOrder: ['col1'],
|
||||
columns: {
|
||||
col1: currentColumn,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
expect(
|
||||
updateColumnParam({
|
||||
state,
|
||||
layerId: 'first',
|
||||
currentColumn,
|
||||
columnId: 'col1',
|
||||
paramName: 'format',
|
||||
value: { id: 'bytes' },
|
||||
}).layers.first.columns.col1
|
||||
}).columns.col1
|
||||
).toEqual({
|
||||
...currentColumn,
|
||||
params: { format: { id: 'bytes' } },
|
||||
|
|
|
@ -13,14 +13,8 @@ import {
|
|||
IndexPatternColumn,
|
||||
RequiredReference,
|
||||
} from './definitions';
|
||||
import type {
|
||||
IndexPattern,
|
||||
IndexPatternField,
|
||||
IndexPatternLayer,
|
||||
IndexPatternPrivateState,
|
||||
} from '../types';
|
||||
import type { IndexPattern, IndexPatternField, IndexPatternLayer } from '../types';
|
||||
import { getSortScoreByPriority } from './operations';
|
||||
import { mergeLayer } from '../state_helpers';
|
||||
import { generateId } from '../../id_generator';
|
||||
import { ReferenceBasedIndexPatternColumn } from './definitions/column_types';
|
||||
|
||||
|
@ -390,40 +384,29 @@ export function getMetricOperationTypes(field: IndexPatternField) {
|
|||
}
|
||||
|
||||
export function updateColumnParam<C extends IndexPatternColumn>({
|
||||
state,
|
||||
layerId,
|
||||
currentColumn,
|
||||
layer,
|
||||
columnId,
|
||||
paramName,
|
||||
value,
|
||||
}: {
|
||||
state: IndexPatternPrivateState;
|
||||
layerId: string;
|
||||
currentColumn: C;
|
||||
layer: IndexPatternLayer;
|
||||
columnId: string;
|
||||
paramName: string;
|
||||
value: unknown;
|
||||
}): IndexPatternPrivateState {
|
||||
const columnId = Object.entries(state.layers[layerId].columns).find(
|
||||
([_columnId, column]) => column === currentColumn
|
||||
)![0];
|
||||
|
||||
const layer = state.layers[layerId];
|
||||
|
||||
return mergeLayer({
|
||||
state,
|
||||
layerId,
|
||||
newLayer: {
|
||||
columns: {
|
||||
...layer.columns,
|
||||
[columnId]: {
|
||||
...currentColumn,
|
||||
params: {
|
||||
...currentColumn.params,
|
||||
[paramName]: value,
|
||||
},
|
||||
}): IndexPatternLayer {
|
||||
return {
|
||||
...layer,
|
||||
columns: {
|
||||
...layer.columns,
|
||||
[columnId]: {
|
||||
...layer.columns[columnId],
|
||||
params: {
|
||||
...layer.columns[columnId].params,
|
||||
[paramName]: value,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
} as Record<string, IndexPatternColumn>,
|
||||
};
|
||||
}
|
||||
|
||||
function adjustColumnReferencesForChangedColumn(
|
||||
|
|
Loading…
Reference in a new issue