ebbc062689
* 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
167 lines
4.2 KiB
TypeScript
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>
|
|
);
|
|
}
|