From 45155f089d96853ad489fdae149a52272d20529a Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 23 Feb 2021 17:34:59 +0100 Subject: [PATCH] [ML] Show mini histograms by default if row count below threshold. (#92021) Show mini histograms by default if row count below threshold of 10000 docs. --- x-pack/plugins/ml/common/index.ts | 2 +- x-pack/plugins/ml/common/types/es_client.ts | 8 +++++- .../components/data_grid/common.ts | 1 + .../components/data_grid/data_grid.tsx | 5 ++-- .../application/components/data_grid/index.ts | 1 + .../application/components/data_grid/types.ts | 10 ++++++- .../components/data_grid/use_data_grid.tsx | 28 +++++++++++++++++-- .../common/get_index_data.ts | 2 ++ .../configuration_step_form.tsx | 25 +++++++++++++---- .../configuration_step/use_saved_search.ts | 18 ++++++++++-- .../hooks/use_index_data.ts | 19 +++++++------ .../expandable_section_results.tsx | 11 ++++++-- x-pack/plugins/ml/public/index.ts | 1 + .../job_validation/job_validation.test.ts | 4 ++- .../transform/common/shared_imports.ts | 3 +- .../public/__mocks__/shared_imports.ts | 2 +- .../public/app/hooks/__mocks__/use_api.ts | 2 +- .../public/app/hooks/use_index_data.ts | 2 ++ .../public/app/hooks/use_pivot_data.ts | 6 +++- .../transform/public/shared_imports.ts | 1 + x-pack/test/accessibility/apps/ml.ts | 2 +- .../outlier_detection_creation.ts | 2 +- .../apps/transform/creation_index_pattern.ts | 2 +- .../ml/data_frame_analytics_creation.ts | 10 ++++--- .../functional/services/transform/wizard.ts | 10 ++++--- 25 files changed, 135 insertions(+), 42 deletions(-) diff --git a/x-pack/plugins/ml/common/index.ts b/x-pack/plugins/ml/common/index.ts index 9c8131a98f89..c049b68990d2 100644 --- a/x-pack/plugins/ml/common/index.ts +++ b/x-pack/plugins/ml/common/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -export { SearchResponse7 } from './types/es_client'; +export { HitsTotalRelation, SearchResponse7, HITS_TOTAL_RELATION } from './types/es_client'; export { ANOMALY_SEVERITY, ANOMALY_THRESHOLD, SEVERITY_COLORS } from './constants/anomalies'; export { getSeverityColor, getSeverityType } from './util/anomaly_utils'; export { composeValidators, patternValidator } from './util/validators'; diff --git a/x-pack/plugins/ml/common/types/es_client.ts b/x-pack/plugins/ml/common/types/es_client.ts index 767e8a18cb98..0674ec600115 100644 --- a/x-pack/plugins/ml/common/types/es_client.ts +++ b/x-pack/plugins/ml/common/types/es_client.ts @@ -7,13 +7,19 @@ import { SearchResponse, ShardsResponse } from 'elasticsearch'; +export const HITS_TOTAL_RELATION = { + EQ: 'eq', + GTE: 'gte', +} as const; +export type HitsTotalRelation = typeof HITS_TOTAL_RELATION[keyof typeof HITS_TOTAL_RELATION]; + // The types specified in `@types/elasticsearch` are out of date and still have `total: number`. interface SearchResponse7Hits { hits: SearchResponse['hits']['hits']; max_score: number; total: { value: number; - relation: string; + relation: HitsTotalRelation; }; } export interface SearchResponse7 { diff --git a/x-pack/plugins/ml/public/application/components/data_grid/common.ts b/x-pack/plugins/ml/public/application/components/data_grid/common.ts index 069c13df2470..c2a1af4824c2 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/common.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/common.ts @@ -53,6 +53,7 @@ import { RuntimeMappings } from '../../../../common/types/fields'; import { isPopulatedObject } from '../../../../common/util/object_utils'; export const INIT_MAX_COLUMNS = 10; +export const COLUMN_CHART_DEFAULT_VISIBILITY_ROWS_THRESHOLED = 10000; export const euiDataGridStyle: EuiDataGridStyle = { border: 'all', diff --git a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx index 5dad9801eb64..f4c6a41f697c 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx +++ b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx @@ -312,15 +312,16 @@ export const DataGrid: FC = memo( })} > {i18n.translate('xpack.ml.dataGrid.histogramButtonText', { defaultMessage: 'Histogram charts', diff --git a/x-pack/plugins/ml/public/application/components/data_grid/index.ts b/x-pack/plugins/ml/public/application/components/data_grid/index.ts index 79a8d65f9905..a3f199573662 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/index.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/index.ts @@ -23,6 +23,7 @@ export { DataGridItem, EsSorting, RenderCellValue, + RowCountRelation, UseDataGridReturnType, UseIndexDataReturnType, } from './types'; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/types.ts b/x-pack/plugins/ml/public/application/components/data_grid/types.ts index e57579809f7d..77c7bdb38546 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/types.ts +++ b/x-pack/plugins/ml/public/application/components/data_grid/types.ts @@ -10,6 +10,7 @@ import { Dispatch, SetStateAction } from 'react'; import { EuiDataGridPaginationProps, EuiDataGridSorting, EuiDataGridColumn } from '@elastic/eui'; import { Dictionary } from '../../../../common/types/common'; +import { HitsTotalRelation } from '../../../../common/types/es_client'; import { INDEX_STATUS } from '../../data_frame_analytics/common/analytics'; @@ -19,6 +20,10 @@ import { FeatureImportanceBaseline } from '../../../../common/types/feature_impo export type ColumnId = string; export type DataGridItem = Record; +// `undefined` is used to indicate a non-initialized state. +export type ChartsVisible = boolean | undefined; +export type RowCountRelation = HitsTotalRelation | undefined; + export type IndexPagination = Pick; export type OnChangeItemsPerPage = (pageSize: any) => void; @@ -60,6 +65,7 @@ export interface UseIndexDataReturnType | 'setPagination' | 'setVisibleColumns' | 'rowCount' + | 'rowCountRelation' | 'sortingColumns' | 'status' | 'tableItems' @@ -73,7 +79,7 @@ export interface UseIndexDataReturnType } export interface UseDataGridReturnType { - chartsVisible: boolean; + chartsVisible: ChartsVisible; chartsButtonVisible: boolean; columnsWithCharts: EuiDataGridColumn[]; errorMessage: string; @@ -85,11 +91,13 @@ export interface UseDataGridReturnType { pagination: IndexPagination; resetPagination: () => void; rowCount: number; + rowCountRelation: RowCountRelation; setColumnCharts: Dispatch>; setErrorMessage: Dispatch>; setNoDataMessage: Dispatch>; setPagination: Dispatch>; setRowCount: Dispatch>; + setRowCountRelation: Dispatch>; setSortingColumns: Dispatch>; setStatus: Dispatch>; setTableItems: Dispatch>; diff --git a/x-pack/plugins/ml/public/application/components/data_grid/use_data_grid.tsx b/x-pack/plugins/ml/public/application/components/data_grid/use_data_grid.tsx index b3a034d6614f..4129f3a01bce 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/use_data_grid.tsx +++ b/x-pack/plugins/ml/public/application/components/data_grid/use_data_grid.tsx @@ -9,17 +9,21 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { EuiDataGridSorting, EuiDataGridColumn } from '@elastic/eui'; +import { HITS_TOTAL_RELATION } from '../../../../common/types/es_client'; + import { INDEX_STATUS } from '../../data_frame_analytics/common'; import { ColumnChart } from './column_chart'; -import { INIT_MAX_COLUMNS } from './common'; +import { COLUMN_CHART_DEFAULT_VISIBILITY_ROWS_THRESHOLED, INIT_MAX_COLUMNS } from './common'; import { + ChartsVisible, ColumnId, DataGridItem, IndexPagination, OnChangeItemsPerPage, OnChangePage, OnSort, + RowCountRelation, UseDataGridReturnType, } from './types'; import { ChartData } from './use_column_chart'; @@ -36,14 +40,17 @@ export const useDataGrid = ( const [errorMessage, setErrorMessage] = useState(''); const [status, setStatus] = useState(INDEX_STATUS.UNUSED); const [rowCount, setRowCount] = useState(0); + const [rowCountRelation, setRowCountRelation] = useState(undefined); const [columnCharts, setColumnCharts] = useState([]); const [tableItems, setTableItems] = useState([]); const [pagination, setPagination] = useState(defaultPagination); const [sortingColumns, setSortingColumns] = useState([]); - const [chartsVisible, setChartsVisible] = useState(false); + const [chartsVisible, setChartsVisible] = useState(undefined); const toggleChartVisibility = () => { - setChartsVisible(!chartsVisible); + if (chartsVisible !== undefined) { + setChartsVisible(!chartsVisible); + } }; const onChangeItemsPerPage: OnChangeItemsPerPage = useCallback((pageSize) => { @@ -131,6 +138,19 @@ export const useDataGrid = ( }); }, [columns, columnCharts, chartsVisible, JSON.stringify(visibleColumns)]); + // Initialize the mini histogram charts toggle button. + // On load `chartsVisible` is set to `undefined`, the button will be disabled. + // Once we know how many rows have been returned, + // we decide whether to show or hide the charts by default. + useEffect(() => { + if (chartsVisible === undefined && rowCount > 0 && rowCountRelation !== undefined) { + setChartsVisible( + rowCount <= COLUMN_CHART_DEFAULT_VISIBILITY_ROWS_THRESHOLED && + rowCountRelation !== HITS_TOTAL_RELATION.GTE + ); + } + }, [chartsVisible, rowCount, rowCountRelation]); + return { chartsVisible, chartsButtonVisible: true, @@ -144,11 +164,13 @@ export const useDataGrid = ( pagination, resetPagination, rowCount, + rowCountRelation, setColumnCharts, setErrorMessage, setNoDataMessage, setPagination, setRowCount, + setRowCountRelation, setSortingColumns, setStatus, setTableItems, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts index 47af92c79072..d0bcbd2ff63b 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/common/get_index_data.ts @@ -28,6 +28,7 @@ export const getIndexData = async ( pagination, setErrorMessage, setRowCount, + setRowCountRelation, setStatus, setTableItems, sortingColumns, @@ -64,6 +65,7 @@ export const getIndexData = async ( if (!options.didCancel) { setRowCount(resp.hits.total.value); + setRowCountRelation(resp.hits.total.relation); setTableItems( resp.hits.hits.map((d) => getProcessedFields(d.fields, (key: string) => diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx index 07331c208482..aa008192bbce 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/configuration_step_form.tsx @@ -49,13 +49,22 @@ import { DataGrid } from '../../../../../components/data_grid'; import { fetchExplainData } from '../shared'; import { useIndexData } from '../../hooks'; import { ExplorationQueryBar } from '../../../analytics_exploration/components/exploration_query_bar'; -import { useSavedSearch } from './use_saved_search'; +import { useSavedSearch, SavedSearchQuery } from './use_saved_search'; import { SEARCH_QUERY_LANGUAGE } from '../../../../../../../common/constants/search'; import { ExplorationQueryBarProps } from '../../../analytics_exploration/components/exploration_query_bar/exploration_query_bar'; import { Query } from '../../../../../../../../../../src/plugins/data/common/query'; import { ScatterplotMatrix } from '../../../../../components/scatterplot_matrix'; +function getIndexDataQuery(savedSearchQuery: SavedSearchQuery, jobConfigQuery: any) { + // Return `undefined` if savedSearchQuery itself is `undefined`, meaning it hasn't been initialized yet. + if (savedSearchQuery === undefined) { + return; + } + + return savedSearchQuery !== null ? savedSearchQuery : jobConfigQuery; +} + const requiredFieldsErrorText = i18n.translate( 'xpack.ml.dataframe.analytics.createWizard.requiredFieldsErrorMessage', { @@ -130,7 +139,7 @@ export const ConfigurationStepForm: FC = ({ const indexData = useIndexData( currentIndexPattern, - savedSearchQuery !== undefined ? savedSearchQuery : jobConfigQuery, + getIndexDataQuery(savedSearchQuery, jobConfigQuery), toastNotifications ); @@ -296,7 +305,7 @@ export const ConfigurationStepForm: FC = ({ }, []); useEffect(() => { - if (savedSearchQueryStr !== undefined) { + if (typeof savedSearchQueryStr === 'string') { setFormState({ jobConfigQuery: savedSearchQuery, jobConfigQueryString: savedSearchQueryStr }); } }, [JSON.stringify(savedSearchQuery), savedSearchQueryStr]); @@ -343,12 +352,16 @@ export const ConfigurationStepForm: FC = ({ !dependentVariableEmpty)) && scatterplotFieldOptions.length > 1; + // Don't render until `savedSearchQuery` has been initialized. + // `undefined` means uninitialized, `null` means initialized but not used. + if (savedSearchQuery === undefined) return null; + return ( - {savedSearchQuery === undefined && ( + {savedSearchQuery === null && ( = ({ - {savedSearchQuery !== undefined && ( + {savedSearchQuery !== null && ( {i18n.translate('xpack.ml.dataframe.analytics.create.savedSearchLabel', { defaultMessage: 'Saved search', @@ -373,7 +386,7 @@ export const ConfigurationStepForm: FC = ({ )} - {savedSearchQuery !== undefined + {savedSearchQuery !== null ? currentSavedSearch?.attributes.title : currentIndexPattern.title} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts index 7c3349c7bc1f..551a576ac619 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/components/configuration_step/use_saved_search.ts @@ -11,9 +11,20 @@ import { esQuery, esKuery } from '../../../../../../../../../../src/plugins/data import { SEARCH_QUERY_LANGUAGE } from '../../../../../../../common/constants/search'; import { getQueryFromSavedSearch } from '../../../../../util/index_utils'; +// `undefined` is used for a non-initialized state +// `null` is set if no saved search is used +export type SavedSearchQuery = Record | null | undefined; +export type SavedSearchQueryStr = + | string + | { + [key: string]: any; + } + | null + | undefined; + export function useSavedSearch() { - const [savedSearchQuery, setSavedSearchQuery] = useState(undefined); - const [savedSearchQueryStr, setSavedSearchQueryStr] = useState(undefined); + const [savedSearchQuery, setSavedSearchQuery] = useState(undefined); + const [savedSearchQueryStr, setSavedSearchQueryStr] = useState(undefined); const mlContext = useMlContext(); const { currentSavedSearch, currentIndexPattern, kibanaConfig } = mlContext; @@ -37,6 +48,9 @@ export function useSavedSearch() { setSavedSearchQuery(qry); setSavedSearchQueryStr(qryString); + } else { + setSavedSearchQuery(null); + setSavedSearchQueryStr(null); } }; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts index 8d6fc25a36ec..ecda624c71d9 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_creation/hooks/use_index_data.ts @@ -36,7 +36,7 @@ type IndexSearchResponse = SearchResponse7; export const useIndexData = ( indexPattern: IndexPattern, - query: any, + query: Record | undefined, toastNotifications: CoreSetup['notifications']['toasts'] ): UseIndexDataReturnType => { const indexPatternFields = useMemo(() => getFieldsFromKibanaIndexPattern(indexPattern), [ @@ -59,6 +59,7 @@ export const useIndexData = ( resetPagination, setErrorMessage, setRowCount, + setRowCountRelation, setStatus, setTableItems, sortingColumns, @@ -81,8 +82,7 @@ export const useIndexData = ( const esSearchRequest = { index: indexPattern.title, body: { - // Instead of using the default query (`*`), fall back to a more efficient `match_all` query. - query, // isDefaultQuery(query) ? matchAllQuery : query, + query, from: pagination.pageIndex * pagination.pageSize, size: pagination.pageSize, fields: ['*'], @@ -97,6 +97,7 @@ export const useIndexData = ( const docs = resp.hits.hits.map((d) => getProcessedFields(d.fields)); setRowCount(resp.hits.total.value); + setRowCountRelation(resp.hits.total.relation); setTableItems(docs); setStatus(INDEX_STATUS.LOADED); } catch (e) { @@ -106,7 +107,9 @@ export const useIndexData = ( }; useEffect(() => { - getIndexData(); + if (query !== undefined) { + getIndexData(); + } // custom comparison }, [indexPattern.title, indexPatternFields, JSON.stringify([query, pagination, sortingColumns])]); @@ -114,7 +117,7 @@ export const useIndexData = ( indexPattern, ]); - const fetchColumnChartsData = async function () { + const fetchColumnChartsData = async function (fieldHistogramsQuery: Record) { try { const columnChartsData = await dataLoader.loadFieldHistograms( columns @@ -123,7 +126,7 @@ export const useIndexData = ( fieldName: cT.id, type: getFieldType(cT.schema), })), - query + fieldHistogramsQuery ); dataGrid.setColumnCharts(columnChartsData); } catch (e) { @@ -132,8 +135,8 @@ export const useIndexData = ( }; useEffect(() => { - if (dataGrid.chartsVisible) { - fetchColumnChartsData(); + if (dataGrid.chartsVisible && query !== undefined) { + fetchColumnChartsData(query); } // custom comparison }, [ diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx index e0080d2a881a..654af03d102e 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/expandable_section/expandable_section_results.tsx @@ -18,10 +18,15 @@ import { isClassificationAnalysis, isRegressionAnalysis, } from '../../../../../../../common/util/analytics_utils'; +import { HITS_TOTAL_RELATION } from '../../../../../../../common/types/es_client'; import { getToastNotifications } from '../../../../../util/dependency_cache'; import { useColorRange, ColorRangeLegend } from '../../../../../components/color_range_legend'; -import { DataGrid, UseIndexDataReturnType } from '../../../../../components/data_grid'; +import { + DataGrid, + RowCountRelation, + UseIndexDataReturnType, +} from '../../../../../components/data_grid'; import { SavedSearchQuery } from '../../../../../contexts/ml'; import { @@ -59,6 +64,7 @@ const getResultsSectionHeaderItems = ( status: INDEX_STATUS, tableItems: Array>, rowCount: number, + rowCountRelation: RowCountRelation, colorRange?: ReturnType ): ExpandableSectionProps['headerItems'] => { return columnsWithCharts.length > 0 && (tableItems.length > 0 || status === INDEX_STATUS.LOADED) @@ -71,7 +77,7 @@ const getResultsSectionHeaderItems = ( defaultMessage="Total docs" /> ), - value: rowCount, + value: `${rowCountRelation === HITS_TOTAL_RELATION.GTE ? '>' : ''}${rowCount}`, }, ...(colorRange !== undefined ? [ @@ -120,6 +126,7 @@ export const ExpandableSectionResults: FC = ({ status, tableItems, indexData.rowCount, + indexData.rowCountRelation, colorRange ); const analysisType = diff --git a/x-pack/plugins/ml/public/index.ts b/x-pack/plugins/ml/public/index.ts index c88ce2d7f95d..9280f4603b34 100755 --- a/x-pack/plugins/ml/public/index.ts +++ b/x-pack/plugins/ml/public/index.ts @@ -50,6 +50,7 @@ export { getSeverityType, getFormattedSeverityScore, } from '../common/util/anomaly_utils'; +export { HITS_TOTAL_RELATION } from '../common/types/es_client'; export { ANOMALY_SEVERITY } from '../common'; export { useMlHref, ML_PAGES, MlUrlGenerator } from './ml_url_generator'; diff --git a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts index ec2d852d0e29..c3c3d52465d4 100644 --- a/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts +++ b/x-pack/plugins/ml/server/models/job_validation/job_validation.test.ts @@ -9,11 +9,13 @@ import { IScopedClusterClient } from 'kibana/server'; import { validateJob, ValidateJobPayload } from './job_validation'; import { JobValidationMessage } from '../../../common/constants/messages'; +import { HITS_TOTAL_RELATION } from '../../../common/types/es_client'; import type { MlClient } from '../../lib/ml_client'; const callAs = { fieldCaps: () => Promise.resolve({ body: { fields: [] } }), - search: () => Promise.resolve({ body: { hits: { total: { value: 1, relation: 'eq' } } } }), + search: () => + Promise.resolve({ body: { hits: { total: { value: 1, relation: HITS_TOTAL_RELATION.EQ } } } }), }; const mlClusterClient = ({ diff --git a/x-pack/plugins/transform/common/shared_imports.ts b/x-pack/plugins/transform/common/shared_imports.ts index a2fde05a5440..4506083a1876 100644 --- a/x-pack/plugins/transform/common/shared_imports.ts +++ b/x-pack/plugins/transform/common/shared_imports.ts @@ -5,5 +5,6 @@ * 2.0. */ -export type { SearchResponse7 } from '../../ml/common'; +export type { HitsTotalRelation, SearchResponse7 } from '../../ml/common'; +export { HITS_TOTAL_RELATION } from '../../ml/common'; export { composeValidators, patternValidator } from '../../ml/common'; diff --git a/x-pack/plugins/transform/public/__mocks__/shared_imports.ts b/x-pack/plugins/transform/public/__mocks__/shared_imports.ts index 628cabec5ecc..00a92865789f 100644 --- a/x-pack/plugins/transform/public/__mocks__/shared_imports.ts +++ b/x-pack/plugins/transform/public/__mocks__/shared_imports.ts @@ -16,4 +16,4 @@ export const useRequest = jest.fn(() => ({ export const createSavedSearchesLoader = jest.fn(); // just passing through the reimports -export { getMlSharedImports } from '../../../ml/public'; +export { getMlSharedImports, HITS_TOTAL_RELATION } from '../../../ml/public'; diff --git a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts index ac5b3e2592ad..7aaca793c2a1 100644 --- a/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts +++ b/x-pack/plugins/transform/public/app/hooks/__mocks__/use_api.ts @@ -140,7 +140,7 @@ const apiFactory = () => ({ hits: [], total: { value: 0, - relation: 'the-relation', + relation: 'eq', }, max_score: 0, }, diff --git a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts index abc63d886dbc..dde4c7eb0f3a 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_index_data.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_index_data.ts @@ -87,6 +87,7 @@ export const useIndexData = ( setColumnCharts, setErrorMessage, setRowCount, + setRowCountRelation, setStatus, setTableItems, sortingColumns, @@ -135,6 +136,7 @@ export const useIndexData = ( const docs = resp.hits.hits.map((d) => getProcessedFields(d.fields)); setRowCount(resp.hits.total.value); + setRowCountRelation(resp.hits.total.relation); setTableItems(docs); setStatus(INDEX_STATUS.LOADED); }; diff --git a/x-pack/plugins/transform/public/app/hooks/use_pivot_data.ts b/x-pack/plugins/transform/public/app/hooks/use_pivot_data.ts index 62b3a077df5e..32d8ed16a643 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_pivot_data.ts +++ b/x-pack/plugins/transform/public/app/hooks/use_pivot_data.ts @@ -18,7 +18,7 @@ import type { PreviewMappingsProperties } from '../../../common/api_schemas/tran import { isPostTransformsPreviewResponseSchema } from '../../../common/api_schemas/type_guards'; import { getNestedProperty } from '../../../common/utils/object_utils'; -import { RenderCellValue, UseIndexDataReturnType } from '../../shared_imports'; +import { RenderCellValue, UseIndexDataReturnType, HITS_TOTAL_RELATION } from '../../shared_imports'; import { getErrorMessage } from '../../../common/utils/errors'; import { useAppDependencies } from '../app_dependencies'; @@ -117,6 +117,7 @@ export const usePivotData = ( setErrorMessage, setNoDataMessage, setRowCount, + setRowCountRelation, setStatus, setTableItems, sortingColumns, @@ -127,6 +128,7 @@ export const usePivotData = ( if (!validationStatus.isValid) { setTableItems([]); setRowCount(0); + setRowCountRelation(HITS_TOTAL_RELATION.EQ); setNoDataMessage(validationStatus.errorMessage!); return; } @@ -147,6 +149,7 @@ export const usePivotData = ( setErrorMessage(getErrorMessage(resp)); setTableItems([]); setRowCount(0); + setRowCountRelation(HITS_TOTAL_RELATION.EQ); setPreviewMappingsProperties({}); setStatus(INDEX_STATUS.ERROR); return; @@ -154,6 +157,7 @@ export const usePivotData = ( setTableItems(resp.preview); setRowCount(resp.preview.length); + setRowCountRelation(HITS_TOTAL_RELATION.EQ); setPreviewMappingsProperties(resp.generated_dest_index.mappings.properties); setStatus(INDEX_STATUS.LOADED); diff --git a/x-pack/plugins/transform/public/shared_imports.ts b/x-pack/plugins/transform/public/shared_imports.ts index 1a219e97ddcf..ddf5cf7cb5cb 100644 --- a/x-pack/plugins/transform/public/shared_imports.ts +++ b/x-pack/plugins/transform/public/shared_imports.ts @@ -15,6 +15,7 @@ export { UseIndexDataReturnType, EsSorting, RenderCellValue, + HITS_TOTAL_RELATION, } from '../../ml/public'; import { XJson } from '../../../../src/plugins/es_ui_shared/public'; diff --git a/x-pack/test/accessibility/apps/ml.ts b/x-pack/test/accessibility/apps/ml.ts index 0dbc7cbb041d..323fe5d783c7 100644 --- a/x-pack/test/accessibility/apps/ml.ts +++ b/x-pack/test/accessibility/apps/ml.ts @@ -265,7 +265,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('displays the source data preview'); await ml.dataFrameAnalyticsCreation.assertSourceDataPreviewExists(); await ml.testExecution.logTestStep('enables the source data preview histogram charts'); - await ml.dataFrameAnalyticsCreation.enableSourceDataPreviewHistogramCharts(); + await ml.dataFrameAnalyticsCreation.enableSourceDataPreviewHistogramCharts(true); await ml.testExecution.logTestStep('displays the include fields selection'); await ml.dataFrameAnalyticsCreation.assertIncludeFieldsSelectionExists(); // EuiDataGrid does not have row roles diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts index 8b291fa36867..33bb05abbbb8 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/outlier_detection_creation.ts @@ -117,7 +117,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataFrameAnalyticsCreation.assertSourceDataPreviewExists(); await ml.testExecution.logTestStep('enables the source data preview histogram charts'); - await ml.dataFrameAnalyticsCreation.enableSourceDataPreviewHistogramCharts(); + await ml.dataFrameAnalyticsCreation.enableSourceDataPreviewHistogramCharts(true); await ml.testExecution.logTestStep('displays the source data preview histogram charts'); await ml.dataFrameAnalyticsCreation.assertSourceDataPreviewHistogramCharts( diff --git a/x-pack/test/functional/apps/transform/creation_index_pattern.ts b/x-pack/test/functional/apps/transform/creation_index_pattern.ts index c28b3cfec85a..fbd98e506738 100644 --- a/x-pack/test/functional/apps/transform/creation_index_pattern.ts +++ b/x-pack/test/functional/apps/transform/creation_index_pattern.ts @@ -396,7 +396,7 @@ export default function ({ getService }: FtrProviderContext) { await transform.wizard.assertAdvancedQueryEditorSwitchCheckState(false); await transform.testExecution.logTestStep('enables the index preview histogram charts'); - await transform.wizard.enableIndexPreviewHistogramCharts(); + await transform.wizard.enableIndexPreviewHistogramCharts(true); await transform.testExecution.logTestStep('displays the index preview histogram charts'); await transform.wizard.assertIndexPreviewHistogramCharts( diff --git a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts index 66c259912743..509f6170a20f 100644 --- a/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts +++ b/x-pack/test/functional/services/ml/data_frame_analytics_creation.ts @@ -116,10 +116,12 @@ export function MachineLearningDataFrameAnalyticsCreationProvider( await testSubjects.existOrFail('mlAnalyticsCreationDataGridHistogramButton'); }, - async enableSourceDataPreviewHistogramCharts() { - await this.assertSourceDataPreviewHistogramChartButtonCheckState(false); - await testSubjects.click('mlAnalyticsCreationDataGridHistogramButton'); - await this.assertSourceDataPreviewHistogramChartButtonCheckState(true); + async enableSourceDataPreviewHistogramCharts(expectedDefaultButtonState: boolean) { + await this.assertSourceDataPreviewHistogramChartButtonCheckState(expectedDefaultButtonState); + if (expectedDefaultButtonState === false) { + await testSubjects.click('mlAnalyticsCreationDataGridHistogramButton'); + await this.assertSourceDataPreviewHistogramChartButtonCheckState(true); + } }, async assertSourceDataPreviewHistogramChartButtonCheckState(expectedCheckState: boolean) { diff --git a/x-pack/test/functional/services/transform/wizard.ts b/x-pack/test/functional/services/transform/wizard.ts index 518accdeaf47..95695656130a 100644 --- a/x-pack/test/functional/services/transform/wizard.ts +++ b/x-pack/test/functional/services/transform/wizard.ts @@ -177,10 +177,12 @@ export function TransformWizardProvider({ getService }: FtrProviderContext) { await testSubjects.existOrFail('transformIndexPreviewHistogramButton'); }, - async enableIndexPreviewHistogramCharts() { - await this.assertIndexPreviewHistogramChartButtonCheckState(false); - await testSubjects.click('transformIndexPreviewHistogramButton'); - await this.assertIndexPreviewHistogramChartButtonCheckState(true); + async enableIndexPreviewHistogramCharts(expectedDefaultButtonState: boolean) { + await this.assertIndexPreviewHistogramChartButtonCheckState(expectedDefaultButtonState); + if (expectedDefaultButtonState === false) { + await testSubjects.click('transformIndexPreviewHistogramButton'); + await this.assertIndexPreviewHistogramChartButtonCheckState(true); + } }, async assertIndexPreviewHistogramChartButtonCheckState(expectedCheckState: boolean) {