[Workplace Search] Port PR 4033 from ent-search to Kibana and update typings (#105054)
* Improve typings Custom API Source allow indexing several types of data. We didn't account for all of them. For example, geolocation can be array of arrays of numbers. This commit improves typings. The following commits mostly fix TS errors that appear after this commit. * Remove type castings to account for all possible variable types * Update helper functions to accept new CustomAPIFieldValue * Fix TS error: convert url to string before using it in EuiLink * Update mock and tests to match updated typings Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
e279042c56
commit
fdc99681a7
11 changed files with 65 additions and 17 deletions
|
@ -303,6 +303,7 @@ export const exampleResult = {
|
|||
titleField: 'otherTitle',
|
||||
subtitleField: 'otherSubtitle',
|
||||
urlField: 'myLink',
|
||||
urlFieldIsLinkable: true,
|
||||
color: '#e3e3e3',
|
||||
descriptionField: 'about',
|
||||
typeField: 'otherType',
|
||||
|
@ -314,14 +315,18 @@ export const exampleResult = {
|
|||
{ fieldName: 'dogs', label: 'Canines' },
|
||||
],
|
||||
},
|
||||
titleFieldHover: false,
|
||||
urlFieldHover: false,
|
||||
exampleDocuments: [
|
||||
{
|
||||
myLink: 'http://foo',
|
||||
otherTitle: 'foo',
|
||||
content_source_id: '60e85e7ea2564c265a88a4f0',
|
||||
external_id: 'doc-60e85eb7a2564c937a88a4f3',
|
||||
last_updated: '2021-07-09T14:35:35+00:00',
|
||||
updated_at: '2021-07-09T14:35:35+00:00',
|
||||
source: 'custom',
|
||||
},
|
||||
],
|
||||
schemaFields: {},
|
||||
};
|
||||
|
||||
export const mostRecentIndexJob = {
|
||||
|
|
|
@ -96,7 +96,7 @@ export interface ContentSource {
|
|||
export interface SourceContentItem {
|
||||
id: string;
|
||||
last_updated: string;
|
||||
[key: string]: string;
|
||||
[key: string]: string | CustomAPIFieldValue;
|
||||
}
|
||||
|
||||
export interface ContentSourceDetails extends ContentSource {
|
||||
|
@ -186,8 +186,25 @@ export interface CustomSource {
|
|||
id: string;
|
||||
}
|
||||
|
||||
// https://www.elastic.co/guide/en/workplace-search/current/workplace-search-custom-sources-api.html#_schema_data_types
|
||||
type CustomAPIString = string | string[];
|
||||
type CustomAPINumber = number | number[];
|
||||
type CustomAPIDate = string | string[];
|
||||
type CustomAPIGeolocation = string | string[] | number[] | number[][];
|
||||
|
||||
export type CustomAPIFieldValue =
|
||||
| CustomAPIString
|
||||
| CustomAPINumber
|
||||
| CustomAPIDate
|
||||
| CustomAPIGeolocation;
|
||||
|
||||
export interface Result {
|
||||
[key: string]: string | string[];
|
||||
content_source_id: string;
|
||||
last_updated: string;
|
||||
external_id: string;
|
||||
updated_at: string;
|
||||
source: string;
|
||||
[key: string]: CustomAPIFieldValue;
|
||||
}
|
||||
|
||||
export interface OptionValue {
|
||||
|
|
|
@ -14,6 +14,12 @@ describe('getAsLocalDateTimeString', () => {
|
|||
expect(getAsLocalDateTimeString(date)).toEqual(new Date(Date.parse(date)).toLocaleString());
|
||||
});
|
||||
|
||||
it('returns null if passed value is not a string', () => {
|
||||
const date = ['1', '2'];
|
||||
|
||||
expect(getAsLocalDateTimeString(date)).toEqual(null);
|
||||
});
|
||||
|
||||
it('returns null if string cannot be parsed as date', () => {
|
||||
const date = 'foo';
|
||||
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export const getAsLocalDateTimeString = (str: string) => {
|
||||
const dateValue = Date.parse(str);
|
||||
import { CustomAPIFieldValue } from '../types';
|
||||
|
||||
export const getAsLocalDateTimeString = (maybeDate: CustomAPIFieldValue) => {
|
||||
if (typeof maybeDate !== 'string') return null;
|
||||
|
||||
const dateValue = Date.parse(maybeDate);
|
||||
return dateValue ? new Date(dateValue).toLocaleString() : null;
|
||||
};
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CustomAPIFieldValue } from '../types';
|
||||
|
||||
const mimeTypes = {
|
||||
'application/iwork-keynote-sffkey': 'Keynote',
|
||||
'application/x-iwork-keynote-sffkey': 'Keynote',
|
||||
|
@ -51,4 +53,5 @@ const mimeTypes = {
|
|||
'video/quicktime': 'MOV',
|
||||
} as { [key: string]: string };
|
||||
|
||||
export const mimeType = (type: string) => mimeTypes[type.toLowerCase()] || type;
|
||||
export const mimeType = (type: CustomAPIFieldValue) =>
|
||||
mimeTypes[type.toString().toLowerCase()] || type;
|
||||
|
|
|
@ -62,7 +62,7 @@ export const ExampleResultDetailCard: React.FC = () => {
|
|||
<div className="example-result-detail-card__content">
|
||||
{detailFields.length > 0 ? (
|
||||
detailFields.map(({ fieldName, label }, index) => {
|
||||
const value = result[fieldName] as string;
|
||||
const value = result[fieldName];
|
||||
const dateValue = getAsLocalDateTimeString(value);
|
||||
|
||||
return (
|
||||
|
|
|
@ -117,7 +117,7 @@ export const ExampleSearchResultGroup: React.FC = () => {
|
|||
data-test-subj="MediaTypeField"
|
||||
>
|
||||
<span className="example-search-result__tag-content">
|
||||
{mimeType(result[mediaTypeField] as string)}
|
||||
{mimeType(result[mediaTypeField])}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
@ -135,8 +135,7 @@ export const ExampleSearchResultGroup: React.FC = () => {
|
|||
by {result[updatedByField]}
|
||||
</span>
|
||||
)}
|
||||
{getAsLocalDateTimeString(result.last_updated as string) ||
|
||||
result.last_updated}
|
||||
{getAsLocalDateTimeString(result.last_updated) || result.last_updated}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -109,7 +109,7 @@ export const ExampleStandoutResult: React.FC = () => {
|
|||
data-test-subj="MediaTypeField"
|
||||
>
|
||||
<span className="example-search-result__tag-content">
|
||||
{mimeType(result[mediaTypeField] as string)}
|
||||
{mimeType(result[mediaTypeField])}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
@ -127,7 +127,7 @@ export const ExampleStandoutResult: React.FC = () => {
|
|||
by {result[updatedByField]}
|
||||
</span>
|
||||
)}
|
||||
{getAsLocalDateTimeString(result.last_updated as string) || result.last_updated}
|
||||
{getAsLocalDateTimeString(result.last_updated) || result.last_updated}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { exampleResult } from '../../../../__mocks__/content_sources.mock';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
|
@ -12,7 +14,11 @@ import { shallow } from 'enzyme';
|
|||
import { SubtitleField } from './subtitle_field';
|
||||
|
||||
describe('SubtitleField', () => {
|
||||
const result = { foo: 'bar' };
|
||||
const result = {
|
||||
...exampleResult.exampleDocuments[0],
|
||||
foo: 'bar',
|
||||
};
|
||||
|
||||
it('renders', () => {
|
||||
const props = {
|
||||
result,
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { exampleResult } from '../../../../__mocks__/content_sources.mock';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { shallow } from 'enzyme';
|
||||
|
@ -12,7 +14,10 @@ import { shallow } from 'enzyme';
|
|||
import { TitleField } from './title_field';
|
||||
|
||||
describe('TitleField', () => {
|
||||
const result = { foo: 'bar' };
|
||||
const result = {
|
||||
...exampleResult.exampleDocuments[0],
|
||||
foo: 'bar',
|
||||
};
|
||||
it('renders', () => {
|
||||
const props = {
|
||||
result,
|
||||
|
@ -26,7 +31,10 @@ describe('TitleField', () => {
|
|||
|
||||
it('handles title when array', () => {
|
||||
const props = {
|
||||
result: { foo: ['baz', 'bar'] },
|
||||
result: {
|
||||
...exampleResult.exampleDocuments[0],
|
||||
foo: ['baz', 'bar'],
|
||||
},
|
||||
titleField: 'foo',
|
||||
titleFieldHover: false,
|
||||
};
|
||||
|
|
|
@ -137,7 +137,7 @@ export const SourceContent: React.FC = () => {
|
|||
<TruncatedContent tooltipType="title" content={url.toString()} length={MAX_LENGTH} />
|
||||
)}
|
||||
{urlFieldIsLinkable && (
|
||||
<EuiLink target="_blank" href={url}>
|
||||
<EuiLink target="_blank" href={url.toString()}>
|
||||
<TruncatedContent tooltipType="title" content={url.toString()} length={MAX_LENGTH} />
|
||||
</EuiLink>
|
||||
)}
|
||||
|
|
Loading…
Reference in a new issue