Skip to content

Commit

Permalink
add icons to search preview document flyout
Browse files Browse the repository at this point in the history
  • Loading branch information
Sloane Perrault committed Mar 28, 2023
1 parent c2910f9 commit b68b0e5
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';

import { FieldIcon } from '@kbn/react-field';

import { SchemaField } from '../../../../../common/types/engines';
import { docLinks } from '../../../shared/doc_links';
import { generateEncodedPath } from '../../../shared/encode_path_params';
Expand All @@ -37,6 +35,7 @@ import { EnterpriseSearchEnginesPageTemplate } from '../layout/engines_page_temp
import { EngineIndicesLogic } from './engine_indices_logic';

import { EngineViewLogic } from './engine_view_logic';
import { FieldIcon } from './field_icon';

const SchemaFieldDetails: React.FC<{ schemaField: SchemaField }> = ({ schemaField }) => {
const { navigateToUrl } = useValues(KibanaLogic);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ export interface ConvertedResult {
value: string;
}

export interface ConvertedResultWithType extends ConvertedResult {
type: string;
}

export const convertResults = (result: Record<string, unknown>): ConvertedResult[] => {
const flattenedResult = flattenObject(result);
const unsortedFields = Object.entries(flattenedResult).map(
Expand All @@ -39,3 +43,13 @@ export const convertResults = (result: Record<string, unknown>): ConvertedResult
const sortedFields = unsortedFields.sort((a, b) => a.field.localeCompare(b.field));
return sortedFields;
};

export const addTypeToResults = (
results: ConvertedResult[],
fieldTypes: Record<string, string>
): ConvertedResultWithType[] => {
return results.map((result) => {
const type = fieldTypes[result.field];
return { ...result, type };
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import React, { useMemo } from 'react';

import { useValues } from 'kea';

import {
EuiBasicTableColumn,
EuiFlexGroup,
Expand All @@ -21,14 +23,21 @@ import {
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';

import { ConvertedResult, convertResults } from './convert_results';
import { FieldIcon } from '../field_icon';

import { addTypeToResults, ConvertedResultWithType, convertResults } from './convert_results';
import { useSelectedDocument } from './document_context';
import { EngineSearchPreviewLogic } from './engine_search_preview_logic';

export const DocumentFlyout: React.FC = () => {
const { fieldTypesByIndex } = useValues(EngineSearchPreviewLogic);
const { selectedDocument, setSelectedDocument } = useSelectedDocument();

const [id, items] = useMemo((): [string | null, ConvertedResult[]] => {
if (!selectedDocument) return [null, []];
const index = selectedDocument?._meta.rawHit._index;

const [id, items] = useMemo((): [string | null, ConvertedResultWithType[]] => {
const fieldTypes = fieldTypesByIndex[index];
if (!selectedDocument || !fieldTypes) return [null, []];
const {
_meta: { id: encodedId },
id: _id,
Expand All @@ -41,24 +50,26 @@ export const DocumentFlyout: React.FC = () => {
),
id: parsedId,
};
return [parsedId, convertResults(fields)];
}, [selectedDocument]);
return [parsedId, addTypeToResults(convertResults(fields), fieldTypes)];
}, [fieldTypesByIndex, index, selectedDocument]);

if (selectedDocument === null) return null;

const columns: Array<EuiBasicTableColumn<ConvertedResult>> = [
const columns: Array<EuiBasicTableColumn<ConvertedResultWithType>> = [
{
field: 'field',
name: i18n.translate(
'xpack.enterpriseSearch.content.engine.searchPreview.documentFlyout.fieldLabel',
{ defaultMessage: 'Field' }
),
render: (key: string) => (
<EuiText>
<EuiTextColor color="subdued">
<code>{key}</code>
</EuiTextColor>
</EuiText>
render: ({ field: key, type }: ConvertedResultWithType) => (
<EuiFlexGroup direction="row" gutterSize="s" alignItems="center">
<FieldIcon type={type} />
<EuiText>
<EuiTextColor color="subdued">
<code>{key}</code>
</EuiTextColor>
</EuiText>
</EuiFlexGroup>
),
truncateText: false,
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface EngineSearchPreviewActions {
export interface EngineSearchPreviewValues {
engineFieldCapabilitiesData: typeof FetchEngineFieldCapabilitiesApiLogic.values.data;
engineName: typeof EngineNameLogic.values.engineName;
fieldTypesByIndex: Record<string, Record<string, string>>;
resultFields: Record<string, FieldConfiguration>;
searchableFields: Record<string, SearchFieldConfiguration>;
sortableFields: string[];
Expand Down Expand Up @@ -50,6 +51,27 @@ export const EngineSearchPreviewLogic = kea<
}),
path: ['enterprise_search', 'content', 'engine_search_preview_logic'],
selectors: ({ selectors }) => ({
fieldTypesByIndex: [
() => [selectors.engineFieldCapabilitiesData],
(data: EngineSearchPreviewValues['engineFieldCapabilitiesData']) => {
if (!data) return {};

return data.fields.reduce(
(out: Record<string, Record<string, string>>, field) =>
field.indices.reduce(
(acc: Record<string, Record<string, string>>, index) => ({
...acc,
[index.name]: {
...(acc[index.name] || {}),
[field.name]: index.type,
},
}),
out
),
{}
);
},
],
resultFields: [
() => [selectors.engineFieldCapabilitiesData],
(data: EngineSearchPreviewValues['engineFieldCapabilitiesData']) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 { EuiTokenProps } from '@elastic/eui';
import { FieldIcon as KbnFieldIcon } from '@kbn/react-field';

// Remappings from type to a supported `FieldIcon` type
const typeToFieldIconType: Partial<Record<string, string>> = {
integer: 'number',
};

// Mappings for types missing from `FieldIcon`
const typeToEuiIconMap: Partial<Record<string, EuiTokenProps>> = {
object: { color: 'euiColorVis3', iconType: 'tokenObject' },
};

export interface FieldIconProps {
type: string;
}

export const FieldIcon: React.FC<FieldIconProps> = (props) => {
const type = typeToFieldIconType[props.type] || props.type;
const overrides = typeToEuiIconMap[type] || {};
return <KbnFieldIcon type={type} {...overrides} />;
};

0 comments on commit b68b0e5

Please sign in to comment.