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] Kibana Management Jobs list: Ensure proper title, tagline, and link to documentation #43418

Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import { getAnalyticsFactory } from '../../services/analytics_service';
import { getColumns } from './columns';
import { ExpandedRow } from './expanded_row';
import { ProgressBar, AnalyticsTable } from './analytics_table';
import { useRefreshInterval } from './use_refresh_interval';

function getItemIdToExpandedRowMap(
itemIds: DataFrameAnalyticsId[],
Expand Down Expand Up @@ -65,12 +64,15 @@ function stringMatch(str: string | undefined, substr: string) {

interface Props {
isManagementTable?: boolean;
blockRefresh?: boolean;
}
// isManagementTable - for use in Kibana managagement ML section
export const DataFrameAnalyticsList: FC<Props> = ({ isManagementTable }) => {
export const DataFrameAnalyticsList: FC<Props> = ({
isManagementTable = false,
blockRefresh = false,
}) => {
const [isInitialized, setIsInitialized] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [blockRefresh, setBlockRefresh] = useState(false);
const [filterActive, setFilterActive] = useState(false);

const [analytics, setAnalytics] = useState<DataFrameAnalyticsListRow[]>([]);
Expand Down Expand Up @@ -101,8 +103,6 @@ export const DataFrameAnalyticsList: FC<Props> = ({ isManagementTable }) => {
isLoading: setIsLoading,
onRefresh: () => getAnalytics(true),
});
// Call useRefreshInterval() after the subscription above is set up.
useRefreshInterval(setBlockRefresh);

const onQueryChange = ({ query, error }: { query: Query; error: any }) => {
if (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export const getColumns = (
name: 'ID',
sortable: true,
truncateText: true,
width: isManagementTable === true ? '20%' : undefined,
},
// Description is not supported yet by API
/*
Expand All @@ -124,6 +125,7 @@ export const getColumns = (
}),
sortable: true,
truncateText: true,
width: isManagementTable === true ? '25%' : undefined,
},
{
field: DataFrameAnalyticsListColumn.configDestIndex,
Expand All @@ -132,6 +134,7 @@ export const getColumns = (
}),
sortable: true,
truncateText: true,
width: isManagementTable === true ? '20%' : undefined,
},
{
name: i18n.translate('xpack.ml.dataframe.analyticsList.status', { defaultMessage: 'Status' }),
Expand Down Expand Up @@ -208,7 +211,14 @@ export const getColumns = (
},
];

if (isManagementTable === false) {
if (isManagementTable === true) {
columns.push({
name: i18n.translate('xpack.ml.jobsList.analyticsSpacesLabel', {
defaultMessage: 'Spaces',
}),
render: () => <EuiBadge color={'hollow'}>{'all'}</EuiBadge>,
});
} else {
columns.push({
name: i18n.translate('xpack.ml.dataframe.analyticsList.tableActionLabel', {
defaultMessage: 'Actions',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,25 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { FC } from 'react';
import React, { FC, useState } from 'react';

import { EuiButtonEmpty } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import { useRefreshAnalyticsList } from '../../../../common';

interface RefreshAnalyticsListButtonProps {
isLoading: boolean;
onClick(): void;
}
export const RefreshAnalyticsListButton: FC<RefreshAnalyticsListButtonProps> = ({
onClick,
isLoading,
}) => (
<EuiButtonEmpty
data-test-subj="mlRefreshAnalyticsListButton"
onClick={onClick}
isLoading={isLoading}
>
<FormattedMessage
id="xpack.ml.dataframe.analyticsList.refreshButtonLabel"
defaultMessage="Refresh"
/>
</EuiButtonEmpty>
);
export const RefreshAnalyticsListButton: FC = () => {
const [isLoading, setIsLoading] = useState(false);
const { refresh } = useRefreshAnalyticsList({ isLoading: setIsLoading });
return (
<EuiButtonEmpty
data-test-subj="mlRefreshAnalyticsListButton"
onClick={refresh}
isLoading={isLoading}
>
<FormattedMessage
id="xpack.ml.dataframe.analyticsList.refreshButtonLabel"
defaultMessage="Refresh"
/>
</EuiButtonEmpty>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,15 @@ import {
} from '@elastic/eui';

import { NavigationMenu } from '../../../components/navigation_menu/navigation_menu';
import { useRefreshAnalyticsList } from '../../common';
import { CreateAnalyticsButton } from './components/create_analytics_button';
import { DataFrameAnalyticsList } from './components/analytics_list';
import { RefreshAnalyticsListButton } from './components/refresh_analytics_list_button';
import { useRefreshInterval } from './components/analytics_list/use_refresh_interval';

export const Page: FC = () => {
const [isLoading, setIsLoading] = useState(false);
const { refresh } = useRefreshAnalyticsList({ isLoading: setIsLoading });
const [blockRefresh, setBlockRefresh] = useState(false);

useRefreshInterval(setBlockRefresh);

return (
<Fragment>
Expand Down Expand Up @@ -68,7 +69,7 @@ export const Page: FC = () => {
<EuiFlexGroup alignItems="center">
{/* grow={false} fixes IE11 issue with nested flex */}
<EuiFlexItem grow={false}>
{<RefreshAnalyticsListButton onClick={refresh} isLoading={isLoading} />}
<RefreshAnalyticsListButton />
</EuiFlexItem>
{/* grow={false} fixes IE11 issue with nested flex */}
<EuiFlexItem grow={false}>
Expand All @@ -80,7 +81,7 @@ export const Page: FC = () => {
<EuiPageContentBody>
<EuiSpacer size="l" />
<EuiPanel>
<DataFrameAnalyticsList />
<DataFrameAnalyticsList blockRefresh={blockRefresh} />
</EuiPanel>
</EuiPageContentBody>
</EuiPageBody>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,11 @@
.mlTaskStateBadge {
max-width: 100px;
}

.mlKibanaManagement__analyticsSpacer {
clear: both;
}

.mlKibanaManagement__analyticsRefreshButton {
float: right;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,38 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { Fragment, FC } from 'react';
import React, { Fragment, FC, useState } from 'react';
import { i18n } from '@kbn/i18n';
import { I18nContext } from 'ui/i18n';
import {
EuiButtonEmpty,
EuiFlexGroup,
EuiFlexItem,
EuiPageContent,
EuiPageContentBody,
EuiPageContentHeader,
EuiPageContentHeaderSection,
EuiSpacer,
EuiTabbedContent,
EuiText,
EuiTitle,
} from '@elastic/eui';
import { metadata } from 'ui/metadata';

// @ts-ignore undeclared module
import { JobsListView } from '../../../../jobs/jobs_list/components/jobs_list_view';
import { DataFrameAnalyticsList } from '../../../../data_frame_analytics/pages/analytics_management/components/analytics_list';
import { RefreshAnalyticsListButton } from '../../../../data_frame_analytics/pages/analytics_management/components/refresh_analytics_list_button';

interface Props {
isMlEnabledInSpace: boolean;
}
interface Tab {
id: string;
name: string;
content: any;
}

export const JobsListPage: FC<Props> = ({ isMlEnabledInSpace }) => {
const tabs = [
function getTabs(isMlEnabledInSpace: boolean): Tab[] {
return [
{
id: 'anomaly_detection_jobs',
name: i18n.translate('xpack.ml.management.jobsList.anomalyDetectionTab', {
Expand All @@ -47,30 +56,88 @@ export const JobsListPage: FC<Props> = ({ isMlEnabledInSpace }) => {
content: (
<Fragment>
<EuiSpacer size="m" />
<span className="mlKibanaManagement__analyticsRefreshButton">
<RefreshAnalyticsListButton />
</span>
<EuiSpacer size="s" className="mlKibanaManagement__analyticsSpacer" />
<DataFrameAnalyticsList isManagementTable={true} />
</Fragment>
),
},
];
}

export const JobsListPage: FC<Props> = ({ isMlEnabledInSpace }) => {
const tabs = getTabs(isMlEnabledInSpace);
const [currentTabId, setCurrentTabId] = useState(tabs[0].id);

// metadata.branch corresponds to the version used in documentation links.
const anomalyDetectionJobsUrl = `https://www.elastic.co/guide/en/elastic-stack-overview/${metadata.branch}/ml-jobs.html`;
const anomalyJobsUrl = `https://www.elastic.co/guide/en/elastic-stack-overview/${metadata.branch}/ml-dfanalytics.html`;

const anomalyDetectionDocsLabel = i18n.translate(
'xpack.ml.management.jobsList.anomalyDetectionDocsLabel',
{
defaultMessage: 'Anomaly detection jobs docs',
}
);
const analyticsDocsLabel = i18n.translate('xpack.ml.management.jobsList.analyticsDocsLabel', {
defaultMessage: 'Analytics jobs docs',
});

function renderTabs() {
return <EuiTabbedContent size="s" tabs={tabs} initialSelectedTab={tabs[0]} />;
return (
<EuiTabbedContent
onTabClick={({ id }: { id: string }) => {
setCurrentTabId(id);
}}
size="s"
tabs={getTabs(isMlEnabledInSpace)}
initialSelectedTab={tabs[0]}
/>
);
}

return (
<I18nContext>
<EuiPageContent>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle>
<h2>
<EuiTitle size="l">
<EuiFlexGroup alignItems="center" justifyContent="spaceBetween">
<EuiFlexItem grow={false}>
<h1>
{i18n.translate('xpack.ml.management.jobsList.jobsListTitle', {
defaultMessage: 'Jobs',
defaultMessage: 'Machine Learning Jobs',
})}
</h2>
</EuiTitle>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
</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>
</I18nContext>
Expand Down