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] Rename columns #38278

Merged
merged 39 commits into from
Jun 12, 2019
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
f46855e
[lens] Dimension panel lets users select operations and fields indivi…
wylieconlon May 30, 2019
7ae8d66
Basic xy chart suggestions
chrisdavies May 31, 2019
6e4d523
Re-apply XY config panel after force merge
chrisdavies May 31, 2019
a57f406
Merge upstream
chrisdavies May 31, 2019
dcde41d
Merge remote-tracking branch 'origin/feature/lens' into lens/aggregat…
wylieconlon May 31, 2019
0a9facd
Tweaks per Wylie's feedback
chrisdavies May 31, 2019
291883c
Merge branch 'feature/lens' of github.com:elastic/kibana into lens/xy…
chrisdavies Jun 3, 2019
be86ff3
Add xy chart internationalization
chrisdavies Jun 3, 2019
4a3ea3f
Merge remote-tracking branch 'origin/master' into lens/aggregations
wylieconlon Jun 3, 2019
30f69e3
Split files and add tests
wylieconlon Jun 3, 2019
82e2865
Merge remote-tracking branch 'origin/feature/lens' into lens/aggregat…
wylieconlon Jun 3, 2019
18efd00
Update xy chart i18n implementation
chrisdavies Jun 4, 2019
fe4238a
Fix dimension labeling and add clear button
wylieconlon Jun 4, 2019
1fe793b
Fix i18n id
chrisdavies Jun 5, 2019
7a04220
Merge upstream
chrisdavies Jun 5, 2019
91691fb
pass datasource api into visualization init
flash1293 Jun 5, 2019
dbd98fc
fix type errors
flash1293 Jun 5, 2019
4d09416
Support more aggregations, aggregation nesting, rollups, and clearing
wylieconlon Jun 5, 2019
6f81ded
Merge remote-tracking branch 'origin/feature/lens' into lens/aggregat…
wylieconlon Jun 5, 2019
3bf54d4
Fix esaggs expression
wylieconlon Jun 5, 2019
60408c5
Merge branch 'feature/lens' into lens/datasource-in-vis
flash1293 Jun 6, 2019
1a0ac97
fix test
flash1293 Jun 6, 2019
4bbb927
Merge branch 'lens/datasource-in-vis' into lens/aggregations
flash1293 Jun 6, 2019
cf82581
add function to remap columns to their real names
flash1293 Jun 6, 2019
07188d1
add tests for rename_columns function
flash1293 Jun 6, 2019
9983e86
Merge branch 'feature/lens' into lens/datasource-in-vis
flash1293 Jun 6, 2019
81df38a
Merge branch 'feature/lens' into lens/rename-columns
flash1293 Jun 6, 2019
241187b
Merge remote-tracking branch 'origin/feature/lens' into lens/aggregat…
wylieconlon Jun 6, 2019
8c50598
Increase top-level test coverage of dimension panel
wylieconlon Jun 6, 2019
64a8951
switch initialize parameters
flash1293 Jun 7, 2019
08a7a80
Merge branch 'feature/lens' into lens/datasource-in-vis
flash1293 Jun 7, 2019
d4f4ea5
fix test
flash1293 Jun 7, 2019
a33283c
Merge branch 'lens/datasource-in-vis' into lens/rename-columns
flash1293 Jun 7, 2019
e02f87c
Fix tests
flash1293 Jun 7, 2019
680ddeb
Merge branch 'lens/aggregations' into lens/rename-columns
flash1293 Jun 7, 2019
934e4cc
Merge branch 'feature/lens' into lens/rename-columns
flash1293 Jun 7, 2019
dbef025
Merge branch 'feature/lens' into lens/rename-columns
flash1293 Jun 8, 2019
5f1b4c3
Merge branch 'feature/lens' into lens/rename-columns
flash1293 Jun 11, 2019
70dda55
improve code style and add i18n for expression function
flash1293 Jun 12, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ describe('IndexPattern Data Source', () => {
};
const state = await indexPatternDatasource.initialize(queryPersistedState);
expect(indexPatternDatasource.toExpression(state)).toMatchInlineSnapshot(
`"esdocs index=\\"my-fake-index-pattern\\" fields=\\"source, bytes\\" sort=\\"source, DESC\\""`
`"esdocs index=\\"my-fake-index-pattern\\" fields=\\"source, bytes\\" sort=\\"source, DESC\\" | lens_rename_columns idMap='{\\"source\\":\\"col1\\",\\"bytes\\":\\"col2\\"}'"`
);
});

Expand Down Expand Up @@ -262,7 +262,7 @@ describe('IndexPattern Data Source', () => {
index=\\"1\\"
metricsAtAllLevels=\\"false\\"
partialRows=\\"false\\"
aggConfigs='[{\\"id\\":\\"col1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}},{\\"id\\":\\"col2\\",\\"enabled\\":true,\\"type\\":\\"date_histogram\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"timestamp\\",\\"timeRange\\":{\\"from\\":\\"now-1d\\",\\"to\\":\\"now\\"},\\"useNormalizedEsInterval\\":true,\\"interval\\":\\"1h\\",\\"drop_partials\\":false,\\"min_doc_count\\":1,\\"extended_bounds\\":{}}}]'"
aggConfigs='[{\\"id\\":\\"col1\\",\\"enabled\\":true,\\"type\\":\\"count\\",\\"schema\\":\\"metric\\",\\"params\\":{}},{\\"id\\":\\"col2\\",\\"enabled\\":true,\\"type\\":\\"date_histogram\\",\\"schema\\":\\"segment\\",\\"params\\":{\\"field\\":\\"timestamp\\",\\"timeRange\\":{\\"from\\":\\"now-1d\\",\\"to\\":\\"now\\"},\\"useNormalizedEsInterval\\":true,\\"interval\\":\\"1h\\",\\"drop_partials\\":false,\\"min_doc_count\\":1,\\"extended_bounds\\":{}}}]' | lens_rename_columns idMap='{\\"col-0-col1\\":\\"col1\\",\\"col-1-col2\\":\\"col2\\"}'"
`);
});
});
Expand Down
34 changes: 32 additions & 2 deletions x-pack/plugins/lens/public/indexpattern_plugin/plugin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,39 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { Registry } from '@kbn/interpreter/target/common';
import { CoreSetup } from 'src/core/public';
import chrome from 'ui/chrome';
import { toastNotifications } from 'ui/notify';
import { getIndexPatternDatasource } from './indexpattern';

import {
functionsRegistry,
// @ts-ignore untyped dependency
} from '../../../../../src/legacy/core_plugins/interpreter/public/registries';
import { ExpressionFunction } from '../../../../../src/legacy/core_plugins/interpreter/public';
import { renameColumns } from './rename_columns';

// TODO these are intermediary types because interpreter is not typed yet
// They can get replaced by references to the real interfaces as soon as they
// are available

export interface IndexPatternDatasourcePluginPlugins {
interpreter: InterpreterSetup;
}

export interface InterpreterSetup {
functionsRegistry: Registry<
ExpressionFunction<string, unknown, unknown, unknown>,
ExpressionFunction<string, unknown, unknown, unknown>
>;
}

class IndexPatternDatasourcePlugin {
constructor() {}

setup() {
setup(_core: CoreSetup | null, { interpreter }: IndexPatternDatasourcePluginPlugins) {
interpreter.functionsRegistry.register(() => renameColumns);
return getIndexPatternDatasource(chrome, toastNotifications);
}

Expand All @@ -20,5 +45,10 @@ class IndexPatternDatasourcePlugin {

const plugin = new IndexPatternDatasourcePlugin();

export const indexPatternDatasourceSetup = () => plugin.setup();
export const indexPatternDatasourceSetup = () =>
plugin.setup(null, {
interpreter: {
functionsRegistry,
},
});
export const indexPatternDatasourceStop = () => plugin.stop();
103 changes: 103 additions & 0 deletions x-pack/plugins/lens/public/indexpattern_plugin/rename_columns.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { renameColumns } from './rename_columns';
import { KibanaDatatable } from 'src/legacy/core_plugins/interpreter/types';

describe('rename_columns', () => {
it('should rename columns of a given datatable', () => {
const input: KibanaDatatable = {
type: 'kibana_datatable',
columns: [{ id: 'a', name: 'A' }, { id: 'b', name: 'B' }],
rows: [{ a: 1, b: 2 }, { a: 3, b: 4 }, { a: 5, b: 6 }, { a: 7, b: 8 }],
};

const idMap = {
a: 'b',
b: 'c',
};

expect(renameColumns.fn(input, { idMap: JSON.stringify(idMap) }, {})).toMatchInlineSnapshot(`
Object {
"columns": Array [
Object {
"id": "b",
"name": "A",
},
Object {
"id": "c",
"name": "B",
},
],
"rows": Array [
Object {
"b": 1,
"c": 2,
},
Object {
"b": 3,
"c": 4,
},
Object {
"b": 5,
"c": 6,
},
Object {
"b": 7,
"c": 8,
},
],
"type": "kibana_datatable",
}
`);
});

it('should keep columns which are not mapped', () => {
const input: KibanaDatatable = {
type: 'kibana_datatable',
columns: [{ id: 'a', name: 'A' }, { id: 'b', name: 'B' }],
rows: [{ a: 1, b: 2 }, { a: 3, b: 4 }, { a: 5, b: 6 }, { a: 7, b: 8 }],
};

const idMap = {
b: 'c',
};

expect(renameColumns.fn(input, { idMap: JSON.stringify(idMap) }, {})).toMatchInlineSnapshot(`
Object {
"columns": Array [
Object {
"id": "a",
"name": "A",
},
Object {
"id": "c",
"name": "B",
},
],
"rows": Array [
Object {
"a": 1,
"c": 2,
},
Object {
"a": 3,
"c": 4,
},
Object {
"a": 5,
"c": 6,
},
Object {
"a": 7,
"c": 8,
},
],
"type": "kibana_datatable",
}
`);
});
});
57 changes: 57 additions & 0 deletions x-pack/plugins/lens/public/indexpattern_plugin/rename_columns.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import { ExpressionFunction } from 'src/legacy/core_plugins/interpreter/types';
import { KibanaDatatable } from '../types';

interface RemapArgs {
idMap: string;
}

export const renameColumns: ExpressionFunction<
'lens_rename_columns',
KibanaDatatable,
RemapArgs,
KibanaDatatable
> = {
name: 'lens_rename_columns',
type: 'kibana_datatable',
help: 'A helper to rename the columns of a datatable',
args: {
idMap: {
types: ['string'],
help:
'A JSON encoded object in which keys are the old column ids and values are the corresponding new ones. All other columns ids are kept.',
},
},
flash1293 marked this conversation as resolved.
Show resolved Hide resolved
context: {
types: ['kibana_datatable'],
},
fn(data: KibanaDatatable, { idMap: encodedIdMap }: RemapArgs) {
const idMap = JSON.parse(encodedIdMap) as Record<string, string>;
return {
type: 'kibana_datatable',
rows: data.rows.map(row => {
const mappedRow: Record<string, unknown> = {};
Object.entries(idMap).forEach(([fromId, toId]) => {
mappedRow[toId] = row[fromId];
});

Object.keys(row)
.filter(id => !(id in idMap))
.forEach(unchangedId => {
mappedRow[unchangedId] = row[unchangedId];
});
flash1293 marked this conversation as resolved.
Show resolved Hide resolved

return mappedRow;
}),
columns: data.columns.map(column => ({
...column,
id: idMap[column.id] ? idMap[column.id] : column.id,
})),
};
},
};
21 changes: 18 additions & 3 deletions x-pack/plugins/lens/public/indexpattern_plugin/to_expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,16 @@ export function toExpression(state: IndexPatternPrivateState) {
const indexName = state.indexPatterns[state.currentIndexPatternId].title;

if (sortedColumns.every(({ operationType }) => operationType === 'value')) {
const idMap = fieldNames.reduce(
(currentIdMap, fieldName, index) => ({
...currentIdMap,
[fieldName]: state.columnOrder[index],
}),
{} as Record<string, string>
);
return `esdocs index="${indexName}" fields="${fieldNames.join(', ')}" sort="${
fieldNames[0]
}, DESC"`;
}, DESC" | lens_rename_columns idMap='${JSON.stringify(idMap)}'`;
} else if (sortedColumns.length) {
const firstMetric = sortedColumns.findIndex(({ isBucketed }) => !isBucketed);
const aggs = sortedColumns.map((col, index) => {
Expand Down Expand Up @@ -83,12 +90,20 @@ export function toExpression(state: IndexPatternPrivateState) {
}
});

const idMap = state.columnOrder.reduce(
(currentIdMap, columnId, index) => ({
...currentIdMap,
[`col-${index}-${columnId}`]: columnId,
}),
{} as Record<string, string>
);

return `esaggs
index="${state.currentIndexPatternId}"
metricsAtAllLevels="false"
partialRows="false"
aggConfigs='${JSON.stringify(aggs)}'`;
aggConfigs='${JSON.stringify(aggs)}' | lens_rename_columns idMap='${JSON.stringify(idMap)}'`;
}

return '';
return null;
}