mirror of
https://github.com/elastic/kibana.git
synced 2025-06-27 10:40:07 -04:00
[UnifiedDocViewer] Move Discover doc viewer into plugin/package (#162847)
## Summary Replaces https://github.com/elastic/kibana/pull/154012. Moves the Discover doc viewer component into a new plugin/package, `@kbn/unified-doc-viewer` and `@kbn/unified-doc-viewer-plugin`. ### Checklist - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Shahzad <shahzad31comp@gmail.com>
This commit is contained in:
parent
59231988c7
commit
09cd69d386
137 changed files with 1325 additions and 760 deletions
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
|
@ -750,6 +750,9 @@ test/plugin_functional/plugins/ui_settings_plugin @elastic/kibana-core
|
|||
packages/kbn-ui-shared-deps-npm @elastic/kibana-operations
|
||||
packages/kbn-ui-shared-deps-src @elastic/kibana-operations
|
||||
packages/kbn-ui-theme @elastic/kibana-operations
|
||||
packages/kbn-unified-doc-viewer @elastic/kibana-data-discovery
|
||||
examples/unified_doc_viewer @elastic/kibana-core
|
||||
src/plugins/unified_doc_viewer @elastic/kibana-data-discovery
|
||||
packages/kbn-unified-field-list @elastic/kibana-data-discovery
|
||||
examples/unified_field_list_examples @elastic/kibana-data-discovery
|
||||
src/plugins/unified_histogram @elastic/kibana-data-discovery
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
"visTypeXy": "src/plugins/vis_types/xy",
|
||||
"visualizations": "src/plugins/visualizations",
|
||||
"visualizationUiComponents": "packages/kbn-visualization-ui-components",
|
||||
"unifiedDocViewer": ["src/plugins/unified_doc_viewer", "packages/kbn-unified-doc-viewer"],
|
||||
"unifiedSearch": "src/plugins/unified_search",
|
||||
"unifiedFieldList": "packages/kbn-unified-field-list",
|
||||
"unifiedHistogram": "src/plugins/unified_histogram"
|
||||
|
|
|
@ -336,6 +336,10 @@ In general this plugin provides:
|
|||
|Registers commercially licensed generic actions like per panel time range and contains some code that supports drilldown work.
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/src/plugins/unified_doc_viewer/README.md[unifiedDocViewer]
|
||||
|This plugin contains services reliant on the plugin lifecycle for the unified doc viewer component (see @kbn/unified-doc-viewer).
|
||||
|
||||
|
||||
|{kib-repo}blob/{branch}/src/plugins/unified_histogram/README.md[unifiedHistogram]
|
||||
|Unified Histogram is a UX Building Block including a layout with a resizable histogram and a main display.
|
||||
It manages its own state and data fetching, and can easily be dropped into pages with minimal setup.
|
||||
|
|
3
examples/unified_doc_viewer/README.md
Normal file
3
examples/unified_doc_viewer/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
## Unified Doc Viewer
|
||||
|
||||
An example plugin showing usage of the unified doc viewer plugin (plugins/unified_doc_viewer) and package (@kbn/unified-doc-viewer).
|
16
examples/unified_doc_viewer/kibana.jsonc
Normal file
16
examples/unified_doc_viewer/kibana.jsonc
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"type": "plugin",
|
||||
"id": "@kbn/unified-doc-viewer-examples",
|
||||
"owner": "@elastic/kibana-core",
|
||||
"description": "Examples showing usage of the unified doc viewer.",
|
||||
"plugin": {
|
||||
"id": "unifiedDocViewerExamples",
|
||||
"server": false,
|
||||
"browser": true,
|
||||
"requiredPlugins": [
|
||||
"data",
|
||||
"developerExamples",
|
||||
"unifiedDocViewer"
|
||||
]
|
||||
}
|
||||
}
|
72
examples/unified_doc_viewer/public/application.tsx
Normal file
72
examples/unified_doc_viewer/public/application.tsx
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import type { AppMountParameters, CoreStart } from '@kbn/core/public';
|
||||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils/types';
|
||||
import type { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { UnifiedDocViewer } from '@kbn/unified-doc-viewer-plugin/public';
|
||||
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import type { StartDeps } from './plugin';
|
||||
|
||||
export const renderApp = (
|
||||
core: CoreStart,
|
||||
{ data }: StartDeps,
|
||||
{ element }: AppMountParameters
|
||||
) => {
|
||||
ReactDOM.render(<UnifiedDocViewerExamplesApp data={data} />, element);
|
||||
|
||||
return () => {
|
||||
ReactDOM.unmountComponentAtNode(element);
|
||||
};
|
||||
};
|
||||
|
||||
function UnifiedDocViewerExamplesApp({ data }: { data: DataPublicPluginStart }) {
|
||||
const [dataView, setDataView] = useState<DataView | null>();
|
||||
const [hit, setHit] = useState<DataTableRecord | null>();
|
||||
|
||||
useEffect(() => {
|
||||
data.dataViews.getDefault().then((defaultDataView) => setDataView(defaultDataView));
|
||||
}, [data]);
|
||||
|
||||
useEffect(() => {
|
||||
const setDefaultHit = async () => {
|
||||
if (!dataView?.id) return;
|
||||
const response = await data.search
|
||||
.search({
|
||||
params: {
|
||||
index: dataView?.getIndexPattern(),
|
||||
body: {
|
||||
fields: ['*'],
|
||||
_source: false,
|
||||
},
|
||||
},
|
||||
})
|
||||
.toPromise();
|
||||
const docs = response?.rawResponse?.hits?.hits ?? [];
|
||||
if (docs.length > 0) {
|
||||
const record = buildDataTableRecord(docs[0], dataView);
|
||||
setHit(record);
|
||||
}
|
||||
};
|
||||
|
||||
setDefaultHit();
|
||||
}, [data, dataView]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{dataView?.id && hit ? (
|
||||
<UnifiedDocViewer hit={hit} dataView={dataView} />
|
||||
) : (
|
||||
'Loading... (make sure you have a default data view and at least one matching document)'
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
12
examples/unified_doc_viewer/public/index.ts
Normal file
12
examples/unified_doc_viewer/public/index.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import { UnifiedDocViewerExamplesPlugin } from './plugin';
|
||||
|
||||
export function plugin() {
|
||||
return new UnifiedDocViewerExamplesPlugin();
|
||||
}
|
49
examples/unified_doc_viewer/public/plugin.tsx
Normal file
49
examples/unified_doc_viewer/public/plugin.tsx
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
import { AppMountParameters, CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
|
||||
import { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public';
|
||||
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
|
||||
export interface SetupDeps {
|
||||
developerExamples: DeveloperExamplesSetup;
|
||||
}
|
||||
|
||||
export interface StartDeps {
|
||||
data: DataPublicPluginStart;
|
||||
}
|
||||
|
||||
export class UnifiedDocViewerExamplesPlugin implements Plugin<void, void, SetupDeps, StartDeps> {
|
||||
public setup(core: CoreSetup<StartDeps>, deps: SetupDeps) {
|
||||
// Register an application into the side navigation menu
|
||||
core.application.register({
|
||||
id: 'unifiedDocViewer',
|
||||
title: 'Unified Doc Viewer Examples',
|
||||
async mount(params: AppMountParameters) {
|
||||
// Load application bundle
|
||||
const { renderApp } = await import('./application');
|
||||
// Get start services as specified in kibana.json
|
||||
const [coreStart, depsStart] = await core.getStartServices();
|
||||
// Render the application
|
||||
return renderApp(coreStart, depsStart, params);
|
||||
},
|
||||
});
|
||||
|
||||
// This section is only needed to get this example plugin to show up in our Developer Examples.
|
||||
deps.developerExamples.register({
|
||||
appId: 'unifiedDocViewer',
|
||||
title: 'Unified Doc Viewer Examples',
|
||||
description: 'Examples showcasing the unified doc viewer.',
|
||||
});
|
||||
}
|
||||
|
||||
public start(core: CoreStart) {
|
||||
return {};
|
||||
}
|
||||
|
||||
public stop() {}
|
||||
}
|
24
examples/unified_doc_viewer/tsconfig.json
Normal file
24
examples/unified_doc_viewer/tsconfig.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types"
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"common/**/*.ts",
|
||||
"public/**/*.ts",
|
||||
"public/**/*.tsx",
|
||||
"../../typings/**/*"
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/core",
|
||||
"@kbn/data-plugin",
|
||||
"@kbn/data-views-plugin",
|
||||
"@kbn/developer-examples-plugin",
|
||||
"@kbn/discover-utils",
|
||||
"@kbn/unified-doc-viewer-plugin",
|
||||
]
|
||||
}
|
|
@ -742,6 +742,9 @@
|
|||
"@kbn/ui-shared-deps-npm": "link:packages/kbn-ui-shared-deps-npm",
|
||||
"@kbn/ui-shared-deps-src": "link:packages/kbn-ui-shared-deps-src",
|
||||
"@kbn/ui-theme": "link:packages/kbn-ui-theme",
|
||||
"@kbn/unified-doc-viewer": "link:packages/kbn-unified-doc-viewer",
|
||||
"@kbn/unified-doc-viewer-examples": "link:examples/unified_doc_viewer",
|
||||
"@kbn/unified-doc-viewer-plugin": "link:src/plugins/unified_doc_viewer",
|
||||
"@kbn/unified-field-list": "link:packages/kbn-unified-field-list",
|
||||
"@kbn/unified-field-list-examples-plugin": "link:examples/unified_field_list_examples",
|
||||
"@kbn/unified-histogram-plugin": "link:src/plugins/unified_histogram",
|
||||
|
|
|
@ -16,6 +16,8 @@ export {
|
|||
ENABLE_SQL,
|
||||
FIELDS_LIMIT_SETTING,
|
||||
HIDE_ANNOUNCEMENTS,
|
||||
KNOWN_FIELD_TYPE_LIST,
|
||||
KNOWN_FIELD_TYPES,
|
||||
MAX_DOC_FIELDS_DISPLAYED,
|
||||
MODIFY_COLUMNS_ON_SWITCH,
|
||||
ROW_HEIGHT_OPTION,
|
||||
|
@ -34,8 +36,10 @@ export {
|
|||
formatFieldValue,
|
||||
formatHit,
|
||||
getDocId,
|
||||
getFieldTypeName,
|
||||
getIgnoredReason,
|
||||
getShouldShowFieldHandler,
|
||||
isKnownFieldType,
|
||||
isNestedFieldParent,
|
||||
usePager,
|
||||
} from './src';
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import type { SearchHit } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
export type { IgnoredReason, ShouldShowFieldInTableHandler } from './utils';
|
||||
export type { FieldTypeKnown, IgnoredReason, ShouldShowFieldInTableHandler } from './utils';
|
||||
|
||||
export interface EsHitRecord extends Omit<SearchHit, '_source'> {
|
||||
_source?: Record<string, unknown>;
|
||||
|
|
|
@ -6,7 +6,12 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { FieldTypeKnown } from '../../types';
|
||||
import type { DataViewField } from '@kbn/data-views-plugin/common';
|
||||
|
||||
export type FieldTypeKnown = Exclude<
|
||||
DataViewField['timeSeriesMetric'] | DataViewField['type'],
|
||||
undefined
|
||||
>;
|
||||
|
||||
/**
|
||||
* Field types for which name and description are defined
|
|
@ -14,7 +14,7 @@ import { KNOWN_FIELD_TYPES } from './field_types';
|
|||
* A user-friendly name of an unknown field type
|
||||
*/
|
||||
export const UNKNOWN_FIELD_TYPE_MESSAGE = i18n.translate(
|
||||
'unifiedFieldList.fieldNameIcons.unknownFieldAriaLabel',
|
||||
'discover.fieldNameIcons.unknownFieldAriaLabel',
|
||||
{
|
||||
defaultMessage: 'Unknown field',
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ export function getFieldTypeName(type?: string) {
|
|||
|
||||
if (type === 'source') {
|
||||
// Note that this type is currently not provided, type for _source is undefined
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.sourceFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.sourceFieldAriaLabel', {
|
||||
defaultMessage: 'Source field',
|
||||
});
|
||||
}
|
||||
|
@ -40,107 +40,107 @@ export function getFieldTypeName(type?: string) {
|
|||
const knownType: KNOWN_FIELD_TYPES = type as KNOWN_FIELD_TYPES;
|
||||
switch (knownType) {
|
||||
case KNOWN_FIELD_TYPES.DOCUMENT:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.recordAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.recordAriaLabel', {
|
||||
defaultMessage: 'Records',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.BINARY:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.binaryAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.binaryAriaLabel', {
|
||||
defaultMessage: 'Binary',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.BOOLEAN:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.booleanAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.booleanAriaLabel', {
|
||||
defaultMessage: 'Boolean',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.CONFLICT:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.conflictFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.conflictFieldAriaLabel', {
|
||||
defaultMessage: 'Conflict',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.COUNTER:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.counterFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.counterFieldAriaLabel', {
|
||||
defaultMessage: 'Counter metric',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.DATE:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.dateFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.dateFieldAriaLabel', {
|
||||
defaultMessage: 'Date',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.DATE_RANGE:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.dateRangeFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.dateRangeFieldAriaLabel', {
|
||||
defaultMessage: 'Date range',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.DENSE_VECTOR:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.denseVectorFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.denseVectorFieldAriaLabel', {
|
||||
defaultMessage: 'Dense vector',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.GAUGE:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.gaugeFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.gaugeFieldAriaLabel', {
|
||||
defaultMessage: 'Gauge metric',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.GEO_POINT:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.geoPointFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.geoPointFieldAriaLabel', {
|
||||
defaultMessage: 'Geo point',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.GEO_SHAPE:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.geoShapeFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.geoShapeFieldAriaLabel', {
|
||||
defaultMessage: 'Geo shape',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.HISTOGRAM:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.histogramFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.histogramFieldAriaLabel', {
|
||||
defaultMessage: 'Histogram',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.IP:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.ipAddressFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.ipAddressFieldAriaLabel', {
|
||||
defaultMessage: 'IP address',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.IP_RANGE:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.ipRangeFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.ipRangeFieldAriaLabel', {
|
||||
defaultMessage: 'IP range',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.FLATTENED:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.flattenedFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.flattenedFieldAriaLabel', {
|
||||
defaultMessage: 'Flattened',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.MURMUR3:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.murmur3FieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.murmur3FieldAriaLabel', {
|
||||
defaultMessage: 'Murmur3',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.NUMBER:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.numberFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.numberFieldAriaLabel', {
|
||||
defaultMessage: 'Number',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.RANK_FEATURE:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.rankFeatureFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.rankFeatureFieldAriaLabel', {
|
||||
defaultMessage: 'Rank feature',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.RANK_FEATURES:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.rankFeaturesFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.rankFeaturesFieldAriaLabel', {
|
||||
defaultMessage: 'Rank features',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.POINT:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.pointFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.pointFieldAriaLabel', {
|
||||
defaultMessage: 'Point',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.SHAPE:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.shapeFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.shapeFieldAriaLabel', {
|
||||
defaultMessage: 'Shape',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.STRING:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.stringFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.stringFieldAriaLabel', {
|
||||
defaultMessage: 'String',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.TEXT:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.textFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.textFieldAriaLabel', {
|
||||
defaultMessage: 'Text',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.KEYWORD:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.keywordFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.keywordFieldAriaLabel', {
|
||||
defaultMessage: 'Keyword',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.NESTED:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.nestedFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.nestedFieldAriaLabel', {
|
||||
defaultMessage: 'Nested',
|
||||
});
|
||||
case KNOWN_FIELD_TYPES.VERSION:
|
||||
return i18n.translate('unifiedFieldList.fieldNameIcons.versionFieldAriaLabel', {
|
||||
return i18n.translate('discover.fieldNameIcons.versionFieldAriaLabel', {
|
||||
defaultMessage: 'Version',
|
||||
});
|
||||
default:
|
|
@ -7,9 +7,11 @@
|
|||
*/
|
||||
|
||||
export * from './build_data_record';
|
||||
export * from './field_types';
|
||||
export * from './format_hit';
|
||||
export * from './format_value';
|
||||
export * from './get_doc_id';
|
||||
export * from './get_field_type_name';
|
||||
export * from './get_ignored_reason';
|
||||
export * from './get_should_show_field_handler';
|
||||
export * from './nested_fields';
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
export type {
|
||||
DataTableRecord,
|
||||
EsHitRecord,
|
||||
FieldTypeKnown,
|
||||
IgnoredReason,
|
||||
ShouldShowFieldInTableHandler,
|
||||
} from './src/types';
|
||||
|
|
|
@ -142,6 +142,7 @@ pageLoadAssetSize:
|
|||
triggersActionsUi: 135613
|
||||
uiActions: 35121
|
||||
uiActionsEnhanced: 38494
|
||||
unifiedDocViewer: 25099
|
||||
unifiedHistogram: 19928
|
||||
unifiedSearch: 71059
|
||||
upgradeAssistant: 81241
|
||||
|
|
15
packages/kbn-unified-doc-viewer/README.md
Normal file
15
packages/kbn-unified-doc-viewer/README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# @kbn/unified-doc-viewer
|
||||
|
||||
This package contains components and services for the unified doc viewer component.
|
||||
|
||||
Discover (Classic view → Expanded document)
|
||||
|
||||

|
||||
|
||||
Discover (Document explorer → Toggle dialog with details)
|
||||
|
||||

|
||||
|
||||
Discover (View single document)
|
||||
|
||||

|
|
@ -6,10 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export enum ElasticRequestState {
|
||||
Loading,
|
||||
NotFound,
|
||||
Found,
|
||||
Error,
|
||||
NotFoundDataView,
|
||||
}
|
||||
export { DocViewer, DocViewsRegistry, ElasticRequestState, FieldName } from './src';
|
13
packages/kbn-unified-doc-viewer/jest.config.js
Normal file
13
packages/kbn-unified-doc-viewer/jest.config.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../..',
|
||||
roots: ['<rootDir>/packages/kbn-unified-doc-viewer'],
|
||||
};
|
5
packages/kbn-unified-doc-viewer/kibana.jsonc
Normal file
5
packages/kbn-unified-doc-viewer/kibana.jsonc
Normal file
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"type": "shared-common",
|
||||
"id": "@kbn/unified-doc-viewer",
|
||||
"owner": "@elastic/kibana-data-discovery"
|
||||
}
|
7
packages/kbn-unified-doc-viewer/package.json
Normal file
7
packages/kbn-unified-doc-viewer/package.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"name": "@kbn/unified-doc-viewer",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"license": "SSPL-1.0 OR Elastic License 2.0",
|
||||
"sideEffects": false
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Render <DocViewer/> with 3 different tabs 1`] = `
|
||||
exports[`<DocViewer /> Render <DocViewer/> with 3 different tabs 1`] = `
|
||||
<div
|
||||
className="kbnDocViewer"
|
||||
data-test-subj="kbnDocViewer"
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { DocViewer } from './doc_viewer';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import type { DocViewRenderProps } from '../../types';
|
||||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
import { DocViewsRegistry } from '../..';
|
||||
|
||||
describe('<DocViewer />', () => {
|
||||
test('Render <DocViewer/> with 3 different tabs', () => {
|
||||
const registry = new DocViewsRegistry();
|
||||
registry.addDocView({ order: 10, title: 'Render function', render: jest.fn() });
|
||||
registry.addDocView({ order: 20, title: 'React component', component: () => <div>test</div> });
|
||||
// @ts-expect-error This should be invalid and will throw an error when rendering
|
||||
registry.addDocView({ order: 30, title: 'Invalid doc view' });
|
||||
|
||||
const renderProps = { hit: {} } as DocViewRenderProps;
|
||||
|
||||
const wrapper = shallow(
|
||||
<DocViewer docViews={registry.getDocViewsSorted(renderProps.hit)} {...renderProps} />
|
||||
);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Render <DocViewer/> with 1 tab displaying error message', () => {
|
||||
function SomeComponent() {
|
||||
// this is just a placeholder
|
||||
return null;
|
||||
}
|
||||
|
||||
const registry = new DocViewsRegistry();
|
||||
registry.addDocView({
|
||||
order: 10,
|
||||
title: 'React component',
|
||||
component: SomeComponent,
|
||||
});
|
||||
|
||||
const renderProps = {
|
||||
hit: buildDataTableRecord({ _index: 't', _id: '1' }),
|
||||
} as DocViewRenderProps;
|
||||
const errorMsg = 'Catch me if you can!';
|
||||
|
||||
const wrapper = mount(
|
||||
<DocViewer docViews={registry.getDocViewsSorted(renderProps.hit)} {...renderProps} />
|
||||
);
|
||||
const error = new Error(errorMsg);
|
||||
wrapper.find(SomeComponent).simulateError(error);
|
||||
const errorMsgComponent = findTestSubject(wrapper, 'docViewerError');
|
||||
expect(errorMsgComponent.text()).toMatch(new RegExp(`${errorMsg}`));
|
||||
});
|
||||
});
|
|
@ -8,9 +8,12 @@
|
|||
|
||||
import React from 'react';
|
||||
import { EuiTabbedContent } from '@elastic/eui';
|
||||
import { getDocViewsRegistry } from '../../../../kibana_services';
|
||||
import { DocViewerTab } from './doc_viewer_tab';
|
||||
import { DocView, DocViewRenderProps } from '../../doc_views_types';
|
||||
import type { DocView, DocViewRenderProps } from '../../types';
|
||||
|
||||
export interface DocViewerProps extends DocViewRenderProps {
|
||||
docViews: DocView[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rendering tabs with different views of 1 Elasticsearch hit in Discover.
|
||||
|
@ -18,26 +21,23 @@ import { DocView, DocViewRenderProps } from '../../doc_views_types';
|
|||
* A view can contain a React `component`, or any JS framework by using
|
||||
* a `render` function.
|
||||
*/
|
||||
export function DocViewer(renderProps: DocViewRenderProps) {
|
||||
const docViewsRegistry = getDocViewsRegistry();
|
||||
const tabs = docViewsRegistry
|
||||
.getDocViewsSorted(renderProps.hit)
|
||||
.map(({ title, render, component }: DocView, idx: number) => {
|
||||
return {
|
||||
id: `kbn_doc_viewer_tab_${idx}`,
|
||||
name: title,
|
||||
content: (
|
||||
<DocViewerTab
|
||||
id={idx}
|
||||
title={title}
|
||||
component={component}
|
||||
renderProps={renderProps}
|
||||
render={render}
|
||||
/>
|
||||
),
|
||||
['data-test-subj']: `docViewerTab-${idx}`,
|
||||
};
|
||||
});
|
||||
export function DocViewer({ docViews, ...renderProps }: DocViewerProps) {
|
||||
const tabs = docViews.map(({ title, render, component }: DocView, idx: number) => {
|
||||
return {
|
||||
id: `kbn_doc_viewer_tab_${idx}`,
|
||||
name: title,
|
||||
content: (
|
||||
<DocViewerTab
|
||||
id={idx}
|
||||
title={title}
|
||||
component={component}
|
||||
renderProps={renderProps}
|
||||
render={render}
|
||||
/>
|
||||
),
|
||||
['data-test-subj']: `docViewerTab-${idx}`,
|
||||
};
|
||||
});
|
||||
|
||||
if (!tabs.length) {
|
||||
// There there's a minimum of 2 tabs active in Discover.
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { DocViewerError } from './doc_viewer_error';
|
||||
|
||||
test('DocViewerError should wrap error in boundary', () => {
|
||||
const props = {
|
||||
error: new Error('my error'),
|
||||
};
|
||||
|
||||
expect(() => {
|
||||
const wrapper = mount(<DocViewerError {...props} />);
|
||||
const html = wrapper.html();
|
||||
expect(html).toContain('euiErrorBoundary');
|
||||
expect(html).toContain('my error');
|
||||
}).not.toThrowError();
|
||||
});
|
|
@ -9,7 +9,7 @@
|
|||
import React from 'react';
|
||||
import { mount } from 'enzyme';
|
||||
import { DocViewRenderTab } from './doc_viewer_render_tab';
|
||||
import { DocViewRenderProps } from '../../doc_views_types';
|
||||
import type { DocViewRenderProps } from '../../types';
|
||||
|
||||
test('Mounting and unmounting DocViewerRenderTab', () => {
|
||||
const unmountFn = jest.fn();
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { DocViewRenderFn, DocViewRenderProps } from '../../doc_views_types';
|
||||
import type { DocViewRenderFn, DocViewRenderProps } from '../../types';
|
||||
|
||||
interface Props {
|
||||
render: DocViewRenderFn;
|
|
@ -9,8 +9,8 @@
|
|||
import React from 'react';
|
||||
import { isEqual } from 'lodash';
|
||||
import { DocViewRenderTab } from './doc_viewer_render_tab';
|
||||
import { DocViewerError } from './doc_viewer_render_error';
|
||||
import { DocViewRenderFn, DocViewRenderProps } from '../../doc_views_types';
|
||||
import { DocViewerError } from './doc_viewer_error';
|
||||
import type { DocViewRenderFn, DocViewRenderProps } from '../../types';
|
||||
|
||||
interface Props {
|
||||
id: number;
|
|
@ -12,8 +12,9 @@ import { EuiBadge, EuiFlexGroup, EuiFlexItem, EuiToolTip, EuiHighlight } from '@
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FieldIcon, FieldIconProps } from '@kbn/react-field';
|
||||
import { type DataViewField, getFieldSubtypeMulti } from '@kbn/data-views-plugin/public';
|
||||
import { getFieldTypeName } from '@kbn/unified-field-list/src/utils/field_types/get_field_type_name';
|
||||
import type { DataViewField } from '@kbn/data-views-plugin/public';
|
||||
import { getDataViewFieldSubtypeMulti } from '@kbn/es-query';
|
||||
import { getFieldTypeName } from '@kbn/discover-utils';
|
||||
|
||||
interface Props {
|
||||
fieldName: string;
|
||||
|
@ -36,7 +37,7 @@ export function FieldName({
|
|||
const displayName =
|
||||
fieldMapping && fieldMapping.displayName ? fieldMapping.displayName : fieldName;
|
||||
const tooltip = displayName !== fieldName ? `${fieldName} (${displayName})` : fieldName;
|
||||
const subTypeMulti = fieldMapping && getFieldSubtypeMulti(fieldMapping.spec);
|
||||
const subTypeMulti = fieldMapping && getDataViewFieldSubtypeMulti(fieldMapping.spec);
|
||||
const isMultiField = !!subTypeMulti?.multi;
|
||||
|
||||
return (
|
||||
|
@ -62,7 +63,7 @@ export function FieldName({
|
|||
position="top"
|
||||
delay="long"
|
||||
content={i18n.translate(
|
||||
'discover.fieldChooser.discoverField.multiFieldTooltipContent',
|
||||
'unifiedDocViewer.fieldChooser.discoverField.multiFieldTooltipContent',
|
||||
{
|
||||
defaultMessage: 'Multi-fields can have multiple values per field',
|
||||
}
|
||||
|
@ -75,7 +76,7 @@ export function FieldName({
|
|||
data-test-subj={`tableDocViewRow-${fieldName}-multifieldBadge`}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="discover.fieldChooser.discoverField.multiField"
|
||||
id="unifiedDocViewer.fieldChooser.discoverField.multiField"
|
||||
defaultMessage="multi-field"
|
||||
/>
|
||||
</EuiBadge>
|
|
@ -6,4 +6,4 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { DeferredSpinner } from './common/deferred_spinner';
|
||||
export * from './field_name';
|
10
packages/kbn-unified-doc-viewer/src/components/index.ts
Normal file
10
packages/kbn-unified-doc-viewer/src/components/index.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export * from './doc_viewer';
|
||||
export * from './field_name';
|
10
packages/kbn-unified-doc-viewer/src/index.ts
Normal file
10
packages/kbn-unified-doc-viewer/src/index.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export * from './components';
|
||||
export * from './services';
|
|
@ -7,7 +7,15 @@
|
|||
*/
|
||||
|
||||
import type { DataTableRecord } from '@kbn/discover-utils/types';
|
||||
import { DocView, DocViewInput, DocViewInputFn } from './doc_views_types';
|
||||
import { DocView, DocViewInput, DocViewInputFn } from './types';
|
||||
|
||||
export enum ElasticRequestState {
|
||||
Loading,
|
||||
NotFound,
|
||||
Found,
|
||||
Error,
|
||||
NotFoundDataView,
|
||||
}
|
||||
|
||||
export class DocViewsRegistry {
|
||||
private docViews: DocView[] = [];
|
||||
|
@ -17,10 +25,10 @@ export class DocViewsRegistry {
|
|||
*/
|
||||
addDocView(docViewRaw: DocViewInput | DocViewInputFn) {
|
||||
const docView = typeof docViewRaw === 'function' ? docViewRaw() : docViewRaw;
|
||||
if (typeof docView.shouldShow !== 'function') {
|
||||
docView.shouldShow = () => true;
|
||||
}
|
||||
this.docViews.push(docView as DocView);
|
||||
this.docViews.push({
|
||||
...docView,
|
||||
shouldShow: docView.shouldShow ?? (() => true),
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Returns a sorted array of doc_views for rendering tabs
|
9
packages/kbn-unified-doc-viewer/src/services/index.ts
Normal file
9
packages/kbn-unified-doc-viewer/src/services/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { DocViewsRegistry, ElasticRequestState } from './doc_views_registry';
|
|
@ -6,7 +6,7 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
|
||||
import type { DataView, DataViewField } from '@kbn/data-views-plugin/public';
|
||||
import type { AggregateQuery, Query } from '@kbn/es-query';
|
||||
import type { DataTableRecord, IgnoredReason } from '@kbn/discover-utils/types';
|
||||
|
15
packages/kbn-unified-doc-viewer/src/types.ts
Normal file
15
packages/kbn-unified-doc-viewer/src/types.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export type {
|
||||
DocView,
|
||||
DocViewFilterFn,
|
||||
DocViewRenderFn,
|
||||
DocViewRenderProps,
|
||||
FieldRecordLegacy,
|
||||
} from './services/types';
|
27
packages/kbn-unified-doc-viewer/tsconfig.json
Normal file
27
packages/kbn-unified-doc-viewer/tsconfig.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "target/types",
|
||||
"types": [
|
||||
"jest",
|
||||
"node",
|
||||
"react"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"**/*.ts",
|
||||
"**/*.tsx",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*"
|
||||
],
|
||||
"kbn_references": [
|
||||
"@kbn/discover-utils",
|
||||
"@kbn/data-views-plugin",
|
||||
"@kbn/es-query",
|
||||
"@kbn/data-plugin",
|
||||
"@kbn/i18n-react",
|
||||
"@kbn/i18n",
|
||||
"@kbn/react-field",
|
||||
]
|
||||
}
|
10
packages/kbn-unified-doc-viewer/types.ts
Normal file
10
packages/kbn-unified-doc-viewer/types.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export type { ElasticRequestState } from '.';
|
||||
export type { DocViewFilterFn, DocViewRenderProps, FieldRecordLegacy } from './src/types';
|
|
@ -48,7 +48,6 @@ export type {
|
|||
AddFieldFilterHandler,
|
||||
FieldListGroups,
|
||||
FieldsGroupDetails,
|
||||
FieldTypeKnown,
|
||||
FieldListItem,
|
||||
GetCustomFieldType,
|
||||
RenderFieldItemParams,
|
||||
|
@ -86,13 +85,7 @@ export {
|
|||
type QuerySubscriberParams,
|
||||
} from './src/hooks/use_query_subscriber';
|
||||
|
||||
export {
|
||||
getFieldTypeName,
|
||||
getFieldTypeDescription,
|
||||
KNOWN_FIELD_TYPES,
|
||||
getFieldType,
|
||||
getFieldIconType,
|
||||
} from './src/utils/field_types';
|
||||
export { getFieldTypeDescription, getFieldType, getFieldIconType } from './src/utils/field_types';
|
||||
|
||||
export {
|
||||
UnifiedFieldListSidebarContainer,
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import React from 'react';
|
||||
import { FieldIcon as KbnFieldIcon, FieldIconProps as KbnFieldIconProps } from '@kbn/react-field';
|
||||
import { getFieldTypeName } from '../../utils/field_types';
|
||||
import { getFieldTypeName } from '@kbn/discover-utils';
|
||||
|
||||
export type FieldIconProps = KbnFieldIconProps;
|
||||
|
||||
|
|
|
@ -32,15 +32,11 @@ import type { CoreStart } from '@kbn/core-lifecycle-browser';
|
|||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { type DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import type { FieldTypeKnown } from '@kbn/discover-utils/types';
|
||||
import { getFieldTypeName, isKnownFieldType, KNOWN_FIELD_TYPE_LIST } from '@kbn/discover-utils';
|
||||
import { FieldIcon } from '../field_icon';
|
||||
import {
|
||||
getFieldIconType,
|
||||
getFieldTypeName,
|
||||
getFieldTypeDescription,
|
||||
isKnownFieldType,
|
||||
KNOWN_FIELD_TYPE_LIST,
|
||||
} from '../../utils/field_types';
|
||||
import type { FieldListItem, FieldTypeKnown, GetCustomFieldType } from '../../types';
|
||||
import { getFieldIconType, getFieldTypeDescription } from '../../utils/field_types';
|
||||
import type { FieldListItem, GetCustomFieldType } from '../../types';
|
||||
|
||||
const EQUAL_HEIGHT_OFFSET = 2; // to avoid changes in the header's height after "Clear all" button appears
|
||||
const popoverTitleStyle = css`
|
||||
|
|
|
@ -10,8 +10,9 @@ import { useMemo, useState } from 'react';
|
|||
import { htmlIdGenerator } from '@elastic/eui';
|
||||
import { type DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import type { CoreStart } from '@kbn/core-lifecycle-browser';
|
||||
import type { FieldTypeKnown } from '@kbn/discover-utils/types';
|
||||
import { type FieldListFiltersProps } from '../components/field_list_filters';
|
||||
import { type FieldListItem, type FieldTypeKnown, GetCustomFieldType } from '../types';
|
||||
import { type FieldListItem, GetCustomFieldType } from '../types';
|
||||
import { getFieldIconType } from '../utils/field_types';
|
||||
import { fieldNameWildcardMatcher } from '../utils/field_name_wildcard_matcher';
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
import type { DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import type { EuiButtonIconProps, EuiButtonProps } from '@elastic/eui';
|
||||
import type { FieldTypeKnown } from '@kbn/discover-utils/types';
|
||||
|
||||
export interface BucketedAggregation<KeyType = string> {
|
||||
buckets: Array<{
|
||||
|
@ -89,11 +90,6 @@ export type FieldListGroups<T extends FieldListItem> = {
|
|||
[key in FieldsGroupNames]?: FieldsGroup<T>;
|
||||
};
|
||||
|
||||
export type FieldTypeKnown = Exclude<
|
||||
DataViewField['timeSeriesMetric'] | DataViewField['type'],
|
||||
undefined
|
||||
>;
|
||||
|
||||
export type GetCustomFieldType<T extends FieldListItem> = (field: T) => FieldTypeKnown;
|
||||
|
||||
export interface RenderFieldItemParams<T extends FieldListItem> {
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
*/
|
||||
|
||||
import { type DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import { isKnownFieldType } from '@kbn/discover-utils';
|
||||
import type { FieldListItem, GetCustomFieldType } from '../../types';
|
||||
import { getFieldType } from './get_field_type';
|
||||
import { isKnownFieldType } from './field_types';
|
||||
|
||||
/**
|
||||
* Returns an icon type for a field
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
*/
|
||||
|
||||
import { type DataViewField } from '@kbn/data-views-plugin/common';
|
||||
import type { FieldListItem, FieldTypeKnown } from '../../types';
|
||||
import type { FieldTypeKnown } from '@kbn/discover-utils/types';
|
||||
import type { FieldListItem } from '../../types';
|
||||
|
||||
/**
|
||||
* Returns a field type. Time series metric type will override the original field type.
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
*/
|
||||
|
||||
import { getFieldTypeDescription, UNKNOWN_FIELD_TYPE_DESC } from './get_field_type_description';
|
||||
import { KNOWN_FIELD_TYPES } from './field_types';
|
||||
import { KNOWN_FIELD_TYPES } from '@kbn/discover-utils';
|
||||
|
||||
describe('UnifiedFieldList getFieldTypeDescription()', () => {
|
||||
describe('known field types should be recognized', () => {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { KBN_FIELD_TYPES } from '@kbn/field-types';
|
||||
import { KNOWN_FIELD_TYPES } from './field_types';
|
||||
import { KNOWN_FIELD_TYPES } from '@kbn/discover-utils';
|
||||
|
||||
/**
|
||||
* A user-friendly description of an unknown field type
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export { KNOWN_FIELD_TYPES, KNOWN_FIELD_TYPE_LIST, isKnownFieldType } from './field_types';
|
||||
export { getFieldTypeName } from './get_field_type_name';
|
||||
export { getFieldTypeDescription } from './get_field_type_description';
|
||||
export { getFieldType } from './get_field_type';
|
||||
export { getFieldIconType } from './get_field_icon_type';
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export enum KNOWN_FIELD_TYPES {
|
||||
BOOLEAN = 'boolean',
|
||||
CONFLICT = 'conflict',
|
||||
DATE = 'date',
|
||||
DATE_RANGE = 'date_range',
|
||||
GEO_POINT = 'geo_point',
|
||||
GEO_SHAPE = 'geo_shape',
|
||||
HISTOGRAM = 'histogram',
|
||||
IP = 'ip',
|
||||
IP_RANGE = 'ip_range',
|
||||
KEYWORD = 'keyword',
|
||||
MURMUR3 = 'murmur3',
|
||||
NUMBER = 'number',
|
||||
NESTED = 'nested',
|
||||
STRING = 'string',
|
||||
TEXT = 'text',
|
||||
VERSION = 'version',
|
||||
}
|
|
@ -24,6 +24,7 @@
|
|||
"dataViewFieldEditor",
|
||||
"dataViewEditor",
|
||||
"expressions",
|
||||
"unifiedDocViewer",
|
||||
"unifiedSearch",
|
||||
"unifiedHistogram",
|
||||
"contentManagement"
|
||||
|
|
|
@ -19,6 +19,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { reportPerformanceMetricEvent } from '@kbn/ebt-tools';
|
||||
import { removeInterceptedWarningDuplicates } from '@kbn/search-response-warnings';
|
||||
import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { ContextErrorMessage } from './components/context_error_message';
|
||||
import { LoadingStatus } from './services/context_query_state';
|
||||
import { AppState, GlobalState, isEqualFilters } from './services/context_state';
|
||||
|
@ -28,7 +29,6 @@ import { useContextAppFetch } from './hooks/use_context_app_fetch';
|
|||
import { popularizeField } from '../../utils/popularize_field';
|
||||
import { ContextAppContent } from './context_app_content';
|
||||
import { SurrDocType } from './services/context';
|
||||
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
|
||||
import { useDiscoverServices } from '../../hooks/use_discover_services';
|
||||
import { setBreadcrumbs } from '../../utils/breadcrumbs';
|
||||
|
||||
|
|
|
@ -19,17 +19,16 @@ import {
|
|||
SearchResponseWarnings,
|
||||
} from '@kbn/search-response-warnings';
|
||||
import { CONTEXT_STEP_SETTING, DOC_HIDE_TIME_COLUMN_SETTING } from '@kbn/discover-utils';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { LoadingStatus } from './services/context_query_state';
|
||||
import { ActionBar } from './components/action_bar/action_bar';
|
||||
import { DataLoadingState, DiscoverGrid } from '../../components/discover_grid/discover_grid';
|
||||
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
|
||||
import { AppState } from './services/context_state';
|
||||
import { SurrDocType } from './services/context';
|
||||
import { MAX_CONTEXT_SIZE, MIN_CONTEXT_SIZE } from './services/constants';
|
||||
import { DocTableContext } from '../../components/doc_table/doc_table_context';
|
||||
import { useDiscoverServices } from '../../hooks/use_discover_services';
|
||||
import { DiscoverGridFlyout } from '../../components/discover_grid/discover_grid_flyout';
|
||||
import { DocViewer } from '../../services/doc_views/components/doc_viewer';
|
||||
|
||||
export interface ContextAppContentProps {
|
||||
columns: string[];
|
||||
|
@ -157,7 +156,6 @@ export function ContextAppContent({
|
|||
sort={sort}
|
||||
useNewFieldsApi={useNewFieldsApi}
|
||||
dataTestSubj="contextDocTable"
|
||||
DocViewer={DocViewer}
|
||||
/>
|
||||
)}
|
||||
{!isLegacy && (
|
||||
|
|
|
@ -16,29 +16,11 @@ import { Doc, DocProps } from './doc';
|
|||
import { SEARCH_FIELDS_FROM_SOURCE as mockSearchFieldsFromSource } from '@kbn/discover-utils';
|
||||
import { dataViewMock } from '@kbn/discover-utils/src/__mocks__';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { setUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/plugin';
|
||||
import { mockUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/__mocks__';
|
||||
|
||||
const mockSearchApi = jest.fn();
|
||||
|
||||
jest.mock('../../../kibana_services', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let registry: any[] = [];
|
||||
|
||||
return {
|
||||
getDocViewsRegistry: () => ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
addDocView(view: any) {
|
||||
registry.push(view);
|
||||
},
|
||||
getDocViewsSorted() {
|
||||
return registry;
|
||||
},
|
||||
resetRegistry: () => {
|
||||
registry = [];
|
||||
},
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
@ -86,6 +68,7 @@ async function mountDoc(update = false) {
|
|||
locator: { getUrl: jest.fn(() => Promise.resolve('mock-url')) },
|
||||
chrome: { setBreadcrumbs: jest.fn() },
|
||||
};
|
||||
setUnifiedDocViewerServices(mockUnifiedDocViewerServices);
|
||||
await act(async () => {
|
||||
comp = mountWithIntl(
|
||||
<KibanaContextProvider services={services}>
|
||||
|
|
|
@ -9,40 +9,18 @@
|
|||
import React, { useEffect } from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { EuiCallOut, EuiLink, EuiLoadingSpinner, EuiPage, EuiPageBody } from '@elastic/eui';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils/types';
|
||||
import { ElasticRequestState } from '@kbn/unified-doc-viewer';
|
||||
import { UnifiedDocViewer, useEsDocSearch } from '@kbn/unified-doc-viewer-plugin/public';
|
||||
import type { EsDocSearchProps } from '@kbn/unified-doc-viewer-plugin/public/types';
|
||||
import { setBreadcrumbs } from '../../../utils/breadcrumbs';
|
||||
import { DocViewer } from '../../../services/doc_views/components/doc_viewer';
|
||||
import { ElasticRequestState } from '../types';
|
||||
import { useEsDocSearch } from '../../../hooks/use_es_doc_search';
|
||||
import { useDiscoverServices } from '../../../hooks/use_discover_services';
|
||||
|
||||
export interface DocProps {
|
||||
/**
|
||||
* Id of the doc in ES
|
||||
*/
|
||||
id: string;
|
||||
/**
|
||||
* Index in ES to query
|
||||
*/
|
||||
index: string;
|
||||
/**
|
||||
* DataView entity
|
||||
*/
|
||||
dataView: DataView;
|
||||
/**
|
||||
* If set, will always request source, regardless of the global `fieldsFromSource` setting
|
||||
*/
|
||||
requestSource?: boolean;
|
||||
export interface DocProps extends EsDocSearchProps {
|
||||
/**
|
||||
* Discover main view url
|
||||
*/
|
||||
referrer?: string;
|
||||
/**
|
||||
* Records fetched from text based query
|
||||
*/
|
||||
textBasedHits?: DataTableRecord[];
|
||||
}
|
||||
|
||||
export function Doc(props: DocProps) {
|
||||
|
@ -141,7 +119,7 @@ export function Doc(props: DocProps) {
|
|||
|
||||
{reqState === ElasticRequestState.Found && hit !== null && dataView && (
|
||||
<div data-test-subj="doc-hit">
|
||||
<DocViewer hit={hit} dataView={dataView} />
|
||||
<UnifiedDocViewer hit={hit} dataView={dataView} />
|
||||
</div>
|
||||
)}
|
||||
</EuiPageBody>
|
||||
|
|
|
@ -28,10 +28,10 @@ import {
|
|||
SAMPLE_SIZE_SETTING,
|
||||
SEARCH_FIELDS_FROM_SOURCE,
|
||||
} from '@kbn/discover-utils';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { useInternalStateSelector } from '../../services/discover_internal_state_container';
|
||||
import { useAppStateSelector } from '../../services/discover_app_state_container';
|
||||
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
|
||||
import { DocViewFilterFn } from '../../../../services/doc_views/doc_views_types';
|
||||
import { DataLoadingState, DiscoverGrid } from '../../../../components/discover_grid/discover_grid';
|
||||
import { FetchStatus } from '../../../types';
|
||||
import { useColumns } from '../../../../hooks/use_data_grid_columns';
|
||||
|
@ -44,7 +44,6 @@ import { DocumentExplorerUpdateCallout } from '../document_explorer_callout/docu
|
|||
import { DiscoverTourProvider } from '../../../../components/discover_tour';
|
||||
import { getRawRecordType } from '../../utils/get_raw_record_type';
|
||||
import { DiscoverGridFlyout } from '../../../../components/discover_grid/discover_grid_flyout';
|
||||
import { DocViewer } from '../../../../services/doc_views/components/doc_viewer';
|
||||
import { useSavedSearchInitial } from '../../services/discover_state_provider';
|
||||
import { useFetchMoreRecords } from './use_fetch_more_records';
|
||||
|
||||
|
@ -236,7 +235,6 @@ function DiscoverDocumentsComponent({
|
|||
onSort={!isTextBasedQuery ? onSort : undefined}
|
||||
useNewFieldsApi={useNewFieldsApi}
|
||||
dataTestSubj="discoverDocTable"
|
||||
DocViewer={DocViewer}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
|
|
|
@ -24,6 +24,7 @@ import { generateFilters } from '@kbn/data-plugin/public';
|
|||
import { useDragDropContext } from '@kbn/dom-drag-drop';
|
||||
import { DataViewField, DataViewType } from '@kbn/data-views-plugin/public';
|
||||
import { SEARCH_FIELDS_FROM_SOURCE, SHOW_FIELD_STATISTICS } from '@kbn/discover-utils';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { useSavedSearchInitial } from '../../services/discover_state_provider';
|
||||
import { DiscoverStateContainer } from '../../services/discover_state';
|
||||
import { VIEW_MODE } from '../../../../../common/constants';
|
||||
|
@ -36,7 +37,6 @@ import { LoadingSpinner } from '../loading_spinner/loading_spinner';
|
|||
import { DiscoverSidebarResponsive } from '../sidebar';
|
||||
import { popularizeField } from '../../../../utils/popularize_field';
|
||||
import { DiscoverTopNav } from '../top_nav/discover_topnav';
|
||||
import { DocViewFilterFn } from '../../../../services/doc_views/doc_views_types';
|
||||
import { getResultState } from '../../utils/get_result_state';
|
||||
import { DiscoverUninitialized } from '../uninitialized/uninitialized';
|
||||
import { DataMainMsg, RecordRawType } from '../../services/discover_data_state_container';
|
||||
|
|
|
@ -12,10 +12,10 @@ import React, { useCallback } from 'react';
|
|||
import { DataView } from '@kbn/data-views-plugin/common';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { VIEW_MODE } from '../../../../../common/constants';
|
||||
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
|
||||
import { DocumentViewModeToggle } from '../../../../components/view_mode_toggle';
|
||||
import { DocViewFilterFn } from '../../../../services/doc_views/doc_views_types';
|
||||
import { DiscoverStateContainer } from '../../services/discover_state';
|
||||
import { FieldStatisticsTab } from '../field_stats_table';
|
||||
import { DiscoverDocuments } from './discover_documents';
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
/**
|
||||
* A component that shows it children with a 300ms delay. This is good for wrapping
|
||||
* loading spinners for tasks that might potentially be very fast (e.g. loading async chunks).
|
||||
* That way we don't show a quick flash of the spinner before the actual content and will only
|
||||
* show the spinner once loading takes a bit longer (more than 300ms).
|
||||
*/
|
||||
export const DeferredSpinner: React.FC = ({ children }) => {
|
||||
const timeoutRef = useRef<number>();
|
||||
const [showContent, setShowContent] = useState(false);
|
||||
useEffect(() => {
|
||||
timeoutRef.current = window.setTimeout(() => {
|
||||
setShowContent(true);
|
||||
}, 300);
|
||||
return () => {
|
||||
if (timeoutRef.current) {
|
||||
clearTimeout(timeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return showContent ? <React.Fragment>{children}</React.Fragment> : null;
|
||||
};
|
|
@ -42,7 +42,7 @@ import {
|
|||
MAX_DOC_FIELDS_DISPLAYED,
|
||||
SHOW_MULTIFIELDS,
|
||||
} from '@kbn/discover-utils';
|
||||
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { getSchemaDetectors } from './discover_grid_schema';
|
||||
import { DiscoverGridFlyout } from './discover_grid_flyout';
|
||||
import { DiscoverGridContext } from './discover_grid_context';
|
||||
|
|
|
@ -10,7 +10,7 @@ import React, { useContext } from 'react';
|
|||
import { EuiDataGridColumnCellActionProps } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { DataViewField } from '@kbn/data-views-plugin/public';
|
||||
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { DiscoverGridContext, GridContext } from './discover_grid_context';
|
||||
import { useDiscoverServices } from '../../hooks/use_discover_services';
|
||||
import { copyValueToClipboard } from '../../utils/copy_value_to_clipboard';
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { ToastsStart, IUiSettingsClient } from '@kbn/core/public';
|
||||
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { ExpandButton } from './discover_grid_expand_button';
|
||||
import { DiscoverGridSettings } from './types';
|
||||
import type { ValueToStringConverter } from '../../types';
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
import React from 'react';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils/types';
|
||||
import type { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import type { ValueToStringConverter } from '../../types';
|
||||
|
||||
export interface GridContext {
|
||||
|
|
|
@ -14,8 +14,6 @@ import { DiscoverGridFlyout, DiscoverGridFlyoutProps } from './discover_grid_fly
|
|||
import { createFilterManagerMock } from '@kbn/data-plugin/public/query/filter_manager/filter_manager.mock';
|
||||
import { dataViewMock, esHitsMock } from '@kbn/discover-utils/src/__mocks__';
|
||||
import { DiscoverServices } from '../../build_services';
|
||||
import { DocViewsRegistry } from '../../services/doc_views/doc_views_registry';
|
||||
import { setDocViewsRegistry } from '../../kibana_services';
|
||||
import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
|
@ -23,6 +21,8 @@ import type { DataTableRecord, EsHitRecord } from '@kbn/discover-utils/types';
|
|||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { ReactWrapper } from 'enzyme';
|
||||
import { setUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/plugin';
|
||||
import { mockUnifiedDocViewerServices } from '@kbn/unified-doc-viewer-plugin/public/__mocks__';
|
||||
|
||||
const waitNextTick = () => new Promise((resolve) => setTimeout(resolve, 0));
|
||||
|
||||
|
@ -34,8 +34,6 @@ const waitNextUpdate = async (component: ReactWrapper) => {
|
|||
};
|
||||
|
||||
describe('Discover flyout', function () {
|
||||
setDocViewsRegistry(new DocViewsRegistry());
|
||||
|
||||
const mountComponent = async ({
|
||||
dataView,
|
||||
hits,
|
||||
|
@ -60,6 +58,7 @@ describe('Discover flyout', function () {
|
|||
contextLocator: { getRedirectUrl: jest.fn(() => 'mock-context-redirect-url') },
|
||||
singleDocLocator: { getRedirectUrl: jest.fn(() => 'mock-doc-redirect-url') },
|
||||
} as unknown as DiscoverServices;
|
||||
setUnifiedDocViewerServices(mockUnifiedDocViewerServices);
|
||||
|
||||
const hit = buildDataTableRecord(
|
||||
hitIndex ? esHitsMock[hitIndex] : (esHitsMock[0] as EsHitRecord),
|
||||
|
|
|
@ -27,8 +27,8 @@ import {
|
|||
} from '@elastic/eui';
|
||||
import type { Filter, Query, AggregateQuery } from '@kbn/es-query';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils/types';
|
||||
import { DocViewer } from '../../services/doc_views/components/doc_viewer/doc_viewer';
|
||||
import { DocViewFilterFn } from '../../services/doc_views/doc_views_types';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { UnifiedDocViewer } from '@kbn/unified-doc-viewer-plugin/public';
|
||||
import { useNavigationProps } from '../../hooks/use_navigation_props';
|
||||
import { useDiscoverServices } from '../../hooks/use_discover_services';
|
||||
import { isTextBasedQuery } from '../../application/main/utils/is_text_based_query';
|
||||
|
@ -225,7 +225,7 @@ export function DiscoverGridFlyout({
|
|||
</EuiFlexGroup>
|
||||
</EuiFlyoutHeader>
|
||||
<EuiFlyoutBody>
|
||||
<DocViewer
|
||||
<UnifiedDocViewer
|
||||
hit={actualHit}
|
||||
columns={columns}
|
||||
dataView={dataView}
|
||||
|
|
|
@ -285,7 +285,7 @@ describe('Discover grid cell rendering', function () {
|
|||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<JsonCodeEditor
|
||||
<ForwardRef
|
||||
height={200}
|
||||
json={
|
||||
Object {
|
||||
|
@ -517,7 +517,7 @@ describe('Discover grid cell rendering', function () {
|
|||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<JsonCodeEditor
|
||||
<ForwardRef
|
||||
height={200}
|
||||
json={
|
||||
Object {
|
||||
|
@ -681,7 +681,7 @@ describe('Discover grid cell rendering', function () {
|
|||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<JsonCodeEditor
|
||||
<ForwardRef
|
||||
height={200}
|
||||
json={
|
||||
Object {
|
||||
|
|
|
@ -27,8 +27,8 @@ import type {
|
|||
ShouldShowFieldInTableHandler,
|
||||
} from '@kbn/discover-utils/types';
|
||||
import { MAX_DOC_FIELDS_DISPLAYED, formatFieldValue, formatHit } from '@kbn/discover-utils';
|
||||
import { JsonCodeEditor } from '@kbn/unified-doc-viewer-plugin/public';
|
||||
import { DiscoverGridContext } from './discover_grid_context';
|
||||
import { JsonCodeEditor } from '../json_code_editor/json_code_editor';
|
||||
import { defaultMonacoEditorWidth } from './constants';
|
||||
import { useDiscoverServices } from '../../hooks/use_discover_services';
|
||||
|
||||
|
|
|
@ -9,13 +9,10 @@
|
|||
import React from 'react';
|
||||
import { mountWithIntl, findTestSubject } from '@kbn/test-jest-helpers';
|
||||
import { TableRow, TableRowProps } from './table_row';
|
||||
import { setDocViewsRegistry } from '../../../kibana_services';
|
||||
import { createFilterManagerMock } from '@kbn/data-plugin/public/query/filter_manager/filter_manager.mock';
|
||||
import { dataViewWithTimefieldMock } from '../../../__mocks__/data_view_with_timefield';
|
||||
import { DocViewsRegistry } from '../../../services/doc_views/doc_views_registry';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { discoverServiceMock } from '../../../__mocks__/services';
|
||||
import { DocViewer } from '../../../services/doc_views/components/doc_viewer';
|
||||
|
||||
import { DOC_HIDE_TIME_COLUMN_SETTING, MAX_DOC_FIELDS_DISPLAYED } from '@kbn/discover-utils';
|
||||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
|
@ -81,13 +78,8 @@ describe('Doc table row component', () => {
|
|||
useNewFieldsApi: true,
|
||||
filterManager: mockFilterManager,
|
||||
addBasePath: (path: string) => path,
|
||||
DocViewer,
|
||||
} as unknown as TableRowProps;
|
||||
|
||||
beforeEach(() => {
|
||||
setDocViewsRegistry(new DocViewsRegistry());
|
||||
});
|
||||
|
||||
it('should render __document__ column', () => {
|
||||
const component = mountComponent({ ...defaultProps, columns: [] });
|
||||
const docTableField = findTestSubject(component, 'docTableField');
|
||||
|
|
|
@ -19,10 +19,10 @@ import type {
|
|||
} from '@kbn/discover-utils/types';
|
||||
import { formatFieldValue } from '@kbn/discover-utils';
|
||||
import { DOC_HIDE_TIME_COLUMN_SETTING, MAX_DOC_FIELDS_DISPLAYED } from '@kbn/discover-utils';
|
||||
import { DocViewRenderProps } from '../../../services/doc_views/doc_views_types';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { UnifiedDocViewer } from '@kbn/unified-doc-viewer-plugin/public';
|
||||
import { TableCell } from './table_row/table_cell';
|
||||
import { formatRow, formatTopLevelObject } from '../utils/row_formatter';
|
||||
import { DocViewFilterFn } from '../../../services/doc_views/doc_views_types';
|
||||
import { TableRowDetails } from './table_row_details';
|
||||
import { useDiscoverServices } from '../../../hooks/use_discover_services';
|
||||
|
||||
|
@ -43,7 +43,6 @@ export interface TableRowProps {
|
|||
shouldShowFieldHandler: ShouldShowFieldInTableHandler;
|
||||
onAddColumn?: (column: string) => void;
|
||||
onRemoveColumn?: (column: string) => void;
|
||||
DocViewer: React.ComponentType<DocViewRenderProps>;
|
||||
}
|
||||
|
||||
export const TableRow = ({
|
||||
|
@ -59,7 +58,6 @@ export const TableRow = ({
|
|||
shouldShowFieldHandler,
|
||||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
DocViewer,
|
||||
}: TableRowProps) => {
|
||||
const { uiSettings, fieldFormats } = useDiscoverServices();
|
||||
const [maxEntries, hideTimeColumn] = useMemo(
|
||||
|
@ -223,7 +221,7 @@ export const TableRow = ({
|
|||
savedSearchId={savedSearchId}
|
||||
isPlainRecord={isPlainRecord}
|
||||
>
|
||||
<DocViewer
|
||||
<UnifiedDocViewer
|
||||
columns={columns}
|
||||
filter={filter}
|
||||
hit={row}
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
import React from 'react';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
import { DocTableEmbeddable, DocTableEmbeddableProps } from './doc_table_embeddable';
|
||||
import { DocViewer } from '../../services/doc_views/components/doc_viewer';
|
||||
|
||||
export function DiscoverDocTableEmbeddable(renderProps: DocTableEmbeddableProps) {
|
||||
return (
|
||||
|
@ -35,7 +34,6 @@ export function DiscoverDocTableEmbeddable(renderProps: DocTableEmbeddableProps)
|
|||
isPlainRecord={renderProps.isPlainRecord}
|
||||
interceptedWarnings={renderProps.interceptedWarnings}
|
||||
dataTestSubj="embeddedSavedSearchDocTable"
|
||||
DocViewer={DocViewer}
|
||||
/>
|
||||
</I18nProvider>
|
||||
);
|
||||
|
|
|
@ -15,7 +15,6 @@ import { discoverServiceMock } from '../../__mocks__/services';
|
|||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
import type { EsHitRecord } from '@kbn/discover-utils/types';
|
||||
import { DocViewer } from '../../services/doc_views/components/doc_viewer';
|
||||
|
||||
describe('Doc table component', () => {
|
||||
const mountComponent = (customProps?: Partial<DocTableWrapperProps>) => {
|
||||
|
@ -48,7 +47,6 @@ describe('Doc table component', () => {
|
|||
render: () => {
|
||||
return <div data-test-subj="docTable">mock</div>;
|
||||
},
|
||||
DocViewer,
|
||||
...(customProps || {}),
|
||||
};
|
||||
|
||||
|
|
|
@ -14,9 +14,9 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
import { Filter } from '@kbn/es-query';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils/types';
|
||||
import { SHOW_MULTIFIELDS, getShouldShowFieldHandler } from '@kbn/discover-utils';
|
||||
import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types';
|
||||
import { TableHeader } from './components/table_header/table_header';
|
||||
import { TableRow } from './components/table_row';
|
||||
import { DocViewFilterFn, DocViewRenderProps } from '../../services/doc_views/doc_views_types';
|
||||
import { useDiscoverServices } from '../../hooks/use_discover_services';
|
||||
|
||||
export interface DocTableProps {
|
||||
|
@ -89,10 +89,6 @@ export interface DocTableProps {
|
|||
* Remove column callback
|
||||
*/
|
||||
onRemoveColumn?: (column: string) => void;
|
||||
/**
|
||||
* Doc viewer component
|
||||
*/
|
||||
DocViewer: React.ComponentType<DocViewRenderProps>;
|
||||
}
|
||||
|
||||
export interface DocTableRenderProps {
|
||||
|
@ -133,7 +129,6 @@ export const DocTableWrapper = forwardRef(
|
|||
sharedItemTitle,
|
||||
dataTestSubj,
|
||||
isLoading,
|
||||
DocViewer,
|
||||
}: DocTableWrapperProps,
|
||||
ref
|
||||
) => {
|
||||
|
@ -191,7 +186,6 @@ export const DocTableWrapper = forwardRef(
|
|||
shouldShowFieldHandler={shouldShowFieldHandler}
|
||||
onAddColumn={onAddColumn}
|
||||
onRemoveColumn={onRemoveColumn}
|
||||
DocViewer={DocViewer}
|
||||
isPlainRecord={isPlainRecord}
|
||||
rows={rows}
|
||||
/>
|
||||
|
@ -207,7 +201,6 @@ export const DocTableWrapper = forwardRef(
|
|||
shouldShowFieldHandler,
|
||||
onAddColumn,
|
||||
onRemoveColumn,
|
||||
DocViewer,
|
||||
isPlainRecord,
|
||||
rows,
|
||||
]
|
||||
|
|
|
@ -12,7 +12,6 @@ import type { ScopedHistory, AppMountParameters } from '@kbn/core/public';
|
|||
import type { UiActionsStart } from '@kbn/ui-actions-plugin/public';
|
||||
import { createGetterSetter } from '@kbn/kibana-utils-plugin/public';
|
||||
import { HistoryLocationState } from './build_services';
|
||||
import { DocViewsRegistry } from './services/doc_views/doc_views_registry';
|
||||
|
||||
let uiActions: UiActionsStart;
|
||||
export interface UrlTracker {
|
||||
|
@ -29,9 +28,6 @@ export const [getHeaderActionMenuMounter, setHeaderActionMenuMounter] =
|
|||
|
||||
export const [getUrlTracker, setUrlTracker] = createGetterSetter<UrlTracker>('urlTracker');
|
||||
|
||||
export const [getDocViewsRegistry, setDocViewsRegistry] =
|
||||
createGetterSetter<DocViewsRegistry>('DocViewsRegistry');
|
||||
|
||||
/**
|
||||
* Makes sure discover and context are using one instance of history.
|
||||
*/
|
||||
|
|
|
@ -15,9 +15,6 @@ export type Start = jest.Mocked<DiscoverStart>;
|
|||
|
||||
const createSetupContract = (): Setup => {
|
||||
const setupContract: Setup = {
|
||||
docViews: {
|
||||
addDocView: jest.fn(),
|
||||
},
|
||||
locator: sharePluginMock.createLocator(),
|
||||
};
|
||||
return setupContract;
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React, { ComponentType } from 'react';
|
||||
import { BehaviorSubject, combineLatest, map } from 'rxjs';
|
||||
import {
|
||||
|
@ -26,7 +25,6 @@ import { SharePluginStart, SharePluginSetup } from '@kbn/share-plugin/public';
|
|||
import { UrlForwardingSetup, UrlForwardingStart } from '@kbn/url-forwarding-plugin/public';
|
||||
import { HomePublicPluginSetup } from '@kbn/home-plugin/public';
|
||||
import { Start as InspectorPublicPluginStart } from '@kbn/inspector-plugin/public';
|
||||
import { EuiSkeletonText } from '@elastic/eui';
|
||||
import { DataPublicPluginSetup, DataPublicPluginStart } from '@kbn/data-plugin/public';
|
||||
import { SavedObjectsStart } from '@kbn/saved-objects-plugin/public';
|
||||
import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public';
|
||||
|
@ -42,16 +40,14 @@ import type { SavedObjectTaggingOssPluginStart } from '@kbn/saved-objects-taggin
|
|||
import type { SavedObjectsManagementPluginStart } from '@kbn/saved-objects-management-plugin/public';
|
||||
import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public';
|
||||
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
|
||||
import type { UnifiedDocViewerStart } from '@kbn/unified-doc-viewer-plugin/public';
|
||||
import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/public';
|
||||
import type { LensPublicStart } from '@kbn/lens-plugin/public';
|
||||
import { TRUNCATE_MAX_HEIGHT } from '@kbn/discover-utils';
|
||||
import type { ServerlessPluginStart } from '@kbn/serverless/public';
|
||||
import { DOC_TABLE_LEGACY, TRUNCATE_MAX_HEIGHT } from '@kbn/discover-utils';
|
||||
import { NoDataPagePluginStart } from '@kbn/no-data-page-plugin/public';
|
||||
import { PLUGIN_ID } from '../common';
|
||||
import { DocViewInput, DocViewInputFn } from './services/doc_views/doc_views_types';
|
||||
import { DocViewsRegistry } from './services/doc_views/doc_views_registry';
|
||||
import {
|
||||
setDocViewsRegistry,
|
||||
setHeaderActionMenuMounter,
|
||||
setScopedHistory,
|
||||
setUiActions,
|
||||
|
@ -61,10 +57,8 @@ import {
|
|||
import { registerFeature } from './register_feature';
|
||||
import { buildServices } from './build_services';
|
||||
import { SearchEmbeddableFactory } from './embeddable';
|
||||
import { DeferredSpinner } from './components';
|
||||
import { ViewSavedSearchAction } from './embeddable/view_saved_search_action';
|
||||
import { injectTruncateStyles } from './utils/truncate_styles';
|
||||
import { useDiscoverServices } from './hooks/use_discover_services';
|
||||
import { initializeKbnUrlTracking } from './utils/initialize_kbn_url_tracking';
|
||||
import {
|
||||
DiscoverContextAppLocator,
|
||||
|
@ -86,24 +80,10 @@ import {
|
|||
type DiscoverContainerProps,
|
||||
} from './components/discover_container';
|
||||
|
||||
const DocViewerLegacyTable = React.lazy(
|
||||
() => import('./services/doc_views/components/doc_viewer_table/legacy')
|
||||
);
|
||||
const DocViewerTable = React.lazy(() => import('./services/doc_views/components/doc_viewer_table'));
|
||||
const SourceViewer = React.lazy(() => import('./services/doc_views/components/doc_viewer_source'));
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export interface DiscoverSetup {
|
||||
docViews: {
|
||||
/**
|
||||
* Add new doc view shown along with table view and json view in the details of each document in Discover.
|
||||
* @param docViewRaw
|
||||
*/
|
||||
addDocView(docViewRaw: DocViewInput | DocViewInputFn): void;
|
||||
};
|
||||
|
||||
/**
|
||||
* `share` plugin URL locator for Discover app. Use it to generate links into
|
||||
* Discover application, for example, navigate:
|
||||
|
@ -211,6 +191,7 @@ export interface DiscoverStartPlugins {
|
|||
savedObjectsManagement: SavedObjectsManagementPluginStart;
|
||||
savedSearch: SavedSearchPublicPluginStart;
|
||||
unifiedSearch: UnifiedSearchPublicPluginStart;
|
||||
unifiedDocViewer: UnifiedDocViewerStart;
|
||||
lens: LensPublicStart;
|
||||
contentManagement: ContentManagementPublicStart;
|
||||
serverless?: ServerlessPluginStart;
|
||||
|
@ -227,7 +208,6 @@ export class DiscoverPlugin
|
|||
constructor(private readonly initializerContext: PluginInitializerContext) {}
|
||||
|
||||
private appStateUpdater = new BehaviorSubject<AppUpdater>(() => ({}));
|
||||
private docViewsRegistry: DocViewsRegistry | null = null;
|
||||
private stopUrlTracking: (() => void) | undefined = undefined;
|
||||
private profileRegistry = createProfileRegistry();
|
||||
private locator?: DiscoverAppLocator;
|
||||
|
@ -253,59 +233,6 @@ export class DiscoverPlugin
|
|||
);
|
||||
}
|
||||
|
||||
this.docViewsRegistry = new DocViewsRegistry();
|
||||
setDocViewsRegistry(this.docViewsRegistry);
|
||||
this.docViewsRegistry.addDocView({
|
||||
title: i18n.translate('discover.docViews.table.tableTitle', {
|
||||
defaultMessage: 'Table',
|
||||
}),
|
||||
order: 10,
|
||||
component: (props) => {
|
||||
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||
const services = useDiscoverServices();
|
||||
const DocView = services.uiSettings.get(DOC_TABLE_LEGACY)
|
||||
? DocViewerLegacyTable
|
||||
: DocViewerTable;
|
||||
|
||||
return (
|
||||
<React.Suspense
|
||||
fallback={
|
||||
<DeferredSpinner>
|
||||
<EuiSkeletonText />
|
||||
</DeferredSpinner>
|
||||
}
|
||||
>
|
||||
<DocView {...props} />
|
||||
</React.Suspense>
|
||||
);
|
||||
},
|
||||
});
|
||||
this.docViewsRegistry.addDocView({
|
||||
title: i18n.translate('discover.docViews.json.jsonTitle', {
|
||||
defaultMessage: 'JSON',
|
||||
}),
|
||||
order: 20,
|
||||
component: ({ hit, dataView, query, textBasedHits }) => {
|
||||
return (
|
||||
<React.Suspense
|
||||
fallback={
|
||||
<DeferredSpinner>
|
||||
<EuiSkeletonText />
|
||||
</DeferredSpinner>
|
||||
}
|
||||
>
|
||||
<SourceViewer
|
||||
index={hit.raw._index}
|
||||
id={hit.raw._id ?? hit.id}
|
||||
dataView={dataView}
|
||||
textBasedHits={textBasedHits}
|
||||
hasLineNumbers
|
||||
/>
|
||||
</React.Suspense>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
const {
|
||||
setTrackedUrl,
|
||||
restorePreviousUrl,
|
||||
|
@ -418,9 +345,6 @@ export class DiscoverPlugin
|
|||
this.registerEmbeddable(core, plugins);
|
||||
|
||||
return {
|
||||
docViews: {
|
||||
addDocView: this.docViewsRegistry.addDocView.bind(this.docViewsRegistry),
|
||||
},
|
||||
locator: this.locator,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { mount, shallow } from 'enzyme';
|
||||
import { DocViewer } from './doc_viewer';
|
||||
import { findTestSubject } from '@elastic/eui/lib/test';
|
||||
import { getDocViewsRegistry } from '../../../../kibana_services';
|
||||
import { DocViewRenderProps } from '../../doc_views_types';
|
||||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
|
||||
jest.mock('../../../../kibana_services', () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
let registry: any[] = [];
|
||||
return {
|
||||
getDocViewsRegistry: () => ({
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
addDocView(view: any) {
|
||||
registry.push(view);
|
||||
},
|
||||
getDocViewsSorted() {
|
||||
return registry;
|
||||
},
|
||||
resetRegistry: () => {
|
||||
registry = [];
|
||||
},
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
jest.mock('../../../../hooks/use_discover_services', () => {
|
||||
return {
|
||||
useDiscoverServices: {
|
||||
uiSettings: {
|
||||
get: jest.fn(),
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
(getDocViewsRegistry() as any).resetRegistry();
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
test('Render <DocViewer/> with 3 different tabs', () => {
|
||||
const registry = getDocViewsRegistry();
|
||||
registry.addDocView({ order: 10, title: 'Render function', render: jest.fn() });
|
||||
registry.addDocView({ order: 20, title: 'React component', component: () => <div>test</div> });
|
||||
// @ts-expect-error This should be invalid and will throw an error when rendering
|
||||
registry.addDocView({ order: 30, title: 'Invalid doc view' });
|
||||
|
||||
const renderProps = { hit: {} } as DocViewRenderProps;
|
||||
|
||||
const wrapper = shallow(<DocViewer {...renderProps} />);
|
||||
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test('Render <DocViewer/> with 1 tab displaying error message', () => {
|
||||
function SomeComponent() {
|
||||
// this is just a placeholder
|
||||
return null;
|
||||
}
|
||||
|
||||
const registry = getDocViewsRegistry();
|
||||
registry.addDocView({
|
||||
order: 10,
|
||||
title: 'React component',
|
||||
component: SomeComponent,
|
||||
});
|
||||
|
||||
const renderProps = {
|
||||
hit: buildDataTableRecord({ _index: 't', _id: '1' }),
|
||||
} as DocViewRenderProps;
|
||||
const errorMsg = 'Catch me if you can!';
|
||||
|
||||
const wrapper = mount(<DocViewer {...renderProps} />);
|
||||
const error = new Error(errorMsg);
|
||||
wrapper.find(SomeComponent).simulateError(error);
|
||||
const errorMsgComponent = findTestSubject(wrapper, 'docViewerError');
|
||||
expect(errorMsgComponent.text()).toMatch(new RegExp(`${errorMsg}`));
|
||||
});
|
|
@ -51,8 +51,6 @@
|
|||
"@kbn/shared-ux-page-analytics-no-data",
|
||||
"@kbn/alerting-plugin",
|
||||
"@kbn/ui-theme",
|
||||
"@kbn/react-field",
|
||||
"@kbn/monaco",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/storybook",
|
||||
"@kbn/shared-ux-router",
|
||||
|
@ -68,6 +66,8 @@
|
|||
"@kbn/field-types",
|
||||
"@kbn/search-response-warnings",
|
||||
"@kbn/content-management-plugin",
|
||||
"@kbn/unified-doc-viewer",
|
||||
"@kbn/unified-doc-viewer-plugin",
|
||||
"@kbn/serverless",
|
||||
"@kbn/react-kibana-mount",
|
||||
"@kbn/react-kibana-context-render",
|
||||
|
|
3
src/plugins/unified_doc_viewer/README.md
Normal file
3
src/plugins/unified_doc_viewer/README.md
Normal file
|
@ -0,0 +1,3 @@
|
|||
# unifiedDocViewer
|
||||
|
||||
This plugin contains services reliant on the plugin lifecycle for the unified doc viewer component (see @kbn/unified-doc-viewer).
|
18
src/plugins/unified_doc_viewer/jest.config.js
Normal file
18
src/plugins/unified_doc_viewer/jest.config.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
preset: '@kbn/test',
|
||||
rootDir: '../../..',
|
||||
roots: ['<rootDir>/src/plugins/unified_doc_viewer'],
|
||||
coverageDirectory: '<rootDir>/target/kibana-coverage/jest/src/plugins/unified_doc_viewer',
|
||||
coverageReporters: ['text', 'html'],
|
||||
collectCoverageFrom: [
|
||||
'<rootDir>/src/plugins/unified_doc_viewer/{common,public,server}/**/*.{ts,tsx}',
|
||||
],
|
||||
};
|
13
src/plugins/unified_doc_viewer/kibana.jsonc
Normal file
13
src/plugins/unified_doc_viewer/kibana.jsonc
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"type": "plugin",
|
||||
"id": "@kbn/unified-doc-viewer-plugin",
|
||||
"owner": "@elastic/kibana-data-discovery",
|
||||
"description": "This plugin contains services reliant on the plugin lifecycle for the unified doc viewer component (see @kbn/unified-doc-viewer).",
|
||||
"plugin": {
|
||||
"id": "unifiedDocViewer",
|
||||
"server": false,
|
||||
"browser": true,
|
||||
"requiredBundles": ["kibanaUtils", "kibanaReact"],
|
||||
"requiredPlugins": ["data", "fieldFormats"],
|
||||
}
|
||||
}
|
9
src/plugins/unified_doc_viewer/public/__mocks__/index.ts
Normal file
9
src/plugins/unified_doc_viewer/public/__mocks__/index.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
export * from './services';
|
27
src/plugins/unified_doc_viewer/public/__mocks__/services.ts
Normal file
27
src/plugins/unified_doc_viewer/public/__mocks__/services.ts
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks';
|
||||
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
|
||||
import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks';
|
||||
import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks';
|
||||
import type { UnifiedDocViewerServices, UnifiedDocViewerStart } from '../types';
|
||||
import { Storage } from '@kbn/kibana-utils-plugin/public';
|
||||
|
||||
export const mockUnifiedDocViewer: jest.Mocked<UnifiedDocViewerStart> = {
|
||||
getDocViews: jest.fn().mockReturnValue([]),
|
||||
};
|
||||
|
||||
export const mockUnifiedDocViewerServices: jest.Mocked<UnifiedDocViewerServices> = {
|
||||
analytics: analyticsServiceMock.createAnalyticsServiceStart(),
|
||||
data: dataPluginMock.createStartContract(),
|
||||
fieldFormats: fieldFormatsMock,
|
||||
storage: new Storage(localStorage),
|
||||
uiSettings: uiSettingsServiceMock.createStartContract(),
|
||||
unifiedDocViewer: mockUnifiedDocViewer,
|
||||
};
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import type { DocViewRenderProps } from '@kbn/unified-doc-viewer/types';
|
||||
import { DocViewer } from '@kbn/unified-doc-viewer';
|
||||
import { getUnifiedDocViewerServices } from '../../plugin';
|
||||
|
||||
export function UnifiedDocViewer(props: DocViewRenderProps) {
|
||||
const services = getUnifiedDocViewerServices();
|
||||
return (
|
||||
<KibanaContextProvider services={services}>
|
||||
<DocViewer docViews={services.unifiedDocViewer.getDocViews(props.hit)} {...props} />
|
||||
</KibanaContextProvider>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* 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 and the Server Side Public License, v 1; you may not use this file except
|
||||
* in compliance with, at your election, the Elastic License 2.0 or the Server
|
||||
* Side Public License, v 1.
|
||||
*/
|
||||
|
||||
import { UnifiedDocViewer } from './doc_viewer';
|
||||
|
||||
// Required for usage in React.lazy
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default UnifiedDocViewer;
|
|
@ -10,10 +10,10 @@ import React from 'react';
|
|||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import { mountWithIntl } from '@kbn/test-jest-helpers';
|
||||
import { DocViewerSource } from './source';
|
||||
import * as hooks from '../../../../hooks/use_es_doc_search';
|
||||
import * as hooks from '../../hooks/use_es_doc_search';
|
||||
import * as useUiSettingHook from '@kbn/kibana-react-plugin/public/ui_settings/use_ui_setting';
|
||||
import { EuiButton, EuiEmptyPrompt, EuiLoadingSpinner } from '@elastic/eui';
|
||||
import { JsonCodeEditorCommon } from '../../../../components/json_code_editor/json_code_editor_common';
|
||||
import { JsonCodeEditorCommon } from '../json_code_editor';
|
||||
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
|
||||
import { buildDataTableRecord } from '@kbn/discover-utils';
|
||||
import { of } from 'rxjs';
|
||||
|
@ -53,6 +53,7 @@ describe('Source Viewer component', () => {
|
|||
dataView={mockDataView}
|
||||
width={123}
|
||||
hasLineNumbers={true}
|
||||
onRefresh={() => {}}
|
||||
/>
|
||||
</KibanaContextProvider>
|
||||
);
|
||||
|
@ -71,6 +72,7 @@ describe('Source Viewer component', () => {
|
|||
dataView={mockDataView}
|
||||
width={123}
|
||||
hasLineNumbers={true}
|
||||
onRefresh={() => {}}
|
||||
/>
|
||||
</KibanaContextProvider>
|
||||
);
|
||||
|
@ -110,6 +112,7 @@ describe('Source Viewer component', () => {
|
|||
dataView={mockDataView}
|
||||
width={123}
|
||||
hasLineNumbers={true}
|
||||
onRefresh={() => {}}
|
||||
/>
|
||||
</KibanaContextProvider>
|
||||
);
|
|
@ -12,14 +12,14 @@ import { FormattedMessage } from '@kbn/i18n-react';
|
|||
import { monaco } from '@kbn/monaco';
|
||||
import { EuiButton, EuiEmptyPrompt, EuiLoadingSpinner, EuiSpacer, EuiText } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { DataView } from '@kbn/data-views-plugin/public';
|
||||
import type { DataView } from '@kbn/data-views-plugin/public';
|
||||
import type { DataTableRecord } from '@kbn/discover-utils/types';
|
||||
import { ElasticRequestState } from '@kbn/unified-doc-viewer';
|
||||
import { DOC_TABLE_LEGACY, SEARCH_FIELDS_FROM_SOURCE } from '@kbn/discover-utils';
|
||||
import { useDiscoverServices } from '../../../../hooks/use_discover_services';
|
||||
import { JSONCodeEditorCommonMemoized } from '../../../../components/json_code_editor/json_code_editor_common';
|
||||
import { useEsDocSearch } from '../../../../hooks/use_es_doc_search';
|
||||
import { ElasticRequestState } from '../../../../application/doc/types';
|
||||
import { useEsDocSearch } from '../../hooks';
|
||||
import { useUnifiedDocViewerServices } from '../../hooks';
|
||||
import { getHeight } from './get_height';
|
||||
import { JSONCodeEditorCommonMemoized } from '../json_code_editor';
|
||||
|
||||
interface SourceViewerProps {
|
||||
id: string;
|
||||
|
@ -28,6 +28,8 @@ interface SourceViewerProps {
|
|||
textBasedHits?: DataTableRecord[];
|
||||
hasLineNumbers: boolean;
|
||||
width?: number;
|
||||
requestState?: ElasticRequestState;
|
||||
onRefresh: () => void;
|
||||
}
|
||||
|
||||
// Ihe number of lines displayed without scrolling used for classic table, which renders the component
|
||||
|
@ -43,14 +45,15 @@ export const DocViewerSource = ({
|
|||
width,
|
||||
hasLineNumbers,
|
||||
textBasedHits,
|
||||
onRefresh,
|
||||
}: SourceViewerProps) => {
|
||||
const [editor, setEditor] = useState<monaco.editor.IStandaloneCodeEditor>();
|
||||
const [editorHeight, setEditorHeight] = useState<number>();
|
||||
const [jsonValue, setJsonValue] = useState<string>('');
|
||||
const { uiSettings } = useDiscoverServices();
|
||||
const { uiSettings } = useUnifiedDocViewerServices();
|
||||
const useNewFieldsApi = !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE);
|
||||
const useDocExplorer = !uiSettings.get(DOC_TABLE_LEGACY);
|
||||
const [reqState, hit, requestData] = useEsDocSearch({
|
||||
const [requestState, hit] = useEsDocSearch({
|
||||
id,
|
||||
index,
|
||||
dataView,
|
||||
|
@ -59,10 +62,10 @@ export const DocViewerSource = ({
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (reqState === ElasticRequestState.Found && hit) {
|
||||
if (requestState === ElasticRequestState.Found && hit) {
|
||||
setJsonValue(JSON.stringify(hit.raw, undefined, 2));
|
||||
}
|
||||
}, [reqState, hit]);
|
||||
}, [requestState, hit]);
|
||||
|
||||
// setting editor height
|
||||
// - classic view: based on lines height and count to stretch and fit its content
|
||||
|
@ -93,26 +96,26 @@ export const DocViewerSource = ({
|
|||
<div className="sourceViewer__loading">
|
||||
<EuiLoadingSpinner className="sourceViewer__loadingSpinner" />
|
||||
<EuiText size="xs" color="subdued">
|
||||
<FormattedMessage id="discover.loadingJSON" defaultMessage="Loading JSON" />
|
||||
<FormattedMessage id="unifiedDocViewer.loadingJSON" defaultMessage="Loading JSON" />
|
||||
</EuiText>
|
||||
</div>
|
||||
);
|
||||
|
||||
const errorMessageTitle = (
|
||||
<h2>
|
||||
{i18n.translate('discover.sourceViewer.errorMessageTitle', {
|
||||
{i18n.translate('unifiedDocViewer.sourceViewer.errorMessageTitle', {
|
||||
defaultMessage: 'An Error Occurred',
|
||||
})}
|
||||
</h2>
|
||||
);
|
||||
const errorMessage = (
|
||||
<div>
|
||||
{i18n.translate('discover.sourceViewer.errorMessage', {
|
||||
{i18n.translate('unifiedDocViewer.sourceViewer.errorMessage', {
|
||||
defaultMessage: 'Could not fetch data at this time. Refresh the tab to try again.',
|
||||
})}
|
||||
<EuiSpacer size="s" />
|
||||
<EuiButton iconType="refresh" onClick={requestData}>
|
||||
{i18n.translate('discover.sourceViewer.refresh', {
|
||||
<EuiButton iconType="refresh" onClick={onRefresh}>
|
||||
{i18n.translate('unifiedDocViewer.sourceViewer.refresh', {
|
||||
defaultMessage: 'Refresh',
|
||||
})}
|
||||
</EuiButton>
|
||||
|
@ -122,11 +125,11 @@ export const DocViewerSource = ({
|
|||
<EuiEmptyPrompt iconType="warning" title={errorMessageTitle} body={errorMessage} />
|
||||
);
|
||||
|
||||
if (reqState === ElasticRequestState.Error || reqState === ElasticRequestState.NotFound) {
|
||||
if (requestState === ElasticRequestState.Error || requestState === ElasticRequestState.NotFound) {
|
||||
return errorState;
|
||||
}
|
||||
|
||||
if (reqState === ElasticRequestState.Loading || jsonValue === '') {
|
||||
if (requestState === ElasticRequestState.Loading || jsonValue === '') {
|
||||
return loadingState;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue