Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ML] Add Create Data Frame Analytics card to Data Visualizer #91011

Merged
merged 5 commits into from
Feb 11, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions x-pack/plugins/ml/common/constants/ml_url_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const ML_PAGES = {
*/
DATA_VISUALIZER_INDEX_VIEWER: 'jobs/new_job/datavisualizer',
ANOMALY_DETECTION_CREATE_JOB: `jobs/new_job`,
ANOMALY_DETECTION_CREATE_JOB_ADVANCED: `jobs/new_job/advanced`,
ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE: `jobs/new_job/step/job_type`,
ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX: `jobs/new_job/step/index_or_search`,
SETTINGS: 'settings',
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/ml/common/types/ml_url_generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export interface DataVisualizerFileBasedAppState extends Omit<ListingPageUrlStat
export type MlGenericUrlState = MLPageState<
| typeof ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER
| typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB
| typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_ADVANCED
| typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE
| typeof ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_INDEX
| typeof ML_PAGES.DATA_FRAME_ANALYTICS_CREATE_JOB
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import React from 'react';
import PropTypes from 'prop-types';

import { EuiIcon, EuiFlexItem } from '@elastic/eui';
import { CreateJobLinkCard } from '../create_job_link_card';
import { LinkCard } from '../link_card';
import { useMlKibana } from '../../contexts/kibana';

export const RecognizedResult = ({ config, indexPattern, savedSearch }) => {
Expand All @@ -34,7 +34,7 @@ export const RecognizedResult = ({ config, indexPattern, savedSearch }) => {

return (
<EuiFlexItem>
<CreateJobLinkCard
<LinkCard
data-test-subj={`mlRecognizerCard ${config.id}`}
href={href}
title={config.title}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* 2.0.
*/

export { CreateJobLinkCard } from './create_job_link_card';
export { LinkCard } from './link_card';
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ interface Props {

// Component for rendering a card which links to the Create Job page, displaying an
// icon, card title, description and link.
export const CreateJobLinkCard: FC<Props> = ({
export const LinkCard: FC<Props> = ({
icon,
iconAreaLabel,
title,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,15 @@ import React, { FC, useState, useEffect } from 'react';

import { FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
import {
EuiSpacer,
EuiText,
EuiTitle,
EuiFlexGroup,
EuiFlexItem,
EuiCard,
EuiIcon,
} from '@elastic/eui';
import { Link } from 'react-router-dom';
import { CreateJobLinkCard } from '../../../../components/create_job_link_card';
import { EuiSpacer, EuiText, EuiTitle, EuiFlexGroup } from '@elastic/eui';
import { LinkCard } from '../../../../components/link_card';
import { DataRecognizer } from '../../../../components/data_recognizer';
import { ML_PAGES } from '../../../../../../common/constants/ml_url_generator';
import {
DISCOVER_APP_URL_GENERATOR,
DiscoverUrlGeneratorState,
} from '../../../../../../../../../src/plugins/discover/public';
import { useMlKibana } from '../../../../contexts/kibana';
import { useMlKibana, useMlLink } from '../../../../contexts/kibana';
import { isFullLicense } from '../../../../license';
import { checkPermission } from '../../../../capabilities/check_capabilities';
import { mlNodesAvailable } from '../../../../ml_nodes_check';
Expand Down Expand Up @@ -57,12 +48,18 @@ export const ActionsPanel: FC<Props> = ({ indexPattern, searchString, searchQuer
setRecognizerResultsCount(recognizerResults.count);
},
};
const showCreateJob =
isFullLicense() &&
checkPermission('canCreateJob') &&
mlNodesAvailable() &&
indexPattern.timeFieldName !== undefined;
const createJobLink = `/${ML_PAGES.ANOMALY_DETECTION_CREATE_JOB}/advanced?index=${indexPattern.id}`;
const mlAvailable = isFullLicense() && checkPermission('canCreateJob') && mlNodesAvailable();
const showCreateAnomalyDetectionJob = mlAvailable && indexPattern.timeFieldName !== undefined;

const createJobLink = useMlLink({
page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_ADVANCED,
pageState: { index: indexPattern.id },
});

const createDataFrameAnalyticsLink = useMlLink({
page: ML_PAGES.DATA_FRAME_ANALYTICS_CREATE_JOB,
pageState: { index: indexPattern.id },
});

useEffect(() => {
let unmounted = false;
Expand Down Expand Up @@ -95,6 +92,7 @@ export const ActionsPanel: FC<Props> = ({ indexPattern, searchString, searchQuer
setDiscoverLink(discoverUrl);
}
};

getDiscoverUrl();
return () => {
unmounted = true;
Expand All @@ -106,7 +104,7 @@ export const ActionsPanel: FC<Props> = ({ indexPattern, searchString, searchQuer
// controls whether the recognizer section is ultimately displayed.
return (
<div data-test-subj="mlDataVisualizerActionsPanel">
{showCreateJob && (
{mlAvailable && (
<>
<EuiTitle size="s">
<h2>
Expand All @@ -117,50 +115,84 @@ export const ActionsPanel: FC<Props> = ({ indexPattern, searchString, searchQuer
</h2>
</EuiTitle>
<EuiSpacer size="s" />
<div hidden={recognizerResultsCount === 0}>
<EuiText size="s" color="subdued">
<p>
<FormattedMessage
id="xpack.ml.datavisualizer.actionsPanel.selectKnownConfigurationDescription"
defaultMessage="Select known configurations for recognized data:"
/>
</p>
</EuiText>
<EuiSpacer size="m" />
<EuiFlexGroup gutterSize="l" responsive={true} wrap={true}>
<DataRecognizer
indexPattern={indexPattern}
savedSearch={null}
results={recognizerResults}
{showCreateAnomalyDetectionJob && (
<>
<div hidden={recognizerResultsCount === 0}>
<EuiText size="s" color="subdued">
<p>
<FormattedMessage
id="xpack.ml.datavisualizer.actionsPanel.selectKnownConfigurationDescription"
defaultMessage="Select known configurations for recognized data:"
/>
</p>
</EuiText>
<EuiSpacer size="m" />
<EuiFlexGroup gutterSize="l" responsive={true} wrap={true}>
<DataRecognizer
indexPattern={indexPattern}
savedSearch={null}
results={recognizerResults}
/>
</EuiFlexGroup>
<EuiSpacer size="l" />
</div>
<EuiText size="s" color="subdued">
<p>
<FormattedMessage
id="xpack.ml.datavisualizer.actionsPanel.createJobDescription"
defaultMessage="Use the Advanced job wizard to create a job to find anomalies in this data:"
/>
</p>
</EuiText>
<EuiSpacer size="m" />
<LinkCard
href={createJobLink}
icon="createAdvancedJob"
title={i18n.translate('xpack.ml.datavisualizer.actionsPanel.advancedTitle', {
defaultMessage: 'Advanced',
})}
description={i18n.translate(
'xpack.ml.datavisualizer.actionsPanel.advancedDescription',
{
defaultMessage:
'Create a job with the full range of options for more advanced use cases',
}
)}
data-test-subj="mlDataVisualizerCreateAdvancedJobCard"
/>
</EuiFlexGroup>
<EuiSpacer size="l" />
</div>
<EuiSpacer size="m" />
</>
)}
</>
)}
{mlAvailable && indexPattern.id !== undefined && createDataFrameAnalyticsLink && (
<>
<EuiText size="s" color="subdued">
<p>
<FormattedMessage
id="xpack.ml.datavisualizer.actionsPanel.createJobDescription"
defaultMessage="Use the Advanced job wizard to create a job to find anomalies in this data:"
id="xpack.ml.datavisualizer.actionsPanel.createDataFrameAnalyticsDescription"
defaultMessage="Use the Data Frame Analytics wizard to perform analyses of your data:"
/>
</p>
</EuiText>
<EuiSpacer size="m" />
<Link to={createJobLink}>
<CreateJobLinkCard
icon="createAdvancedJob"
title={i18n.translate('xpack.ml.datavisualizer.actionsPanel.advancedTitle', {
defaultMessage: 'Advanced',
})}
description={i18n.translate(
'xpack.ml.datavisualizer.actionsPanel.advancedDescription',
{
defaultMessage:
'Use the full range of options to create a job for more advanced use cases',
}
)}
data-test-subj="mlDataVisualizerCreateAdvancedJobCard"
/>
</Link>
<LinkCard
href={createDataFrameAnalyticsLink}
icon="classificationJob"
description={i18n.translate(
'xpack.ml.datavisualizer.actionsPanel.dataframeTypesDescription',
{
defaultMessage: 'Create outlier detection, regression, or classification analytics',
}
)}
title={
<FormattedMessage
id="xpack.ml.datavisualizer.actionsPanel.dataframeAnalyticsTitle"
defaultMessage="Data Frame Analytics"
/>
}
data-test-subj="mlDataVisualizerCreateDataFrameAnalyticsCard"
/>
<EuiSpacer size="m" />
</>
)}
Expand All @@ -176,25 +208,23 @@ export const ActionsPanel: FC<Props> = ({ indexPattern, searchString, searchQuer
</h2>
</EuiTitle>
<EuiSpacer size="m" />
<EuiFlexItem>
<EuiCard
data-test-subj="mlDataVisualizerViewInDiscoverCard"
icon={<EuiIcon size="xxl" type={`discoverApp`} />}
description={i18n.translate(
'xpack.ml.datavisualizer.actionsPanel.viewIndexInDiscoverDescription',
{
defaultMessage: 'Explore index in Discover',
}
)}
title={
<FormattedMessage
id="xpack.ml.datavisualizer.actionsPanel.discoverAppTitle"
defaultMessage="Discover"
/>
<LinkCard
href={discoverLink}
icon="discoverApp"
description={i18n.translate(
'xpack.ml.datavisualizer.actionsPanel.viewIndexInDiscoverDescription',
{
defaultMessage: 'Explore index in Discover',
}
href={discoverLink}
/>
</EuiFlexItem>
)}
title={
<FormattedMessage
id="xpack.ml.datavisualizer.actionsPanel.discoverAppTitle"
defaultMessage="Discover"
/>
}
data-test-subj="mlDataVisualizerViewInDiscoverCard"
/>
</>
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { isSavedSearchSavedObject } from '../../../../../../common/types/kibana'
import { DataRecognizer } from '../../../../components/data_recognizer';
import { addItemToRecentlyAccessed } from '../../../../util/recently_accessed';
import { timeBasedIndexCheck } from '../../../../util/index_utils';
import { CreateJobLinkCard } from '../../../../components/create_job_link_card';
import { LinkCard } from '../../../../components/link_card';
import { CategorizationIcon } from './categorization_job_icon';
import { ML_PAGES } from '../../../../../../common/constants/ml_url_generator';
import { useCreateAndNavigateToMlLink } from '../../../../contexts/kibana/use_create_url';
Expand Down Expand Up @@ -257,7 +257,7 @@ export const Page: FC = () => {
<EuiFlexGrid gutterSize="l" columns={4}>
{jobTypes.map(({ onClick, icon, title, description, id }) => (
<EuiFlexItem key={id}>
<CreateJobLinkCard
<LinkCard
data-test-subj={id}
onClick={onClick}
icon={icon.type}
Expand Down Expand Up @@ -294,7 +294,7 @@ export const Page: FC = () => {

<EuiFlexGrid gutterSize="l" columns={4}>
<EuiFlexItem>
<CreateJobLinkCard
<LinkCard
icon="dataVisualizer"
iconAreaLabel={i18n.translate(
'xpack.ml.newJob.wizard.jobType.dataVisualizerAriaLabel',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export class MlUrlGenerator implements UrlGeneratorsDefinition<typeof ML_APP_URL
case ML_PAGES.DATA_FRAME_ANALYTICS_EXPLORATION:
return createDataFrameAnalyticsExplorationUrl(appBasePath, mlUrlGeneratorState.pageState);
case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB:
case ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_ADVANCED:
case ML_PAGES.DATA_VISUALIZER:
case ML_PAGES.DATA_VISUALIZER_FILE:
case ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('displays the actions panel with advanced job card');
await ml.dataVisualizerIndexBased.assertActionsPanelExists();
await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardExists();
await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardExists();

// Note the search is not currently passed to the wizard, just the index.
await ml.testExecution.logTestStep('displays the actions panel with advanced job card');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('should display job cards');
await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardExists();
await ml.dataVisualizerIndexBased.assertRecognizerCardExists(ecExpectedModuleId);
await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardExists();
});

it('should display elements on File Data Visualizer page correctly', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('should not display job cards');
await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists();
await ml.dataVisualizerIndexBased.assertRecognizerCardNotExists(ecExpectedModuleId);
await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists();
});

it('should display elements on File Data Visualizer page correctly', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,14 @@ export function MachineLearningDataVisualizerIndexBasedProvider({
await testSubjects.clickWhenNotDisabled('mlDataVisualizerCreateAdvancedJobCard');
},

async assertCreateDataFrameAnalyticsCardExists() {
await testSubjects.existOrFail('mlDataVisualizerCreateDataFrameAnalyticsCard');
},

async assertCreateDataFrameAnalyticsCardNotExists() {
await testSubjects.missingOrFail('mlDataVisualizerCreateDataFrameAnalyticsCard');
},

async assertViewInDiscoverCardExists() {
await testSubjects.existOrFail('mlDataVisualizerViewInDiscoverCard');
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ export default function ({ getService }: FtrProviderContext) {
});

it('navigates to Discover page', async () => {
await ml.testExecution.logTestStep('should not display create job card');
await ml.testExecution.logTestStep('should not display create job cards');
await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists();
await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists();

await ml.testExecution.logTestStep('displays the actions panel with view in Discover card');
await ml.dataVisualizerIndexBased.assertActionsPanelExists();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('should not display job cards');
await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists();
await ml.dataVisualizerIndexBased.assertRecognizerCardNotExists(ecExpectedModuleId);
await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists();
});

it('should display elements on File Data Visualizer page correctly', async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ export default function ({ getService }: FtrProviderContext) {
await ml.testExecution.logTestStep('should not display job cards');
await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists();
await ml.dataVisualizerIndexBased.assertRecognizerCardNotExists(ecExpectedModuleId);
await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists();
});

it('should display elements on File Data Visualizer page correctly', async () => {
Expand Down