fix link to analytics results from management (#69550)

This commit is contained in:
Melissa Alvarez 2020-06-23 16:19:07 -04:00 committed by GitHub
parent 22d09a3bbd
commit e87a4b2a31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 166 additions and 130 deletions

View file

@ -344,7 +344,7 @@ export function getCloneAction(createAnalyticsForm: CreateAnalyticsFormProps) {
}
interface CloneActionProps {
item: DeepReadonly<DataFrameAnalyticsListRow>;
item: DataFrameAnalyticsListRow;
createAnalyticsForm: CreateAnalyticsFormProps;
}

View file

@ -4,10 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/
import React from 'react';
import React, { FC } from 'react';
import { i18n } from '@kbn/i18n';
import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui';
import { DeepReadonly } from '../../../../../../../common/types/common';
import {
checkPermission,
@ -21,6 +20,7 @@ import {
isClassificationAnalysis,
} from '../../../../common/analytics';
import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form';
import { useMlKibana } from '../../../../../contexts/kibana';
import { CloneAction } from './action_clone';
import { getResultsUrl, isDataFrameAnalyticsRunning, DataFrameAnalyticsListRow } from './common';
@ -29,87 +29,123 @@ import { stopAnalytics } from '../../services/analytics_service';
import { StartAction } from './action_start';
import { DeleteAction } from './action_delete';
export const AnalyticsViewAction = {
interface Props {
item: DataFrameAnalyticsListRow;
isManagementTable: boolean;
}
const AnalyticsViewButton: FC<Props> = ({ item, isManagementTable }) => {
const {
services: {
application: { navigateToUrl, navigateToApp },
},
} = useMlKibana();
const analysisType = getAnalysisType(item.config.analysis);
const isDisabled =
!isRegressionAnalysis(item.config.analysis) &&
!isOutlierAnalysis(item.config.analysis) &&
!isClassificationAnalysis(item.config.analysis);
const url = getResultsUrl(item.id, analysisType);
const navigator = isManagementTable
? () => navigateToApp('ml', { path: url })
: () => navigateToUrl(url);
return (
<EuiButtonEmpty
isDisabled={isDisabled}
onClick={navigator}
size="xs"
color="text"
iconType="visTable"
aria-label={i18n.translate('xpack.ml.dataframe.analyticsList.viewAriaLabel', {
defaultMessage: 'View',
})}
data-test-subj="mlAnalyticsJobViewButton"
>
{i18n.translate('xpack.ml.dataframe.analyticsList.viewActionName', {
defaultMessage: 'View',
})}
</EuiButtonEmpty>
);
};
interface Action {
isPrimary?: boolean;
render: (item: DataFrameAnalyticsListRow) => any;
}
export const getAnalyticsViewAction = (isManagementTable: boolean = false): Action => ({
isPrimary: true,
render: (item: DataFrameAnalyticsListRow) => {
const analysisType = getAnalysisType(item.config.analysis);
const isDisabled =
!isRegressionAnalysis(item.config.analysis) &&
!isOutlierAnalysis(item.config.analysis) &&
!isClassificationAnalysis(item.config.analysis);
render: (item: DataFrameAnalyticsListRow) => (
<AnalyticsViewButton item={item} isManagementTable={isManagementTable} />
),
});
const url = getResultsUrl(item.id, analysisType);
return (
<EuiButtonEmpty
isDisabled={isDisabled}
onClick={() => (window.location.href = url)}
size="xs"
color="text"
iconType="visTable"
aria-label={i18n.translate('xpack.ml.dataframe.analyticsList.viewAriaLabel', {
defaultMessage: 'View',
})}
data-test-subj="mlAnalyticsJobViewButton"
>
{i18n.translate('xpack.ml.dataframe.analyticsList.viewActionName', {
defaultMessage: 'View',
})}
</EuiButtonEmpty>
);
},
};
export const getActions = (createAnalyticsForm: CreateAnalyticsFormProps) => {
export const getActions = (
createAnalyticsForm: CreateAnalyticsFormProps,
isManagementTable: boolean
) => {
const canStartStopDataFrameAnalytics: boolean = checkPermission('canStartStopDataFrameAnalytics');
const actions: Action[] = [getAnalyticsViewAction(isManagementTable)];
return [
AnalyticsViewAction,
{
render: (item: DataFrameAnalyticsListRow) => {
if (!isDataFrameAnalyticsRunning(item.stats.state)) {
return <StartAction item={item} />;
}
if (isManagementTable === false) {
actions.push(
...[
{
render: (item: DataFrameAnalyticsListRow) => {
if (!isDataFrameAnalyticsRunning(item.stats.state)) {
return <StartAction item={item} />;
}
const buttonStopText = i18n.translate('xpack.ml.dataframe.analyticsList.stopActionName', {
defaultMessage: 'Stop',
});
const buttonStopText = i18n.translate(
'xpack.ml.dataframe.analyticsList.stopActionName',
{
defaultMessage: 'Stop',
}
);
const stopButton = (
<EuiButtonEmpty
size="xs"
color="text"
disabled={!canStartStopDataFrameAnalytics}
iconType="stop"
onClick={() => stopAnalytics(item)}
aria-label={buttonStopText}
data-test-subj="mlAnalyticsJobStopButton"
>
{buttonStopText}
</EuiButtonEmpty>
);
if (!canStartStopDataFrameAnalytics) {
return (
<EuiToolTip
position="top"
content={createPermissionFailureMessage('canStartStopDataFrameAnalytics')}
>
{stopButton}
</EuiToolTip>
);
}
const stopButton = (
<EuiButtonEmpty
size="xs"
color="text"
disabled={!canStartStopDataFrameAnalytics}
iconType="stop"
onClick={() => stopAnalytics(item)}
aria-label={buttonStopText}
data-test-subj="mlAnalyticsJobStopButton"
>
{buttonStopText}
</EuiButtonEmpty>
);
if (!canStartStopDataFrameAnalytics) {
return (
<EuiToolTip
position="top"
content={createPermissionFailureMessage('canStartStopDataFrameAnalytics')}
>
{stopButton}
</EuiToolTip>
);
}
return stopButton;
},
},
{
render: (item: DataFrameAnalyticsListRow) => {
return <DeleteAction item={item} />;
},
},
{
render: (item: DeepReadonly<DataFrameAnalyticsListRow>) => {
return <CloneAction item={item} createAnalyticsForm={createAnalyticsForm} />;
},
},
];
return stopButton;
},
},
{
render: (item: DataFrameAnalyticsListRow) => {
return <DeleteAction item={item} />;
},
},
{
render: (item: DataFrameAnalyticsListRow) => {
return <CloneAction item={item} createAnalyticsForm={createAnalyticsForm} />;
},
},
]
);
}
return actions;
};

View file

@ -33,7 +33,7 @@ import {
DataFrameAnalyticsListRow,
DataFrameAnalyticsStats,
} from './common';
import { getActions, AnalyticsViewAction } from './actions';
import { getActions } from './actions';
enum TASK_STATE_COLOR {
analyzing = 'primary',
@ -148,8 +148,7 @@ export const getColumns = (
isMlEnabledInSpace: boolean = true,
createAnalyticsForm?: CreateAnalyticsFormProps
) => {
const actions =
isManagementTable === true ? [AnalyticsViewAction] : getActions(createAnalyticsForm!);
const actions = getActions(createAnalyticsForm!, isManagementTable);
function toggleDetails(item: DataFrameAnalyticsListRow) {
const index = expandedRowItemIds.indexOf(item.config.id);

View file

@ -122,5 +122,5 @@ export function isCompletedAnalyticsJob(stats: DataFrameAnalyticsStats) {
}
export function getResultsUrl(jobId: string, analysisType: string) {
return `ml#/data_frame_analytics/exploration?_g=(ml:(jobId:${jobId},analysisType:${analysisType}))`;
return `#/data_frame_analytics/exploration?_g=(ml:(jobId:${jobId},analysisType:${analysisType}))`;
}

View file

@ -21,6 +21,7 @@ import {
} from '@elastic/eui';
import { checkGetManagementMlJobsResolver } from '../../../../capabilities/check_capabilities';
import { KibanaContextProvider } from '../../../../../../../../../src/plugins/kibana_react/public';
import { getDocLinks } from '../../../../util/dependency_cache';
// @ts-ignore undeclared module
@ -65,13 +66,12 @@ function getTabs(isMlEnabledInSpace: boolean): Tab[] {
];
}
export const JobsListPage: FC<{ I18nContext: CoreStart['i18n']['Context'] }> = ({
I18nContext,
}) => {
export const JobsListPage: FC<{ coreStart: CoreStart }> = ({ coreStart }) => {
const [initialized, setInitialized] = useState(false);
const [isMlEnabledInSpace, setIsMlEnabledInSpace] = useState(false);
const tabs = getTabs(isMlEnabledInSpace);
const [currentTabId, setCurrentTabId] = useState(tabs[0].id);
const I18nContext = coreStart.i18n.Context;
const check = async () => {
try {
@ -122,46 +122,48 @@ export const JobsListPage: FC<{ I18nContext: CoreStart['i18n']['Context'] }> = (
return (
<I18nContext>
<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>
<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>
</KibanaContextProvider>
</I18nContext>
);
};

View file

@ -14,8 +14,7 @@ import { getJobsListBreadcrumbs } from '../breadcrumbs';
import { setDependencyCache, clearCache } from '../../util/dependency_cache';
const renderApp = (element: HTMLElement, coreStart: CoreStart) => {
const I18nContext = coreStart.i18n.Context;
ReactDOM.render(React.createElement(JobsListPage, { I18nContext }), element);
ReactDOM.render(React.createElement(JobsListPage, { coreStart }), element);
return () => {
unmountComponentAtNode(element);
clearCache();

View file

@ -23,7 +23,7 @@ import {
getTaskStateBadge,
progressColumn,
} from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/columns';
import { AnalyticsViewAction } from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/actions';
import { getAnalyticsViewAction } from '../../../data_frame_analytics/pages/analytics_management/components/analytics_list/actions';
import { formatHumanReadableDateTimeSeconds } from '../../../util/date_utils';
const MlInMemoryTable = mlInMemoryTableFactory<DataFrameAnalyticsListRow>();
@ -82,7 +82,7 @@ export const AnalyticsTable: FC<Props> = ({ items }) => {
name: i18n.translate('xpack.ml.overview.analyticsList.tableActionLabel', {
defaultMessage: 'Actions',
}),
actions: [AnalyticsViewAction],
actions: [getAnalyticsViewAction()],
width: '100px',
},
];