Skip to content

Commit d61387c

Browse files
Constancecee-chen
authored andcommitted
[App Search] Implement initial Engine routing/navigation (#82549)
* [Setup] Update routes + role privileges Routes: use generatePath to better match ent-search Roles: We're using "Search UI" in the nav copy now, so we should update our vars accordingly * Add new EngineNav and EngineRouter components * Update existing components to use new EngineRouter/EngineNav * Add App Search engine label & new SideNavItem component * Add EngineRouter breadcrumbs * [Refactor] DRY out i18n constants
1 parent fc89b7a commit d61387c

15 files changed

Lines changed: 555 additions & 17 deletions

File tree

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import { i18n } from '@kbn/i18n';
8+
9+
// TODO: It's very likely that we'll move these i18n constants to their respective component
10+
// folders once those are migrated over. This is a temporary way of DRYing them out for now.
11+
12+
export const ENGINES_TITLE = i18n.translate('xpack.enterpriseSearch.appSearch.engines.title', {
13+
defaultMessage: 'Engines',
14+
});
15+
16+
export const OVERVIEW_TITLE = i18n.translate(
17+
'xpack.enterpriseSearch.appSearch.engine.overview.title',
18+
{ defaultMessage: 'Overview' }
19+
);
20+
export const ANALYTICS_TITLE = i18n.translate(
21+
'xpack.enterpriseSearch.appSearch.engine.analytics.title',
22+
{ defaultMessage: 'Analytics' }
23+
);
24+
export const DOCUMENTS_TITLE = i18n.translate(
25+
'xpack.enterpriseSearch.appSearch.engine.documents.title',
26+
{ defaultMessage: 'Documents' }
27+
);
28+
export const SCHEMA_TITLE = i18n.translate('xpack.enterpriseSearch.appSearch.engine.schema.title', {
29+
defaultMessage: 'Schema',
30+
});
31+
export const CRAWLER_TITLE = i18n.translate(
32+
'xpack.enterpriseSearch.appSearch.engine.crawler.title',
33+
{ defaultMessage: 'Crawler' }
34+
);
35+
export const RELEVANCE_TUNING_TITLE = i18n.translate(
36+
'xpack.enterpriseSearch.appSearch.engine.relevanceTuning.title',
37+
{ defaultMessage: 'Relevance Tuning' }
38+
);
39+
export const SYNONYMS_TITLE = i18n.translate(
40+
'xpack.enterpriseSearch.appSearch.engine.synonyms.title',
41+
{ defaultMessage: 'Synonyms' }
42+
);
43+
export const CURATIONS_TITLE = i18n.translate(
44+
'xpack.enterpriseSearch.appSearch.engine.curations.title',
45+
{ defaultMessage: 'Curations' }
46+
);
47+
export const RESULT_SETTINGS_TITLE = i18n.translate(
48+
'xpack.enterpriseSearch.appSearch.engine.resultSettings.title',
49+
{ defaultMessage: 'Result Settings' }
50+
);
51+
export const SEARCH_UI_TITLE = i18n.translate(
52+
'xpack.enterpriseSearch.appSearch.engine.searchUI.title',
53+
{ defaultMessage: 'Search UI' }
54+
);
55+
export const API_LOGS_TITLE = i18n.translate(
56+
'xpack.enterpriseSearch.appSearch.engine.apiLogs.title',
57+
{ defaultMessage: 'API Logs' }
58+
);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
.appSearchNavEngineLabel {
8+
padding-top: $euiSizeS;
9+
padding-bottom: $euiSizeS;
10+
11+
.euiText {
12+
font-weight: $euiFontWeightMedium;
13+
}
14+
.euiBadge {
15+
margin-top: $euiSizeXS;
16+
}
17+
}
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
import '../../../__mocks__/react_router_history.mock';
8+
import { setMockValues } from '../../../__mocks__/kea.mock';
9+
10+
import React from 'react';
11+
import { shallow, mount } from 'enzyme';
12+
import { Switch, useParams } from 'react-router-dom';
13+
import { EuiBadge } from '@elastic/eui';
14+
15+
import { EngineRouter, EngineNav } from './';
16+
17+
describe('EngineRouter', () => {
18+
it('renders a default engine overview', () => {
19+
setMockValues({ myRole: {} });
20+
const wrapper = shallow(<EngineRouter />);
21+
22+
expect(wrapper.find(Switch)).toHaveLength(1);
23+
expect(wrapper.find('[data-test-subj="EngineOverviewTODO"]')).toHaveLength(1);
24+
});
25+
26+
it('renders an analytics view', () => {
27+
setMockValues({ myRole: { canViewEngineAnalytics: true } });
28+
const wrapper = shallow(<EngineRouter />);
29+
30+
expect(wrapper.find('[data-test-subj="AnalyticsTODO"]')).toHaveLength(1);
31+
});
32+
});
33+
34+
describe('EngineNav', () => {
35+
beforeEach(() => {
36+
(useParams as jest.Mock).mockReturnValue({ engineName: 'some-engine' });
37+
});
38+
39+
it('does not render without an engine name', () => {
40+
setMockValues({ myRole: {} });
41+
(useParams as jest.Mock).mockReturnValue({ engineName: '' });
42+
const wrapper = shallow(<EngineNav />);
43+
expect(wrapper.isEmptyRender()).toBe(true);
44+
});
45+
46+
it('renders an engine label', () => {
47+
setMockValues({ myRole: {} });
48+
const wrapper = mount(<EngineNav />);
49+
50+
const label = wrapper.find('[data-test-subj="EngineLabel"]').last();
51+
expect(label.text()).toEqual(expect.stringContaining('SOME-ENGINE'));
52+
53+
// TODO: Test sample & meta engine conditional rendering
54+
expect(label.find(EuiBadge).text()).toEqual('SAMPLE ENGINE');
55+
});
56+
57+
it('renders a default engine overview link', () => {
58+
setMockValues({ myRole: {} });
59+
const wrapper = shallow(<EngineNav />);
60+
expect(wrapper.find('[data-test-subj="EngineOverviewLink"]')).toHaveLength(1);
61+
});
62+
63+
it('renders an analytics link', () => {
64+
setMockValues({ myRole: { canViewEngineAnalytics: true } });
65+
const wrapper = shallow(<EngineNav />);
66+
expect(wrapper.find('[data-test-subj="EngineAnalyticsLink"]')).toHaveLength(1);
67+
});
68+
69+
it('renders a documents link', () => {
70+
setMockValues({ myRole: { canViewEngineDocuments: true } });
71+
const wrapper = shallow(<EngineNav />);
72+
expect(wrapper.find('[data-test-subj="EngineDocumentsLink"]')).toHaveLength(1);
73+
});
74+
75+
it('renders a schema link', () => {
76+
setMockValues({ myRole: { canViewEngineSchema: true } });
77+
const wrapper = shallow(<EngineNav />);
78+
expect(wrapper.find('[data-test-subj="EngineSchemaLink"]')).toHaveLength(1);
79+
80+
// TODO: Schema warning icon
81+
});
82+
83+
// TODO: Unskip when EngineLogic is migrated
84+
it.skip('renders a crawler link', () => {
85+
setMockValues({ myRole: { canViewEngineCrawler: true } });
86+
const wrapper = shallow(<EngineNav />);
87+
expect(wrapper.find('[data-test-subj="EngineCrawlerLink"]')).toHaveLength(1);
88+
89+
// TODO: Test that the crawler link does NOT show up for meta/sample engines
90+
});
91+
92+
// TODO: Unskip when EngineLogic is migrated
93+
it.skip('renders a meta engine source engines link', () => {
94+
setMockValues({ myRole: { canViewMetaEngineSourceEngines: true } });
95+
const wrapper = shallow(<EngineNav />);
96+
expect(wrapper.find('[data-test-subj="MetaEngineEnginesLink"]')).toHaveLength(1);
97+
98+
// TODO: Test that the crawler link does NOT show up for non-meta engines
99+
});
100+
101+
it('renders a relevance tuning link', () => {
102+
setMockValues({ myRole: { canManageEngineRelevanceTuning: true } });
103+
const wrapper = shallow(<EngineNav />);
104+
expect(wrapper.find('[data-test-subj="EngineRelevanceTuningLink"]')).toHaveLength(1);
105+
106+
// TODO: Boost error icon
107+
});
108+
109+
it('renders a synonyms link', () => {
110+
setMockValues({ myRole: { canManageEngineSynonyms: true } });
111+
const wrapper = shallow(<EngineNav />);
112+
expect(wrapper.find('[data-test-subj="EngineSynonymsLink"]')).toHaveLength(1);
113+
});
114+
115+
it('renders a curations link', () => {
116+
setMockValues({ myRole: { canManageEngineCurations: true } });
117+
const wrapper = shallow(<EngineNav />);
118+
expect(wrapper.find('[data-test-subj="EngineCurationsLink"]')).toHaveLength(1);
119+
});
120+
121+
it('renders a results settings link', () => {
122+
setMockValues({ myRole: { canManageEngineResultSettings: true } });
123+
const wrapper = shallow(<EngineNav />);
124+
expect(wrapper.find('[data-test-subj="EngineResultSettingsLink"]')).toHaveLength(1);
125+
});
126+
127+
it('renders a Search UI link', () => {
128+
setMockValues({ myRole: { canManageEngineSearchUi: true } });
129+
const wrapper = shallow(<EngineNav />);
130+
expect(wrapper.find('[data-test-subj="EngineSearchUILink"]')).toHaveLength(1);
131+
});
132+
133+
it('renders an API logs link', () => {
134+
setMockValues({ myRole: { canViewEngineApiLogs: true } });
135+
const wrapper = shallow(<EngineNav />);
136+
expect(wrapper.find('[data-test-subj="EngineAPILogsLink"]')).toHaveLength(1);
137+
});
138+
});

0 commit comments

Comments
 (0)