diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/columns.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/columns.tsx index 194d59faccf3fd..19b51f76153454 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/columns.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/columns.tsx @@ -23,6 +23,7 @@ import { getAnalysisType, DataFrameAnalyticsId } from '../../../../common'; import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form'; import { getDataFrameAnalyticsProgress, + getDataFrameAnalyticsProgressPhase, isDataFrameAnalyticsFailed, isDataFrameAnalyticsRunning, isDataFrameAnalyticsStopped, @@ -72,22 +73,12 @@ export const getJobTypeBadge = (jobType: string) => ( export const progressColumn = { name: i18n.translate('xpack.ml.dataframe.analyticsList.progress', { - defaultMessage: 'Progress per Step', + defaultMessage: 'Progress', }), sortable: (item: DataFrameAnalyticsListRow) => getDataFrameAnalyticsProgress(item.stats), truncateText: true, render(item: DataFrameAnalyticsListRow) { - const totalSteps = item.stats.progress.length; - let step = 0; - let progress = 0; - - for (const progressStep of item.stats.progress) { - step++; - progress = progressStep.progress_percent; - if (progressStep.progress_percent < 100) { - break; - } - } + const { currentPhase, progress, totalPhases } = getDataFrameAnalyticsProgressPhase(item.stats); // For now all analytics jobs are batch jobs. const isBatchTransform = true; @@ -96,25 +87,30 @@ export const progressColumn = { {isBatchTransform && ( - - - {progress}% - - - - {`${progress}%`} - - + - {step}/{totalSteps} + Phase {currentPhase}/{totalPhases} + + + + + )} {!isBatchTransform && ( diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.test.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.test.ts index 19a3857f3f71c3..20cfad2b02c2cd 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.test.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.test.ts @@ -7,6 +7,8 @@ import StatsMock from './__mocks__/analytics_stats.json'; import { + getDataFrameAnalyticsProgress, + getDataFrameAnalyticsProgressPhase, isCompletedAnalyticsJob, isDataFrameAnalyticsRunning, isDataFrameAnalyticsStats, @@ -17,13 +19,15 @@ import { const completedJob = StatsMock.data_frame_analytics[0] as DataFrameAnalyticsStats; const runningJob = StatsMock.data_frame_analytics[1] as DataFrameAnalyticsStats; -describe('Data Frame Analytics: common utils', () => { - test('isCompletedAnalyticsJob()', () => { +describe('Data Frame Analytics: isCompletedAnalyticsJob()', () => { + test('should report if job is completed', () => { expect(isCompletedAnalyticsJob(completedJob)).toBe(true); expect(isCompletedAnalyticsJob(runningJob)).toBe(false); }); +}); - test('isDataFrameAnalyticsRunning()', () => { +describe('Data Frame Analytics: isDataFrameAnalyticsRunning()', () => { + test('should report if job is running', () => { expect(isDataFrameAnalyticsRunning(completedJob.state)).toBe(false); expect(isDataFrameAnalyticsRunning(runningJob.state)).toBe(true); runningJob.state = DATA_FRAME_TASK_STATE.STARTED; @@ -35,11 +39,35 @@ describe('Data Frame Analytics: common utils', () => { runningJob.state = DATA_FRAME_TASK_STATE.FAILED; expect(isDataFrameAnalyticsRunning(runningJob.state)).toBe(false); }); +}); - test('isDataFrameAnalyticsStats()', () => { +describe('Data Frame Analytics: isDataFrameAnalyticsStats()', () => { + test('should return if valid analytics stats', () => { expect(isDataFrameAnalyticsStats(completedJob)).toBe(true); expect(isDataFrameAnalyticsStats(runningJob)).toBe(true); expect(isDataFrameAnalyticsStats({})).toBe(false); expect(isDataFrameAnalyticsStats('no-object')).toBe(false); }); }); + +describe('Data Frame Analytics: getDataFrameAnalyticsProgress()', () => { + test('should report overall job progress percentage', () => { + expect(getDataFrameAnalyticsProgress(completedJob)).toBe(100); + expect(getDataFrameAnalyticsProgress(runningJob)).toBe(59); + }); +}); + +describe('Data Frame Analytics: getDataFrameAnalyticsProgressPhase()', () => { + test('should report progress by current phase', () => { + expect(getDataFrameAnalyticsProgressPhase(completedJob)).toStrictEqual({ + currentPhase: 4, + progress: 100, + totalPhases: 4, + }); + expect(getDataFrameAnalyticsProgressPhase(runningJob)).toStrictEqual({ + currentPhase: 3, + progress: 37, + totalPhases: 4, + }); + }); +}); diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts index 6f49e546981bbf..e0622efe35ab63 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/common.ts @@ -81,6 +81,22 @@ export function getDataFrameAnalyticsProgress(stats: DataFrameAnalyticsStats) { return undefined; } +export function getDataFrameAnalyticsProgressPhase( + stats: DataFrameAnalyticsStats +): { currentPhase: number; progress: number; totalPhases: number } { + let phase = 0; + let progress = 0; + + for (const progressPhase of stats.progress) { + phase++; + progress = progressPhase.progress_percent; + if (progressPhase.progress_percent < 100) { + break; + } + } + return { currentPhase: phase, progress, totalPhases: stats.progress.length }; +} + export interface DataFrameAnalyticsListRow { id: DataFrameAnalyticsId; checkpointing: object; diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx index adb6822c524ab0..94dc7ec87cc61a 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/analytics_list/expanded_row.tsx @@ -25,7 +25,7 @@ import { Eval, } from '../../../../common'; import { getTaskStateBadge } from './columns'; -import { isCompletedAnalyticsJob } from './common'; +import { getDataFrameAnalyticsProgressPhase, isCompletedAnalyticsJob } from './common'; import { isRegressionAnalysis, ANALYSIS_CONFIG_TYPE, @@ -171,14 +171,7 @@ export const ExpandedRow: FC = ({ item }) => { position: 'left', }; - const totalSteps = item.stats.progress.length; - let step = 0; - for (const progressStep of item.stats.progress) { - step++; - if (progressStep.progress_percent < 100) { - break; - } - } + const { currentPhase, totalPhases } = getDataFrameAnalyticsProgressPhase(item.stats); const progress: SectionConfig = { title: i18n.translate( @@ -188,10 +181,10 @@ export const ExpandedRow: FC = ({ item }) => { items: [ { title: i18n.translate( - 'xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.step', - { defaultMessage: 'Step' } + 'xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.phase', + { defaultMessage: 'Phase' } ), - description: `${step}/${totalSteps}`, + description: `${currentPhase}/${totalPhases}`, }, ...item.stats.progress.map(s => { return {