Skip to content

Commit

Permalink
[ML] DF Analytics results: ensure View link is only enabled when jo…
Browse files Browse the repository at this point in the history
…b has successfully completed (#73539)

* disable view link if job is incomplete or failed

* ensure hooks run before return to avoid react error
  • Loading branch information
alvarezmelissa87 authored Jul 29, 2020
1 parent 4f8e7ba commit 2dca40a
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) =

const { columnsWithCharts, errorMessage, status, tableItems } = outlierData;

/* eslint-disable-next-line react-hooks/rules-of-hooks */
const colorRange = useColorRange(
COLOR_RANGE.BLUE,
COLOR_RANGE_SCALE.INFLUENCER,
jobConfig !== undefined ? getFeatureCount(jobConfig.dest.results_field, tableItems) : 1
);

// if it's a searchBar syntax error leave the table visible so they can try again
if (status === INDEX_STATUS.ERROR && !errorMessage.includes('failed to create query')) {
return (
Expand All @@ -74,13 +81,6 @@ export const OutlierExploration: FC<ExplorationProps> = React.memo(({ jobId }) =
);
}

/* eslint-disable-next-line react-hooks/rules-of-hooks */
const colorRange = useColorRange(
COLOR_RANGE.BLUE,
COLOR_RANGE_SCALE.INFLUENCER,
jobConfig !== undefined ? getFeatureCount(jobConfig.dest.results_field, tableItems) : 1
);

return (
<EuiPanel data-test-subj="mlDFAnalyticsOutlierExplorationTablePanel">
{jobConfig !== undefined && needsDestIndexPattern && (
Expand Down
Original file line number Diff line number Diff line change
@@ -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 { i18n } from '@kbn/i18n';
import {
isRegressionAnalysis,
isOutlierAnalysis,
isClassificationAnalysis,
} from '../../../../common/analytics';
import {
DataFrameAnalyticsListRow,
isDataFrameAnalyticsStopped,
isDataFrameAnalyticsFailed,
getDataFrameAnalyticsProgressPhase,
} from '../analytics_list/common';

const unknownJobTypeMessage = i18n.translate(
'xpack.ml.dataframe.analyticsList.viewActionUnknownJobTypeToolTipContent',
{
defaultMessage: 'There is no results page available for this type of data frame analytics job.',
}
);
const jobNotStartedMessage = i18n.translate(
'xpack.ml.dataframe.analyticsList.viewActionJobNotStartedToolTipContent',
{
defaultMessage:
'The data frame analytics job did not start. There is no results page available.',
}
);
const jobNotFinishedMessage = i18n.translate(
'xpack.ml.dataframe.analyticsList.viewActionJobNotFinishedToolTipContent',
{
defaultMessage:
'The data frame analytics job is not finished. There is no results page available.',
}
);
const jobFailedMessage = i18n.translate(
'xpack.ml.dataframe.analyticsList.viewActionJobFailedToolTipContent',
{
defaultMessage: 'The data frame analytics job failed. There is no results page available.',
}
);

interface ViewLinkStatusReturn {
disabled: boolean;
tooltipContent?: string;
}

export function getViewLinkStatus(item: DataFrameAnalyticsListRow): ViewLinkStatusReturn {
const viewLinkStatus: ViewLinkStatusReturn = { disabled: false };

const progressStats = getDataFrameAnalyticsProgressPhase(item.stats);
const jobFailed = isDataFrameAnalyticsFailed(item.stats.state);
const jobNotStarted = progressStats.currentPhase === 1 && progressStats.progress === 0;
const jobFinished =
isDataFrameAnalyticsStopped(item.stats.state) &&
progressStats.currentPhase === progressStats.totalPhases &&
progressStats.progress === 100;
const isUnknownJobType =
!isRegressionAnalysis(item.config.analysis) &&
!isOutlierAnalysis(item.config.analysis) &&
!isClassificationAnalysis(item.config.analysis);

const disabled = !jobFinished || jobFailed || isUnknownJobType;

if (disabled) {
viewLinkStatus.disabled = true;
if (isUnknownJobType) {
viewLinkStatus.tooltipContent = unknownJobTypeMessage;
} else if (jobFailed) {
viewLinkStatus.tooltipContent = jobFailedMessage;
} else if (jobNotStarted) {
viewLinkStatus.tooltipContent = jobNotStartedMessage;
} else if (!jobFinished) {
viewLinkStatus.tooltipContent = jobNotFinishedMessage;
}
}

return viewLinkStatus;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,13 @@ import React, { FC } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui';

import {
getAnalysisType,
isRegressionAnalysis,
isOutlierAnalysis,
isClassificationAnalysis,
} from '../../../../common/analytics';
import { getAnalysisType } from '../../../../common/analytics';
import { useMlKibana } from '../../../../../contexts/kibana';

import { getResultsUrl, DataFrameAnalyticsListRow } from '../analytics_list/common';

import { getViewLinkStatus } from './get_view_link_status';

interface ViewButtonProps {
item: DataFrameAnalyticsListRow;
isManagementTable: boolean;
Expand All @@ -30,11 +27,8 @@ export const ViewButton: FC<ViewButtonProps> = ({ item, isManagementTable }) =>
},
} = useMlKibana();

const { disabled, tooltipContent } = getViewLinkStatus(item);
const analysisType = getAnalysisType(item.config.analysis);
const buttonDisabled =
!isRegressionAnalysis(item.config.analysis) &&
!isOutlierAnalysis(item.config.analysis) &&
!isClassificationAnalysis(item.config.analysis);

const url = getResultsUrl(item.id, analysisType);
const navigator = isManagementTable
Expand All @@ -52,23 +46,17 @@ export const ViewButton: FC<ViewButtonProps> = ({ item, isManagementTable }) =>
data-test-subj="mlAnalyticsJobViewButton"
flush="left"
iconType="visTable"
isDisabled={buttonDisabled}
isDisabled={disabled}
onClick={navigator}
size="s"
>
{buttonText}
</EuiButtonEmpty>
);

if (buttonDisabled) {
if (disabled) {
return (
<EuiToolTip
position="top"
content={i18n.translate('xpack.ml.dataframe.analyticsList.viewActionToolTipContent', {
defaultMessage:
'There is no results page available for this type of data frame analytics job.',
})}
>
<EuiToolTip position="top" content={tooltipContent}>
{button}
</EuiToolTip>
);
Expand Down

0 comments on commit 2dca40a

Please sign in to comment.