From 145ee14ac27dc0f7964f271396959be6e71db14a Mon Sep 17 00:00:00 2001 From: "Quynh Nguyen (Quinn)" <43350163+qn895@users.noreply.github.com> Date: Fri, 23 Sep 2022 10:43:35 -0500 Subject: [PATCH] [8.4] Fix Open in Single Metric Viewer links not reflecting custom time range for Anomaly chart embeddables (#141007) (#141551) --- .../number_content.tsx | 20 ++--- .../field_data_row/number_content_preview.tsx | 44 +++++----- ...metric_distribution_chart_data_builder.tsx | 5 +- .../index_based/index_data_visualizer.tsx | 87 ++++++++++--------- 4 files changed, 75 insertions(+), 81 deletions(-) diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_expanded_row/number_content.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_expanded_row/number_content.tsx index 8f97619308f84..1c54a591fd905 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_expanded_row/number_content.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_expanded_row/number_content.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { FC, ReactNode, useEffect, useState } from 'react'; +import React, { FC, ReactNode, useMemo } from 'react'; import { EuiBasicTable, EuiFlexItem, @@ -19,11 +19,7 @@ import { FormattedMessage } from '@kbn/i18n-react'; import { i18n } from '@kbn/i18n'; import type { FieldDataRowProps } from '../../types/field_data_row'; import { kibanaFieldFormat, numberAsOrdinal } from '../../../utils'; -import { - MetricDistributionChart, - MetricDistributionChartData, - buildChartDataFromStats, -} from '../metric_distribution_chart'; +import { MetricDistributionChart, buildChartDataFromStats } from '../metric_distribution_chart'; import { TopValues } from '../../../top_values'; import { ExpandedRowFieldHeader } from '../expanded_row_field_header'; import { DocumentStatsTable } from './document_stats'; @@ -42,14 +38,10 @@ interface SummaryTableItem { export const NumberContent: FC = ({ config, onAddFilter }) => { const { stats } = config; - useEffect(() => { - const chartData = buildChartDataFromStats(stats, METRIC_DISTRIBUTION_CHART_WIDTH); - setDistributionChartData(chartData); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const defaultChartData: MetricDistributionChartData[] = []; - const [distributionChartData, setDistributionChartData] = useState(defaultChartData); + const distributionChartData = useMemo( + () => buildChartDataFromStats(stats?.distribution, METRIC_DISTRIBUTION_CHART_WIDTH), + [stats?.distribution] + ); if (stats === undefined) return null; const { min, median, max, distribution } = stats; diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/number_content_preview.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/number_content_preview.tsx index 1068d6e1d6393..54633d4c6c74c 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/number_content_preview.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/field_data_row/number_content_preview.tsx @@ -5,13 +5,9 @@ * 2.0. */ -import React, { FC, useEffect, useState } from 'react'; +import React, { FC, useMemo } from 'react'; import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; -import { - MetricDistributionChart, - MetricDistributionChartData, - buildChartDataFromStats, -} from '../metric_distribution_chart'; +import { MetricDistributionChart, buildChartDataFromStats } from '../metric_distribution_chart'; import { FieldVisConfig } from '../../types'; import { kibanaFieldFormat, formatSingleValue } from '../../../utils'; @@ -24,25 +20,25 @@ export interface NumberContentPreviewProps { export const IndexBasedNumberContentPreview: FC = ({ config }) => { const { stats, fieldFormat, fieldName } = config; - const defaultChartData: MetricDistributionChartData[] = []; - const [distributionChartData, setDistributionChartData] = useState(defaultChartData); - const [legendText, setLegendText] = useState<{ min: number; max: number } | undefined>(); const dataTestSubj = `dataVisualizerDataGridChart-${fieldName}`; - useEffect(() => { - const chartData = buildChartDataFromStats(stats, METRIC_DISTRIBUTION_CHART_WIDTH); - if ( - Array.isArray(chartData) && - chartData[0].x !== undefined && - chartData[chartData.length - 1].x !== undefined - ) { - setDistributionChartData(chartData); - setLegendText({ - min: formatSingleValue(chartData[0].x), - max: formatSingleValue(chartData[chartData.length - 1].x), - }); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + + const distributionChartData = useMemo( + () => buildChartDataFromStats(stats?.distribution, METRIC_DISTRIBUTION_CHART_WIDTH), + [stats?.distribution] + ); + + const legendText = useMemo( + () => + Array.isArray(distributionChartData) && + distributionChartData[0].x !== undefined && + distributionChartData[distributionChartData.length - 1].x !== undefined + ? { + min: formatSingleValue(distributionChartData[0].x), + max: formatSingleValue(distributionChartData[distributionChartData.length - 1].x), + } + : '', + [distributionChartData] + ); return (
diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/metric_distribution_chart/metric_distribution_chart_data_builder.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/metric_distribution_chart/metric_distribution_chart_data_builder.tsx index a65b6bdc7458f..642cbd49541e1 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/metric_distribution_chart/metric_distribution_chart_data_builder.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/components/metric_distribution_chart/metric_distribution_chart_data_builder.tsx @@ -27,19 +27,18 @@ interface DistributionChartBar { } export function buildChartDataFromStats( - stats: any, + distribution: any, chartWidth: number ): MetricDistributionChartData[] { // Process the raw percentiles data so it is in a suitable format for plotting in the metric distribution chart. let chartData: MetricDistributionChartData[] = []; - const distribution = stats.distribution; if (distribution === undefined) { return chartData; } const percentiles: DistributionPercentile[] = distribution.percentiles; - if (percentiles.length === 0) { + if (percentiles?.length === 0) { return chartData; } diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx index ae5c7c9948f18..48618868035f9 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx @@ -45,6 +45,7 @@ export const IndexDataVisualizerPage: FC = () => { }, } = useMlKibana(); const mlLocator = useMlLocator()!; + const mlFeaturesDisabled = !isFullLicense(); getMlNodeCount(); const [IndexDataVisualizer, setIndexDataVisualizer] = useState( @@ -136,49 +137,55 @@ export const IndexDataVisualizerPage: FC = () => { const getAsyncRecognizedModuleCards = async (params: GetAdditionalLinksParams) => { const { dataViewId, dataViewTitle } = params; - const modules = await http.fetch( - `/api/ml/modules/recognize/${dataViewTitle}`, - { - method: 'GET', - } - ); - return modules?.map( - (m): ResultLink => ({ - id: m.id, - title: m.title, - description: m.description, - icon: m.logo.icon, - type: 'index', - getUrl: async () => { - return await mlLocator.getUrl({ - page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_RECOGNIZER, - pageState: { - id: m.id, - index: dataViewId, - }, - }); - }, - canDisplay: async () => { - try { - const { timeFieldName } = await getDataView(dataViewId); - return ( - isFullLicense() && - timeFieldName !== undefined && - checkPermission('canCreateJob') && - mlNodesAvailable() - ); - } catch (error) { - return false; - } - }, - 'data-test-subj': m.id, - }) - ); + try { + const modules = await http.fetch( + `/api/ml/modules/recognize/${dataViewTitle}`, + { + method: 'GET', + } + ); + return modules?.map( + (m): ResultLink => ({ + id: m.id, + title: m.title, + description: m.description, + icon: m.logo.icon, + type: 'index', + getUrl: async () => { + return await mlLocator.getUrl({ + page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_RECOGNIZER, + pageState: { + id: m.id, + index: dataViewId, + }, + }); + }, + canDisplay: async () => { + try { + const { timeFieldName } = await getDataView(dataViewId); + return ( + isFullLicense() && + timeFieldName !== undefined && + checkPermission('canCreateJob') && + mlNodesAvailable() + ); + } catch (error) { + return false; + } + }, + 'data-test-subj': m.id, + }) + ); + } catch (error) { + // eslint-disable-next-line no-console + console.error('Platinum, Enterprise or trial license needed'); + return []; + } }; const getAdditionalLinks: GetAdditionalLinks = useMemo( - () => [getAsyncRecognizedModuleCards, getAsyncMLCards], - [mlLocator] + () => (mlFeaturesDisabled ? [] : [getAsyncRecognizedModuleCards, getAsyncMLCards]), + [mlLocator, mlFeaturesDisabled] ); return IndexDataVisualizer ? (