diff --git a/packages/deeplinks/observability/locators/dataset_quality.ts b/packages/deeplinks/observability/locators/dataset_quality.ts index bfa760bf62c06..e30648e3f129c 100644 --- a/packages/deeplinks/observability/locators/dataset_quality.ts +++ b/packages/deeplinks/observability/locators/dataset_quality.ts @@ -8,7 +8,7 @@ import { SerializableRecord } from '@kbn/utility-types'; -export const DATASET_QUALITY_LOCATOR_ID = 'DATASET_QUALITY_LOCATOR'; +export const DATA_QUALITY_LOCATOR_ID = 'DATA_QUALITY_LOCATOR'; // eslint-disable-next-line @typescript-eslint/consistent-type-definitions type RefreshInterval = { @@ -23,11 +23,22 @@ type TimeRangeConfig = { refresh: RefreshInterval; }; +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +type DatasetConfig = { + rawName: string; + type: string; + name: string; + namespace: string; +}; + // eslint-disable-next-line @typescript-eslint/consistent-type-definitions type Filters = { timeRange: TimeRangeConfig; }; -export interface DatasetQualityLocatorParams extends SerializableRecord { +export interface DataQualityLocatorParams extends SerializableRecord { filters?: Filters; + flyout?: { + dataset: DatasetConfig; + }; } diff --git a/src/plugins/unified_doc_viewer/kibana.jsonc b/src/plugins/unified_doc_viewer/kibana.jsonc index 2361a10120e9b..e2febffda4df6 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"], + "requiredPlugins": ["data", "discoverShared", "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 8496b919b38f0..29ae5f2981a6e 100644 --- a/src/plugins/unified_doc_viewer/public/__mocks__/services.ts +++ b/src/plugins/unified_doc_viewer/public/__mocks__/services.ts @@ -12,6 +12,7 @@ import { discoverSharedPluginMock } from '@kbn/discover-shared-plugin/public/moc 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'; +import { sharePluginMock } from '@kbn/share-plugin/public/mocks'; import type { UnifiedDocViewerServices, UnifiedDocViewerStart } from '../types'; import { Storage } from '@kbn/kibana-utils-plugin/public'; import { DocViewsRegistry } from '@kbn/unified-doc-viewer'; @@ -29,4 +30,5 @@ export const mockUnifiedDocViewerServices: jest.Mocked storage: new Storage(localStorage), uiSettings: uiSettingsServiceMock.createStartContract(), unifiedDocViewer: mockUnifiedDocViewer, + share: sharePluginMock.createStartContract(), }; diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.test.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.test.tsx index 7b9379654cec1..a0f4ba8e993ff 100644 --- a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.test.tsx +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview.test.tsx @@ -18,6 +18,8 @@ const DATASET_NAME = 'logs.overview'; const NAMESPACE = 'default'; const DATA_STREAM_NAME = `logs-${DATASET_NAME}-${NAMESPACE}`; const NOW = Date.now(); +const MORE_THAN_1024_CHARS = + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?'; const dataView = { fields: { @@ -82,7 +84,7 @@ const fullHit = buildDataTableRecord( cloud: { provider: ['gcp'], region: 'us-central-1', - availability_zone: 'us-central-1a', + availability_zone: MORE_THAN_1024_CHARS, project: { id: 'elastic-project', }, @@ -92,6 +94,9 @@ const fullHit = buildDataTableRecord( }, 'agent.name': 'node', }, + ignored_field_values: { + 'cloud.availability_zone': [MORE_THAN_1024_CHARS], + }, }, dataView ); @@ -159,4 +164,37 @@ describe('LogsOverview', () => { expect(screen.queryByTestId('unifiedDocViewLogsOverviewLogShipper')).toBeInTheDocument(); }); }); + describe('Degraded Fields section', () => { + it('should load the degraded fields container when present', async () => { + expect( + screen.queryByTestId('unifiedDocViewLogsOverviewDegradedFieldsAccordion') + ).toBeInTheDocument(); + expect( + screen.queryByTestId('unifiedDocViewLogsOverviewDegradedFieldsTechPreview') + ).toBeInTheDocument(); + expect( + screen.queryByTestId('unifiedDocViewLogsOverviewDegradedFieldTitleCount') + ).toBeInTheDocument(); + + // The accordion must be closed by default + const accordion = screen.queryByTestId('unifiedDocViewLogsOverviewDegradedFieldsAccordion1'); + + if (accordion === null) { + return; + } + const button = accordion.querySelector('button'); + + if (button === null) { + return; + } + // Check the aria-expanded property of the button + const isExpanded = button.getAttribute('aria-expanded'); + expect(isExpanded).toBe('false'); + + button.click(); + expect( + screen.queryByTestId('unifiedDocViewLogsOverviewDegradedFieldsQualityIssuesTable') + ).toBeInTheDocument(); + }); + }); }); 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 c0161d112e955..b46570f4f0d37 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 @@ -15,6 +15,7 @@ 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 function LogsOverview({ columns, @@ -38,6 +39,7 @@ export function LogsOverview({ + ); diff --git a/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview_degraded_fields.tsx b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview_degraded_fields.tsx new file mode 100644 index 0000000000000..976ef71c6b647 --- /dev/null +++ b/src/plugins/unified_doc_viewer/public/components/doc_viewer_logs_overview/logs_overview_degraded_fields.tsx @@ -0,0 +1,321 @@ +/* + * 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, { useMemo, useState } from 'react'; +import { DataTableRecord } from '@kbn/discover-utils'; +import { + EuiAccordion, + EuiBadge, + EuiBetaBadge, + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiTitle, + EuiBasicTable, + useGeneratedHtmlId, + EuiBasicTableColumn, + EuiHeaderLink, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { orderBy } from 'lodash'; +import { getRouterLinkProps } from '@kbn/router-utils'; +import { DATA_QUALITY_LOCATOR_ID, DataQualityLocatorParams } from '@kbn/deeplinks-observability'; +import { BrowserUrlService } from '@kbn/share-plugin/public'; +import { getUnifiedDocViewerServices } from '../../plugin'; + +type Direction = 'asc' | 'desc'; +type SortField = 'issue' | 'values'; + +const DEFAULT_SORT_FIELD = 'issue'; +const DEFAULT_SORT_DIRECTION = 'asc'; +const DEFAULT_ROWS_PER_PAGE = 5; + +interface DegradedField { + issue: string; + values: string[]; +} + +interface ParamsForLocator { + dataStreamType: string; + dataStreamName: string; + dataStreamNamespace: string; + rawName: string; +} + +interface TableOptions { + page: { + index: number; + size: number; + }; + sort: { + field: SortField; + direction: Direction; + }; +} + +const DEFAULT_TABLE_OPTIONS: TableOptions = { + page: { + index: 0, + size: 0, + }, + sort: { + field: DEFAULT_SORT_FIELD, + direction: DEFAULT_SORT_DIRECTION, + }, +}; + +const qualityIssuesAccordionTitle = i18n.translate( + 'unifiedDocViewer.docView.logsOverview.accordion.title.qualityIssues', + { + defaultMessage: 'Quality Issues', + } +); + +const qualityIssuesAccordionTechPreviewBadge = i18n.translate( + 'unifiedDocViewer.docView.logsOverview.accordion.title.techPreview', + { + defaultMessage: 'TECH PREVIEW', + } +); + +const issueColumnName = i18n.translate( + 'unifiedDocViewer.docView.logsOverview.accordion.qualityIssues.table.field', + { + defaultMessage: 'Issue', + } +); + +const valuesColumnName = i18n.translate( + 'unifiedDocViewer.docView.logsOverview.accordion.qualityIssues.table.values', + { + defaultMessage: 'Values', + } +); + +const textFieldIgnored = i18n.translate( + 'unifiedDocViewer.docView.logsOverview.accordion.qualityIssues.table.textIgnored', + { + defaultMessage: 'field ignored', + } +); + +export const datasetQualityLinkTitle = i18n.translate( + 'unifiedDocViewer.docView.logsOverview.accordion.qualityIssues.table.datasetQualityLinkTitle', + { + defaultMessage: 'Data set details', + } +); + +export const LogsOverviewDegradedFields = ({ rawDoc }: { rawDoc: DataTableRecord['raw'] }) => { + const { ignored_field_values: ignoredFieldValues = {}, fields: sourceFields = {} } = rawDoc; + const countOfDegradedFields = Object.keys(ignoredFieldValues)?.length; + + const columns = getDegradedFieldsColumns(); + const tableData = getDataFormattedForTable(ignoredFieldValues); + + const paramsForLocator = getParamsForLocator(sourceFields); + + const accordionId = useGeneratedHtmlId({ + prefix: qualityIssuesAccordionTitle, + }); + + const [tableOptions, setTableOptions] = useState(DEFAULT_TABLE_OPTIONS); + + const onTableChange = (options: { + page: { index: number; size: number }; + sort?: { field: SortField; direction: Direction }; + }) => { + setTableOptions({ + page: { + index: options.page.index, + size: options.page.size, + }, + sort: { + field: options.sort?.field ?? DEFAULT_SORT_FIELD, + direction: options.sort?.direction ?? DEFAULT_SORT_DIRECTION, + }, + }); + }; + + const pagination = useMemo( + () => ({ + pageIndex: tableOptions.page.index, + pageSize: DEFAULT_ROWS_PER_PAGE, + totalItemCount: tableData?.length ?? 0, + hidePerPageOptions: true, + }), + [tableData, tableOptions] + ); + + const renderedItems = useMemo(() => { + const sortedItems = orderBy(tableData, tableOptions.sort.field, tableOptions.sort.direction); + return sortedItems.slice( + tableOptions.page.index * DEFAULT_ROWS_PER_PAGE, + (tableOptions.page.index + 1) * DEFAULT_ROWS_PER_PAGE + ); + }, [tableData, tableOptions]); + + const { share } = getUnifiedDocViewerServices(); + const { url: urlService } = share; + + const accordionTitle = ( + + + +

{qualityIssuesAccordionTitle}

+
+
+ + + {countOfDegradedFields} + + + + + +
+ ); + + return countOfDegradedFields > 0 ? ( + <> + + } + data-test-subj="unifiedDocViewLogsOverviewDegradedFieldsAccordion" + > + + + + + ) : null; +}; + +const getDegradedFieldsColumns = (): Array> => [ + { + name: issueColumnName, + sortable: true, + field: 'issue', + render: (issue: string) => { + return ( + <> + {issue} {textFieldIgnored} + + ); + }, + }, + { + name: valuesColumnName, + sortable: true, + field: 'values', + render: (values: string[]) => { + return values.map((value, idx) => {value}); + }, + }, +]; + +const getDataFormattedForTable = ( + ignoredFieldValues: Record +): DegradedField[] => { + return Object.entries(ignoredFieldValues).map(([field, values]) => ({ + issue: field, + values, + })); +}; + +const getParamsForLocator = ( + sourceFields: DataTableRecord['raw']['fields'] +): ParamsForLocator | undefined => { + if (sourceFields) { + const dataStreamTypeArr = sourceFields['data_stream.type']; + const dataStreamType = dataStreamTypeArr ? dataStreamTypeArr[0] : undefined; + const dataStreamNameArr = sourceFields['data_stream.dataset']; + const dataStreamName = dataStreamNameArr ? dataStreamNameArr[0] : undefined; + const dataStreamNamespaceArr = sourceFields['data_stream.namespace']; + const dataStreamNamespace = dataStreamNamespaceArr ? dataStreamNamespaceArr[0] : undefined; + let rawName; + + if (dataStreamType && dataStreamName && dataStreamNamespace) { + rawName = `${dataStreamType}-${dataStreamName}-${dataStreamNamespace}`; + } + + if (rawName) { + return { + dataStreamType, + dataStreamName, + dataStreamNamespace, + rawName, + }; + } + } +}; + +const DatasetQualityLink = React.memo( + ({ + urlService, + paramsForLocator, + }: { + urlService: BrowserUrlService; + paramsForLocator?: ParamsForLocator; + }) => { + const locator = urlService.locators.get(DATA_QUALITY_LOCATOR_ID); + const locatorParams: DataQualityLocatorParams = paramsForLocator + ? { + flyout: { + dataset: { + rawName: paramsForLocator.rawName, + type: paramsForLocator.dataStreamType, + name: paramsForLocator.dataStreamName, + namespace: paramsForLocator.dataStreamNamespace, + }, + }, + } + : {}; + + const datasetQualityUrl = locator?.getRedirectUrl(locatorParams); + + const navigateToDatasetQuality = () => { + locator?.navigate(locatorParams); + }; + + const datasetQualityLinkProps = getRouterLinkProps({ + href: datasetQualityUrl, + onClick: navigateToDatasetQuality, + }); + + return paramsForLocator ? ( + + {datasetQualityLinkTitle} + + ) : null; + } +); diff --git a/src/plugins/unified_doc_viewer/public/plugin.tsx b/src/plugins/unified_doc_viewer/public/plugin.tsx index 13027a2541084..9c4d7117c37dd 100644 --- a/src/plugins/unified_doc_viewer/public/plugin.tsx +++ b/src/plugins/unified_doc_viewer/public/plugin.tsx @@ -19,6 +19,7 @@ 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'; export const [getUnifiedDocViewerServices, setUnifiedDocViewerServices] = @@ -52,6 +53,7 @@ export interface UnifiedDocViewerStartDeps { discoverShared: DiscoverSharedPublicStart; fieldFormats: FieldFormatsStart; fieldsMetadata: FieldsMetadataPublicStart; + share: SharePluginStart; } export class UnifiedDocViewerPublicPlugin @@ -121,7 +123,7 @@ export class UnifiedDocViewerPublicPlugin public start(core: CoreStart, deps: UnifiedDocViewerStartDeps) { const { analytics, uiSettings } = core; - const { data, discoverShared, fieldFormats, fieldsMetadata } = deps; + const { data, discoverShared, fieldFormats, fieldsMetadata, share } = deps; const storage = new Storage(localStorage); const unifiedDocViewer = { registry: this.docViewsRegistry, @@ -135,6 +137,7 @@ export class UnifiedDocViewerPublicPlugin storage, uiSettings, unifiedDocViewer, + share, }; setUnifiedDocViewerServices(services); return unifiedDocViewer; diff --git a/src/plugins/unified_doc_viewer/public/types.ts b/src/plugins/unified_doc_viewer/public/types.ts index c19c60da72b13..e471fa87b85c1 100644 --- a/src/plugins/unified_doc_viewer/public/types.ts +++ b/src/plugins/unified_doc_viewer/public/types.ts @@ -5,7 +5,6 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ - export type { JsonCodeEditorProps } from './components'; export type { EsDocSearchProps } from './hooks'; export type { UnifiedDocViewerSetup, UnifiedDocViewerStart } from './plugin'; @@ -17,6 +16,7 @@ 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'; import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser'; +import type { SharePluginStart } from '@kbn/share-plugin/public'; import type { UnifiedDocViewerStart } from './plugin'; export interface UnifiedDocViewerServices { @@ -28,4 +28,5 @@ export interface UnifiedDocViewerServices { storage: Storage; uiSettings: IUiSettingsClient; unifiedDocViewer: UnifiedDocViewerStart; + share: SharePluginStart; } diff --git a/src/plugins/unified_doc_viewer/tsconfig.json b/src/plugins/unified_doc_viewer/tsconfig.json index fbe2ac83c5f1a..3b271744ed4af 100644 --- a/src/plugins/unified_doc_viewer/tsconfig.json +++ b/src/plugins/unified_doc_viewer/tsconfig.json @@ -32,7 +32,10 @@ "@kbn/discover-shared-plugin", "@kbn/fields-metadata-plugin", "@kbn/unified-data-table", - "@kbn/core-notifications-browser" + "@kbn/core-notifications-browser", + "@kbn/deeplinks-observability", + "@kbn/share-plugin", + "@kbn/router-utils" ], "exclude": [ "target/**/*", diff --git a/x-pack/plugins/data_quality/common/index.ts b/x-pack/plugins/data_quality/common/index.ts index 79bbe59ff35d2..1b174a9efe524 100644 --- a/x-pack/plugins/data_quality/common/index.ts +++ b/x-pack/plugins/data_quality/common/index.ts @@ -13,6 +13,3 @@ export const PLUGIN_NAME = i18n.translate('xpack.dataQuality.name', { }); export { DATA_QUALITY_URL_STATE_KEY, datasetQualityUrlSchemaV1 } from './url_schema'; - -export { DATA_QUALITY_LOCATOR_ID } from './locators'; -export type { DataQualityLocatorParams } from './locators'; diff --git a/x-pack/plugins/data_quality/common/locators/construct_dataset_quality_locator_path.ts b/x-pack/plugins/data_quality/common/locators/construct_dataset_quality_locator_path.ts index 45f58752bd2fc..f5b5b0bf7ce59 100644 --- a/x-pack/plugins/data_quality/common/locators/construct_dataset_quality_locator_path.ts +++ b/x-pack/plugins/data_quality/common/locators/construct_dataset_quality_locator_path.ts @@ -8,9 +8,9 @@ import { setStateToKbnUrl } from '@kbn/kibana-utils-plugin/common'; import { ManagementAppLocatorParams } from '@kbn/management-plugin/common/locator'; import { LocatorPublic } from '@kbn/share-plugin/common'; +import { DataQualityLocatorParams } from '@kbn/deeplinks-observability'; import { datasetQualityUrlSchemaV1, DATA_QUALITY_URL_STATE_KEY } from '../url_schema'; import { deepCompactObject } from '../utils/deep_compact_object'; -import { DataQualityLocatorParams } from './types'; interface LocatorPathConstructionParams { locatorParams: DataQualityLocatorParams; @@ -20,7 +20,7 @@ interface LocatorPathConstructionParams { export const constructDatasetQualityLocatorPath = async (params: LocatorPathConstructionParams) => { const { - locatorParams: { filters }, + locatorParams: { filters, flyout }, useHash, managementLocator, } = params; @@ -29,6 +29,7 @@ export const constructDatasetQualityLocatorPath = async (params: LocatorPathCons deepCompactObject({ v: 1, filters, + flyout, }) ); diff --git a/x-pack/plugins/data_quality/common/locators/dataset_quality_locator.ts b/x-pack/plugins/data_quality/common/locators/dataset_quality_locator.ts index 70e4770090ef3..4bf804955b6bc 100644 --- a/x-pack/plugins/data_quality/common/locators/dataset_quality_locator.ts +++ b/x-pack/plugins/data_quality/common/locators/dataset_quality_locator.ts @@ -6,11 +6,8 @@ */ import type { LocatorDefinition, LocatorPublic } from '@kbn/share-plugin/public'; -import { - DataQualityLocatorDependencies, - DataQualityLocatorParams, - DATA_QUALITY_LOCATOR_ID, -} from './types'; +import { DataQualityLocatorParams, DATA_QUALITY_LOCATOR_ID } from '@kbn/deeplinks-observability'; +import { DataQualityLocatorDependencies } from './types'; import { constructDatasetQualityLocatorPath } from './construct_dataset_quality_locator_path'; export type DatasetQualityLocator = LocatorPublic; diff --git a/x-pack/plugins/data_quality/common/locators/types.ts b/x-pack/plugins/data_quality/common/locators/types.ts index 57067cd0e482a..786b5e1cf567f 100644 --- a/x-pack/plugins/data_quality/common/locators/types.ts +++ b/x-pack/plugins/data_quality/common/locators/types.ts @@ -7,31 +7,6 @@ import { ManagementAppLocatorParams } from '@kbn/management-plugin/common/locator'; import { LocatorPublic } from '@kbn/share-plugin/common'; -import { SerializableRecord } from '@kbn/utility-types'; - -export const DATA_QUALITY_LOCATOR_ID = 'DATA_QUALITY_LOCATOR'; - -// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -type RefreshInterval = { - pause: boolean; - value: number; -}; - -// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -type TimeRangeConfig = { - from: string; - to: string; - refresh: RefreshInterval; -}; - -// eslint-disable-next-line @typescript-eslint/consistent-type-definitions -type Filters = { - timeRange: TimeRangeConfig; -}; - -export interface DataQualityLocatorParams extends SerializableRecord { - filters?: Filters; -} export interface DataQualityLocatorDependencies { useHash: boolean; diff --git a/x-pack/plugins/data_quality/common/url_schema/url_schema_v1.ts b/x-pack/plugins/data_quality/common/url_schema/url_schema_v1.ts index 6fd5781a217e8..076e1b641b7e2 100644 --- a/x-pack/plugins/data_quality/common/url_schema/url_schema_v1.ts +++ b/x-pack/plugins/data_quality/common/url_schema/url_schema_v1.ts @@ -37,11 +37,11 @@ const datasetRT = rt.intersection([ type: rt.string, name: rt.string, namespace: rt.string, - title: rt.string, }), rt.exact( rt.partial({ integration: integrationRT, + title: rt.string, }) ), ]); diff --git a/x-pack/plugins/data_quality/tsconfig.json b/x-pack/plugins/data_quality/tsconfig.json index 7a904e9f95cda..911c4fbfff557 100644 --- a/x-pack/plugins/data_quality/tsconfig.json +++ b/x-pack/plugins/data_quality/tsconfig.json @@ -25,8 +25,8 @@ "@kbn/core-chrome-browser", "@kbn/features-plugin", "@kbn/share-plugin", - "@kbn/utility-types", "@kbn/deeplinks-management", + "@kbn/deeplinks-observability", "@kbn/ebt-tools", ], "exclude": ["target/**/*"] diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts index 5968c369732de..164a43c625fb1 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/data_streams_stats/data_stream_stat.ts @@ -17,7 +17,7 @@ export class DataStreamStat { type: DataStreamType; name: DataStreamStatType['name']; namespace: string; - title: string; + title?: string; size?: DataStreamStatType['size']; // total datastream size sizeBytes?: DataStreamStatType['sizeBytes']; // total datastream size lastActivity?: DataStreamStatType['lastActivity']; diff --git a/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts b/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts index ca5c4632ec0d3..82d7b64e25f63 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts +++ b/x-pack/plugins/observability_solution/dataset_quality/common/types/common.ts @@ -22,6 +22,5 @@ export interface BasicDataStream { name: DataStreamStatType['name']; rawName: string; namespace: string; - title: string; integration?: Integration; } diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx index 7411067a7317f..7dc455b280444 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/flyout.tsx @@ -43,15 +43,16 @@ export default function Flyout({ dataset, closeFlyout }: FlyoutProps) { integration, } = useDatasetQualityFlyout(); - const titleAndLinkDetails: BasicDataStream = { + const linkDetails: BasicDataStream = { name: dataset.name, rawName: dataset.rawName, integration: integration?.integrationDetails, type: dataset.type, namespace: dataset.namespace, - title: integration?.integrationDetails?.datasets?.[dataset.name] ?? dataset.name, }; + const title = integration?.integrationDetails?.datasets?.[dataset.name] ?? dataset.name; + const { startTracking } = useDatasetDetailsTelemetry(); useEffect(() => { @@ -70,8 +71,9 @@ export default function Flyout({ dataset, closeFlyout }: FlyoutProps) { ) : ( <>
diff --git a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx index 5fc66f79b79ba..10d0c96a057bd 100644 --- a/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx +++ b/x-pack/plugins/observability_solution/dataset_quality/public/components/flyout/header.tsx @@ -27,17 +27,19 @@ import { IntegrationIcon } from '../common'; import { BasicDataStream } from '../../../common/types'; export function Header({ - titleAndLinkDetails, + linkDetails, loading, + title, }: { - titleAndLinkDetails: BasicDataStream; + linkDetails: BasicDataStream; loading: boolean; + title: string; }) { - const { integration, title } = titleAndLinkDetails; + const { integration } = linkDetails; const euiShadow = useEuiShadow('s'); const { euiTheme } = useEuiTheme(); const redirectLinkProps = useRedirectLink({ - dataStreamStat: titleAndLinkDetails, + dataStreamStat: linkDetails, telemetry: { page: 'details', navigationSource: NavigationSource.Header, diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/dataset_quality_link.tsx b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/dataset_quality_link.tsx index 24782cd2ab2bb..6610db470014b 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/dataset_quality_link.tsx +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/public/components/dataset_quality_link.tsx @@ -12,7 +12,7 @@ import { BrowserUrlService } from '@kbn/share-plugin/public'; import { MatchedStateFromActor } from '@kbn/xstate-utils'; import { useActor } from '@xstate/react'; import React from 'react'; -import { DataQualityLocatorParams, DATA_QUALITY_LOCATOR_ID } from '@kbn/data-quality-plugin/common'; +import { DataQualityLocatorParams, DATA_QUALITY_LOCATOR_ID } from '@kbn/deeplinks-observability'; import { datasetQualityLinkTitle } from '../../common/translations'; import { ObservabilityLogsExplorerService, diff --git a/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json b/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json index 446c237e257eb..26db8756fb9a1 100644 --- a/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json +++ b/x-pack/plugins/observability_solution/observability_logs_explorer/tsconfig.json @@ -49,7 +49,6 @@ "@kbn/es-query", "@kbn/core-analytics-browser", "@kbn/react-hooks", - "@kbn/data-quality-plugin", "@kbn/ebt", ], "exclude": [ diff --git a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/home.ts b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/home.ts index 7deeeff7e9bc1..a1c285146e5e5 100644 --- a/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/home.ts +++ b/x-pack/test_serverless/functional/test_suites/observability/dataset_quality/home.ts @@ -49,6 +49,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('dataset quality table exists', async () => { await PageObjects.datasetQuality.navigateTo(); + await PageObjects.datasetQuality.waitUntilTableLoaded(); await testSubjects.existOrFail( PageObjects.datasetQuality.testSubjectSelectors.datasetQualityTable );