mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[AppSearch] Add click count to ResultHeader component (#122981)
* Add click count to ResultHeader component This adds click count to the header item for the suggested Adaptive Relevance results. Added _meta optional field to the CurationResult type.
This commit is contained in:
parent
3819b3bd21
commit
c99dbe301c
9 changed files with 75 additions and 13 deletions
|
@ -5,7 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Result } from '../../../result/types';
|
||||
import { Result, ResultMeta } from '../../../result/types';
|
||||
import { CurationResult } from '../../types';
|
||||
|
||||
/**
|
||||
|
@ -19,19 +19,32 @@ import { CurationResult } from '../../types';
|
|||
* remove this file when that happens
|
||||
*/
|
||||
|
||||
const mergeMetas = (partialMeta: ResultMeta, secondPartialMeta: ResultMeta): ResultMeta => {
|
||||
return {
|
||||
...(partialMeta || {}),
|
||||
...secondPartialMeta,
|
||||
};
|
||||
};
|
||||
|
||||
export const convertToResultFormat = (document: CurationResult): Result => {
|
||||
const result = {} as Result;
|
||||
|
||||
// Convert `key: 'value'` into `key: { raw: 'value' }`
|
||||
Object.entries(document).forEach(([key, value]) => {
|
||||
result[key] = {
|
||||
raw: value,
|
||||
snippet: null, // Don't try to provide a snippet, we can't really guesstimate it
|
||||
};
|
||||
// don't convert _meta if exists
|
||||
if (key === '_meta') {
|
||||
result[key] = value as ResultMeta;
|
||||
} else {
|
||||
result[key] = {
|
||||
raw: value,
|
||||
snippet: null, // Don't try to provide a snippet, we can't really guesstimate it
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
// Add the _meta obj needed by Result
|
||||
result._meta = convertIdToMeta(document.id);
|
||||
const convertedMetaObj = convertIdToMeta(document.id);
|
||||
result._meta = mergeMetas(result._meta, convertedMetaObj);
|
||||
|
||||
return result;
|
||||
};
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { Meta } from '../../../../../common/types';
|
||||
import { Result } from '../result/types';
|
||||
import { Result, ResultMeta } from '../result/types';
|
||||
|
||||
export interface CurationSuggestion {
|
||||
query: string;
|
||||
|
@ -44,5 +44,6 @@ export interface CurationsAPIResponse {
|
|||
export interface CurationResult {
|
||||
// TODO: Consider updating our internal API to return more standard Result data in the future
|
||||
id: string;
|
||||
[key: string]: string | string[];
|
||||
_meta?: ResultMeta;
|
||||
[key: string]: string | string[] | ResultMeta | undefined;
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ describe('CurationResultPanel', () => {
|
|||
resultPosition: 1,
|
||||
isMetaEngine: true,
|
||||
schemaForTypeHighlights: values.engine.schema,
|
||||
showClick: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@ export const CurationResultPanel: React.FC<Props> = ({ variant, results }) => {
|
|||
isMetaEngine={isMetaEngine}
|
||||
schemaForTypeHighlights={engine.schema}
|
||||
resultPosition={index + 1}
|
||||
showClick
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
))
|
||||
|
|
|
@ -33,6 +33,7 @@ interface Props {
|
|||
schemaForTypeHighlights?: Schema;
|
||||
actions?: ResultAction[];
|
||||
dragHandleProps?: DraggableProvidedDragHandleProps;
|
||||
showClick?: boolean;
|
||||
}
|
||||
|
||||
const RESULT_CUTOFF = 5;
|
||||
|
@ -46,6 +47,7 @@ export const Result: React.FC<Props> = ({
|
|||
actions = [],
|
||||
dragHandleProps,
|
||||
resultPosition,
|
||||
showClick = false,
|
||||
}) => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
|
||||
|
@ -57,7 +59,6 @@ export const Result: React.FC<Props> = ({
|
|||
[result]
|
||||
);
|
||||
const numResults = resultFields.length;
|
||||
|
||||
const typeForField = (fieldName: string) => {
|
||||
if (schemaForTypeHighlights) return schemaForTypeHighlights[fieldName];
|
||||
};
|
||||
|
@ -103,6 +104,7 @@ export const Result: React.FC<Props> = ({
|
|||
documentLink={documentLink}
|
||||
actions={actions}
|
||||
resultPosition={resultPosition}
|
||||
showClick={showClick}
|
||||
/>
|
||||
{resultFields
|
||||
.slice(0, isOpen ? resultFields.length : RESULT_CUTOFF)
|
||||
|
|
|
@ -24,6 +24,7 @@ describe('ResultHeader', () => {
|
|||
};
|
||||
const props = {
|
||||
showScore: false,
|
||||
showClick: false,
|
||||
isMetaEngine: false,
|
||||
resultMeta,
|
||||
actions: [],
|
||||
|
@ -69,6 +70,18 @@ describe('ResultHeader', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('clicks', () => {
|
||||
it('renders clicks if showClick is true', () => {
|
||||
const wrapper = shallow(<ResultHeader {...props} showClick />);
|
||||
expect(wrapper.find('[data-test-subj="ResultClicks"]').exists()).toBe(true);
|
||||
});
|
||||
|
||||
it(' does not render clicks if showClick is false', () => {
|
||||
const wrapper = shallow(<ResultHeader {...props} showClick={false} />);
|
||||
expect(wrapper.find('[data-test-subj="ResultClicks"]').exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('engine', () => {
|
||||
it('renders engine name if this is a meta engine', () => {
|
||||
const wrapper = shallow(<ResultHeader {...props} isMetaEngine />);
|
||||
|
|
|
@ -24,6 +24,7 @@ interface Props {
|
|||
actions: ResultAction[];
|
||||
documentLink?: string;
|
||||
resultPosition?: number;
|
||||
showClick: boolean;
|
||||
}
|
||||
|
||||
export const ResultHeader: React.FC<Props> = ({
|
||||
|
@ -33,6 +34,7 @@ export const ResultHeader: React.FC<Props> = ({
|
|||
actions,
|
||||
documentLink,
|
||||
resultPosition,
|
||||
showClick,
|
||||
}) => {
|
||||
return (
|
||||
<header className="appSearchResultHeader">
|
||||
|
@ -65,6 +67,16 @@ export const ResultHeader: React.FC<Props> = ({
|
|||
type="id"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
{showClick && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<ResultHeaderItem
|
||||
data-test-subj="ResultClicks"
|
||||
field="clicks"
|
||||
value={resultMeta.clicks}
|
||||
type="clicks"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
{showScore && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<ResultHeaderItem
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
|
||||
import React from 'react';
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import './result_header_item.scss';
|
||||
|
||||
import { EuiLinkTo } from '../../../shared/react_router_helpers/eui_components';
|
||||
|
@ -16,7 +18,7 @@ import { TruncatedContent } from '../../../shared/truncate';
|
|||
interface Props {
|
||||
field: string;
|
||||
value?: string | number;
|
||||
type: 'id' | 'score' | 'string';
|
||||
type: 'id' | 'score' | 'string' | 'clicks';
|
||||
href?: string;
|
||||
}
|
||||
|
||||
|
@ -27,7 +29,15 @@ export const ResultHeaderItem: React.FC<Props> = ({ field, type, value, href })
|
|||
if (typeof value === 'string') {
|
||||
formattedValue = value;
|
||||
} else if (typeof value === 'number') {
|
||||
formattedValue = parseFloat((value as number).toFixed(2)).toString();
|
||||
if (type === 'clicks') {
|
||||
formattedValue = i18n.translate('xpack.enterpriseSearch.appSearch.result.clicks', {
|
||||
defaultMessage: '{clicks} Clicks',
|
||||
values: { clicks: value },
|
||||
description: 'This is click count for Adaptive Relevance suggestion results',
|
||||
});
|
||||
} else {
|
||||
formattedValue = parseFloat((value as number).toFixed(2)).toString();
|
||||
}
|
||||
}
|
||||
|
||||
const HeaderItemContent = () => (
|
||||
|
@ -45,8 +55,16 @@ export const ResultHeaderItem: React.FC<Props> = ({ field, type, value, href })
|
|||
type === 'score' && 'appSearchResultHeaderItem__score'
|
||||
}`}
|
||||
>
|
||||
<TruncatedContent content={`${field}:`} length={MAX_CHARACTER_LENGTH} tooltipType="title" />
|
||||
|
||||
{type !== 'clicks' && (
|
||||
<>
|
||||
<TruncatedContent
|
||||
content={`${field}:`}
|
||||
length={MAX_CHARACTER_LENGTH}
|
||||
tooltipType="title"
|
||||
/>
|
||||
|
||||
</>
|
||||
)}
|
||||
{href ? (
|
||||
<EuiLinkTo to={href}>
|
||||
<HeaderItemContent />
|
||||
|
|
|
@ -22,6 +22,7 @@ export interface ResultMeta {
|
|||
id: string;
|
||||
score?: number;
|
||||
engine: string;
|
||||
clicks?: number;
|
||||
}
|
||||
|
||||
// A search result item
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue