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

[App Search] Migrate expanded rows for meta engines table in Engines Overview #96251

Merged
merged 23 commits into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
c28c2b9
Pull out columns to be re-used for MetaEnginesTable
byronhulcher Mar 29, 2021
85e8857
Add route to get source engines for meta engines
byronhulcher Mar 29, 2021
34c8798
New MetaEnginesTableLogic
byronhulcher Mar 29, 2021
0cf74f5
New MetaEnginesTable component
byronhulcher Mar 29, 2021
30dc408
Remove isMeta prop from EnginesTable
byronhulcher Mar 30, 2021
fc882da
Swap EnginesTable with MetaEnginesTable in EnginesOverview for meta e…
byronhulcher Mar 29, 2021
3770f9e
Missing test for MetaEnginesTableNameColumnContent
byronhulcher Apr 5, 2021
6982ce0
Created new /app_search/components/engines/components/tables directory
byronhulcher Apr 8, 2021
aabd29a
Moving columns to shared_columns.tsx file
byronhulcher Apr 8, 2021
a364bf8
Updates to MetaEnginesTableExpandedRow and MetaEnginesTableNameColumn…
byronhulcher Apr 8, 2021
dbfcc82
Fixes to EnginesTable, MetaEnginesTable, MetaEnginesTableLogic
byronhulcher Apr 8, 2021
391331e
Merge remote-tracking branch 'origin/master' into meta-engines-table
byronhulcher Apr 8, 2021
0bac01f
Merge remote-tracking branch 'origin/master' into meta-engines-table
byronhulcher Apr 12, 2021
a29c45a
Remove flatten import
byronhulcher Apr 12, 2021
39146c5
Fix i18n
byronhulcher Apr 12, 2021
b9aba42
Merge remote-tracking branch 'origin/master' into meta-engines-table
byronhulcher Apr 12, 2021
024b1f2
PR Feedback
byronhulcher Apr 12, 2021
a24ee83
Merge branch 'master' into meta-engines-table
kibanamachine Apr 12, 2021
821f132
Merge branch 'master' into meta-engines-table
kibanamachine Apr 13, 2021
d78c067
Merge branch 'master' into meta-engines-table
kibanamachine Apr 13, 2021
abeda3c
DRY out shared engine link helpers
cee-chen Apr 13, 2021
5f30950
DRY out shared ACTIONS_COLUMN
cee-chen Apr 13, 2021
6fcf91c
Tests: DRY out shared columns/props tests
cee-chen Apr 13, 2021
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
@@ -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