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 b97ddb2690982..08b2d48a982d6 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 @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useMemo, useState } from 'react'; import { EuiDataGridSorting, EuiDataGridColumn } from '@elastic/eui'; @@ -93,10 +93,8 @@ export const useDataGrid = ( [columns] ); - return { - chartsVisible, - chartsButtonVisible: true, - columnsWithCharts: columns.map((c, index) => { + const columnsWithCharts = useMemo(() => { + const updatedColumns = columns.map((c, index) => { const chartData = columnCharts.find((cd) => cd.id === c.id); return { @@ -110,7 +108,32 @@ export const useDataGrid = ( /> ) : undefined, }; - }), + }); + + // Sort the columns to be in line with the current order of visible columns. + // EuiDataGrid misses a callback for the order of all available columns, so + // this only can retain the order of visible columns. + return updatedColumns.sort((a, b) => { + // This will always move visible columns above invisible ones. + if (visibleColumns.indexOf(a.id) === -1 && visibleColumns.indexOf(b.id) > -1) { + return 1; + } + if (visibleColumns.indexOf(b.id) === -1 && visibleColumns.indexOf(a.id) > -1) { + return -1; + } + if (visibleColumns.indexOf(a.id) === -1 && visibleColumns.indexOf(b.id) === -1) { + return a.id.localeCompare(b.id); + } + + // If both columns are visible sort by their visible sorting order. + return visibleColumns.indexOf(a.id) - visibleColumns.indexOf(b.id); + }); + }, [columns, columnCharts, chartsVisible, JSON.stringify(visibleColumns)]); + + return { + chartsVisible, + chartsButtonVisible: true, + columnsWithCharts, errorMessage, invalidSortingColumnns, noDataMessage, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx index 06bcdfd364d66..c837fcbacdd55 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_query_bar/exploration_query_bar.tsx @@ -149,11 +149,11 @@ export const ExplorationQueryBar: FC = ({ placeholder={ searchInput.language === SEARCH_QUERY_LANGUAGE.KUERY ? i18n.translate('xpack.ml.stepDefineForm.queryPlaceholderKql', { - defaultMessage: 'e.g. {example}', + defaultMessage: 'Search for e.g. {example}', values: { example: 'method : "GET" or status : "404"' }, }) : i18n.translate('xpack.ml.stepDefineForm.queryPlaceholderLucene', { - defaultMessage: 'e.g. {example}', + defaultMessage: 'Search for e.g. {example}', values: { example: 'method:GET OR status:404' }, }) } diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts index eded8e82a7919..88aa06808e8a7 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/outlier_exploration/use_outlier_data.ts @@ -52,17 +52,21 @@ export const useOutlierData = ( const needsDestIndexFields = indexPattern !== undefined && indexPattern.title === jobConfig?.source.index[0]; - const columns: EuiDataGridColumn[] = []; - - if (jobConfig !== undefined && indexPattern !== undefined) { - const resultsField = jobConfig.dest.results_field; - const { fieldTypes } = getIndexFields(jobConfig, needsDestIndexFields); - columns.push( - ...getDataGridSchemasFromFieldTypes(fieldTypes, resultsField).sort((a: any, b: any) => - sortExplorationResultsFields(a.id, b.id, jobConfig) - ) - ); - } + const columns = useMemo(() => { + const newColumns: EuiDataGridColumn[] = []; + + if (jobConfig !== undefined && indexPattern !== undefined) { + const resultsField = jobConfig.dest.results_field; + const { fieldTypes } = getIndexFields(jobConfig, needsDestIndexFields); + newColumns.push( + ...getDataGridSchemasFromFieldTypes(fieldTypes, resultsField).sort((a: any, b: any) => + sortExplorationResultsFields(a.id, b.id, jobConfig) + ) + ); + } + + return newColumns; + }, [jobConfig, indexPattern]); const dataGrid = useDataGrid( columns, @@ -124,7 +128,10 @@ export const useOutlierData = ( }, [ dataGrid.chartsVisible, jobConfig?.dest.index, - JSON.stringify([searchQuery, dataGrid.visibleColumns]), + // Only trigger when search or the visible columns changes. + // We're only interested in the visible columns but not their order, that's + // why we sort for comparison (and copying it via spread to avoid sort in place). + JSON.stringify([searchQuery, [...dataGrid.visibleColumns].sort()]), ]); const colorRange = useColorRange(