diff --git a/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx b/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx index 22344427e8d27..5130a511a92c3 100644 --- a/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx +++ b/x-pack/packages/ml/aiops_components/src/progress_controls/progress_controls.tsx @@ -57,7 +57,10 @@ export function ProgressControls({ {!isRunning && ( - + )} {isRunning && ( diff --git a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx index e37b301f36da3..f41ef5d8c88e2 100644 --- a/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx +++ b/x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx @@ -6,8 +6,18 @@ */ import React, { FC, useCallback, useMemo, useState } from 'react'; -import { EuiBadge, EuiBasicTable, EuiBasicTableColumn } from '@elastic/eui'; +import { + EuiBadge, + EuiBasicTable, + EuiBasicTableColumn, + EuiIcon, + EuiTableSortingType, + EuiToolTip, +} from '@elastic/eui'; +import { sortBy } from 'lodash'; + import { i18n } from '@kbn/i18n'; +import { FormattedMessage } from '@kbn/i18n-react'; import type { ChangePoint } from '@kbn/ml-agg-utils'; import { MiniHistogram } from '../mini_histogram'; @@ -18,6 +28,8 @@ const PAGINATION_SIZE_OPTIONS = [5, 10, 20, 50]; const noDataText = i18n.translate('xpack.aiops.correlations.correlationsTable.noDataText', { defaultMessage: 'No data', }); +const DEFAULT_SORT_FIELD = 'pValue'; +const DEFAULT_SORT_DIRECTION = 'asc'; interface SpikeAnalysisTableProps { changePoints: ChangePoint[]; @@ -38,6 +50,8 @@ export const SpikeAnalysisTable: FC = ({ }) => { const [pageIndex, setPageIndex] = useState(0); const [pageSize, setPageSize] = useState(10); + const [sortField, setSortField] = useState(DEFAULT_SORT_FIELD); + const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>(DEFAULT_SORT_DIRECTION); const columns: Array> = [ { @@ -60,14 +74,24 @@ export const SpikeAnalysisTable: FC = ({ { field: 'pValue', name: ( - <> - {i18n.translate( - 'xpack.aiops.correlations.failedTransactions.correlationsTable.logRateLabel', + + > + <> + + + + ), render: (_, { histogram, fieldName, fieldValue }) => { return histogram ? ( @@ -78,21 +102,49 @@ export const SpikeAnalysisTable: FC = ({ }, { field: 'pValue', - name: 'p-value', + name: ( + + <> + + + + + ), render: (pValue: number) => pValue.toPrecision(3), sortable: true, }, { field: 'pValue', name: ( - <> - {i18n.translate( - 'xpack.aiops.correlations.failedTransactions.correlationsTable.impactLabel', + + > + <> + + + + ), render: (_, { pValue }) => { const label = getFailedTransactionsCorrelationImpactLabel(pValue); @@ -104,30 +156,44 @@ export const SpikeAnalysisTable: FC = ({ const onChange = useCallback((tableSettings) => { const { index, size } = tableSettings.page; + const { field, direction } = tableSettings.sort; setPageIndex(index); setPageSize(size); + setSortField(field); + setSortDirection(direction); }, []); - const { pagination, pageOfItems } = useMemo(() => { + const { pagination, pageOfItems, sorting } = useMemo(() => { const pageStart = pageIndex * pageSize; - const itemCount = changePoints?.length ?? 0; + + let items: ChangePoint[] = changePoints ?? []; + items = sortBy(changePoints, (item) => { + if (item && typeof item[sortField] === 'string') { + // @ts-ignore Object is possibly null or undefined + return item[sortField].toLowerCase(); + } + return item[sortField]; + }); + items = sortDirection === 'asc' ? items : items.reverse(); + return { - pageOfItems: changePoints - // Temporary default sorting by ascending pValue until we add native table sorting - ?.sort((a, b) => { - return (a?.pValue ?? 1) - (b?.pValue ?? 0); - }) - .slice(pageStart, pageStart + pageSize), + pageOfItems: items.slice(pageStart, pageStart + pageSize), pagination: { pageIndex, pageSize, totalItemCount: itemCount, pageSizeOptions: PAGINATION_SIZE_OPTIONS, }, + sorting: { + sort: { + field: sortField, + direction: sortDirection, + }, + }, }; - }, [pageIndex, pageSize, changePoints]); + }, [pageIndex, pageSize, sortField, sortDirection, changePoints]); return ( = ({ pagination={pagination} loading={loading} error={error} - // sorting={sorting} + sorting={sorting as EuiTableSortingType} rowProps={(changePoint) => { return { onClick: () => {