kibana/x-pack/plugins/lens/public/datatable_visualization/expression.tsx
Tim Roes ebbc062689
Move Lens frontend to Kibana Platform (#62965)
* Move Lens frontend to Kibana platform

* Fix line breaks

* Fix jest tests

* Fix remaining test

* Remove old Lens plugin entry

* Fix i18n prefix

* Add config schema

* Address review
2020-04-15 12:22:37 +02:00

167 lines
4.2 KiB
TypeScript

/*
* 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 React from 'react';
import ReactDOM from 'react-dom';
import { i18n } from '@kbn/i18n';
import { EuiBasicTable } from '@elastic/eui';
import { FormatFactory, LensMultiTable } from '../types';
import {
ExpressionFunctionDefinition,
ExpressionRenderDefinition,
IInterpreterRenderHandlers,
} from '../../../../../src/plugins/expressions/public';
import { VisualizationContainer } from '../visualization_container';
export interface DatatableColumns {
columnIds: string[];
}
interface Args {
title: string;
columns: DatatableColumns & { type: 'lens_datatable_columns' };
}
export interface DatatableProps {
data: LensMultiTable;
args: Args;
}
export interface DatatableRender {
type: 'render';
as: 'lens_datatable_renderer';
value: DatatableProps;
}
export const datatable: ExpressionFunctionDefinition<
'lens_datatable',
LensMultiTable,
Args,
DatatableRender
> = {
name: 'lens_datatable',
type: 'render',
inputTypes: ['lens_multitable'],
help: i18n.translate('xpack.lens.datatable.expressionHelpLabel', {
defaultMessage: 'Datatable renderer',
}),
args: {
title: {
types: ['string'],
help: i18n.translate('xpack.lens.datatable.titleLabel', {
defaultMessage: 'Title',
}),
},
columns: {
types: ['lens_datatable_columns'],
help: '',
},
},
fn(data, args) {
return {
type: 'render',
as: 'lens_datatable_renderer',
value: {
data,
args,
},
};
},
};
type DatatableColumnsResult = DatatableColumns & { type: 'lens_datatable_columns' };
export const datatableColumns: ExpressionFunctionDefinition<
'lens_datatable_columns',
null,
DatatableColumns,
DatatableColumnsResult
> = {
name: 'lens_datatable_columns',
aliases: [],
type: 'lens_datatable_columns',
help: '',
inputTypes: ['null'],
args: {
columnIds: {
types: ['string'],
multi: true,
help: '',
},
},
fn: function fn(input: unknown, args: DatatableColumns) {
return {
type: 'lens_datatable_columns',
...args,
};
},
};
export const getDatatableRenderer = (
formatFactory: Promise<FormatFactory>
): ExpressionRenderDefinition<DatatableProps> => ({
name: 'lens_datatable_renderer',
displayName: i18n.translate('xpack.lens.datatable.visualizationName', {
defaultMessage: 'Datatable',
}),
help: '',
validate: () => undefined,
reuseDomNode: true,
render: async (
domNode: Element,
config: DatatableProps,
handlers: IInterpreterRenderHandlers
) => {
const resolvedFormatFactory = await formatFactory;
ReactDOM.render(
<DatatableComponent {...config} formatFactory={resolvedFormatFactory} />,
domNode,
() => {
handlers.done();
}
);
handlers.onDestroy(() => ReactDOM.unmountComponentAtNode(domNode));
},
});
function DatatableComponent(props: DatatableProps & { formatFactory: FormatFactory }) {
const [firstTable] = Object.values(props.data.tables);
const formatters: Record<string, ReturnType<FormatFactory>> = {};
firstTable.columns.forEach(column => {
formatters[column.id] = props.formatFactory(column.formatHint);
});
return (
<VisualizationContainer>
<EuiBasicTable
className="lnsDataTable"
data-test-subj="lnsDataTable"
columns={props.args.columns.columnIds
.map(field => {
const col = firstTable.columns.find(c => c.id === field);
return {
field,
name: (col && col.name) || '',
};
})
.filter(({ field }) => !!field)}
items={
firstTable
? firstTable.rows.map(row => {
const formattedRow: Record<string, unknown> = {};
Object.entries(formatters).forEach(([columnId, formatter]) => {
formattedRow[columnId] = formatter.convert(row[columnId]);
});
return formattedRow;
})
: []
}
/>
</VisualizationContainer>
);
}