Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[Lens] Auto date histogram #43775

Merged
merged 4 commits into from
Aug 23, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,123 +4,10 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { createMockedIndexPattern, createMockedRestrictedIndexPattern } from '../mocks';

export function getIndexPatterns() {
return new Promise(resolve => {
resolve([
{
id: '1',
title: 'my-fake-index-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'start_date',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'memory',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
{
name: 'dest',
type: 'string',
aggregatable: true,
searchable: true,
},
],
},
{
id: '2',
title: 'my-fake-restricted-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
],
typeMeta: {
params: {
rollup_index: 'my-fake-index-pattern',
},
aggs: {
terms: {
source: {
agg: 'terms',
},
},
date_histogram: {
timestamp: {
agg: 'date_histogram',
fixed_interval: '1d',
delay: '7d',
time_zone: 'UTC',
},
},
histogram: {
bytes: {
agg: 'histogram',
interval: 1000,
},
},
avg: {
bytes: {
agg: 'avg',
},
},
max: {
bytes: {
agg: 'max',
},
},
min: {
bytes: {
agg: 'min',
},
},
sum: {
bytes: {
agg: 'sum',
},
},
},
},
},
]);
resolve([createMockedIndexPattern(), createMockedRestrictedIndexPattern()]);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ import {
OperationType,
} from '../indexpattern';

import { getAvailableOperationsByMetadata, buildColumn } from '../operations';
import {
getAvailableOperationsByMetadata,
buildColumn,
operationDefinitionMap,
OperationDefinition,
} from '../operations';
import { PopoverEditor } from './popover_editor';
import { DragContextState, ChildDragDropProvider, DragDrop } from '../../drag_drop';
import { changeColumn, deleteColumn } from '../state_helpers';
import { isDraggedField } from '../utils';
import { isDraggedField, hasField } from '../utils';

export type IndexPatternDimensionPanelProps = DatasourceDimensionPanelProps & {
state: IndexPatternPrivateState;
Expand Down Expand Up @@ -109,18 +114,42 @@ export const IndexPatternDimensionPanel = memo(function IndexPatternDimensionPan
return;
}

props.setState(
changeColumn({
state: props.state,
layerId,
columnId: props.columnId,
newColumn: buildColumn({
const operationsForNewField =
operationFieldSupportMatrix.operationByField[droppedItem.field.name];

// We need to check if dragging in a new field, was just a field change on the same
// index pattern and on the same operations (therefore checking if the new field supports
// our previous operation)
const hasFieldChanged =
selectedColumn &&
hasField(selectedColumn) &&
selectedColumn.sourceField !== droppedItem.field.name &&
operationsForNewField &&
operationsForNewField.includes(selectedColumn.operationType);

// If only the field has changed use the onFieldChange method on the operation to get the
// new column, otherwise use the regular buildColumn to get a new column.
const newColumn = hasFieldChanged
? (operationDefinitionMap[selectedColumn.operationType] as OperationDefinition<
IndexPatternColumn
>).onFieldChange(selectedColumn, currentIndexPattern, droppedItem.field)
: buildColumn({
columns: props.state.layers[props.layerId].columns,
indexPattern: currentIndexPattern,
layerId,
suggestedPriority: props.suggestedPriority,
field: droppedItem.field,
}),
});

props.setState(
changeColumn({
state: props.state,
layerId,
columnId: props.columnId,
newColumn,
// If the field has changed, the onFieldChange method needs to take care of everything including moving
// over params. If we create a new column above we want changeColumn to move over params.
keepParams: !hasFieldChanged,
})
);
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,12 @@ import {
IndexPatternField,
} from '../indexpattern';
import { IndexPatternDimensionPanelProps, OperationFieldSupportMatrix } from './dimension_panel';
import { operationDefinitionMap, getOperationDisplay, buildColumn } from '../operations';
import {
operationDefinitionMap,
getOperationDisplay,
buildColumn,
OperationDefinition,
} from '../operations';
import { deleteColumn, changeColumn } from '../state_helpers';
import { FieldSelect } from './field_select';
import { hasField } from '../utils';
Expand Down Expand Up @@ -271,24 +276,44 @@ export function PopoverEditor(props: PopoverEditorProps) {
);
}}
onChoose={choice => {
const column = buildColumn({
columns: props.state.layers[props.layerId].columns,
field: 'field' in choice ? fieldMap[choice.field] : undefined,
indexPattern: currentIndexPattern,
layerId: props.layerId,
suggestedPriority: props.suggestedPriority,
op:
incompatibleSelectedOperationType ||
('field' in choice ? choice.operationType : undefined),
asDocumentOperation: choice.type === 'document',
});
let column: IndexPatternColumn;
if (
!incompatibleSelectedOperationType &&
selectedColumn &&
('field' in choice && choice.operationType === selectedColumn.operationType)
) {
// If we just changed the field are not in an error state and the operation didn't change,
// we use the operations onFieldChange method to calculate the new column.
const operation = operationDefinitionMap[
choice.operationType
] as OperationDefinition<IndexPatternColumn>;
column = operation.onFieldChange(
selectedColumn,
currentIndexPattern,
fieldMap[choice.field]
);
} else {
// Otherwise we'll use the buildColumn method to calculate a new column
column = buildColumn({
columns: props.state.layers[props.layerId].columns,
field: 'field' in choice ? fieldMap[choice.field] : undefined,
indexPattern: currentIndexPattern,
layerId: props.layerId,
suggestedPriority: props.suggestedPriority,
op:
incompatibleSelectedOperationType ||
('field' in choice ? choice.operationType : undefined),
asDocumentOperation: choice.type === 'document',
});
}

setState(
changeColumn({
state,
layerId,
columnId,
newColumn: column,
keepParams: false,
})
);
setInvalidOperationType(null);
Expand Down
117 changes: 117 additions & 0 deletions x-pack/legacy/plugins/lens/public/indexpattern_plugin/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,123 @@
*/

import { DragContextState } from '../drag_drop';
import { IndexPattern } from './indexpattern';

export const createMockedIndexPattern = (): IndexPattern => ({
id: '1',
title: 'my-fake-index-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'start_date',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'memory',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
{
name: 'dest',
type: 'string',
aggregatable: true,
searchable: true,
},
],
});

export const createMockedRestrictedIndexPattern = () => ({
id: '2',
title: 'my-fake-restricted-pattern',
timeFieldName: 'timestamp',
fields: [
{
name: 'timestamp',
type: 'date',
aggregatable: true,
searchable: true,
},
{
name: 'bytes',
type: 'number',
aggregatable: true,
searchable: true,
},
{
name: 'source',
type: 'string',
aggregatable: true,
searchable: true,
},
],
typeMeta: {
params: {
rollup_index: 'my-fake-index-pattern',
},
aggs: {
terms: {
source: {
agg: 'terms',
},
},
date_histogram: {
timestamp: {
agg: 'date_histogram',
fixed_interval: '1d',
delay: '7d',
time_zone: 'UTC',
},
},
histogram: {
bytes: {
agg: 'histogram',
interval: 1000,
},
},
avg: {
bytes: {
agg: 'avg',
},
},
max: {
bytes: {
agg: 'max',
},
},
min: {
bytes: {
agg: 'min',
},
},
sum: {
bytes: {
agg: 'sum',
},
},
},
},
});

export function createMockedDragDropContext(): jest.Mocked<DragContextState> {
return {
Expand Down
Loading