Skip to content

Commit ee95376

Browse files
daveyhollerJasonStoltzkibanamachine
committed
App Search: Result Component Updates (#96184)
* Starting work on result component * Write tests * Fix types * Cleanup * Fix type errors Co-authored-by: Jason Stoltzfus <jastoltz24@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
1 parent 203214f commit ee95376

17 files changed

Lines changed: 320 additions & 194 deletions

x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/constants.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* 2.0.
66
*/
77

8+
import { EuiButtonIconColor } from '@elastic/eui';
89
import { i18n } from '@kbn/i18n';
910

1011
export const CURATIONS_TITLE = i18n.translate(
@@ -49,26 +50,26 @@ export const PROMOTE_DOCUMENT_ACTION = {
4950
defaultMessage: 'Promote this result',
5051
}),
5152
iconType: 'starPlusEmpty',
52-
iconColor: 'primary',
53+
iconColor: 'primary' as EuiButtonIconColor,
5354
};
5455
export const DEMOTE_DOCUMENT_ACTION = {
5556
title: i18n.translate('xpack.enterpriseSearch.appSearch.engine.curations.demoteButtonLabel', {
5657
defaultMessage: 'Demote this result',
5758
}),
5859
iconType: 'starMinusFilled',
59-
iconColor: 'primary',
60+
iconColor: 'primary' as EuiButtonIconColor,
6061
};
6162
export const HIDE_DOCUMENT_ACTION = {
6263
title: i18n.translate('xpack.enterpriseSearch.appSearch.engine.curations.hideButtonLabel', {
6364
defaultMessage: 'Hide this result',
6465
}),
6566
iconType: 'eyeClosed',
66-
iconColor: 'danger',
67+
iconColor: 'danger' as EuiButtonIconColor,
6768
};
6869
export const SHOW_DOCUMENT_ACTION = {
6970
title: i18n.translate('xpack.enterpriseSearch.appSearch.engine.curations.showButtonLabel', {
7071
defaultMessage: 'Show this result',
7172
}),
7273
iconType: 'eye',
73-
iconColor: 'primary',
74+
iconColor: 'primary' as EuiButtonIconColor,
7475
};

x-pack/plugins/enterprise_search/public/applications/app_search/components/library/library.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
EuiDragDropContext,
1717
EuiDroppable,
1818
EuiDraggable,
19+
EuiButtonIconColor,
1920
} from '@elastic/eui';
2021

2122
import { SetAppSearchChrome as SetPageChrome } from '../../../shared/kibana_chrome';
@@ -78,7 +79,7 @@ export const Library: React.FC = () => {
7879
title: 'Fill this action button',
7980
onClick: () => setIsActionButtonFilled(!isActionButtonFilled),
8081
iconType: isActionButtonFilled ? 'starFilled' : 'starEmpty',
81-
iconColor: 'primary',
82+
iconColor: 'primary' as EuiButtonIconColor,
8283
},
8384
];
8485

@@ -221,7 +222,7 @@ export const Library: React.FC = () => {
221222
<h3>With custom actions and a link</h3>
222223
</EuiTitle>
223224
<EuiSpacer />
224-
<Result {...props} actions={actions} shouldLinkToDetailPage />
225+
<Result {...props} actions={actions} shouldLinkToDetailPage showScore isMetaEngine />
225226
<EuiSpacer />
226227

227228
<EuiSpacer />

x-pack/plugins/enterprise_search/public/applications/app_search/components/result/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
*/
77

88
export { ResultFieldValue } from './result_field_value';
9+
export { ResultToken } from './result_token';
910
export { Result } from './result';

x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.scss

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
'drag content actions'
77
'drag toggle actions';
88
overflow: hidden; // Prevents child background-colors from clipping outside of panel border-radius
9+
border: $euiBorderThin; // TODO: Remove after EUI version is bumped beyond 31.8.0
910

1011
&__content {
1112
grid-area: content;
@@ -44,9 +45,13 @@
4445
display: flex;
4546
justify-content: center;
4647
align-items: center;
47-
width: $euiSizeL * 2;
48+
width: $euiSize * 2;
4849
border-left: $euiBorderThin;
4950

51+
&:first-child {
52+
border-left: none;
53+
}
54+
5055
&:hover,
5156
&:focus {
5257
background-color: $euiPageBackgroundColor;
@@ -62,22 +67,3 @@
6267
border-right: $euiBorderThin;
6368
}
6469
}
65-
66-
/**
67-
* CSS for hover specific logic
68-
* It's mildly horrific, so I pulled it out to its own section here
69-
*/
70-
71-
.appSearchResult--link {
72-
&:hover,
73-
&:focus {
74-
@include euiSlightShadowHover;
75-
}
76-
}
77-
.appSearchResult__content--link:hover {
78-
cursor: pointer;
79-
80-
& ~ .appSearchResult__actionButtons .appSearchResult__actionButton--link {
81-
background-color: $euiPageBackgroundColor;
82-
}
83-
}

x-pack/plugins/enterprise_search/public/applications/app_search/components/result/result.test.tsx

Lines changed: 44 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import { DraggableProvidedDragHandleProps } from 'react-beautiful-dnd';
1010

1111
import { shallow, ShallowWrapper } from 'enzyme';
1212

13-
import { EuiPanel } from '@elastic/eui';
13+
import { EuiButtonIcon, EuiPanel, EuiButtonIconColor } from '@elastic/eui';
1414

15-
import { ReactRouterHelper } from '../../../shared/react_router_helpers/eui_components';
1615
import { SchemaTypes } from '../../../shared/types';
1716

1817
import { Result } from './result';
@@ -64,37 +63,18 @@ describe('Result', () => {
6463
]);
6564
});
6665

67-
it('passes showScore, resultMeta, and isMetaEngine to ResultHeader', () => {
66+
it('renders a header', () => {
6867
const wrapper = shallow(<Result {...props} showScore isMetaEngine />);
69-
expect(wrapper.find(ResultHeader).props()).toEqual({
70-
isMetaEngine: true,
71-
showScore: true,
72-
resultMeta: {
73-
id: '1',
74-
score: 100,
75-
engine: 'my-engine',
76-
},
77-
});
78-
});
79-
80-
describe('document detail link', () => {
81-
it('will render a link if shouldLinkToDetailPage is true', () => {
82-
const wrapper = shallow(<Result {...props} shouldLinkToDetailPage />);
83-
wrapper.find(ReactRouterHelper).forEach((link) => {
84-
expect(link.prop('to')).toEqual('/engines/my-engine/documents/1');
85-
});
86-
expect(wrapper.hasClass('appSearchResult--link')).toBe(true);
87-
expect(wrapper.find('.appSearchResult__content--link').exists()).toBe(true);
88-
expect(wrapper.find('.appSearchResult__actionButton--link').exists()).toBe(true);
89-
});
90-
91-
it('will not render a link if shouldLinkToDetailPage is not set', () => {
92-
const wrapper = shallow(<Result {...props} />);
93-
expect(wrapper.find(ReactRouterHelper).exists()).toBe(false);
94-
expect(wrapper.hasClass('appSearchResult--link')).toBe(false);
95-
expect(wrapper.find('.appSearchResult__content--link').exists()).toBe(false);
96-
expect(wrapper.find('.appSearchResult__actionButton--link').exists()).toBe(false);
97-
});
68+
const header = wrapper.find(ResultHeader);
69+
expect(header.exists()).toBe(true);
70+
expect(header.prop('isMetaEngine')).toBe(true); // passed through from props
71+
expect(header.prop('showScore')).toBe(true); // passed through from props
72+
expect(header.prop('shouldLinkToDetailPage')).toBe(false); // passed through from props
73+
expect(header.prop('resultMeta')).toEqual({
74+
id: '1',
75+
score: 100,
76+
engine: 'my-engine',
77+
}); // passed through from meta in result prop
9878
});
9979

10080
describe('actions', () => {
@@ -103,30 +83,53 @@ describe('Result', () => {
10383
title: 'Hide',
10484
onClick: jest.fn(),
10585
iconType: 'eyeClosed',
106-
iconColor: 'danger',
86+
iconColor: 'danger' as EuiButtonIconColor,
10787
},
10888
{
10989
title: 'Bookmark',
11090
onClick: jest.fn(),
11191
iconType: 'starFilled',
112-
iconColor: 'primary',
92+
iconColor: undefined,
11393
},
11494
];
11595

116-
it('will render an action button for each action passed', () => {
96+
it('will render an action button in the header for each action passed', () => {
11797
const wrapper = shallow(<Result {...props} actions={actions} />);
118-
expect(wrapper.find('.appSearchResult__actionButton')).toHaveLength(2);
119-
120-
wrapper.find('.appSearchResult__actionButton').first().simulate('click');
98+
const header = wrapper.find(ResultHeader);
99+
const renderedActions = shallow(header.prop('actions') as any);
100+
const buttons = renderedActions.find(EuiButtonIcon);
101+
expect(buttons).toHaveLength(2);
102+
103+
expect(buttons.first().prop('iconType')).toEqual('eyeClosed');
104+
expect(buttons.first().prop('color')).toEqual('danger');
105+
buttons.first().simulate('click');
121106
expect(actions[0].onClick).toHaveBeenCalled();
122107

123-
wrapper.find('.appSearchResult__actionButton').last().simulate('click');
108+
expect(buttons.last().prop('iconType')).toEqual('starFilled');
109+
// Note that no iconColor was passed so it was defaulted to primary
110+
expect(buttons.last().prop('color')).toEqual('primary');
111+
buttons.last().simulate('click');
124112
expect(actions[1].onClick).toHaveBeenCalled();
125113
});
126114

127-
it('will render custom actions seamlessly next to the document detail link', () => {
115+
it('will render a document detail link as the first action if shouldLinkToDetailPage is passed', () => {
128116
const wrapper = shallow(<Result {...props} actions={actions} shouldLinkToDetailPage />);
129-
expect(wrapper.find('.appSearchResult__actionButton')).toHaveLength(3);
117+
const header = wrapper.find(ResultHeader);
118+
const renderedActions = shallow(header.prop('actions') as any);
119+
const buttons = renderedActions.find(EuiButtonIcon);
120+
121+
// In addition to the 2 actions passed, we also have a link action
122+
expect(buttons).toHaveLength(3);
123+
124+
expect(buttons.first().prop('data-test-subj')).toEqual('DocumentDetailLink');
125+
});
126+
127+
it('will not render anything if no actions are passed and shouldLinkToDetailPage is false', () => {
128+
const wrapper = shallow(<Result {...props} actions={undefined} />);
129+
const header = wrapper.find(ResultHeader);
130+
const renderedActions = shallow(header.prop('actions') as any);
131+
const buttons = renderedActions.find(EuiButtonIcon);
132+
expect(buttons).toHaveLength(0);
130133
});
131134
});
132135

0 commit comments

Comments
 (0)