Skip to content

Commit

Permalink
[App Search] Migrate expanded rows for meta engines table in Engines …
Browse files Browse the repository at this point in the history
…Overview (elastic#96251) (elastic#97123)

* Pull out columns to be re-used for MetaEnginesTable

* Add route to get source engines for meta engines

* New MetaEnginesTableLogic

* New MetaEnginesTable component

* Remove isMeta prop from EnginesTable

* Swap EnginesTable with MetaEnginesTable in EnginesOverview for meta engines

* Missing test for MetaEnginesTableNameColumnContent

* Created new /app_search/components/engines/components/tables directory

* Moving columns to shared_columns.tsx file

* Updates to MetaEnginesTableExpandedRow and MetaEnginesTableNameColumnContent

* Fixes to EnginesTable, MetaEnginesTable, MetaEnginesTableLogic

* Remove flatten import

* Fix i18n

* PR Feedback

* DRY out shared engine link helpers

* DRY out shared ACTIONS_COLUMN

* Tests: DRY out shared columns/props tests

+ update to account for 2 previous DRY commits (e.g. deleteEngine mock)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Constance Chen <constance.chen.3@gmail.com>

Co-authored-by: Byron Hulcher <byronhulcher@gmail.com>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
3 people committed Apr 14, 2021
1 parent fa0c1a4 commit f8c3ee0
Show file tree
Hide file tree
Showing 28 changed files with 1,751 additions and 471 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

jest.mock('../../../../engines', () => ({
EnginesLogic: { actions: { deleteEngine: jest.fn() } },
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { mockKibanaValues, mockTelemetryActions } from '../../../../../__mocks__';

import React from 'react';

import { shallow } from 'enzyme';

import { EuiLinkTo } from '../../../../../shared/react_router_helpers';

import { navigateToEngine, renderEngineLink } from './engine_link_helpers';

describe('navigateToEngine', () => {
const { navigateToUrl } = mockKibanaValues;
const { sendAppSearchTelemetry } = mockTelemetryActions;

it('sends the user to the engine page and triggers a telemetry event', () => {
navigateToEngine('engine-a');
expect(navigateToUrl).toHaveBeenCalledWith('/engines/engine-a');
expect(sendAppSearchTelemetry).toHaveBeenCalledWith({
action: 'clicked',
metric: 'engine_table_link',
});
});
});

describe('renderEngineLink', () => {
const { sendAppSearchTelemetry } = mockTelemetryActions;

it('renders a link to the engine with telemetry', () => {
const wrapper = shallow(<div>{renderEngineLink('engine-b')}</div>);
const link = wrapper.find(EuiLinkTo);

expect(link.prop('to')).toEqual('/engines/engine-b');

link.simulate('click');
expect(sendAppSearchTelemetry).toHaveBeenCalledWith({
action: 'clicked',
metric: 'engine_table_link',
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';

import { KibanaLogic } from '../../../../../shared/kibana';
import { EuiLinkTo } from '../../../../../shared/react_router_helpers';
import { TelemetryLogic } from '../../../../../shared/telemetry';
import { ENGINE_PATH } from '../../../../routes';
import { generateEncodedPath } from '../../../../utils/encode_path_params';

const sendEngineTableLinkClickTelemetry = () => {
TelemetryLogic.actions.sendAppSearchTelemetry({
action: 'clicked',
metric: 'engine_table_link',
});
};

export const navigateToEngine = (engineName: string) => {
sendEngineTableLinkClickTelemetry();
KibanaLogic.values.navigateToUrl(generateEncodedPath(ENGINE_PATH, { engineName }));
};

export const renderEngineLink = (engineName: string) => (
<EuiLinkTo
to={generateEncodedPath(ENGINE_PATH, { engineName })}
onClick={sendEngineTableLinkClickTelemetry}
data-test-subj="EngineName"
>
{engineName}
</EuiLinkTo>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { mountWithIntl, setMockValues } from '../../../../../__mocks__';
import '../../../../../__mocks__/enterprise_search_url.mock';
import './__mocks__/engines_logic.mock';

import React from 'react';

import { shallow } from 'enzyme';

import { EuiBasicTable } from '@elastic/eui';

import { EngineDetails } from '../../../engine/types';

import { EnginesTable } from './engines_table';

import { runSharedColumnsTests, runSharedPropsTests } from './test_helpers';

describe('EnginesTable', () => {
const data = [
{
name: 'test-engine',
created_at: 'Fri, 1 Jan 1970 12:00:00 +0000',
language: 'English',
isMeta: false,
document_count: 99999,
field_count: 10,
} as EngineDetails,
];
const props = {
items: data,
loading: false,
pagination: {
pageIndex: 0,
pageSize: 10,
totalItemCount: 1,
hidePerPageOptions: true,
},
onChange: () => {},
};
setMockValues({ myRole: { canManageEngines: false } });

beforeEach(() => {
jest.clearAllMocks();
});

it('renders', () => {
const wrapper = shallow(<EnginesTable {...props} />);
expect(wrapper.find(EuiBasicTable)).toHaveLength(1);
});

describe('columns', () => {
const wrapper = shallow(<EnginesTable {...props} />);
const tableContent = mountWithIntl(<EnginesTable {...props} />)
.find(EuiBasicTable)
.text();
runSharedColumnsTests(wrapper, tableContent);
});

describe('language column', () => {
it('renders language when set', () => {
const wrapper = mountWithIntl(
<EnginesTable {...props} items={[{ ...data[0], language: 'German' }]} />
);
expect(wrapper.find(EuiBasicTable).text()).toContain('German');
});

it('renders the language as Universal if no language is set', () => {
const wrapper = mountWithIntl(
<EnginesTable {...props} items={[{ ...data[0], language: null }]} />
);
expect(wrapper.find(EuiBasicTable).text()).toContain('Universal');
});
});

describe('passed props', () => {
const wrapper = shallow(<EnginesTable {...props} />);
runSharedPropsTests(wrapper);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';

import { useValues } from 'kea';

import { EuiBasicTable, EuiBasicTableColumn, EuiTableFieldDataColumnType } from '@elastic/eui';
import { i18n } from '@kbn/i18n';

import { AppLogic } from '../../../../app_logic';
import { UNIVERSAL_LANGUAGE } from '../../../../constants';
import { EngineDetails } from '../../../engine/types';

import { renderEngineLink } from './engine_link_helpers';
import {
ACTIONS_COLUMN,
CREATED_AT_COLUMN,
DOCUMENT_COUNT_COLUMN,
FIELD_COUNT_COLUMN,
NAME_COLUMN,
} from './shared_columns';
import { EnginesTableProps } from './types';

const LANGUAGE_COLUMN: EuiTableFieldDataColumnType<EngineDetails> = {
field: 'language',
name: i18n.translate('xpack.enterpriseSearch.appSearch.enginesOverview.table.column.language', {
defaultMessage: 'Language',
}),
dataType: 'string',
render: (language: string) => language || UNIVERSAL_LANGUAGE,
};

export const EnginesTable: React.FC<EnginesTableProps> = ({
items,
loading,
noItemsMessage,
pagination,
onChange,
}) => {
const {
myRole: { canManageEngines },
} = useValues(AppLogic);

const columns: Array<EuiBasicTableColumn<EngineDetails>> = [
{
...NAME_COLUMN,
render: (name: string) => renderEngineLink(name),
},
CREATED_AT_COLUMN,
LANGUAGE_COLUMN,
DOCUMENT_COUNT_COLUMN,
FIELD_COUNT_COLUMN,
];

if (canManageEngines) {
columns.push(ACTIONS_COLUMN);
}

return (
<EuiBasicTable
items={items}
columns={columns}
loading={loading}
pagination={pagination}
onChange={onChange}
noItemsMessage={noItemsMessage}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { mountWithIntl, setMockValues } from '../../../../../__mocks__';
import '../../../../../__mocks__/enterprise_search_url.mock';
import './__mocks__/engines_logic.mock';

import React from 'react';

import { shallow } from 'enzyme';

import { EuiBasicTable } from '@elastic/eui';

import { EngineDetails } from '../../../engine/types';

import { MetaEnginesTable } from './meta_engines_table';
import { MetaEnginesTableExpandedRow } from './meta_engines_table_expanded_row';
import { MetaEnginesTableNameColumnContent } from './meta_engines_table_name_column_content';

import { runSharedColumnsTests, runSharedPropsTests } from './test_helpers';

describe('MetaEnginesTable', () => {
const data = [
{
name: 'test-engine',
created_at: 'Fri, 1 Jan 1970 12:00:00 +0000',
isMeta: true,
document_count: 99999,
field_count: 10,
includedEngines: [{ name: 'source-engine-1' }, { name: 'source-engine-2' }],
} as EngineDetails,
];
const props = {
items: data,
loading: false,
pagination: {
pageIndex: 0,
pageSize: 10,
totalItemCount: 1,
hidePerPageOptions: true,
},
onChange: () => {},
};

const DEFAULT_VALUES = {
myRole: {
canManageMetaEngines: false,
},
expandedSourceEngines: {},
hideRow: jest.fn(),
fetchOrDisplayRow: jest.fn(),
};
setMockValues(DEFAULT_VALUES);

beforeEach(() => {
jest.clearAllMocks();
});

it('renders', () => {
const wrapper = shallow(<MetaEnginesTable {...props} />);
expect(wrapper.find(EuiBasicTable)).toHaveLength(1);
});

describe('columns', () => {
const wrapper = shallow(<MetaEnginesTable {...props} />);
const tableContent = mountWithIntl(<MetaEnginesTable {...props} />)
.find(EuiBasicTable)
.text();
runSharedColumnsTests(wrapper, tableContent, DEFAULT_VALUES);
});

describe('passed props', () => {
const wrapper = shallow(<MetaEnginesTable {...props} />);
runSharedPropsTests(wrapper);
});

describe('expanded source engines', () => {
it('is hidden by default', () => {
const wrapper = shallow(<MetaEnginesTable {...props} />);
const table = wrapper.find(EuiBasicTable).dive();

expect(table.find(MetaEnginesTableNameColumnContent)).toHaveLength(1);
expect(table.find(MetaEnginesTableExpandedRow)).toHaveLength(0);
});

it('is visible when the row has been expanded', () => {
setMockValues({
...DEFAULT_VALUES,
expandedSourceEngines: { 'test-engine': true },
});
const wrapper = shallow(<MetaEnginesTable {...props} />);
const table = wrapper.find(EuiBasicTable);
expect(table.dive().find(MetaEnginesTableExpandedRow)).toHaveLength(1);
});
});
});
Loading

0 comments on commit f8c3ee0

Please sign in to comment.