mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 11:05:39 -04:00
[ML] DF Analytics creation wizard: show link to results (#74025)
* show view results card once job complete * update types * update types and move css to own file
This commit is contained in:
parent
8759646576
commit
3fb77fb546
10 changed files with 201 additions and 86 deletions
|
@ -1,3 +1,4 @@
|
|||
@import 'pages/analytics_exploration/components/regression_exploration/index';
|
||||
@import 'pages/analytics_management/components/analytics_list/index';
|
||||
@import 'pages/analytics_management/components/create_analytics_button/index';
|
||||
@import 'pages/analytics_creation/components/index';
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.dfAnalyticsCreationWizard__card {
|
||||
width: 300px;
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import React, { FC, Fragment } from 'react';
|
||||
import { EuiCard, EuiHorizontalRule, EuiIcon } from '@elastic/eui';
|
||||
import { EuiCard, EuiIcon } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useNavigateToPath } from '../../../../../contexts/kibana';
|
||||
|
||||
|
@ -18,10 +18,8 @@ export const BackToListPanel: FC = () => {
|
|||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiHorizontalRule />
|
||||
<EuiCard
|
||||
// @ts-ignore
|
||||
style={{ width: '300px' }}
|
||||
className="dfAnalyticsCreationWizard__card"
|
||||
icon={<EuiIcon size="xxl" type="list" />}
|
||||
title={i18n.translate('xpack.ml.dataframe.analytics.create.analyticsListCardTitle', {
|
||||
defaultMessage: 'Data Frame Analytics',
|
||||
|
|
|
@ -18,8 +18,7 @@ import { i18n } from '@kbn/i18n';
|
|||
import { CreateAnalyticsFormProps } from '../../../analytics_management/hooks/use_create_analytics_form';
|
||||
import { Messages } from '../shared';
|
||||
import { ANALYTICS_STEPS } from '../../page';
|
||||
import { BackToListPanel } from '../back_to_list_panel';
|
||||
import { ProgressStats } from './progress_stats';
|
||||
import { CreateStepFooter } from '../create_step_footer';
|
||||
|
||||
interface Props extends CreateAnalyticsFormProps {
|
||||
step: ANALYTICS_STEPS;
|
||||
|
@ -28,7 +27,7 @@ interface Props extends CreateAnalyticsFormProps {
|
|||
export const CreateStep: FC<Props> = ({ actions, state, step }) => {
|
||||
const { createAnalyticsJob, startAnalyticsJob } = actions;
|
||||
const { isAdvancedEditorValidJson, isJobCreated, isJobStarted, isValid, requestMessages } = state;
|
||||
const { jobId } = state.form;
|
||||
const { jobId, jobType } = state.form;
|
||||
|
||||
const [checked, setChecked] = useState<boolean>(true);
|
||||
const [showProgress, setShowProgress] = useState<boolean>(false);
|
||||
|
@ -86,8 +85,9 @@ export const CreateStep: FC<Props> = ({ actions, state, step }) => {
|
|||
)}
|
||||
<EuiSpacer size="s" />
|
||||
<Messages messages={requestMessages} />
|
||||
{isJobCreated === true && showProgress && <ProgressStats jobId={jobId} />}
|
||||
{isJobCreated === true && <BackToListPanel />}
|
||||
{isJobCreated === true && (
|
||||
<CreateStepFooter jobId={jobId} jobType={jobType!} showProgress={showProgress} />
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -4,38 +4,43 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { FC, useState, useEffect } from 'react';
|
||||
import {
|
||||
EuiCallOut,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiProgress,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import React, { FC, useEffect, useState } from 'react';
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useMlKibana } from '../../../../../contexts/kibana';
|
||||
|
||||
import {
|
||||
getDataFrameAnalyticsProgressPhase,
|
||||
DATA_FRAME_TASK_STATE,
|
||||
} from '../../../analytics_management/components/analytics_list/common';
|
||||
import { isGetDataFrameAnalyticsStatsResponseOk } from '../../../analytics_management/services/analytics_service/get_analytics';
|
||||
import { useMlKibana } from '../../../../../contexts/kibana';
|
||||
import { ml } from '../../../../../services/ml_api_service';
|
||||
import { DataFrameAnalyticsId } from '../../../../common/analytics';
|
||||
import { BackToListPanel } from '../back_to_list_panel';
|
||||
import { ViewResultsPanel } from '../view_results_panel';
|
||||
import { ProgressStats } from './progress_stats';
|
||||
import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics';
|
||||
|
||||
export const PROGRESS_REFRESH_INTERVAL_MS = 1000;
|
||||
|
||||
export const ProgressStats: FC<{ jobId: DataFrameAnalyticsId }> = ({ jobId }) => {
|
||||
const [initialized, setInitialized] = useState<boolean>(false);
|
||||
const [failedJobMessage, setFailedJobMessage] = useState<string | undefined>(undefined);
|
||||
const [currentProgress, setCurrentProgress] = useState<
|
||||
| {
|
||||
interface Props {
|
||||
jobId: string;
|
||||
jobType: ANALYSIS_CONFIG_TYPE;
|
||||
showProgress: boolean;
|
||||
}
|
||||
|
||||
export interface AnalyticsProgressStats {
|
||||
currentPhase: number;
|
||||
progress: number;
|
||||
totalPhases: number;
|
||||
}
|
||||
| undefined
|
||||
>(undefined);
|
||||
|
||||
export const CreateStepFooter: FC<Props> = ({ jobId, jobType, showProgress }) => {
|
||||
const [initialized, setInitialized] = useState<boolean>(false);
|
||||
const [failedJobMessage, setFailedJobMessage] = useState<string | undefined>(undefined);
|
||||
const [jobFinished, setJobFinished] = useState<boolean>(false);
|
||||
const [currentProgress, setCurrentProgress] = useState<AnalyticsProgressStats | undefined>(
|
||||
undefined
|
||||
);
|
||||
|
||||
const {
|
||||
services: { notifications },
|
||||
|
@ -77,6 +82,7 @@ export const ProgressStats: FC<{ jobId: DataFrameAnalyticsId }> = ({ jobId }) =>
|
|||
jobStats.state === DATA_FRAME_TASK_STATE.STOPPED
|
||||
) {
|
||||
clearInterval(interval);
|
||||
setJobFinished(true);
|
||||
}
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
|
@ -95,62 +101,26 @@ export const ProgressStats: FC<{ jobId: DataFrameAnalyticsId }> = ({ jobId }) =>
|
|||
return () => clearInterval(interval);
|
||||
}, [initialized]);
|
||||
|
||||
if (currentProgress === undefined) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
{failedJobMessage !== undefined && (
|
||||
<>
|
||||
<EuiCallOut
|
||||
data-test-subj="analyticsWizardProgressCallout"
|
||||
title={i18n.translate(
|
||||
'xpack.ml.dataframe.analytics.create.analyticsProgressCalloutTitle',
|
||||
{
|
||||
defaultMessage: 'Job failed',
|
||||
}
|
||||
)}
|
||||
color={'danger'}
|
||||
iconType={'alert'}
|
||||
size="s"
|
||||
>
|
||||
<p>{failedJobMessage}</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
)}
|
||||
<EuiText size="m">
|
||||
<strong>
|
||||
{i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressTitle', {
|
||||
defaultMessage: 'Progress',
|
||||
})}
|
||||
</strong>
|
||||
</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<strong>
|
||||
{i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressPhaseTitle', {
|
||||
defaultMessage: 'Phase',
|
||||
})}{' '}
|
||||
{currentProgress.currentPhase}/{currentProgress.totalPhases}
|
||||
</strong>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem style={{ width: '400px' }} grow={false}>
|
||||
<EuiProgress
|
||||
value={currentProgress.progress}
|
||||
max={100}
|
||||
color="primary"
|
||||
size="l"
|
||||
data-test-subj="mlAnalyticsCreationWizardProgress"
|
||||
/>
|
||||
{showProgress && (
|
||||
<ProgressStats currentProgress={currentProgress} failedJobMessage={failedJobMessage} />
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">{`${currentProgress.progress}%`}</EuiText>
|
||||
<EuiHorizontalRule />
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem grow={false}>
|
||||
<BackToListPanel />
|
||||
</EuiFlexItem>
|
||||
{jobFinished === true && (
|
||||
<EuiFlexItem grow={false}>
|
||||
<ViewResultsPanel jobId={jobId} analysisType={jobType} />
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { CreateStepFooter } from './create_step_footer';
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { FC } from 'react';
|
||||
import {
|
||||
EuiCallOut,
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiProgress,
|
||||
EuiSpacer,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { AnalyticsProgressStats } from './create_step_footer';
|
||||
|
||||
interface Props {
|
||||
currentProgress?: AnalyticsProgressStats;
|
||||
failedJobMessage: string | undefined;
|
||||
}
|
||||
|
||||
export const ProgressStats: FC<Props> = ({ currentProgress, failedJobMessage }) => {
|
||||
if (currentProgress === undefined) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<EuiSpacer />
|
||||
{failedJobMessage !== undefined && (
|
||||
<>
|
||||
<EuiCallOut
|
||||
data-test-subj="analyticsWizardProgressCallout"
|
||||
title={i18n.translate(
|
||||
'xpack.ml.dataframe.analytics.create.analyticsProgressCalloutTitle',
|
||||
{
|
||||
defaultMessage: 'Job failed',
|
||||
}
|
||||
)}
|
||||
color={'danger'}
|
||||
iconType={'alert'}
|
||||
size="s"
|
||||
>
|
||||
<p>{failedJobMessage}</p>
|
||||
</EuiCallOut>
|
||||
<EuiSpacer size="s" />
|
||||
</>
|
||||
)}
|
||||
<EuiText size="m">
|
||||
<strong>
|
||||
{i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressTitle', {
|
||||
defaultMessage: 'Progress',
|
||||
})}
|
||||
</strong>
|
||||
</EuiText>
|
||||
<EuiSpacer size="s" />
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">
|
||||
<strong>
|
||||
{i18n.translate('xpack.ml.dataframe.analytics.create.analyticsProgressPhaseTitle', {
|
||||
defaultMessage: 'Phase',
|
||||
})}{' '}
|
||||
{currentProgress.currentPhase}/{currentProgress.totalPhases}
|
||||
</strong>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem style={{ width: '400px' }} grow={false}>
|
||||
<EuiProgress
|
||||
value={currentProgress.progress}
|
||||
max={100}
|
||||
color="primary"
|
||||
size="l"
|
||||
data-test-subj="mlAnalyticsCreationWizardProgress"
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiText size="s">{`${currentProgress.progress}%`}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { ViewResultsPanel } from './view_results_panel';
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { FC, Fragment } from 'react';
|
||||
import { EuiCard, EuiIcon } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { useNavigateToPath } from '../../../../../contexts/kibana';
|
||||
import { getResultsUrl } from '../../../analytics_management/components/analytics_list/common';
|
||||
import { ANALYSIS_CONFIG_TYPE } from '../../../../common/analytics';
|
||||
|
||||
interface Props {
|
||||
jobId: string;
|
||||
analysisType: ANALYSIS_CONFIG_TYPE;
|
||||
}
|
||||
|
||||
export const ViewResultsPanel: FC<Props> = ({ jobId, analysisType }) => {
|
||||
const navigateToPath = useNavigateToPath();
|
||||
|
||||
const redirectToAnalyticsManagementPage = async () => {
|
||||
const path = getResultsUrl(jobId, analysisType);
|
||||
await navigateToPath(path);
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
<EuiCard
|
||||
className="dfAnalyticsCreationWizard__card"
|
||||
icon={<EuiIcon size="xxl" type="tableDensityNormal" />}
|
||||
title={i18n.translate('xpack.ml.dataframe.analytics.create.viewResultsCardTitle', {
|
||||
defaultMessage: 'View Results',
|
||||
})}
|
||||
description={i18n.translate(
|
||||
'xpack.ml.dataframe.analytics.create.viewResultsCardDescription',
|
||||
{
|
||||
defaultMessage: 'View results for the analytics job.',
|
||||
}
|
||||
)}
|
||||
onClick={redirectToAnalyticsManagementPage}
|
||||
data-test-subj="analyticsWizardViewResultsCard"
|
||||
/>
|
||||
</Fragment>
|
||||
);
|
||||
};
|
|
@ -130,6 +130,6 @@ export function isCompletedAnalyticsJob(stats: DataFrameAnalyticsStats) {
|
|||
return stats.state === DATA_FRAME_TASK_STATE.STOPPED && progress === 100;
|
||||
}
|
||||
|
||||
export function getResultsUrl(jobId: string, analysisType: string) {
|
||||
export function getResultsUrl(jobId: string, analysisType: ANALYSIS_CONFIG_TYPE | string) {
|
||||
return `#/data_frame_analytics/exploration?_g=(ml:(jobId:${jobId},analysisType:${analysisType}))`;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue