= ({
return null;
}
- return (
+ const result = (
{isTruncated ? (
@@ -61,13 +115,15 @@ export const FieldDescription: React.FC = ({
}
`}
>
- {customDescription}
+
+ {customDescription}
+
) : (
<>
- {customDescription}
+ {customDescription}
{isTooLong && (
= ({
)}
);
+
+ return Wrapper ? {result} : result;
};
diff --git a/packages/kbn-field-utils/tsconfig.json b/packages/kbn-field-utils/tsconfig.json
index 9ac5ba7e942b..5434723e4fd6 100644
--- a/packages/kbn-field-utils/tsconfig.json
+++ b/packages/kbn-field-utils/tsconfig.json
@@ -11,6 +11,8 @@
"@kbn/field-types",
"@kbn/expressions-plugin",
"@kbn/data-view-utils",
+ "@kbn/fields-metadata-plugin",
+ "@kbn/shared-ux-markdown",
],
"exclude": ["target/**/*"]
}
diff --git a/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx b/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx
index 43bebba6e660..e664a447c568 100644
--- a/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx
+++ b/packages/kbn-unified-field-list/src/components/field_popover/field_popover_header.tsx
@@ -20,6 +20,7 @@ import {
import { i18n } from '@kbn/i18n';
import { FieldDescription } from '@kbn/field-utils';
import type { DataViewField } from '@kbn/data-views-plugin/common';
+import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
import type { AddFieldFilterHandler } from '../../types';
export interface FieldPopoverHeaderProps {
@@ -33,6 +34,9 @@ export interface FieldPopoverHeaderProps {
onAddFilter?: AddFieldFilterHandler;
onEditField?: (fieldName: string) => unknown;
onDeleteField?: (fieldName: string) => unknown;
+ services?: {
+ fieldsMetadata?: FieldsMetadataPublicStart;
+ };
}
export const FieldPopoverHeader: React.FC = ({
@@ -46,6 +50,7 @@ export const FieldPopoverHeader: React.FC = ({
onAddFilter,
onEditField,
onDeleteField,
+ services,
}) => {
if (!field) {
return null;
@@ -153,12 +158,20 @@ export const FieldPopoverHeader: React.FC = ({
)}
- {field.customDescription ? (
- <>
-
-
- >
- ) : null}
+
+ >
+ );
+};
+
+const FieldDescriptionWrapper: React.FC = ({ children }) => {
+ return (
+ <>
+
+ {children}
>
);
};
diff --git a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
index d9e02d423cd9..0f74965c9687 100644
--- a/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
+++ b/packages/kbn-unified-field-list/src/containers/unified_field_list_item/field_list_item.tsx
@@ -10,6 +10,7 @@ import React, { memo, useCallback, useMemo, useState } from 'react';
import { EuiSpacer, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { UiCounterMetricType } from '@kbn/analytics';
+import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
import { Draggable } from '@kbn/dom-drag-drop';
import type { DataView, DataViewField } from '@kbn/data-views-plugin/public';
import type { SearchMode } from '../../types';
@@ -119,6 +120,7 @@ export interface UnifiedFieldListItemProps {
*/
services: UnifiedFieldListItemStatsProps['services'] & {
uiActions?: FieldPopoverFooterProps['uiActions'];
+ fieldsMetadata?: FieldsMetadataPublicStart;
};
/**
* Current search mode
@@ -367,6 +369,7 @@ function UnifiedFieldListItemComponent({
data-test-subj={stateService.creationOptions.dataTestSubj?.fieldListItemPopoverDataTestSubj}
renderHeader={() => (
{
const [containerRef, setContainerRef] = useState(null);
- const { fieldFormats, storage, uiSettings } = getUnifiedDocViewerServices();
+ const { fieldFormats, storage, uiSettings, fieldsMetadata } = getUnifiedDocViewerServices();
const showMultiFields = uiSettings.get(SHOW_MULTIFIELDS);
const currentDataViewId = dataView.id!;
@@ -387,9 +387,13 @@ export const DocViewerTable = ({
isPinned={pinned}
/>
- {isDetails && fieldMapping?.customDescription ? (
+ {isDetails && !!fieldMapping ? (
-
+
) : null}
@@ -409,7 +413,7 @@ export const DocViewerTable = ({
return null;
},
- [rows, searchText]
+ [rows, searchText, fieldsMetadata]
);
const renderCellPopover = useCallback(
diff --git a/test/functional/apps/discover/group7/_runtime_fields_editor.ts b/test/functional/apps/discover/group7/_runtime_fields_editor.ts
index 3028096adc60..a7f8c677d865 100644
--- a/test/functional/apps/discover/group7/_runtime_fields_editor.ts
+++ b/test/functional/apps/discover/group7/_runtime_fields_editor.ts
@@ -113,6 +113,51 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
await dataGrid.closeFlyout();
});
+ it('allows to replace ECS description with a custom field description', async function () {
+ await PageObjects.unifiedFieldList.clickFieldListItem('@timestamp');
+ await retry.waitFor('field popover text', async () => {
+ return (await testSubjects.getVisibleText('fieldDescription-@timestamp')).startsWith(
+ 'Date'
+ );
+ });
+ await PageObjects.unifiedFieldList.closeFieldPopover();
+ // check it in the doc viewer too
+ await dataGrid.clickRowToggle({ rowIndex: 0 });
+ await dataGrid.expandFieldNameCellInFlyout('@timestamp');
+ await retry.waitFor('doc viewer popover text', async () => {
+ return (await testSubjects.getVisibleText('fieldDescription-@timestamp')).startsWith(
+ 'Date'
+ );
+ });
+ await dataGrid.closeFlyout();
+
+ const customDescription = 'custom @timestamp description here';
+ // set a custom description
+ await PageObjects.discover.editField('@timestamp');
+ await fieldEditor.enableCustomDescription();
+ await fieldEditor.setCustomDescription(customDescription);
+ await fieldEditor.save();
+ await fieldEditor.waitUntilClosed();
+ await PageObjects.header.waitUntilLoadingHasFinished();
+ await PageObjects.unifiedFieldList.clickFieldListItem('@timestamp');
+ await retry.waitFor('field popover text', async () => {
+ return (
+ (await testSubjects.getVisibleText('fieldDescription-@timestamp')) === customDescription
+ );
+ });
+ await PageObjects.unifiedFieldList.closeFieldPopover();
+ // check it in the doc viewer too
+ await dataGrid.clickRowToggle({ rowIndex: 0 });
+ await dataGrid.expandFieldNameCellInFlyout('@timestamp');
+ await retry.waitFor('doc viewer popover text', async () => {
+ return (
+ (await testSubjects.getVisibleText('fieldDescription-@timestamp')) === customDescription
+ );
+ });
+
+ await dataGrid.closeFlyout();
+ });
+
it('should show a validation error when adding a too long custom description to existing fields', async function () {
const customDescription = 'custom bytes long description here'.repeat(10);
// set a custom description