From 10c27a9bbf4464e4ed3589fa3f8614a8feb06dbd Mon Sep 17 00:00:00 2001 From: Davis McPhee Date: Mon, 15 Jul 2024 19:09:44 -0300 Subject: [PATCH] [Discover] Add support for log overview tab to Discover log profile (#186680) ## Summary This PR adds the log overview tab from Logs Explorer to the Discover log document profile. The only difference between the tab in Logs Explorer and Discover is that the one in Logs Explorer includes the O11y AI assistant while the Discover one doesn't (for now at least): ![log_overview](https://github.com/user-attachments/assets/3c5b3ea0-227e-41fa-ab1e-5618008b5d39) Resolves #187096. ### Checklist - [x] 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 - [x] [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 - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed - [ ] 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) ### 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> --- .../example_data_source_profile/profile.tsx | 10 ++- .../example_document_profile/profile.ts | 4 +- .../accessors/get_doc_viewer.tsx | 33 +++++++++ .../log_document_profile/accessors/index.ts | 9 +++ .../log_document_profile/profile.test.ts | 27 +++++++ .../{profile.ts => profile.tsx} | 5 +- .../register_profile_providers.test.ts | 4 +- src/plugins/unified_doc_viewer/kibana.jsonc | 2 +- .../public/__mocks__/services.ts | 2 - .../doc_viewer_logs_overview/index.ts | 1 + .../logs_overview.tsx | 12 ++- .../logs_overview_ai_assistant.tsx | 24 ------ .../lazy_doc_viewer_logs_overview.tsx | 19 +++++ .../unified_doc_viewer/public/index.tsx | 3 + .../unified_doc_viewer/public/plugin.tsx | 20 +---- .../unified_doc_viewer/public/types.ts | 2 - test/accessibility/apps/discover.ts | 3 +- .../dashboard/group1/url_field_formatter.ts | 5 +- .../context_awareness/_data_source_profile.ts | 8 +- .../extensions/_get_doc_viewer.ts | 73 +++++++++++++++++++ .../apps/discover/context_awareness/index.ts | 1 + .../group2_data_grid1/_data_grid_doc_table.ts | 11 +-- .../discover/context_awareness.json | 25 +++++++ test/functional/page_objects/discover_page.ts | 8 +- test/functional/services/data_grid.ts | 22 +++++- .../logs_explorer/kibana.jsonc | 2 + .../customizations/logs_explorer_profile.tsx | 19 ++++- .../logs_explorer/public/types.ts | 2 + .../logs_explorer/tsconfig.json | 2 + .../feature_controls/discover_security.ts | 5 +- .../context_awareness/_data_source_profile.ts | 8 +- .../extensions/_get_doc_viewer.ts | 72 ++++++++++++++++++ .../discover/context_awareness/index.ts | 1 + .../discover/group2/_data_grid_doc_table.ts | 11 +-- 34 files changed, 356 insertions(+), 99 deletions(-) create mode 100644 src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/get_doc_viewer.tsx create mode 100644 src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/index.ts rename src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/{profile.ts => profile.tsx} (95%) delete mode 100644 src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview_ai_assistant.tsx create mode 100644 src/plugins/unified_doc_viewer/public/components/lazy_doc_viewer_logs_overview.tsx create mode 100644 test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts create mode 100644 x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts diff --git a/src/plugins/discover/public/context_awareness/profile_providers/example_data_source_profile/profile.tsx b/src/plugins/discover/public/context_awareness/profile_providers/example_data_source_profile/profile.tsx index 6b705b00c1ba1..f9cba1592dc30 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/example_data_source_profile/profile.tsx +++ b/src/plugins/discover/public/context_awareness/profile_providers/example_data_source_profile/profile.tsx @@ -58,7 +58,15 @@ export const exampleDataSourceProfileProvider: DataSourceProfileProvider = { return { title: `Record #${recordId}`, docViewsRegistry: (registry) => { - registry.enableById('doc_view_logs_overview'); + registry.add({ + id: 'doc_view_example', + title: 'Example', + order: 0, + component: () => ( +
Example Doc View
+ ), + }); + return prevValue.docViewsRegistry(registry); }, }; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/example_document_profile/profile.ts b/src/plugins/discover/public/context_awareness/profile_providers/example_document_profile/profile.ts index 303efa103e327..9739430e08000 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/example_document_profile/profile.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/example_document_profile/profile.ts @@ -13,14 +13,14 @@ export const exampleDocumentProfileProvider: DocumentProfileProvider = { profileId: 'example-document-profile', profile: {}, resolve: (params) => { - if (getFieldValue(params.record, 'data_stream.type') !== 'logs') { + if (getFieldValue(params.record, 'data_stream.type') !== 'example') { return { isMatch: false }; } return { isMatch: true, context: { - type: DocumentType.Log, + type: DocumentType.Default, }, }; }, diff --git a/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/get_doc_viewer.tsx b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/get_doc_viewer.tsx new file mode 100644 index 0000000000000..c83155c4d3a49 --- /dev/null +++ b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/get_doc_viewer.tsx @@ -0,0 +1,33 @@ +/* + * 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 { i18n } from '@kbn/i18n'; +import { UnifiedDocViewerLogsOverview } from '@kbn/unified-doc-viewer-plugin/public'; +import React from 'react'; +import type { DocumentProfileProvider } from '../../../profiles'; + +export const getDocViewer: DocumentProfileProvider['profile']['getDocViewer'] = + (prev) => (params) => { + const prevDocViewer = prev(params); + + return { + ...prevDocViewer, + docViewsRegistry: (registry) => { + registry.add({ + id: 'doc_view_logs_overview', + title: i18n.translate('discover.docViews.logsOverview.title', { + defaultMessage: 'Log overview', + }), + order: 0, + component: (props) => , + }); + + return prevDocViewer.docViewsRegistry(registry); + }, + }; + }; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/index.ts b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/index.ts new file mode 100644 index 0000000000000..781ad51343123 --- /dev/null +++ b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/accessors/index.ts @@ -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 { getDocViewer } from './get_doc_viewer'; diff --git a/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.test.ts b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.test.ts index 6514eb699e553..a188dd4584508 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.test.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.test.ts @@ -7,6 +7,7 @@ */ import { buildDataTableRecord } from '@kbn/discover-utils'; +import { DocViewsRegistry } from '@kbn/unified-doc-viewer'; import { DocumentType } from '../../profiles'; import { createContextAwarenessMocks } from '../../__mocks__'; import { createLogDocumentProfileProvider } from './profile'; @@ -65,6 +66,32 @@ describe('logDocumentProfileProvider', () => { }) ).toEqual(RESOLUTION_MISMATCH); }); + + describe('getDocViewer', () => { + it('adds a log overview doc view to the registry', () => { + const getDocViewer = logDocumentProfileProvider.profile.getDocViewer!(() => ({ + title: 'test title', + docViewsRegistry: (registry) => registry, + })); + const docViewer = getDocViewer({ + record: buildDataTableRecord({}), + }); + const registry = new DocViewsRegistry(); + + expect(docViewer.title).toBe('test title'); + expect(registry.getAll()).toHaveLength(0); + docViewer.docViewsRegistry(registry); + expect(registry.getAll()).toHaveLength(1); + expect(registry.getAll()[0]).toEqual( + expect.objectContaining({ + id: 'doc_view_logs_overview', + title: 'Log overview', + order: 0, + component: expect.any(Function), + }) + ); + }); + }); }); const buildMockRecord = (index: string, fields: Record = {}) => diff --git a/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.ts b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.tsx similarity index 95% rename from src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.ts rename to src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.tsx index 2d03c9e35398a..bf7276f1d39b8 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/log_document_profile/profile.tsx @@ -9,12 +9,15 @@ import { DataTableRecord } from '@kbn/discover-utils'; import { DocumentProfileProvider, DocumentType } from '../../profiles'; import { ProfileProviderServices } from '../profile_provider_services'; +import { getDocViewer } from './accessors'; export const createLogDocumentProfileProvider = ( services: ProfileProviderServices ): DocumentProfileProvider => ({ profileId: 'log-document-profile', - profile: {}, + profile: { + getDocViewer, + }, resolve: ({ record }) => { const isLogRecord = getIsLogRecord(record, services.logsContextService.isLogsIndexPattern); diff --git a/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts b/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts index c58726ecc1c11..df437d1547cc5 100644 --- a/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts +++ b/src/plugins/discover/public/context_awareness/profile_providers/register_profile_providers.test.ts @@ -68,7 +68,7 @@ describe('registerProfileProviders', () => { const documentContext = documentProfileServiceMock.resolve({ record: { id: 'test', - flattened: { 'data_stream.type': 'logs' }, + flattened: { 'data_stream.type': 'example' }, raw: {}, }, }); @@ -100,7 +100,7 @@ describe('registerProfileProviders', () => { const documentContext = documentProfileServiceMock.resolve({ record: { id: 'test', - flattened: { 'data_stream.type': 'logs' }, + flattened: { 'data_stream.type': 'example' }, raw: {}, }, }); diff --git a/src/plugins/unified_doc_viewer/kibana.jsonc b/src/plugins/unified_doc_viewer/kibana.jsonc index e2febffda4df6..56ea8951e3a2d 100644 --- a/src/plugins/unified_doc_viewer/kibana.jsonc +++ b/src/plugins/unified_doc_viewer/kibana.jsonc @@ -8,7 +8,7 @@ "server": false, "browser": true, "requiredBundles": ["kibanaUtils"], - "requiredPlugins": ["data", "discoverShared", "fieldFormats", "share"], + "requiredPlugins": ["data", "fieldFormats", "share"], "optionalPlugins": ["fieldsMetadata"] } } diff --git a/src/plugins/unified_doc_viewer/public/__mocks__/services.ts b/src/plugins/unified_doc_viewer/public/__mocks__/services.ts index 29ae5f2981a6e..5e7222f261532 100644 --- a/src/plugins/unified_doc_viewer/public/__mocks__/services.ts +++ b/src/plugins/unified_doc_viewer/public/__mocks__/services.ts @@ -8,7 +8,6 @@ import { analyticsServiceMock } from '@kbn/core-analytics-browser-mocks'; import { dataPluginMock } from '@kbn/data-plugin/public/mocks'; -import { discoverSharedPluginMock } from '@kbn/discover-shared-plugin/public/mocks'; import { fieldFormatsMock } from '@kbn/field-formats-plugin/common/mocks'; import { fieldsMetadataPluginPublicMock } from '@kbn/fields-metadata-plugin/public/mocks'; import { uiSettingsServiceMock } from '@kbn/core-ui-settings-browser-mocks'; @@ -24,7 +23,6 @@ export const mockUnifiedDocViewer: jest.Mocked = { export const mockUnifiedDocViewerServices: jest.Mocked = { analytics: analyticsServiceMock.createAnalyticsServiceStart(), data: dataPluginMock.createStartContract(), - discoverShared: discoverSharedPluginMock.createStartContract(), fieldFormats: fieldFormatsMock, fieldsMetadata: fieldsMetadataPluginPublicMock.createStartContract(), storage: new Storage(localStorage), diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/index.ts b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/index.ts index 69f01c944ad25..99416ee140231 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/index.ts +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/index.ts @@ -5,6 +5,7 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ + import { LogsOverview } from './logs_overview'; // Required for usage in React.lazy diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.tsx index b46570f4f0d37..73bcf21dab30c 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.tsx @@ -10,13 +10,17 @@ import React from 'react'; import { DocViewRenderProps } from '@kbn/unified-doc-viewer/types'; import { getLogDocumentOverview } from '@kbn/discover-utils'; import { EuiHorizontalRule, EuiSpacer } from '@elastic/eui'; +import { ObservabilityLogsAIAssistantFeatureRenderDeps } from '@kbn/discover-shared-plugin/public'; import { LogsOverviewHeader } from './logs_overview_header'; import { LogsOverviewHighlights } from './logs_overview_highlights'; import { FieldActionsProvider } from '../../hooks/use_field_actions'; import { getUnifiedDocViewerServices } from '../../plugin'; -import { LogsOverviewAIAssistant } from './logs_overview_ai_assistant'; import { LogsOverviewDegradedFields } from './logs_overview_degraded_fields'; +export type LogsOverviewProps = DocViewRenderProps & { + renderAIAssistant?: (deps: ObservabilityLogsAIAssistantFeatureRenderDeps) => JSX.Element; +}; + export function LogsOverview({ columns, dataView, @@ -24,9 +28,11 @@ export function LogsOverview({ filter, onAddColumn, onRemoveColumn, -}: DocViewRenderProps) { + renderAIAssistant, +}: LogsOverviewProps) { const { fieldFormats } = getUnifiedDocViewerServices(); const parsedDoc = getLogDocumentOverview(hit, { dataView, fieldFormats }); + const LogsOverviewAIAssistant = renderAIAssistant; return ( - + {LogsOverviewAIAssistant && } ); } diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview_ai_assistant.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview_ai_assistant.tsx deleted file mode 100644 index 0e2627a1054fd..0000000000000 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview_ai_assistant.tsx +++ /dev/null @@ -1,24 +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 { DataTableRecord } from '@kbn/discover-utils'; -import { getUnifiedDocViewerServices } from '../../plugin'; - -export function LogsOverviewAIAssistant({ doc }: { doc: DataTableRecord }) { - const { discoverShared } = getUnifiedDocViewerServices(); - - const logsAIAssistantFeature = discoverShared.features.registry.getById( - 'observability-logs-ai-assistant' - ); - - if (!logsAIAssistantFeature) { - return null; - } - - return logsAIAssistantFeature.render({ doc }); -} diff --git a/src/plugins/unified_doc_viewer/public/components/lazy_doc_viewer_logs_overview.tsx b/src/plugins/unified_doc_viewer/public/components/lazy_doc_viewer_logs_overview.tsx new file mode 100644 index 0000000000000..8da9e9b3cb722 --- /dev/null +++ b/src/plugins/unified_doc_viewer/public/components/lazy_doc_viewer_logs_overview.tsx @@ -0,0 +1,19 @@ +/* + * 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 { EuiDelayRender, EuiSkeletonText } from '@elastic/eui'; +import { dynamic } from '@kbn/shared-ux-utility'; + +export const UnifiedDocViewerLogsOverview = dynamic(() => import('./doc_viewer_logs_overview'), { + fallback: ( + + + + ), +}); diff --git a/src/plugins/unified_doc_viewer/public/index.tsx b/src/plugins/unified_doc_viewer/public/index.tsx index b594d8f06c42f..6c5f1d59991c6 100644 --- a/src/plugins/unified_doc_viewer/public/index.tsx +++ b/src/plugins/unified_doc_viewer/public/index.tsx @@ -29,4 +29,7 @@ export { useEsDocSearch } from './hooks'; export { UnifiedDocViewer } from './components/lazy_doc_viewer'; export { UnifiedDocViewerFlyout } from './components/lazy_doc_viewer_flyout'; +export type { LogsOverviewProps as UnifiedDocViewerLogsOverviewProps } from './components/doc_viewer_logs_overview/logs_overview'; +export { UnifiedDocViewerLogsOverview } from './components/lazy_doc_viewer_logs_overview'; + export const plugin = () => new UnifiedDocViewerPublicPlugin(); diff --git a/src/plugins/unified_doc_viewer/public/plugin.tsx b/src/plugins/unified_doc_viewer/public/plugin.tsx index 9c4d7117c37dd..e8a23342e7976 100644 --- a/src/plugins/unified_doc_viewer/public/plugin.tsx +++ b/src/plugins/unified_doc_viewer/public/plugin.tsx @@ -17,7 +17,6 @@ import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import { CoreStart } from '@kbn/core/public'; import { dynamic } from '@kbn/shared-ux-utility'; -import { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; import { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public'; import { SharePluginStart } from '@kbn/share-plugin/public'; import type { UnifiedDocViewerServices } from './types'; @@ -31,9 +30,6 @@ const fallback = ( ); -const LazyDocViewerLogsOverview = dynamic(() => import('./components/doc_viewer_logs_overview'), { - fallback, -}); const LazyDocViewerLegacyTable = dynamic(() => import('./components/doc_viewer_table/legacy'), { fallback, }); @@ -50,7 +46,6 @@ export interface UnifiedDocViewerStart { export interface UnifiedDocViewerStartDeps { data: DataPublicPluginStart; - discoverShared: DiscoverSharedPublicStart; fieldFormats: FieldFormatsStart; fieldsMetadata: FieldsMetadataPublicStart; share: SharePluginStart; @@ -62,18 +57,6 @@ export class UnifiedDocViewerPublicPlugin private docViewsRegistry = new DocViewsRegistry(); public setup(core: CoreSetup) { - this.docViewsRegistry.add({ - id: 'doc_view_logs_overview', - title: i18n.translate('unifiedDocViewer.docViews.logsOverview.title', { - defaultMessage: 'Overview', - }), - order: 0, - enabled: false, // Disabled doc view by default, can be programmatically enabled using the DocViewsRegistry.prototype.enableById method. - component: (props) => { - return ; - }, - }); - this.docViewsRegistry.add({ id: 'doc_view_table', title: i18n.translate('unifiedDocViewer.docViews.table.tableTitle', { @@ -123,7 +106,7 @@ export class UnifiedDocViewerPublicPlugin public start(core: CoreStart, deps: UnifiedDocViewerStartDeps) { const { analytics, uiSettings } = core; - const { data, discoverShared, fieldFormats, fieldsMetadata, share } = deps; + const { data, fieldFormats, fieldsMetadata, share } = deps; const storage = new Storage(localStorage); const unifiedDocViewer = { registry: this.docViewsRegistry, @@ -131,7 +114,6 @@ export class UnifiedDocViewerPublicPlugin const services = { analytics, data, - discoverShared, fieldFormats, fieldsMetadata, storage, diff --git a/src/plugins/unified_doc_viewer/public/types.ts b/src/plugins/unified_doc_viewer/public/types.ts index e471fa87b85c1..9266328306aaf 100644 --- a/src/plugins/unified_doc_viewer/public/types.ts +++ b/src/plugins/unified_doc_viewer/public/types.ts @@ -11,7 +11,6 @@ export type { UnifiedDocViewerSetup, UnifiedDocViewerStart } from './plugin'; import type { AnalyticsServiceStart } from '@kbn/core-analytics-browser'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import type { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public'; import type { Storage } from '@kbn/kibana-utils-plugin/public'; @@ -22,7 +21,6 @@ import type { UnifiedDocViewerStart } from './plugin'; export interface UnifiedDocViewerServices { analytics: AnalyticsServiceStart; data: DataPublicPluginStart; - discoverShared: DiscoverSharedPublicStart; fieldFormats: FieldFormatsStart; fieldsMetadata: FieldsMetadataPublicStart; storage: Storage; diff --git a/test/accessibility/apps/discover.ts b/test/accessibility/apps/discover.ts index abdfe096efab2..ef92ee78f0899 100644 --- a/test/accessibility/apps/discover.ts +++ b/test/accessibility/apps/discover.ts @@ -122,8 +122,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { // adding a11y tests for the new data grid it('a11y test on single document view', async () => { - await testSubjects.click('docTableExpandToggleColumn'); - await PageObjects.discover.clickDocViewerTab('doc_view_table'); + await dataGrid.clickRowToggle(); await a11y.testAppSnapshot(); }); diff --git a/test/functional/apps/dashboard/group1/url_field_formatter.ts b/test/functional/apps/dashboard/group1/url_field_formatter.ts index b408e0aed14d6..1cc49998770bf 100644 --- a/test/functional/apps/dashboard/group1/url_field_formatter.ts +++ b/test/functional/apps/dashboard/group1/url_field_formatter.ts @@ -25,6 +25,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const deployment = getService('deployment'); const retry = getService('retry'); const security = getService('security'); + const dataGrid = getService('dataGrid'); const checkUrl = async (fieldValue: string) => { const windowHandlers = await browser.getAllWindowHandles(); @@ -79,7 +80,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await common.setTime({ from, to }); await common.navigateToApp('discover'); await discover.selectIndexPattern('logstash-*'); - await testSubjects.click('docTableExpandToggleColumn'); + await dataGrid.clickRowToggle(); await retry.waitForWithTimeout(`${fieldName} is visible`, 30000, async () => { return await testSubjects.isDisplayed(`tableDocViewRow-${fieldName}-value`); }); @@ -87,8 +88,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { `[data-test-subj="tableDocViewRow-${fieldName}-value"] a` ); const fieldValue = await fieldLink.getVisibleText(); - await fieldLink.click(); await retry.try(async () => { + await fieldLink.click(); await checkUrl(fieldValue); }); }); diff --git a/test/functional/apps/discover/context_awareness/_data_source_profile.ts b/test/functional/apps/discover/context_awareness/_data_source_profile.ts index f3f7e35d7030b..594e6dee5dd78 100644 --- a/test/functional/apps/discover/context_awareness/_data_source_profile.ts +++ b/test/functional/apps/discover/context_awareness/_data_source_profile.ts @@ -73,7 +73,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.missingOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be('Result'); }); @@ -89,7 +89,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.existOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be('Record #0'); }); }); @@ -136,7 +136,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.missingOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be('Document'); }); @@ -147,7 +147,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.existOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be( 'Record #my-example-logs::XdQFDpABfGznVC1bCHLo::' ); diff --git a/test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts b/test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts new file mode 100644 index 0000000000000..7f60f92cf6191 --- /dev/null +++ b/test/functional/apps/discover/context_awareness/extensions/_get_doc_viewer.ts @@ -0,0 +1,73 @@ +/* + * 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 kbnRison from '@kbn/rison'; +import type { FtrProviderContext } from '../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'discover']); + const testSubjects = getService('testSubjects'); + const dataViews = getService('dataViews'); + const dataGrid = getService('dataGrid'); + + describe('extension getDocViewer', () => { + describe('ES|QL mode', () => { + it('should render logs overview tab for logs data source', async () => { + const state = kbnRison.encode({ + dataSource: { type: 'esql' }, + query: { esql: 'from my-example-logs | sort @timestamp desc' }, + }); + await PageObjects.common.navigateToApp('discover', { + hash: `/?_a=${state}`, + }); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await dataGrid.clickDocViewerTab('doc_view_logs_overview'); + await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader'); + }); + + it('should not render logs overview tab for non-logs data source', async () => { + const state = kbnRison.encode({ + dataSource: { type: 'esql' }, + query: { esql: 'from my-example-metrics | sort @timestamp desc' }, + }); + await PageObjects.common.navigateToApp('discover', { + hash: `/?_a=${state}`, + }); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + }); + }); + + describe('data view mode', () => { + it('should render logs overview tab for logs data source', async () => { + await PageObjects.common.navigateToApp('discover'); + await dataViews.switchTo('my-example-logs'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await dataGrid.clickDocViewerTab('doc_view_logs_overview'); + await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader'); + }); + + it('should not render logs overview tab for non-logs data source', async () => { + await PageObjects.common.navigateToApp('discover'); + await dataViews.switchTo('my-example-metrics'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + }); + }); + }); +} diff --git a/test/functional/apps/discover/context_awareness/index.ts b/test/functional/apps/discover/context_awareness/index.ts index 5ea6bc9ea0e26..b642bcbce7476 100644 --- a/test/functional/apps/discover/context_awareness/index.ts +++ b/test/functional/apps/discover/context_awareness/index.ts @@ -36,5 +36,6 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid loadTestFile(require.resolve('./_root_profile')); loadTestFile(require.resolve('./_data_source_profile')); loadTestFile(require.resolve('./extensions/_get_row_indicator_provider')); + loadTestFile(require.resolve('./extensions/_get_doc_viewer')); }); } diff --git a/test/functional/apps/discover/group2_data_grid1/_data_grid_doc_table.ts b/test/functional/apps/discover/group2_data_grid1/_data_grid_doc_table.ts index 050900047c489..5d96a3d3fb321 100644 --- a/test/functional/apps/discover/group2_data_grid1/_data_grid_doc_table.ts +++ b/test/functional/apps/discover/group2_data_grid1/_data_grid_doc_table.ts @@ -10,7 +10,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const find = getService('find'); const dataGrid = getService('dataGrid'); const log = getService('log'); const retry = getService('retry'); @@ -95,10 +94,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); log.debug(`expanded document id: ${expandDocId}`); - await dataGrid.clickRowToggle(); - await find.clickByCssSelectorWhenNotDisabledWithoutRetry( - '#kbn_doc_viewer_tab_doc_view_source' - ); + await dataGrid.clickRowToggle({ defaultTabId: 'doc_view_source' }); await retry.waitForWithTimeout( 'document id in flyout matching the expanded document id', @@ -139,10 +135,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); log.debug(`expanded document id: ${expandDocId}`); - await dataGrid.clickRowToggle(); - await find.clickByCssSelectorWhenNotDisabledWithoutRetry( - '#kbn_doc_viewer_tab_doc_view_source' - ); + await dataGrid.clickRowToggle({ defaultTabId: 'doc_view_source' }); await retry.waitForWithTimeout( 'document id in flyout matching the expanded document id', diff --git a/test/functional/fixtures/kbn_archiver/discover/context_awareness.json b/test/functional/fixtures/kbn_archiver/discover/context_awareness.json index 5232a109e5799..a4a086afc11ce 100644 --- a/test/functional/fixtures/kbn_archiver/discover/context_awareness.json +++ b/test/functional/fixtures/kbn_archiver/discover/context_awareness.json @@ -46,4 +46,29 @@ "updated_at": "2024-06-12T22:23:21.331Z", "updated_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0", "version": "WzEwLDFd" +} + +{ + "attributes": { + "allowHidden": false, + "fieldAttrs": "{}", + "fieldFormatMap": "{}", + "fields": "[]", + "name": "my-example-metrics", + "runtimeFieldMap": "{}", + "sourceFilters": "[]", + "timeFieldName": "@timestamp", + "title": "my-example-metrics" + }, + "coreMigrationVersion": "8.8.0", + "created_at": "2024-06-12T22:23:31.331Z", + "created_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0", + "id": "795df528-add1-491a-8e25-72a862c4bf3b", + "managed": false, + "references": [], + "type": "index-pattern", + "typeMigrationVersion": "8.0.0", + "updated_at": "2024-06-12T22:23:21.331Z", + "updated_by": "u_mGBROF_q5bmFCATbLXAcCwKa0k8JvONAwSruelyKA5E_0", + "version": "WzEwLDFc" } \ No newline at end of file diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts index 25bbd3900513e..81f4bad5b5b1e 100644 --- a/test/functional/page_objects/discover_page.ts +++ b/test/functional/page_objects/discover_page.ts @@ -431,12 +431,12 @@ export class DiscoverPageObject extends FtrService { return await this.testSubjects.find('discoverDocTableFooter'); } - public async isShowingDocViewer() { - return await this.testSubjects.exists('kbnDocViewer'); + public isShowingDocViewer() { + return this.dataGrid.isShowingDocViewer(); } - public async clickDocViewerTab(id: string) { - return await this.find.clickByCssSelector(`#kbn_doc_viewer_tab_${id}`); + public clickDocViewerTab(id: string) { + return this.dataGrid.clickDocViewerTab(id); } public async expectSourceViewerToExist() { diff --git a/test/functional/services/data_grid.ts b/test/functional/services/data_grid.ts index caa7f5c6b02a2..7df0c5f49bf00 100644 --- a/test/functional/services/data_grid.ts +++ b/test/functional/services/data_grid.ts @@ -302,7 +302,10 @@ export class DataGridService extends FtrService { } public async clickRowToggle( - options: SelectOptions = { isAnchorRow: false, rowIndex: 0 } + { defaultTabId, ...options }: SelectOptions & { defaultTabId?: string } = { + isAnchorRow: false, + rowIndex: 0, + } ): Promise { const testSubj = options.isAnchorRow ? 'docTableExpandToggleColumnAnchor' @@ -321,11 +324,24 @@ export class DataGridService extends FtrService { }); if (toggle) { - await toggle.scrollIntoViewIfNecessary(); - await toggle.click(); + await this.retry.waitFor('doc viewer to open', async () => { + await toggle!.scrollIntoViewIfNecessary(); + await toggle!.click(); + return this.isShowingDocViewer(); + }); } else { throw new Error('Unable to find row toggle element'); } + + await this.clickDocViewerTab(defaultTabId ?? 'doc_view_table'); + } + + public async isShowingDocViewer() { + return await this.testSubjects.exists('kbnDocViewer'); + } + + public async clickDocViewerTab(id: string) { + return await this.find.clickByCssSelector(`#kbn_doc_viewer_tab_${id}`); } public async getDetailsRows(): Promise { diff --git a/x-pack/plugins/observability_solution/logs_explorer/kibana.jsonc b/x-pack/plugins/observability_solution/logs_explorer/kibana.jsonc index b19d2ad0b4e07..60127ebf28f51 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/kibana.jsonc +++ b/x-pack/plugins/observability_solution/logs_explorer/kibana.jsonc @@ -19,6 +19,8 @@ "navigation", "share", "unifiedSearch", + "unifiedDocViewer", + "discoverShared", ], "optionalPlugins": [], "requiredBundles": ["controls","embeddable","fleet", "kibanaReact", "kibanaUtils"], diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx b/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx index 42a3838311a98..7b193f4aafff8 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx +++ b/x-pack/plugins/observability_solution/logs_explorer/public/customizations/logs_explorer_profile.tsx @@ -11,6 +11,7 @@ import type { CustomizationCallback } from '@kbn/discover-plugin/public'; import { i18n } from '@kbn/i18n'; import { waitFor } from 'xstate/lib/waitFor'; import { dynamic } from '@kbn/shared-ux-utility'; +import { UnifiedDocViewerLogsOverview } from '@kbn/unified-doc-viewer-plugin/public'; import type { LogsExplorerController } from '../controller'; import type { LogsExplorerStartDeps } from '../types'; import { useKibanaContextForPluginProvider } from '../utils/use_kibana'; @@ -130,7 +131,23 @@ export const createLogsExplorerProfileCustomizations = }, }, docViewsRegistry: (registry) => { - registry.enableById('doc_view_logs_overview'); + const logsAIAssistantFeature = plugins.discoverShared.features.registry.getById( + 'observability-logs-ai-assistant' + ); + + registry.add({ + id: 'doc_view_logs_overview', + title: i18n.translate('xpack.logsExplorer.docViews.logsOverview.title', { + defaultMessage: 'Overview', + }), + order: 0, + component: (props) => ( + + ), + }); return registry; }, diff --git a/x-pack/plugins/observability_solution/logs_explorer/public/types.ts b/x-pack/plugins/observability_solution/logs_explorer/public/types.ts index cdd8feea3128c..6e4c5fdd4c66b 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/public/types.ts +++ b/x-pack/plugins/observability_solution/logs_explorer/public/types.ts @@ -12,6 +12,7 @@ import type { SharePluginSetup, SharePluginStart } from '@kbn/share-plugin/publi import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public'; import type { NavigationPublicPluginStart } from '@kbn/navigation-plugin/public'; import { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public'; +import type { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; import type { LogsExplorerLocators } from '../common/locators'; import type { LogsExplorerProps } from './components/logs_explorer'; import type { CreateLogsExplorerController } from './controller'; @@ -37,4 +38,5 @@ export interface LogsExplorerStartDeps { navigation: NavigationPublicPluginStart; share: SharePluginStart; unifiedSearch: UnifiedSearchPublicPluginStart; + discoverShared: DiscoverSharedPublicStart; } diff --git a/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json b/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json index b3f8c978a67b4..230fe1987f0ff 100644 --- a/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json +++ b/x-pack/plugins/observability_solution/logs_explorer/tsconfig.json @@ -45,6 +45,8 @@ "@kbn/xstate-utils", "@kbn/esql-utils", "@kbn/data-view-utils", + "@kbn/unified-doc-viewer-plugin", + "@kbn/discover-shared-plugin", ], "exclude": [ "target/**/*" diff --git a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts index bfd732622b785..2d6b56c6d375f 100644 --- a/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts +++ b/x-pack/test/functional/apps/discover/feature_controls/discover_security.ts @@ -17,7 +17,6 @@ export default function (ctx: FtrProviderContext) { const esArchiver = getService('esArchiver'); const esSupertest = getService('esSupertest'); const dataGrid = getService('dataGrid'); - const find = getService('find'); const indexPatterns = getService('indexPatterns'); const retry = getService('retry'); const monacoEditor = getService('monacoEditor'); @@ -524,9 +523,7 @@ export default function (ctx: FtrProviderContext) { ); // check the JSON tab - await find.clickByCssSelectorWhenNotDisabledWithoutRetry( - '#kbn_doc_viewer_tab_doc_view_source' - ); + await dataGrid.clickDocViewerTab('doc_view_source'); await retry.waitForWithTimeout( 'index in flyout JSON tab is matching the logstash index', 5000, diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/_data_source_profile.ts b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/_data_source_profile.ts index 9ce2e79d8f586..38942bf87a3cf 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/_data_source_profile.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/_data_source_profile.ts @@ -68,7 +68,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.missingOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be('Result'); }); @@ -84,7 +84,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.existOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be('Record #0'); }); }); @@ -127,7 +127,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.missingOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be('Document'); }); @@ -138,7 +138,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { await dataGrid.clickRowToggle({ rowIndex: 0 }); await testSubjects.existOrFail('docViewerTab-doc_view_table'); await testSubjects.existOrFail('docViewerTab-doc_view_source'); - await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await testSubjects.existOrFail('docViewerTab-doc_view_example'); expect(await testSubjects.getVisibleText('docViewerRowDetailsTitle')).to.be( 'Record #my-example-logs::XdQFDpABfGznVC1bCHLo::' ); diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts new file mode 100644 index 0000000000000..d9ee508161d92 --- /dev/null +++ b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/extensions/_get_doc_viewer.ts @@ -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; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import kbnRison from '@kbn/rison'; +import type { FtrProviderContext } from '../../../../../ftr_provider_context'; + +export default function ({ getService, getPageObjects }: FtrProviderContext) { + const PageObjects = getPageObjects(['common', 'discover']); + const testSubjects = getService('testSubjects'); + const dataViews = getService('dataViews'); + const dataGrid = getService('dataGrid'); + + describe('extension getDocViewer', () => { + describe('ES|QL mode', () => { + it('should render logs overview tab for logs data source', async () => { + const state = kbnRison.encode({ + dataSource: { type: 'esql' }, + query: { esql: 'from my-example-logs | sort @timestamp desc' }, + }); + await PageObjects.common.navigateToApp('discover', { + hash: `/?_a=${state}`, + }); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await dataGrid.clickDocViewerTab('doc_view_logs_overview'); + await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader'); + }); + + it('should not render logs overview tab for non-logs data source', async () => { + const state = kbnRison.encode({ + dataSource: { type: 'esql' }, + query: { esql: 'from my-example-metrics | sort @timestamp desc' }, + }); + await PageObjects.common.navigateToApp('discover', { + hash: `/?_a=${state}`, + }); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + }); + }); + + describe('data view mode', () => { + it('should render logs overview tab for logs data source', async () => { + await PageObjects.common.navigateToApp('discover'); + await dataViews.switchTo('my-example-logs'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.existOrFail('docViewerTab-doc_view_logs_overview'); + await dataGrid.clickDocViewerTab('doc_view_logs_overview'); + await testSubjects.existOrFail('unifiedDocViewLogsOverviewHeader'); + }); + + it('should not render logs overview tab for non-logs data source', async () => { + await PageObjects.common.navigateToApp('discover'); + await dataViews.switchTo('my-example-metrics'); + await PageObjects.discover.waitUntilSearchingHasFinished(); + await dataGrid.clickRowToggle(); + await testSubjects.existOrFail('docViewerTab-doc_view_table'); + await testSubjects.missingOrFail('docViewerTab-doc_view_logs_overview'); + }); + }); + }); +} diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/index.ts b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/index.ts index 3fddfdaf3ef7a..4e52a62bc6f54 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/index.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/context_awareness/index.ts @@ -37,5 +37,6 @@ export default function ({ getService, getPageObjects, loadTestFile }: FtrProvid loadTestFile(require.resolve('./_root_profile')); loadTestFile(require.resolve('./_data_source_profile')); loadTestFile(require.resolve('./extensions/_get_row_indicator_provider')); + loadTestFile(require.resolve('./extensions/_get_doc_viewer')); }); } diff --git a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts index fafd9b72c50db..2bbbd8353c0ff 100644 --- a/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts +++ b/x-pack/test_serverless/functional/test_suites/common/discover/group2/_data_grid_doc_table.ts @@ -9,7 +9,6 @@ import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../../ftr_provider_context'; export default function ({ getService, getPageObjects }: FtrProviderContext) { - const find = getService('find'); const dataGrid = getService('dataGrid'); const log = getService('log'); const retry = getService('retry'); @@ -96,10 +95,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); log.debug(`expanded document id: ${expandDocId}`); - await dataGrid.clickRowToggle(); - await find.clickByCssSelectorWhenNotDisabledWithoutRetry( - '#kbn_doc_viewer_tab_doc_view_source' - ); + await dataGrid.clickRowToggle({ defaultTabId: 'doc_view_source' }); await retry.waitForWithTimeout( 'document id in flyout matching the expanded document id', @@ -140,10 +136,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); log.debug(`expanded document id: ${expandDocId}`); - await dataGrid.clickRowToggle(); - await find.clickByCssSelectorWhenNotDisabledWithoutRetry( - '#kbn_doc_viewer_tab_doc_view_source' - ); + await dataGrid.clickRowToggle({ defaultTabId: 'doc_view_source' }); await retry.waitForWithTimeout( 'document id in flyout matching the expanded document id',