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] Fix analytics list on management page. #74254

Merged
merged 4 commits into from
Aug 6, 2020
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/

import React, { useEffect, useState, Fragment, FC } from 'react';
import { Router } from 'react-router-dom';
import { i18n } from '@kbn/i18n';
import { CoreStart } from 'kibana/public';

Expand All @@ -20,6 +21,8 @@ import {
EuiTitle,
} from '@elastic/eui';

import { ManagementAppMountParams } from '../../../../../../../../../src/plugins/management/public/';

import { checkGetManagementMlJobsResolver } from '../../../../capabilities/check_capabilities';
import { KibanaContextProvider } from '../../../../../../../../../src/plugins/kibana_react/public';

Expand All @@ -30,6 +33,7 @@ import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/a
import { AccessDeniedPage } from '../access_denied_page';

interface Tab {
'data-test-subj': string;
id: string;
name: string;
content: any;
Expand All @@ -38,6 +42,7 @@ interface Tab {
function getTabs(isMlEnabledInSpace: boolean): Tab[] {
return [
{
'data-test-subj': 'mlStackManagementJobsListAnomalyDetectionTab',
id: 'anomaly_detection_jobs',
name: i18n.translate('xpack.ml.management.jobsList.anomalyDetectionTab', {
defaultMessage: 'Anomaly detection',
Expand All @@ -50,6 +55,7 @@ function getTabs(isMlEnabledInSpace: boolean): Tab[] {
),
},
{
'data-test-subj': 'mlStackManagementJobsListAnalyticsTab',
id: 'analytics_jobs',
name: i18n.translate('xpack.ml.management.jobsList.analyticsTab', {
defaultMessage: 'Analytics',
Expand All @@ -67,7 +73,10 @@ function getTabs(isMlEnabledInSpace: boolean): Tab[] {
];
}

export const JobsListPage: FC<{ coreStart: CoreStart }> = ({ coreStart }) => {
export const JobsListPage: FC<{
coreStart: CoreStart;
history: ManagementAppMountParams['history'];
}> = ({ coreStart, history }) => {
const [initialized, setInitialized] = useState(false);
const [accessDenied, setAccessDenied] = useState(false);
const [isMlEnabledInSpace, setIsMlEnabledInSpace] = useState(false);
Expand Down Expand Up @@ -128,46 +137,51 @@ export const JobsListPage: FC<{ coreStart: CoreStart }> = ({ coreStart }) => {
return (
<I18nContext>
<KibanaContextProvider services={{ ...coreStart }}>
<EuiPageContent id="kibanaManagementMLSection">
<EuiTitle size="l">
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<h1>
{i18n.translate('xpack.ml.management.jobsList.jobsListTitle', {
defaultMessage: 'Machine Learning Jobs',
})}
</h1>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
target="_blank"
iconType="help"
iconSide="left"
color="primary"
href={
currentTabId === 'anomaly_detection_jobs'
? anomalyDetectionJobsUrl
: anomalyJobsUrl
}
>
{currentTabId === 'anomaly_detection_jobs'
? anomalyDetectionDocsLabel
: analyticsDocsLabel}
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiTitle>
<EuiSpacer size="s" />
<EuiTitle size="s">
<EuiText color="subdued">
{i18n.translate('xpack.ml.management.jobsList.jobsListTagline', {
defaultMessage: 'View machine learning analytics and anomaly detection jobs.',
})}
</EuiText>
</EuiTitle>
<EuiSpacer size="l" />
<EuiPageContentBody>{renderTabs()}</EuiPageContentBody>
</EuiPageContent>
<Router history={history}>
<EuiPageContent
id="kibanaManagementMLSection"
data-test-subj="mlPageStackManagementJobsList"
>
<EuiTitle size="l">
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<h1>
{i18n.translate('xpack.ml.management.jobsList.jobsListTitle', {
defaultMessage: 'Machine Learning Jobs',
})}
</h1>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButtonEmpty
target="_blank"
iconType="help"
iconSide="left"
color="primary"
href={
currentTabId === 'anomaly_detection_jobs'
? anomalyDetectionJobsUrl
: anomalyJobsUrl
}
>
{currentTabId === 'anomaly_detection_jobs'
? anomalyDetectionDocsLabel
: analyticsDocsLabel}
</EuiButtonEmpty>
</EuiFlexItem>
</EuiFlexGroup>
</EuiTitle>
<EuiSpacer size="s" />
<EuiTitle size="s">
<EuiText color="subdued">
{i18n.translate('xpack.ml.management.jobsList.jobsListTagline', {
defaultMessage: 'View machine learning analytics and anomaly detection jobs.',
})}
</EuiText>
</EuiTitle>
<EuiSpacer size="l" />
<EuiPageContentBody>{renderTabs()}</EuiPageContentBody>
</EuiPageContent>
</Router>
</KibanaContextProvider>
</I18nContext>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ import { JobsListPage } from './components';
import { getJobsListBreadcrumbs } from '../breadcrumbs';
import { setDependencyCache, clearCache } from '../../util/dependency_cache';

const renderApp = (element: HTMLElement, coreStart: CoreStart) => {
ReactDOM.render(React.createElement(JobsListPage, { coreStart }), element);
const renderApp = (
element: HTMLElement,
history: ManagementAppMountParams['history'],
coreStart: CoreStart
) => {
ReactDOM.render(React.createElement(JobsListPage, { coreStart, history }), element);
return () => {
unmountComponentAtNode(element);
clearCache();
Expand All @@ -36,5 +40,5 @@ export async function mountApp(

params.setBreadcrumbs(getJobsListBreadcrumbs());

return renderApp(params.element, coreStart);
return renderApp(params.element, params.history, coreStart);
}
12 changes: 12 additions & 0 deletions x-pack/test/functional/apps/ml/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,17 @@ export default function ({ getService }: FtrProviderContext) {
await ml.dataVisualizer.assertDataVisualizerImportDataCardExists();
await ml.dataVisualizer.assertDataVisualizerIndexDataCardExists();
});

it('it should load the stack management with the ML menu item being present', async () => {
await ml.navigation.navigateToStackManagement();
});

it('it should load the jobs list page in stack management', async () => {
await ml.navigation.navigateToStackManagementJobsListPage();
});

it('it should load the analytics jobs list page in stack management', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: "it" at the beginning of the sentences seems redundant 🙂

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course 😅 Fixed in 0a1325e.

await ml.navigation.navigateToStackManagementJobsListPageAnalyticsTab();
});
});
}
27 changes: 27 additions & 0 deletions x-pack/test/functional/services/ml/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ export function MachineLearningNavigationProvider({
});
},

async navigateToStackManagement() {
await retry.tryForTime(60 * 1000, async () => {
await PageObjects.common.navigateToApp('management');
await testSubjects.existOrFail('jobsListLink', { timeout: 2000 });
});
},

async assertTabsExist(tabTypeSubject: string, areaSubjects: string[]) {
await retry.tryForTime(10000, async () => {
const allTabs = await testSubjects.findAll(`~${tabTypeSubject}`, 3);
Expand Down Expand Up @@ -76,5 +83,25 @@ export function MachineLearningNavigationProvider({
async navigateToSettings() {
await this.navigateToArea('~mlMainTab & ~settings', 'mlPageSettings');
},

async navigateToStackManagementJobsListPage() {
// clicks the jobsListLink and loads the jobs list page
await testSubjects.click('jobsListLink');
await retry.tryForTime(60 * 1000, async () => {
// verify that the overall page is present
await testSubjects.existOrFail('mlPageStackManagementJobsList');
// verify that the default tab with the anomaly detection jobs list got loaded
await testSubjects.existOrFail('ml-jobs-list');
});
},

async navigateToStackManagementJobsListPageAnalyticsTab() {
// clicks the `Analytics` tab and loads the analytics list page
await testSubjects.click('mlStackManagementJobsListAnalyticsTab');
await retry.tryForTime(60 * 1000, async () => {
// verify that the empty prompt for analytics jobs list got loaded
await testSubjects.existOrFail('mlNoDataFrameAnalyticsFound');
});
},
};
}