mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
* Convert EuiTableOfRecords to EuiBasicTable in scripted fields table. * Convert from EuiBasicTable to EuiInMemoryTable. * Fix bug with filtering and show 'no items' message when the filter doens't match any scripted fields.
This commit is contained in:
parent
1def6ed78f
commit
5168d8fcdc
13 changed files with 316 additions and 566 deletions
|
@ -2,7 +2,9 @@
|
|||
|
||||
exports[`ScriptedFieldsTable should filter based on the lang filter 1`] = `
|
||||
<div>
|
||||
<header />
|
||||
<header
|
||||
addScriptedFieldUrl="#"
|
||||
/>
|
||||
<call-outs
|
||||
deprecatedLangsInUse={
|
||||
Array [
|
||||
|
@ -11,11 +13,6 @@ exports[`ScriptedFieldsTable should filter based on the lang filter 1`] = `
|
|||
}
|
||||
painlessDocLink="painlessDocs"
|
||||
/>
|
||||
<eui-button
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
>
|
||||
Add scripted field
|
||||
</eui-button>
|
||||
<eui-spacer
|
||||
size="l"
|
||||
/>
|
||||
|
@ -27,52 +24,33 @@ exports[`ScriptedFieldsTable should filter based on the lang filter 1`] = `
|
|||
"getScriptedFields": [Function],
|
||||
}
|
||||
}
|
||||
model={
|
||||
Object {
|
||||
"criteria": Object {
|
||||
"page": Object {
|
||||
"index": 0,
|
||||
"size": 10,
|
||||
},
|
||||
"sort": Object {
|
||||
"direction": "asc",
|
||||
"field": "name",
|
||||
},
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "ScriptedField",
|
||||
"script": "x++",
|
||||
},
|
||||
"data": Object {
|
||||
"records": Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "ScriptedField",
|
||||
"script": "x++",
|
||||
},
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
],
|
||||
"totalRecordCount": 2,
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
onDataCriteriaChange={[Function]}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ScriptedFieldsTable should filter based on the query bar 1`] = `
|
||||
<div>
|
||||
<header />
|
||||
<header
|
||||
addScriptedFieldUrl="#"
|
||||
/>
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDocs"
|
||||
/>
|
||||
<eui-button
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
>
|
||||
Add scripted field
|
||||
</eui-button>
|
||||
<eui-spacer
|
||||
size="l"
|
||||
/>
|
||||
|
@ -84,65 +62,53 @@ exports[`ScriptedFieldsTable should filter based on the query bar 1`] = `
|
|||
"getScriptedFields": [Function],
|
||||
}
|
||||
}
|
||||
model={
|
||||
Object {
|
||||
"criteria": Object {
|
||||
"page": Object {
|
||||
"index": 0,
|
||||
"size": 10,
|
||||
},
|
||||
"sort": Object {
|
||||
"direction": "asc",
|
||||
"field": "name",
|
||||
},
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
"data": Object {
|
||||
"records": Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
],
|
||||
"totalRecordCount": 1,
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
onDataCriteriaChange={[Function]}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ScriptedFieldsTable should hide the table if there are no scripted fields 1`] = `
|
||||
<div>
|
||||
<header />
|
||||
<header
|
||||
addScriptedFieldUrl="#"
|
||||
/>
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDocs"
|
||||
/>
|
||||
<eui-button
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
>
|
||||
Add scripted field
|
||||
</eui-button>
|
||||
<eui-spacer
|
||||
size="l"
|
||||
/>
|
||||
<Table
|
||||
deleteField={[Function]}
|
||||
editField={[Function]}
|
||||
indexPattern={
|
||||
Object {
|
||||
"getScriptedFields": [Function],
|
||||
}
|
||||
}
|
||||
items={Array []}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ScriptedFieldsTable should render normally 1`] = `
|
||||
<div>
|
||||
<header />
|
||||
<header
|
||||
addScriptedFieldUrl="#"
|
||||
/>
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDocs"
|
||||
/>
|
||||
<eui-button
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
>
|
||||
Add scripted field
|
||||
</eui-button>
|
||||
<eui-spacer
|
||||
size="l"
|
||||
/>
|
||||
|
@ -154,52 +120,33 @@ exports[`ScriptedFieldsTable should render normally 1`] = `
|
|||
"getScriptedFields": [Function],
|
||||
}
|
||||
}
|
||||
model={
|
||||
Object {
|
||||
"criteria": Object {
|
||||
"page": Object {
|
||||
"index": 0,
|
||||
"size": 10,
|
||||
},
|
||||
"sort": Object {
|
||||
"direction": "asc",
|
||||
"field": "name",
|
||||
},
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "ScriptedField",
|
||||
"script": "x++",
|
||||
},
|
||||
"data": Object {
|
||||
"records": Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "ScriptedField",
|
||||
"script": "x++",
|
||||
},
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
],
|
||||
"totalRecordCount": 2,
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
onDataCriteriaChange={[Function]}
|
||||
/>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`ScriptedFieldsTable should show a delete modal 1`] = `
|
||||
<div>
|
||||
<header />
|
||||
<header
|
||||
addScriptedFieldUrl="#"
|
||||
/>
|
||||
<call-outs
|
||||
deprecatedLangsInUse={Array []}
|
||||
painlessDocLink="painlessDocs"
|
||||
/>
|
||||
<eui-button
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
>
|
||||
Add scripted field
|
||||
</eui-button>
|
||||
<eui-spacer
|
||||
size="l"
|
||||
/>
|
||||
|
@ -211,36 +158,20 @@ exports[`ScriptedFieldsTable should show a delete modal 1`] = `
|
|||
"getScriptedFields": [Function],
|
||||
}
|
||||
}
|
||||
model={
|
||||
Object {
|
||||
"criteria": Object {
|
||||
"page": Object {
|
||||
"index": 0,
|
||||
"size": 10,
|
||||
},
|
||||
"sort": Object {
|
||||
"direction": "asc",
|
||||
"field": "name",
|
||||
},
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "ScriptedField",
|
||||
"script": "x++",
|
||||
},
|
||||
"data": Object {
|
||||
"records": Array [
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "ScriptedField",
|
||||
"script": "x++",
|
||||
},
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
],
|
||||
"totalRecordCount": 2,
|
||||
Object {
|
||||
"lang": "painless",
|
||||
"name": "JustATest",
|
||||
"script": "z++",
|
||||
},
|
||||
}
|
||||
]
|
||||
}
|
||||
onDataCriteriaChange={[Function]}
|
||||
/>
|
||||
<eui-overlay-mask>
|
||||
<eui-confirm-modal
|
||||
|
|
|
@ -4,11 +4,8 @@ import { shallow } from 'enzyme';
|
|||
import { ScriptedFieldsTable } from '../scripted_fields_table';
|
||||
|
||||
jest.mock('@elastic/eui', () => ({
|
||||
EuiButton: 'eui-button',
|
||||
EuiTableOfRecords: 'eui-table-of-records',
|
||||
EuiTitle: 'eui-title',
|
||||
EuiText: 'eui-text',
|
||||
EuiButton: 'eui-button',
|
||||
EuiHorizontalRule: 'eui-horizontal-rule',
|
||||
EuiSpacer: 'eui-spacer',
|
||||
EuiCallOut: 'eui-call-out',
|
||||
|
@ -42,7 +39,7 @@ jest.mock('ui/documentation_links', () => ({
|
|||
|
||||
const helpers = {
|
||||
redirectToRoute: () => {},
|
||||
getRouteHref: () => {},
|
||||
getRouteHref: () => '#',
|
||||
};
|
||||
|
||||
const indexPattern = {
|
||||
|
|
|
@ -1,21 +1,45 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Header should render normally 1`] = `
|
||||
<div>
|
||||
<EuiTitle
|
||||
size="s"
|
||||
<EuiFlexGroup
|
||||
alignItems="center"
|
||||
component="div"
|
||||
gutterSize="l"
|
||||
justifyContent="flexStart"
|
||||
responsive={true}
|
||||
wrap={false}
|
||||
>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={true}
|
||||
>
|
||||
<h3>
|
||||
Scripted fields
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiText>
|
||||
<p>
|
||||
You can use scripted fields in visualizations and display them in your documents. However, you cannot search scripted fields.
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer
|
||||
size="s"
|
||||
/>
|
||||
</div>
|
||||
<EuiTitle
|
||||
size="s"
|
||||
>
|
||||
<h3>
|
||||
Scripted fields
|
||||
</h3>
|
||||
</EuiTitle>
|
||||
<EuiText>
|
||||
<p>
|
||||
You can use scripted fields in visualizations and display them in your documents. However, you cannot search scripted fields.
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem
|
||||
component="div"
|
||||
grow={false}
|
||||
>
|
||||
<EuiButton
|
||||
color="primary"
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
fill={false}
|
||||
href=""
|
||||
iconSide="left"
|
||||
type="button"
|
||||
>
|
||||
Add scripted field
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
`;
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Header } from '../header';
|
|||
describe('Header', () => {
|
||||
it('should render normally', async () => {
|
||||
const component = shallow(
|
||||
<Header/>
|
||||
<Header addScriptedFieldUrl="" />
|
||||
);
|
||||
|
||||
expect(component).toMatchSnapshot();
|
||||
|
|
|
@ -1,22 +1,39 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
EuiTitle,
|
||||
EuiButton,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiText,
|
||||
EuiSpacer,
|
||||
EuiTitle,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export const Header = () => (
|
||||
<div>
|
||||
<EuiTitle size="s">
|
||||
<h3>Scripted fields</h3>
|
||||
</EuiTitle>
|
||||
<EuiText>
|
||||
<p>
|
||||
You can use scripted fields in visualizations and display them in your documents.
|
||||
However, you cannot search scripted fields.
|
||||
</p>
|
||||
</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
</div>
|
||||
export const Header = ({ addScriptedFieldUrl }) => (
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="s">
|
||||
<h3>Scripted fields</h3>
|
||||
</EuiTitle>
|
||||
<EuiText>
|
||||
<p>
|
||||
You can use scripted fields in visualizations and display them in your documents.
|
||||
However, you cannot search scripted fields.
|
||||
</p>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
href={addScriptedFieldUrl}
|
||||
>
|
||||
Add scripted field
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
||||
Header.propTypes = {
|
||||
addScriptedFieldUrl: PropTypes.string.isRequired,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
export { Table } from './table';
|
||||
export { Header } from './header';
|
||||
export { CallOuts } from './call_outs';
|
|
@ -1,94 +1,77 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Table should render normally 1`] = `
|
||||
<EuiTableOfRecords
|
||||
config={
|
||||
Object {
|
||||
"columns": Array [
|
||||
Object {
|
||||
"dataType": "string",
|
||||
"description": "Name of the field",
|
||||
"field": "displayName",
|
||||
"name": "Name",
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"dataType": "string",
|
||||
"description": "Language used for the field",
|
||||
"field": "lang",
|
||||
"name": "Lang",
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"dataType": "string",
|
||||
"description": "Script for the field",
|
||||
"field": "script",
|
||||
"name": "Script",
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"description": "Format used for the field",
|
||||
"field": "name",
|
||||
"name": "Format",
|
||||
"render": [Function],
|
||||
"sortable": false,
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"description": "Edit this field",
|
||||
"icon": "pencil",
|
||||
"name": "Edit",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"color": "danger",
|
||||
"description": "Delete this field",
|
||||
"icon": "trash",
|
||||
"name": "Delete",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"name": "",
|
||||
},
|
||||
],
|
||||
"onDataCriteriaChange": [Function],
|
||||
"pagination": Object {
|
||||
"pageSizeOptions": Array [
|
||||
5,
|
||||
10,
|
||||
25,
|
||||
50,
|
||||
],
|
||||
<EuiInMemoryTable
|
||||
columns={
|
||||
Array [
|
||||
Object {
|
||||
"dataType": "string",
|
||||
"description": "Name of the field",
|
||||
"field": "displayName",
|
||||
"name": "Name",
|
||||
"sortable": true,
|
||||
},
|
||||
"recordId": "name",
|
||||
"selection": undefined,
|
||||
}
|
||||
}
|
||||
model={
|
||||
Object {
|
||||
"criteria": Object {
|
||||
"page": Object {
|
||||
"index": 0,
|
||||
"size": 10,
|
||||
},
|
||||
"sort": Object {
|
||||
"direction": "asc",
|
||||
"field": "name",
|
||||
},
|
||||
Object {
|
||||
"dataType": "string",
|
||||
"description": "Language used for the field",
|
||||
"field": "lang",
|
||||
"name": "Lang",
|
||||
"render": [Function],
|
||||
"sortable": true,
|
||||
},
|
||||
"data": Object {
|
||||
"records": Array [
|
||||
Object {
|
||||
"dataType": "string",
|
||||
"description": "Script for the field",
|
||||
"field": "script",
|
||||
"name": "Script",
|
||||
"sortable": true,
|
||||
},
|
||||
Object {
|
||||
"description": "Format used for the field",
|
||||
"field": "name",
|
||||
"name": "Format",
|
||||
"render": [Function],
|
||||
"sortable": false,
|
||||
},
|
||||
Object {
|
||||
"actions": Array [
|
||||
Object {
|
||||
"id": 1,
|
||||
"name": "Elastic",
|
||||
"description": "Edit this field",
|
||||
"icon": "pencil",
|
||||
"name": "Edit",
|
||||
"onClick": [Function],
|
||||
},
|
||||
Object {
|
||||
"color": "danger",
|
||||
"description": "Delete this field",
|
||||
"icon": "trash",
|
||||
"name": "Delete",
|
||||
"onClick": [Function],
|
||||
},
|
||||
],
|
||||
"totalRecordCount": 1,
|
||||
"name": "",
|
||||
},
|
||||
]
|
||||
}
|
||||
items={
|
||||
Array [
|
||||
Object {
|
||||
"id": 1,
|
||||
"name": "Elastic",
|
||||
},
|
||||
]
|
||||
}
|
||||
pagination={
|
||||
Object {
|
||||
"pageSizeOptions": Array [
|
||||
5,
|
||||
10,
|
||||
25,
|
||||
50,
|
||||
],
|
||||
}
|
||||
}
|
||||
sorting={true}
|
||||
/>
|
||||
`;
|
||||
|
||||
|
|
|
@ -13,32 +13,17 @@ const indexPattern = {
|
|||
}
|
||||
};
|
||||
|
||||
const model = {
|
||||
data: {
|
||||
records: [{ id: 1, name: 'Elastic' }],
|
||||
totalRecordCount: 1,
|
||||
},
|
||||
criteria: {
|
||||
page: {
|
||||
index: 0,
|
||||
size: 10,
|
||||
},
|
||||
sort: {
|
||||
field: 'name',
|
||||
direction: 'asc'
|
||||
},
|
||||
}
|
||||
};
|
||||
const items = [{ id: 1, name: 'Elastic' }];
|
||||
|
||||
describe('Table', () => {
|
||||
it('should render normally', async () => {
|
||||
const component = shallow(
|
||||
<Table
|
||||
indexPattern={indexPattern}
|
||||
model={model}
|
||||
items={items}
|
||||
editField={() => {}}
|
||||
deleteField={() => {}}
|
||||
onDataCriteriaChange={() => {}}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
|
@ -49,14 +34,14 @@ describe('Table', () => {
|
|||
const component = shallow(
|
||||
<Table
|
||||
indexPattern={indexPattern}
|
||||
model={model}
|
||||
items={items}
|
||||
editField={() => {}}
|
||||
deleteField={() => {}}
|
||||
onDataCriteriaChange={() => {}}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
const formatTableCell = shallow(component.prop('config').columns[3].render('Elastic'));
|
||||
const formatTableCell = shallow(component.prop('columns')[3].render('Elastic'));
|
||||
expect(formatTableCell).toMatchSnapshot();
|
||||
});
|
||||
|
||||
|
@ -66,15 +51,15 @@ describe('Table', () => {
|
|||
const component = shallow(
|
||||
<Table
|
||||
indexPattern={indexPattern}
|
||||
model={model}
|
||||
items={items}
|
||||
editField={editField}
|
||||
deleteField={() => {}}
|
||||
onDataCriteriaChange={() => {}}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
// Click the delete button
|
||||
component.prop('config').columns[4].actions[0].onClick();
|
||||
component.prop('columns')[4].actions[0].onClick();
|
||||
expect(editField).toBeCalled();
|
||||
});
|
||||
|
||||
|
@ -84,15 +69,15 @@ describe('Table', () => {
|
|||
const component = shallow(
|
||||
<Table
|
||||
indexPattern={indexPattern}
|
||||
model={model}
|
||||
items={items}
|
||||
editField={() => {}}
|
||||
deleteField={deleteField}
|
||||
onDataCriteriaChange={() => {}}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
// Click the delete button
|
||||
component.prop('config').columns[4].actions[1].onClick();
|
||||
component.prop('columns')[4].actions[1].onClick();
|
||||
expect(deleteField).toBeCalled();
|
||||
});
|
||||
|
||||
|
|
|
@ -2,31 +2,15 @@ import React, { PureComponent } from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import {
|
||||
EuiTableOfRecords
|
||||
EuiInMemoryTable,
|
||||
} from '@elastic/eui';
|
||||
|
||||
export class Table extends PureComponent {
|
||||
static propTypes = {
|
||||
indexPattern: PropTypes.object.isRequired,
|
||||
model: PropTypes.shape({
|
||||
data: PropTypes.shape({
|
||||
records: PropTypes.array.isRequired,
|
||||
totalRecordCount: PropTypes.number.isRequired,
|
||||
}).isRequired,
|
||||
criteria: PropTypes.shape({
|
||||
page: PropTypes.shape({
|
||||
index: PropTypes.number.isRequired,
|
||||
size: PropTypes.number.isRequired,
|
||||
}).isRequired,
|
||||
sort: PropTypes.shape({
|
||||
field: PropTypes.string.isRequired,
|
||||
direction: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
}),
|
||||
items: PropTypes.array.isRequired,
|
||||
editField: PropTypes.func.isRequired,
|
||||
deleteField: PropTypes.func.isRequired,
|
||||
onDataCriteriaChange: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
renderFormatCell = (value) => {
|
||||
|
@ -41,79 +25,71 @@ export class Table extends PureComponent {
|
|||
);
|
||||
}
|
||||
|
||||
getTableConfig() {
|
||||
const { editField, deleteField, onDataCriteriaChange } = this.props;
|
||||
|
||||
return {
|
||||
recordId: 'name',
|
||||
columns: [
|
||||
{
|
||||
field: 'displayName',
|
||||
name: 'Name',
|
||||
description: `Name of the field`,
|
||||
dataType: 'string',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'lang',
|
||||
name: 'Lang',
|
||||
description: `Language used for the field`,
|
||||
dataType: 'string',
|
||||
sortable: true,
|
||||
render: value => {
|
||||
return (
|
||||
<span data-test-subj="scriptedFieldLang">
|
||||
{value}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'script',
|
||||
name: 'Script',
|
||||
description: `Script for the field`,
|
||||
dataType: 'string',
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
field: 'name',
|
||||
name: 'Format',
|
||||
description: `Format used for the field`,
|
||||
render: this.renderFormatCell,
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
name: '',
|
||||
actions: [
|
||||
{
|
||||
name: 'Edit',
|
||||
description: 'Edit this field',
|
||||
icon: 'pencil',
|
||||
onClick: editField,
|
||||
},
|
||||
{
|
||||
name: 'Delete',
|
||||
description: 'Delete this field',
|
||||
icon: 'trash',
|
||||
color: 'danger',
|
||||
onClick: deleteField,
|
||||
},
|
||||
]
|
||||
}
|
||||
],
|
||||
pagination: {
|
||||
pageSizeOptions: [5, 10, 25, 50]
|
||||
},
|
||||
selection: undefined,
|
||||
onDataCriteriaChange,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { model } = this.props;
|
||||
const {
|
||||
items,
|
||||
editField,
|
||||
deleteField,
|
||||
} = this.props;
|
||||
|
||||
const columns = [{
|
||||
field: 'displayName',
|
||||
name: 'Name',
|
||||
description: `Name of the field`,
|
||||
dataType: 'string',
|
||||
sortable: true,
|
||||
}, {
|
||||
field: 'lang',
|
||||
name: 'Lang',
|
||||
description: `Language used for the field`,
|
||||
dataType: 'string',
|
||||
sortable: true,
|
||||
render: value => {
|
||||
return (
|
||||
<span data-test-subj="scriptedFieldLang">
|
||||
{value}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
}, {
|
||||
field: 'script',
|
||||
name: 'Script',
|
||||
description: `Script for the field`,
|
||||
dataType: 'string',
|
||||
sortable: true,
|
||||
}, {
|
||||
field: 'name',
|
||||
name: 'Format',
|
||||
description: `Format used for the field`,
|
||||
render: this.renderFormatCell,
|
||||
sortable: false,
|
||||
}, {
|
||||
name: '',
|
||||
actions: [{
|
||||
name: 'Edit',
|
||||
description: 'Edit this field',
|
||||
icon: 'pencil',
|
||||
onClick: editField,
|
||||
}, {
|
||||
name: 'Delete',
|
||||
description: 'Delete this field',
|
||||
icon: 'trash',
|
||||
color: 'danger',
|
||||
onClick: deleteField,
|
||||
}],
|
||||
}];
|
||||
|
||||
const pagination = {
|
||||
pageSizeOptions: [5, 10, 25, 50],
|
||||
};
|
||||
|
||||
return (
|
||||
<EuiTableOfRecords config={this.getTableConfig()} model={model} />
|
||||
<EuiInMemoryTable
|
||||
items={items}
|
||||
columns={columns}
|
||||
pagination={pagination}
|
||||
sorting={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
import {
|
||||
getTableOfRecordsState,
|
||||
} from '../table';
|
||||
|
||||
jest.mock('@elastic/eui', () => ({
|
||||
Comparators: {
|
||||
property: () => {},
|
||||
default: () => {},
|
||||
},
|
||||
}));
|
||||
|
||||
const items = [
|
||||
{ name: 'Kibana' },
|
||||
{ name: 'Elasticsearch' },
|
||||
{ name: 'Logstash' },
|
||||
];
|
||||
|
||||
describe('getTableOfRecordsState', () => {
|
||||
it('should return a TableOfRecords model', () => {
|
||||
const model = getTableOfRecordsState(items, {
|
||||
page: {
|
||||
index: 0,
|
||||
size: 10,
|
||||
},
|
||||
sort: {
|
||||
field: 'name',
|
||||
direction: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
expect(model).toEqual({
|
||||
data: {
|
||||
records: items,
|
||||
totalRecordCount: items.length,
|
||||
},
|
||||
criteria: {
|
||||
page: {
|
||||
index: 0,
|
||||
size: 10
|
||||
},
|
||||
sort: {
|
||||
field: 'name',
|
||||
direction: 'asc'
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('should paginate', () => {
|
||||
const model = getTableOfRecordsState(items, {
|
||||
page: {
|
||||
index: 1,
|
||||
size: 1,
|
||||
},
|
||||
sort: {
|
||||
field: 'name',
|
||||
direction: 'asc',
|
||||
},
|
||||
});
|
||||
|
||||
expect(model).toEqual({
|
||||
data: {
|
||||
records: [{ name: 'Elasticsearch' }],
|
||||
totalRecordCount: items.length,
|
||||
},
|
||||
criteria: {
|
||||
page: {
|
||||
index: 1,
|
||||
size: 1
|
||||
},
|
||||
sort: {
|
||||
field: 'name',
|
||||
direction: 'asc'
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1 +0,0 @@
|
|||
export * from './table';
|
|
@ -1,61 +0,0 @@
|
|||
import {
|
||||
Comparators
|
||||
} from '@elastic/eui';
|
||||
|
||||
export const getPage = (data, pageIndex, pageSize, sort) => {
|
||||
let list = data;
|
||||
if (sort) {
|
||||
list = data.sort(Comparators.property(sort.field, Comparators.default(sort.direction)));
|
||||
}
|
||||
if (!pageIndex && !pageSize) {
|
||||
return {
|
||||
index: 0,
|
||||
size: list.length,
|
||||
items: list,
|
||||
totalRecordCount: list.length
|
||||
};
|
||||
}
|
||||
const from = pageIndex * pageSize;
|
||||
const items = list.slice(from, Math.min(from + pageSize, list.length));
|
||||
return {
|
||||
index: pageIndex,
|
||||
size: pageSize,
|
||||
items,
|
||||
totalRecordCount: list.length
|
||||
};
|
||||
};
|
||||
|
||||
export const getTableOfRecordsState = (items, criteria) => {
|
||||
const page = getPage(items, criteria.page.index, criteria.page.size, criteria.sort);
|
||||
|
||||
return {
|
||||
data: {
|
||||
records: page.items,
|
||||
totalRecordCount: page.totalRecordCount,
|
||||
},
|
||||
criteria: {
|
||||
page: {
|
||||
index: page.index,
|
||||
size: page.size
|
||||
},
|
||||
sort: criteria.sort,
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
export const DEFAULT_TABLE_OF_RECORDS_STATE = {
|
||||
data: {
|
||||
records: [],
|
||||
totalRecordCount: 0,
|
||||
},
|
||||
criteria: {
|
||||
page: {
|
||||
index: 0,
|
||||
size: 10,
|
||||
},
|
||||
sort: {
|
||||
field: 'name',
|
||||
direction: 'asc',
|
||||
}
|
||||
}
|
||||
};
|
|
@ -4,18 +4,17 @@ import { getSupportedScriptingLanguages, getDeprecatedScriptingLanguages } from
|
|||
import { documentationLinks } from 'ui/documentation_links';
|
||||
|
||||
import {
|
||||
EuiButton,
|
||||
EuiSpacer,
|
||||
EuiOverlayMask,
|
||||
EuiConfirmModal,
|
||||
EUI_MODAL_CONFIRM_BUTTON,
|
||||
} from '@elastic/eui';
|
||||
|
||||
import { Table } from './components/table';
|
||||
import { Header } from './components/header';
|
||||
import { CallOuts } from './components/call_outs';
|
||||
import { getTableOfRecordsState, DEFAULT_TABLE_OF_RECORDS_STATE } from './lib';
|
||||
|
||||
import {
|
||||
Table,
|
||||
Header,
|
||||
CallOuts,
|
||||
} from './components';
|
||||
|
||||
export class ScriptedFieldsTable extends Component {
|
||||
static propTypes = {
|
||||
|
@ -37,7 +36,6 @@ export class ScriptedFieldsTable extends Component {
|
|||
fieldToDelete: undefined,
|
||||
isDeleteConfirmationModalVisible: false,
|
||||
fields: [],
|
||||
...DEFAULT_TABLE_OF_RECORDS_STATE,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -61,34 +59,31 @@ export class ScriptedFieldsTable extends Component {
|
|||
this.setState({
|
||||
fields,
|
||||
deprecatedLangsInUse,
|
||||
...this.computeTableState(this.state.criteria, this.props, fields)
|
||||
});
|
||||
}
|
||||
|
||||
onDataCriteriaChange = criteria => {
|
||||
this.setState(this.computeTableState(criteria));
|
||||
}
|
||||
getFilteredItems = () => {
|
||||
const { fields } = this.state;
|
||||
const { fieldFilter, scriptedFieldLanguageFilter } = this.props;
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (this.props.fieldFilter !== nextProps.fieldFilter) {
|
||||
this.setState(this.computeTableState(this.state.criteria, nextProps));
|
||||
}
|
||||
if (this.props.scriptedFieldLanguageFilter !== nextProps.scriptedFieldLanguageFilter) {
|
||||
this.setState(this.computeTableState(this.state.criteria, nextProps));
|
||||
}
|
||||
}
|
||||
let languageFilteredFields = fields;
|
||||
|
||||
computeTableState(criteria, props = this.props, fields = this.state.fields) {
|
||||
let items = fields;
|
||||
if (props.fieldFilter) {
|
||||
const fieldFilter = props.fieldFilter.toLowerCase();
|
||||
items = items.filter(field => field.name.toLowerCase().includes(fieldFilter));
|
||||
}
|
||||
if (props.scriptedFieldLanguageFilter) {
|
||||
items = items.filter(field => field.lang === props.scriptedFieldLanguageFilter);
|
||||
if (scriptedFieldLanguageFilter) {
|
||||
languageFilteredFields = fields.filter(
|
||||
field => field.lang === this.props.scriptedFieldLanguageFilter
|
||||
);
|
||||
}
|
||||
|
||||
return getTableOfRecordsState(items, criteria);
|
||||
let filteredFields = languageFilteredFields;
|
||||
|
||||
if (fieldFilter) {
|
||||
const normalizedFieldFilter = this.props.fieldFilter.toLowerCase();
|
||||
filteredFields = languageFilteredFields.filter(
|
||||
field => field.name.toLowerCase().includes(normalizedFieldFilter)
|
||||
);
|
||||
}
|
||||
|
||||
return filteredFields;
|
||||
}
|
||||
|
||||
renderCallOuts() {
|
||||
|
@ -147,44 +142,23 @@ export class ScriptedFieldsTable extends Component {
|
|||
indexPattern,
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
data,
|
||||
criteria: {
|
||||
page,
|
||||
sort,
|
||||
},
|
||||
fields,
|
||||
} = this.state;
|
||||
|
||||
const model = {
|
||||
data,
|
||||
criteria: {
|
||||
page,
|
||||
sort,
|
||||
},
|
||||
};
|
||||
const items = this.getFilteredItems();
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Header/>
|
||||
<Header addScriptedFieldUrl={helpers.getRouteHref(indexPattern, 'addField')} />
|
||||
|
||||
{this.renderCallOuts()}
|
||||
<EuiButton
|
||||
data-test-subj="addScriptedFieldLink"
|
||||
href={helpers.getRouteHref(indexPattern, 'addField')}
|
||||
>
|
||||
Add scripted field
|
||||
</EuiButton>
|
||||
|
||||
<EuiSpacer size="l" />
|
||||
{ fields.length > 0 ?
|
||||
<Table
|
||||
indexPattern={indexPattern}
|
||||
model={model}
|
||||
editField={field => this.props.helpers.redirectToRoute(field, 'edit')}
|
||||
deleteField={this.startDeleteField}
|
||||
onDataCriteriaChange={this.onDataCriteriaChange}
|
||||
/>
|
||||
: null
|
||||
}
|
||||
|
||||
<Table
|
||||
indexPattern={indexPattern}
|
||||
items={items}
|
||||
editField={field => this.props.helpers.redirectToRoute(field, 'edit')}
|
||||
deleteField={this.startDeleteField}
|
||||
/>
|
||||
|
||||
{this.renderDeleteConfirmationModal()}
|
||||
</div>
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue