diff --git a/x-pack/plugins/data_visualizer/public/api/index.ts b/x-pack/plugins/data_visualizer/public/api/index.ts index 746b43ac86e30..3b96e4caad340 100644 --- a/x-pack/plugins/data_visualizer/public/api/index.ts +++ b/x-pack/plugins/data_visualizer/public/api/index.ts @@ -8,11 +8,12 @@ import { lazyLoadModules } from '../lazy_load_bundle'; import type { FileDataVisualizerSpec, IndexDataVisualizerSpec } from '../application'; -export async function getFileDataVisualizerComponent(): Promise { +export async function getFileDataVisualizerComponent(): Promise<() => FileDataVisualizerSpec> { const modules = await lazyLoadModules(); - return modules.FileDataVisualizer; + return () => modules.FileDataVisualizer; } -export async function getIndexDataVisualizerComponent(): Promise { + +export async function getIndexDataVisualizerComponent(): Promise<() => IndexDataVisualizerSpec> { const modules = await lazyLoadModules(); - return modules.IndexDataVisualizer; + return () => modules.IndexDataVisualizer; } diff --git a/x-pack/plugins/data_visualizer/public/application/common/components/filebeat_config_flyout/filebeat_config_flyout.tsx b/x-pack/plugins/data_visualizer/public/application/common/components/filebeat_config_flyout/filebeat_config_flyout.tsx index 6c9df5cf2eba7..e43199fabf76c 100644 --- a/x-pack/plugins/data_visualizer/public/application/common/components/filebeat_config_flyout/filebeat_config_flyout.tsx +++ b/x-pack/plugins/data_visualizer/public/application/common/components/filebeat_config_flyout/filebeat_config_flyout.tsx @@ -73,7 +73,12 @@ export const FilebeatConfigFlyout: FC = ({ - + ; + canDisplay(params?: any): Promise; + dataTestSubj?: string; +} + interface Props { fieldStats: FindFileStructureResponse['field_stats']; index: string; @@ -25,6 +38,7 @@ interface Props { timeFieldName?: string; createIndexPattern: boolean; showFilebeatFlyout(): void; + additionalLinks: ResultLink[]; } interface GlobalState { @@ -41,6 +55,7 @@ export const ResultsLinks: FC = ({ timeFieldName, createIndexPattern, showFilebeatFlyout, + additionalLinks, }) => { const { services: { fileUpload }, @@ -55,6 +70,7 @@ export const ResultsLinks: FC = ({ const [discoverLink, setDiscoverLink] = useState(''); const [indexManagementLink, setIndexManagementLink] = useState(''); const [indexPatternManagementLink, setIndexPatternManagementLink] = useState(''); + const [generatedLinks, setGeneratedLinks] = useState>({}); const { services: { @@ -100,6 +116,23 @@ export const ResultsLinks: FC = ({ getDiscoverUrl(); + Promise.all( + additionalLinks.map(async ({ canDisplay, getUrl }) => { + if ((await canDisplay({ indexPatternId })) === false) { + return null; + } + return getUrl({ globalState, indexPatternId }); + }) + ).then((urls) => { + const linksById = urls.reduce((acc, url, i) => { + if (url !== null) { + acc[additionalLinks[i].id] = url; + } + return acc; + }, {} as Record); + setGeneratedLinks(linksById); + }); + if (!unmounted) { setIndexManagementLink( getUrlForApp('management', { path: '/data/index_management/indices' }) @@ -231,6 +264,19 @@ export const ResultsLinks: FC = ({ onClick={showFilebeatFlyout} /> + {additionalLinks + .filter(({ id }) => generatedLinks[id] !== undefined) + .map((link) => ( + + } + data-test-subj="fileDataVisLink" + title={link.title} + description={link.description} + href={generatedLinks[link.id]} + /> + + ))} ); }; diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js index 99b6ef602985f..054416ad7ba36 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/file_data_visualizer_view/file_data_visualizer_view.js @@ -372,6 +372,7 @@ export class FileDataVisualizerView extends Component { hideBottomBar={this.hideBottomBar} savedObjectsClient={this.savedObjectsClient} fileUpload={this.props.fileUpload} + resultsLinks={this.props.resultsLinks} /> {bottomBarVisible && ( diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js index 232a32c75dc29..7e3c6d0c65d3e 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/components/import_view/import_view.js @@ -591,6 +591,7 @@ export class ImportView extends Component { timeFieldName={timeFieldName} createIndexPattern={createIndexPattern} showFilebeatFlyout={this.showFilebeatFlyout} + additionalLinks={this.props.resultsLinks ?? []} /> {isFilebeatFlyoutVisible && ( diff --git a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx index b3f7e8531ebf5..3644f7053f1e8 100644 --- a/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx @@ -11,9 +11,14 @@ import { getCoreStart, getPluginsStart } from '../../kibana_services'; // @ts-ignore import { FileDataVisualizerView } from './components/file_data_visualizer_view/index'; +import { ResultLink } from '../common/components/results_links'; + +interface Props { + additionalLinks?: ResultLink[]; +} export type FileDataVisualizerSpec = typeof FileDataVisualizer; -export const FileDataVisualizer: FC = () => { +export const FileDataVisualizer: FC = ({ additionalLinks }) => { const coreStart = getCoreStart(); const { data, maps, embeddable, share, security, fileUpload } = getPluginsStart(); const services = { @@ -33,6 +38,7 @@ export const FileDataVisualizer: FC = () => { savedObjectsClient={coreStart.savedObjects.client} http={coreStart.http} fileUpload={fileUpload} + resultsLinks={additionalLinks} /> ); diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx index 4b208b0a59ef1..48410aff54577 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/actions_panel/actions_panel.tsx @@ -18,18 +18,26 @@ import type { IndexPattern } from '../../../../../../../../src/plugins/data/comm import { useDataVisualizerKibana } from '../../../kibana_context'; import { useUrlState } from '../../../common/util/url_state'; import { LinkCard } from '../../../common/components/link_card'; +import { ResultLink } from '../../../common/components/results_links'; interface Props { indexPattern: IndexPattern; searchString?: string | { [key: string]: any }; searchQueryLanguage?: string; + additionalLinks: ResultLink[]; } -// @todo: Add back create job card in a follow up PR -export const ActionsPanel: FC = ({ indexPattern, searchString, searchQueryLanguage }) => { +export const ActionsPanel: FC = ({ + indexPattern, + searchString, + searchQueryLanguage, + additionalLinks, +}) => { const [globalState] = useUrlState('_g'); const [discoverLink, setDiscoverLink] = useState(''); + const [generatedLinks, setGeneratedLinks] = useState>({}); + const { services: { application: { capabilities }, @@ -76,17 +84,56 @@ export const ActionsPanel: FC = ({ indexPattern, searchString, searchQuer } }; + Promise.all( + additionalLinks.map(async ({ canDisplay, getUrl }) => { + if ((await canDisplay({ indexPatternId })) === false) { + return null; + } + return getUrl({ globalState, indexPatternId }); + }) + ).then((urls) => { + const linksById = urls.reduce((acc, url, i) => { + if (url !== null) { + acc[additionalLinks[i].id] = url; + } + return acc; + }, {} as Record); + setGeneratedLinks(linksById); + }); + getDiscoverUrl(); return () => { unmounted = true; }; - }, [indexPattern, searchString, searchQueryLanguage, globalState, capabilities, getUrlGenerator]); + }, [ + indexPattern, + searchString, + searchQueryLanguage, + globalState, + capabilities, + getUrlGenerator, + additionalLinks, + ]); // Note we use display:none for the DataRecognizer section as it needs to be // passed the recognizerResults object, and then run the recognizer check which // controls whether the recognizer section is ultimately displayed. return (
+ {additionalLinks + .filter(({ id }) => generatedLinks[id] !== undefined) + .map((link) => ( + <> + + + + ))} {discoverLink && ( <> diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx index b116b25670ad2..c9ae3cf7f69a7 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx @@ -67,6 +67,7 @@ import { HelpMenu } from '../../../common/components/help_menu'; import { TimeBuckets } from '../../services/time_buckets'; import { extractSearchData } from '../../utils/saved_search_utils'; import { DataVisualizerIndexPatternManagement } from '../index_pattern_management'; +import { ResultLink } from '../../../common/components/results_links'; interface DataVisualizerPageState { overallStats: OverallStats; @@ -120,6 +121,7 @@ export const getDefaultDataVisualizerListState = (): Required = (dataVi dataVisualizerProps.currentSavedSearch ); - const { currentIndexPattern } = dataVisualizerProps; + const { currentIndexPattern, additionalLinks } = dataVisualizerProps; useEffect(() => { if (dataVisualizerProps?.currentSavedSearch !== undefined) { @@ -886,6 +888,7 @@ export const IndexDataVisualizerView: FC = (dataVi indexPattern={currentIndexPattern} searchQueryLanguage={searchQueryLanguage} searchString={searchString} + additionalLinks={additionalLinks ?? []} /> diff --git a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx index f9e9aece48a06..8e0230a9bc6f9 100644 --- a/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx +++ b/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx @@ -30,15 +30,18 @@ import { } from '../common/util/url_state'; import { useDataVisualizerKibana } from '../kibana_context'; import { IndexPattern } from '../../../../../../src/plugins/data/common/index_patterns/index_patterns'; +import { ResultLink } from '../common/components/results_links'; export type IndexDataVisualizerSpec = typeof IndexDataVisualizer; export interface DataVisualizerUrlStateContextProviderProps { IndexDataVisualizerComponent: FC; + additionalLinks: ResultLink[]; } export const DataVisualizerUrlStateContextProvider: FC = ({ IndexDataVisualizerComponent, + additionalLinks, }) => { const { services: { @@ -168,6 +171,7 @@ export const DataVisualizerUrlStateContextProvider: FC ) : (
@@ -176,7 +180,7 @@ export const DataVisualizerUrlStateContextProvider: FC { +export const IndexDataVisualizer: FC<{ additionalLinks: ResultLink[] }> = ({ additionalLinks }) => { const coreStart = getCoreStart(); const { data, @@ -204,6 +208,7 @@ export const IndexDataVisualizer: FC = () => { ); diff --git a/x-pack/plugins/data_visualizer/public/index.ts b/x-pack/plugins/data_visualizer/public/index.ts index b0a622dfe490b..1a045f144c015 100644 --- a/x-pack/plugins/data_visualizer/public/index.ts +++ b/x-pack/plugins/data_visualizer/public/index.ts @@ -13,4 +13,9 @@ export function plugin() { export { DataVisualizerPluginStart } from './plugin'; -export type { IndexDataVisualizerViewProps } from './application'; +export type { + FileDataVisualizerSpec, + IndexDataVisualizerSpec, + IndexDataVisualizerViewProps, +} from './application'; +export type { ResultLink } from './application/common/components/results_links'; diff --git a/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx index 0e9eeda51f786..37fd0a20865f7 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/file_based/file_datavisualizer.tsx @@ -5,22 +5,99 @@ * 2.0. */ -import React, { FC, Fragment, useState, useEffect } from 'react'; - +import React, { FC, Fragment, useState, useEffect, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; import { useTimefilter } from '../../contexts/kibana'; import { NavigationMenu } from '../../components/navigation_menu'; import { HelpMenu } from '../../components/help_menu'; -import { useMlKibana } from '../../contexts/kibana'; +import { useMlKibana, useMlUrlGenerator } from '../../contexts/kibana'; + +import { ML_PAGES } from '../../../../common/constants/ml_url_generator'; +import { isFullLicense } from '../../license'; +import { mlNodesAvailable, getMlNodeCount } from '../../ml_nodes_check/check_ml_nodes'; +import { checkPermission } from '../../capabilities/check_capabilities'; +import type { ResultLink, FileDataVisualizerSpec } from '../../../../../data_visualizer/public'; + +interface GetUrlParams { + indexPatternId: string; + globalState: any; +} export const FileDataVisualizerPage: FC = () => { useTimefilter({ timeRangeSelector: false, autoRefreshSelector: false }); const { - services: { docLinks, dataVisualizer }, + services: { + docLinks, + dataVisualizer, + data: { + indexPatterns: { get: getIndexPattern }, + }, + }, } = useMlKibana(); - const [FileDataVisualizer, setFileDataVisualizer] = useState | null>(null); + const mlUrlGenerator = useMlUrlGenerator(); + getMlNodeCount(); + + const [FileDataVisualizer, setFileDataVisualizer] = useState(null); + + const links: ResultLink[] = useMemo( + () => [ + { + id: 'create_ml_job', + title: i18n.translate('xpack.ml.fileDatavisualizer.actionsPanel.anomalyDetectionTitle', { + defaultMessage: 'Create new ML job', + }), + description: '', + icon: 'machineLearningApp', + type: 'file', + getUrl: async ({ indexPatternId, globalState }: GetUrlParams) => { + return await mlUrlGenerator.createUrl({ + page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_SELECT_TYPE, + pageState: { + index: indexPatternId, + globalState, + }, + }); + }, + canDisplay: async ({ indexPatternId }) => { + try { + const { timeFieldName } = await getIndexPattern(indexPatternId); + return ( + isFullLicense() && + timeFieldName !== undefined && + checkPermission('canCreateJob') && + mlNodesAvailable() + ); + } catch (error) { + return false; + } + }, + }, + { + id: 'open_in_data_viz', + title: i18n.translate('xpack.ml.fileDatavisualizer.actionsPanel.dataframeTitle', { + defaultMessage: 'Open in Data Visualizer', + }), + description: '', + icon: 'dataVisualizer', + type: 'file', + getUrl: async ({ indexPatternId, globalState }: GetUrlParams) => { + return await mlUrlGenerator.createUrl({ + page: ML_PAGES.DATA_VISUALIZER_INDEX_VIEWER, + pageState: { + index: indexPatternId, + globalState, + }, + }); + }, + canDisplay: async () => true, + }, + ], + [] + ); useEffect(() => { if (dataVisualizer !== undefined) { + getMlNodeCount(); const { getFileDataVisualizerComponent } = dataVisualizer; getFileDataVisualizerComponent().then(setFileDataVisualizer); } @@ -29,7 +106,7 @@ export const FileDataVisualizerPage: FC = () => { return ( - {FileDataVisualizer} + {FileDataVisualizer !== null && } ); diff --git a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx index af803d32e5139..60b6c90370b61 100644 --- a/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx +++ b/x-pack/plugins/ml/public/application/datavisualizer/index_based/index_data_visualizer.tsx @@ -5,20 +5,40 @@ * 2.0. */ -import React, { FC, Fragment, useEffect, useState } from 'react'; -import { useMlKibana, useTimefilter } from '../../contexts/kibana'; +import React, { FC, Fragment, useEffect, useState, useMemo } from 'react'; +import { i18n } from '@kbn/i18n'; +import { useMlKibana, useTimefilter, useMlUrlGenerator } from '../../contexts/kibana'; import { NavigationMenu } from '../../components/navigation_menu'; import { HelpMenu } from '../../components/help_menu'; -import type { IndexDataVisualizerViewProps } from '../../../../../data_visualizer/public'; +import { ML_PAGES } from '../../../../common/constants/ml_url_generator'; +import { isFullLicense } from '../../license'; +import { mlNodesAvailable, getMlNodeCount } from '../../ml_nodes_check/check_ml_nodes'; +import { checkPermission } from '../../capabilities/check_capabilities'; + +import type { ResultLink, IndexDataVisualizerSpec } from '../../../../../data_visualizer/public'; + +interface GetUrlParams { + indexPatternId: string; + globalState: any; +} + export const IndexDataVisualizerPage: FC = () => { useTimefilter({ timeRangeSelector: false, autoRefreshSelector: false }); const { - services: { docLinks, dataVisualizer }, + services: { + docLinks, + dataVisualizer, + data: { + indexPatterns: { get: getIndexPattern }, + }, + }, } = useMlKibana(); - const [ - IndexDataVisualizer, - setIndexDataVisualizer, - ] = useState | null>(null); + const mlUrlGenerator = useMlUrlGenerator(); + getMlNodeCount(); + + const [IndexDataVisualizer, setIndexDataVisualizer] = useState( + null + ); useEffect(() => { if (dataVisualizer !== undefined) { @@ -26,10 +46,84 @@ export const IndexDataVisualizerPage: FC = () => { getIndexDataVisualizerComponent().then(setIndexDataVisualizer); } }, []); + + const links: ResultLink[] = useMemo( + () => [ + { + id: 'create_ml_ad_job', + title: i18n.translate('xpack.ml.indexDatavisualizer.actionsPanel.anomalyDetectionTitle', { + defaultMessage: 'Advanced anomaly detection', + }), + description: i18n.translate( + 'xpack.ml.indexDatavisualizer.actionsPanel.anomalyDetectionDescription', + { + defaultMessage: + 'Create a job with the full range of options for more advanced use cases.', + } + ), + icon: 'createAdvancedJob', + type: 'file', + getUrl: async ({ indexPatternId, globalState }: GetUrlParams) => { + return await mlUrlGenerator.createUrl({ + page: ML_PAGES.ANOMALY_DETECTION_CREATE_JOB_ADVANCED, + pageState: { + index: indexPatternId, + globalState, + }, + }); + }, + canDisplay: async ({ indexPatternId }) => { + try { + const { timeFieldName } = await getIndexPattern(indexPatternId); + return ( + isFullLicense() && + timeFieldName !== undefined && + checkPermission('canCreateJob') && + mlNodesAvailable() + ); + } catch (error) { + return false; + } + }, + dataTestSubj: 'dataVisualizerCreateAdvancedJobCard', + }, + { + id: 'create_ml_dfa_job', + title: i18n.translate('xpack.ml.indexDatavisualizer.actionsPanel.dataframeTitle', { + defaultMessage: 'Data frame analytics', + }), + description: i18n.translate( + 'xpack.ml.indexDatavisualizer.actionsPanel.dataframeDescription', + { + defaultMessage: 'Create outlier detection, regression, or classification analytics.', + } + ), + icon: 'classificationJob', + type: 'file', + getUrl: async ({ indexPatternId, globalState }: GetUrlParams) => { + return await mlUrlGenerator.createUrl({ + page: ML_PAGES.DATA_FRAME_ANALYTICS_CREATE_JOB, + pageState: { + index: indexPatternId, + globalState, + }, + }); + }, + canDisplay: async () => { + return ( + isFullLicense() && checkPermission('canCreateDataFrameAnalytics') && mlNodesAvailable() + ); + }, + dataTestSubj: 'dataVisualizerCreateDataFrameAnalyticsCard', + }, + ], + [] + ); + return IndexDataVisualizer ? ( - {IndexDataVisualizer} + {IndexDataVisualizer !== null && } ) : ( diff --git a/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts index 3867ed6f7dfea..dee5b5a5e31c0 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/file_data_visualizer.ts @@ -273,6 +273,9 @@ export default function ({ getService }: FtrProviderContext) { await ml.testExecution.logTestStep('creates filebeat config'); await ml.dataVisualizerFileBased.selectCreateFilebeatConfig(); + + await ml.testExecution.logTestStep('closes filebeat config'); + await ml.dataVisualizerFileBased.closeCreateFilebeatConfig(); }); }); } diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts index 93e3b67ca1565..54d7b6ac294d1 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer_actions_panel.ts @@ -15,16 +15,21 @@ export default function ({ getService }: FtrProviderContext) { this.tags(['mlqa']); const indexPatternName = 'ft_farequote'; - // @TODO: Re-enable in follow up - // const advancedJobWizardDatafeedQuery = `{ - // "bool": { - // "must": [ - // { - // "match_all": {} - // } - // ] - // } - // }`; // Note query is not currently passed to the wizard + + const advancedJobWizardDatafeedQuery = JSON.stringify( + { + bool: { + must: [ + { + match_all: {}, + }, + ], + }, + }, + null, + 2 + ); + // Note query is not currently passed to the wizard before(async () => { await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/farequote'); @@ -48,20 +53,19 @@ export default function ({ getService }: FtrProviderContext) { await ml.jobSourceSelection.selectSourceForIndexBasedDataVisualizer(indexPatternName); }); - // @TODO: Re-enable in follow up - // it('opens the advanced job wizard', async () => { - // 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'); - // await ml.dataVisualizerIndexBased.clickCreateAdvancedJobButton(); - // await ml.jobTypeSelection.assertAdvancedJobWizardOpen(); - // await ml.jobWizardAdvanced.assertDatafeedQueryEditorExists(); - // await ml.jobWizardAdvanced.assertDatafeedQueryEditorValue(advancedJobWizardDatafeedQuery); - // }); + it('opens the advanced job wizard', async () => { + 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'); + await ml.dataVisualizerIndexBased.clickCreateAdvancedJobButton(); + await ml.jobTypeSelection.assertAdvancedJobWizardOpen(); + await ml.jobWizardAdvanced.assertDatafeedQueryEditorExists(); + await ml.jobWizardAdvanced.assertDatafeedQueryEditorValue(advancedJobWizardDatafeedQuery); + }); }); describe('view in discover page action', function () { diff --git a/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts b/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts index 18f4f6a38a7b1..10b57de911a10 100644 --- a/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts +++ b/x-pack/test/functional/apps/ml/permissions/full_ml_access.ts @@ -93,8 +93,8 @@ export default function ({ getService }: FtrProviderContext) { const ecIndexPattern = 'ft_module_sample_ecommerce'; const ecExpectedTotalCount = '287'; - // @TODO: Re-enable in follow up - // const ecExpectedModuleId = 'sample_data_ecommerce'; + + const ecExpectedModuleId = 'sample_data_ecommerce'; const uploadFilePath = path.join( __dirname, @@ -365,11 +365,10 @@ export default function ({ getService }: FtrProviderContext) { } await ml.dataVisualizerIndexBased.assertViewInDiscoverCard(testUser.discoverAvailable); - // @TODO: Re-enable in follow up - // await ml.testExecution.logTestStep('should display job cards'); - // await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardExists(); - // await ml.dataVisualizerIndexBased.assertRecognizerCardExists(ecExpectedModuleId); - // await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardExists(); + 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 () => { diff --git a/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts b/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts index a53ed2fafe30c..920d82ed381c0 100644 --- a/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts +++ b/x-pack/test/functional/apps/ml/permissions/read_ml_access.ts @@ -94,7 +94,6 @@ export default function ({ getService }: FtrProviderContext) { const ecIndexPattern = 'ft_module_sample_ecommerce'; const ecExpectedTotalCount = '287'; - // const ecExpectedModuleId = 'sample_data_ecommerce'; const uploadFilePath = path.join( __dirname, @@ -357,11 +356,9 @@ export default function ({ getService }: FtrProviderContext) { } await ml.dataVisualizerIndexBased.assertViewInDiscoverCard(testUser.discoverAvailable); - // @TODO: Re-enable in follow up - // await ml.testExecution.logTestStep('should not display job cards'); - // await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists(); - // await ml.dataVisualizerIndexBased.assertRecognizerCardNotExists(ecExpectedModuleId); - // await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists(); + await ml.testExecution.logTestStep('should not display job cards'); + await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists(); + await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists(); }); it('should display elements on File Data Visualizer page correctly', async () => { diff --git a/x-pack/test/functional/services/ml/data_visualizer_file_based.ts b/x-pack/test/functional/services/ml/data_visualizer_file_based.ts index 291e5a8964553..783be207baf22 100644 --- a/x-pack/test/functional/services/ml/data_visualizer_file_based.ts +++ b/x-pack/test/functional/services/ml/data_visualizer_file_based.ts @@ -139,5 +139,10 @@ export function MachineLearningDataVisualizerFileBasedProvider( await testSubjects.click('fileDataVisFilebeatConfigLink'); await testSubjects.existOrFail('fileDataVisFilebeatConfigPanel'); }, + + async closeCreateFilebeatConfig() { + await testSubjects.click('fileBeatConfigFlyoutCloseButton'); + await testSubjects.missingOrFail('fileDataVisFilebeatConfigPanel'); + }, }; } diff --git a/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts b/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts index aff1402f5567e..901744719144c 100644 --- a/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts +++ b/x-pack/test/functional_basic/apps/ml/permissions/full_ml_access.ts @@ -25,7 +25,6 @@ export default function ({ getService }: FtrProviderContext) { describe(`(${testUser.user})`, function () { const ecIndexPattern = 'ft_module_sample_ecommerce'; const ecExpectedTotalCount = '287'; - // const ecExpectedModuleId = 'sample_data_ecommerce'; const uploadFilePath = path.join( __dirname, @@ -134,11 +133,9 @@ export default function ({ getService }: FtrProviderContext) { } await ml.dataVisualizerIndexBased.assertViewInDiscoverCard(testUser.discoverAvailable); - // @TODO: Re-enable in follow up - // await ml.testExecution.logTestStep('should not display job cards'); - // await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists(); - // await ml.dataVisualizerIndexBased.assertRecognizerCardNotExists(ecExpectedModuleId); - // await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists(); + await ml.testExecution.logTestStep('should not display job cards'); + await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists(); + await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists(); }); it('should display elements on File Data Visualizer page correctly', async () => { diff --git a/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts b/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts index 2e5216d722518..0f271719a0d0f 100644 --- a/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts +++ b/x-pack/test/functional_basic/apps/ml/permissions/read_ml_access.ts @@ -25,8 +25,6 @@ export default function ({ getService }: FtrProviderContext) { describe(`(${testUser.user})`, function () { const ecIndexPattern = 'ft_module_sample_ecommerce'; const ecExpectedTotalCount = '287'; - // @TODO: Re-enable in follow up - // const ecExpectedModuleId = 'sample_data_ecommerce'; const uploadFilePath = path.join( __dirname, @@ -135,11 +133,9 @@ export default function ({ getService }: FtrProviderContext) { } await ml.dataVisualizerIndexBased.assertViewInDiscoverCard(testUser.discoverAvailable); - // @TODO: Re-enable in follow up - // await ml.testExecution.logTestStep('should not display job cards'); - // await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists(); - // await ml.dataVisualizerIndexBased.assertRecognizerCardNotExists(ecExpectedModuleId); - // await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists(); + await ml.testExecution.logTestStep('should not display job cards'); + await ml.dataVisualizerIndexBased.assertCreateAdvancedJobCardNotExists(); + await ml.dataVisualizerIndexBased.assertCreateDataFrameAnalyticsCardNotExists(); }); it('should display elements on File Data Visualizer page correctly', async () => {