From 1b463e3f94fe8723fa09a26669d2614d473963a2 Mon Sep 17 00:00:00 2001 From: achyutjhunjhunwala Date: Thu, 20 Jun 2024 17:01:05 +0200 Subject: [PATCH] Add locator for DQ Flyout --- .../observability/locators/dataset_quality.ts | 16 ++- src/plugins/unified_doc_viewer/kibana.jsonc | 2 +- .../logs_overview_degraded_fields.tsx | 106 +++++++++++++++++- .../unified_doc_viewer/public/plugin.tsx | 5 +- .../unified_doc_viewer/public/types.ts | 3 + src/plugins/unified_doc_viewer/tsconfig.json | 3 +- x-pack/plugins/data_quality/common/index.ts | 3 - .../construct_dataset_quality_locator_path.ts | 5 +- .../locators/dataset_quality_locator.ts | 7 +- .../data_quality/common/locators/types.ts | 25 ----- .../components/dataset_quality_link.tsx | 2 +- 11 files changed, 134 insertions(+), 43 deletions(-) diff --git a/packages/deeplinks/observability/locators/dataset_quality.ts b/packages/deeplinks/observability/locators/dataset_quality.ts index bfa760bf62c06..6b265c653fa11 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,23 @@ type TimeRangeConfig = { refresh: RefreshInterval; }; +// eslint-disable-next-line @typescript-eslint/consistent-type-definitions +type DatasetConfig = { + rawName: string; + type: string; + name: string; + namespace: string; + title: 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/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 index 8bc67568a7b88..ee359232c83d3 100644 --- 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 @@ -18,9 +18,14 @@ import { 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'; @@ -34,6 +39,13 @@ interface DegradedField { values: string[]; } +interface ParamsForLocator { + dataStreamType: string; + dataStreamName: string; + dataStreamNamespace: string; + rawName: string; +} + interface TableOptions { page: { index: number; @@ -91,13 +103,22 @@ const textFieldIgnored = i18n.translate( } ); +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 = {} } = rawDoc; + 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, }); @@ -106,7 +127,7 @@ export const LogsOverviewDegradedFields = ({ rawDoc }: { rawDoc: DataTableRecord const onTableChange = (options: { page: { index: number; size: number }; - sort?: { field: string; direction: Direction }; + sort?: { field: SortField; direction: Direction }; }) => { setTableOptions({ page: { @@ -138,6 +159,9 @@ export const LogsOverviewDegradedFields = ({ rawDoc }: { rawDoc: DataTableRecord ); }, [tableData, tableOptions]); + const { share } = getUnifiedDocViewerServices(); + const { url: urlService } = share; + const accordionTitle = ( @@ -161,6 +185,9 @@ export const LogsOverviewDegradedFields = ({ rawDoc }: { rawDoc: DataTableRecord buttonContent={accordionTitle} paddingSize="m" initialIsOpen={false} + extraAction={ + + } > { + 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, + title: paramsForLocator.dataStreamName, + }, + }, + } + : {}; + + 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..e7a6facb21e35 100644 --- a/src/plugins/unified_doc_viewer/public/plugin.tsx +++ b/src/plugins/unified_doc_viewer/public/plugin.tsx @@ -20,6 +20,7 @@ import { dynamic } from '@kbn/shared-ux-utility'; import { DiscoverSharedPublicStart } from '@kbn/discover-shared-plugin/public'; import { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public'; import type { UnifiedDocViewerServices } from './types'; +import { SharePluginStart } from '@kbn/share-plugin/public'; export const [getUnifiedDocViewerServices, setUnifiedDocViewerServices] = createGetterSetter('UnifiedDocViewerServices'); @@ -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..c60412fee2a6a 100644 --- a/src/plugins/unified_doc_viewer/public/types.ts +++ b/src/plugins/unified_doc_viewer/public/types.ts @@ -6,6 +6,8 @@ * Side Public License, v 1. */ +import { SharePluginStart } from '@kbn/share-plugin/public'; + export type { JsonCodeEditorProps } from './components'; export type { EsDocSearchProps } from './hooks'; export type { UnifiedDocViewerSetup, UnifiedDocViewerStart } from './plugin'; @@ -28,4 +30,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..92bee1cf92a95 100644 --- a/src/plugins/unified_doc_viewer/tsconfig.json +++ b/src/plugins/unified_doc_viewer/tsconfig.json @@ -32,7 +32,8 @@ "@kbn/discover-shared-plugin", "@kbn/fields-metadata-plugin", "@kbn/unified-data-table", - "@kbn/core-notifications-browser" + "@kbn/core-notifications-browser", + "@kbn/deeplinks-observability" ], "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/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,