Skip to content

Commit

Permalink
[ML] Kibana Management Jobs list: Ensure proper title, tagline, and l…
Browse files Browse the repository at this point in the history
…ink to documentation (#43418) (#43585)

* Update KM jobs list title and add tag line and link to docs

* add spaces column to analytics table for use in Kibana management

* add refresh button to kibana management analytics jobs list

* ensure refresh button does not cause bounce when loading

* move refreshInterval hook to page component

* add default value for analyticsTable prop
  • Loading branch information
alvarezmelissa87 committed Aug 20, 2019
1 parent 9d89d37 commit 99e7b20
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 46 deletions.
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

0 comments on commit 99e7b20

Please sign in to comment.