[ML] Add doc link in help menu on more ML pages (#86500)

This commit is contained in:
Lisa Cawley 2021-01-04 12:32:41 -08:00 committed by GitHub
parent a0b4aa35b9
commit 96e9fdd78c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 261 additions and 70 deletions

View file

@ -20,44 +20,53 @@ import {
EuiTitle,
} from '@elastic/eui';
import { NavigationMenu } from '../components/navigation_menu';
import { HelpMenu } from '../components/help_menu';
import { useMlKibana } from '../contexts/kibana';
export const Page = () => (
<Fragment>
<NavigationMenu tabId="access-denied" />
<EuiPage>
<EuiPageBody>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle>
<h1>
<FormattedMessage
id="xpack.ml.management.jobsList.accessDeniedTitle"
defaultMessage="Access denied"
/>
</h1>
</EuiTitle>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
<EuiPageContentBody>
<EuiSpacer size="m" />
<EuiCallOut
title={i18n.translate('xpack.ml.accessDenied.label', {
defaultMessage: 'Insufficient permissions',
})}
color="danger"
iconType="cross"
>
<EuiText size="s">
<p>
<FormattedMessage
id="xpack.ml.accessDenied.description"
defaultMessage="You dont have permission to access the ML plugin"
/>
</p>
</EuiText>
</EuiCallOut>
</EuiPageContentBody>
</EuiPageBody>
</EuiPage>
</Fragment>
);
export const Page = () => {
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.guide;
return (
<Fragment>
<NavigationMenu tabId="access-denied" />
<EuiPage>
<EuiPageBody>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle>
<h1>
<FormattedMessage
id="xpack.ml.management.jobsList.accessDeniedTitle"
defaultMessage="Access denied"
/>
</h1>
</EuiTitle>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
<EuiPageContentBody>
<EuiSpacer size="m" />
<EuiCallOut
title={i18n.translate('xpack.ml.accessDenied.label', {
defaultMessage: 'Insufficient permissions',
})}
color="danger"
iconType="cross"
>
<EuiText size="s">
<p>
<FormattedMessage
id="xpack.ml.accessDenied.description"
defaultMessage="You dont have permission to access the ML plugin"
/>
</p>
</EuiText>
</EuiCallOut>
</EuiPageContentBody>
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
};

View file

@ -23,34 +23,43 @@ import { ClassificationExploration } from './components/classification_explorati
import { ANALYSIS_CONFIG_TYPE } from '../../../../../common/constants/data_frame_analytics';
import { DataFrameAnalysisConfigType } from '../../../../../common/types/data_frame_analytics';
import { HelpMenu } from '../../../components/help_menu';
import { useMlKibana } from '../../../contexts/kibana';
export const Page: FC<{
jobId: string;
analysisType: DataFrameAnalysisConfigType;
}> = ({ jobId, analysisType }) => (
<>
<NavigationMenu tabId="data_frame_analytics" />
<EuiPage data-test-subj="mlPageDataFrameAnalyticsExploration">
<EuiPageBody style={{ maxWidth: 'calc(100% - 0px)' }}>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle>
<h1>{jobId}</h1>
</EuiTitle>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
<EuiPageContentBody style={{ maxWidth: 'calc(100% - 0px)' }}>
{analysisType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION && (
<OutlierExploration jobId={jobId} />
)}
{analysisType === ANALYSIS_CONFIG_TYPE.REGRESSION && (
<RegressionExploration jobId={jobId} />
)}
{analysisType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION && (
<ClassificationExploration jobId={jobId} />
)}
</EuiPageContentBody>
</EuiPageBody>
</EuiPage>
</>
);
}> = ({ jobId, analysisType }) => {
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.dataFrameAnalytics;
return (
<>
<NavigationMenu tabId="data_frame_analytics" />
<EuiPage data-test-subj="mlPageDataFrameAnalyticsExploration">
<EuiPageBody style={{ maxWidth: 'calc(100% - 0px)' }}>
<EuiPageContentHeader>
<EuiPageContentHeaderSection>
<EuiTitle>
<h1>{jobId}</h1>
</EuiTitle>
</EuiPageContentHeaderSection>
</EuiPageContentHeader>
<EuiPageContentBody style={{ maxWidth: 'calc(100% - 0px)' }}>
{analysisType === ANALYSIS_CONFIG_TYPE.OUTLIER_DETECTION && (
<OutlierExploration jobId={jobId} />
)}
{analysisType === ANALYSIS_CONFIG_TYPE.REGRESSION && (
<RegressionExploration jobId={jobId} />
)}
{analysisType === ANALYSIS_CONFIG_TYPE.CLASSIFICATION && (
<ClassificationExploration jobId={jobId} />
)}
</EuiPageContentBody>
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</>
);
};

View file

@ -38,6 +38,8 @@ import { usePageUrlState } from '../../../util/url_state';
import { ListingPageUrlState } from '../../../../../common/types/common';
import { DataFrameAnalyticsListColumn } from './components/analytics_list/common';
import { ML_PAGES } from '../../../../../common/constants/ml_url_generator';
import { HelpMenu } from '../../../components/help_menu';
import { useMlKibana } from '../../../contexts/kibana';
export const getDefaultDFAListState = (): ListingPageUrlState => ({
pageIndex: 0,
@ -61,7 +63,10 @@ export const Page: FC = () => {
const selectedTabId = useMemo(() => location.pathname.split('/').pop(), [location]);
const mapJobId = globalState?.ml?.jobId;
const mapModelId = globalState?.ml?.modelId;
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.dataFrameAnalytics;
return (
<Fragment>
<NavigationMenu tabId="data_frame_analytics" />
@ -130,6 +135,7 @@ export const Page: FC = () => {
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
};

View file

@ -27,6 +27,7 @@ import { useTimefilter, useMlKibana, useNavigateToPath } from '../contexts/kiban
import { NavigationMenu } from '../components/navigation_menu';
import { getMaxBytesFormatted } from './file_based/components/utils';
import { HelpMenu } from '../components/help_menu';
function startTrialDescription() {
return (
@ -55,8 +56,10 @@ export const DatavisualizerSelector: FC = () => {
services: {
licenseManagement,
http: { basePath },
docLinks,
},
} = useMlKibana();
const helpLink = docLinks.links.ml.guide;
const navigateToPath = useNavigateToPath();
const startTrialVisible =
@ -205,6 +208,7 @@ export const DatavisualizerSelector: FC = () => {
)}
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
};

View file

@ -10,6 +10,8 @@ import { IUiSettingsClient } from 'kibana/public';
import { useTimefilter } from '../../contexts/kibana';
import { NavigationMenu } from '../../components/navigation_menu';
import { getIndexPatternsContract } from '../../util/index_utils';
import { HelpMenu } from '../../components/help_menu';
import { useMlKibana } from '../../contexts/kibana';
// @ts-ignore
import { FileDataVisualizerView } from './components/file_datavisualizer_view/index';
@ -21,10 +23,15 @@ export interface FileDataVisualizerPageProps {
export const FileDataVisualizerPage: FC<FileDataVisualizerPageProps> = ({ kibanaConfig }) => {
useTimefilter({ timeRangeSelector: false, autoRefreshSelector: false });
const indexPatterns = getIndexPatternsContract();
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.guide;
return (
<Fragment>
<NavigationMenu tabId="datavisualizer" />
<FileDataVisualizerView indexPatterns={indexPatterns} kibanaConfig={kibanaConfig} />
<HelpMenu docLink={helpLink} />
</Fragment>
);
};

View file

@ -54,6 +54,8 @@ import type { FieldRequestConfig, FieldVisConfig } from './common';
import type { DataVisualizerIndexBasedAppState } from '../../../../common/types/ml_url_generator';
import type { OverallStats } from '../../../../common/types/datavisualizer';
import { MlJobFieldType } from '../../../../common/types/field_types';
import { HelpMenu } from '../../components/help_menu';
import { useMlKibana } from '../../contexts/kibana';
interface DataVisualizerPageState {
overallStats: OverallStats;
@ -659,7 +661,10 @@ export const Page: FC = () => {
}
return { visibleFieldsCount: _visibleFieldsCount, totalFieldsCount: _totalFieldsCount };
}, [overallStats, showEmptyFields]);
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.guide;
return (
<Fragment>
<NavigationMenu tabId="datavisualizer" />
@ -747,6 +752,7 @@ export const Page: FC = () => {
</EuiPageContentBody>
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
};

View file

@ -11,6 +11,8 @@ import { JobsListView } from './components/jobs_list_view/index';
import { usePageUrlState } from '../../util/url_state';
import { ML_PAGES } from '../../../../common/constants/ml_url_generator';
import { ListingPageUrlState } from '../../../../common/types/common';
import { HelpMenu } from '../../components/help_menu';
import { useMlKibana } from '../../contexts/kibana';
interface JobsPageProps {
blockRefresh?: boolean;
@ -31,11 +33,15 @@ export const JobsPage: FC<JobsPageProps> = (props) => {
ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE,
getDefaultAnomalyDetectionJobsListState()
);
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.anomalyDetection;
return (
<div data-test-subj="mlPageJobManagement">
<NavigationMenu tabId="anomaly_detection" />
<JobsListView {...props} jobsViewState={pageState} onJobsViewStateUpdate={setPageState} />
<HelpMenu docLink={helpLink} />
</div>
);
};

View file

@ -44,6 +44,10 @@ jest.mock('../../util/url_state');
jest.mock('../../timeseriesexplorer/hooks/use_timeseriesexplorer_url_state');
jest.mock('../../components/help_menu', () => ({
HelpMenu: () => <div id="mockHelpMenu" />,
}));
jest.mock('../../contexts/kibana/kibana_context', () => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { of } = require('rxjs');
@ -85,6 +89,11 @@ jest.mock('../../contexts/kibana/kibana_context', () => {
addDanger: () => {},
},
},
docLinks: {
links: {
ml: { anomalyDetection: jest.fn() },
},
},
},
};
},

View file

@ -44,5 +44,8 @@ exports[`NewCalendar Renders new calendar form 1`] = `
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;

View file

@ -21,6 +21,8 @@ import { ml } from '../../../services/ml_api_service';
import { withKibana } from '../../../../../../../../src/plugins/kibana_react/public';
import { GLOBAL_CALENDAR } from '../../../../../common/constants/calendars';
import { ML_PAGES } from '../../../../../common/constants/ml_url_generator';
import { getDocLinks } from '../../../util/dependency_cache';
import { HelpMenu } from '../../../components/help_menu';
class NewCalendarUI extends Component {
static propTypes = {
@ -328,6 +330,8 @@ class NewCalendarUI extends Component {
isGlobalCalendar,
} = this.state;
const helpLink = getDocLinks().links.ml.calendars;
let modal = '';
if (isNewEventModalVisible) {
@ -389,6 +393,7 @@ class NewCalendarUI extends Component {
{modal}
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
}

View file

@ -11,6 +11,19 @@ jest.mock('../../../contexts/kibana/use_create_url', () => ({
jest.mock('../../../components/navigation_menu', () => ({
NavigationMenu: () => <div id="mockNavigationMenu" />,
}));
jest.mock('../../../components/help_menu', () => ({
HelpMenu: () => <div id="mockHelpMenu" />,
}));
jest.mock('../../../util/dependency_cache', () => ({
getDocLinks: () => ({
links: {
ml: { calendars: jest.fn() },
},
}),
}));
jest.mock('../../../capabilities/check_capabilities', () => ({
checkPermission: () => true,
}));

View file

@ -71,5 +71,8 @@ exports[`CalendarsList Renders calendar list with calendars 1`] = `
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;

View file

@ -25,6 +25,8 @@ import { deleteCalendars } from './delete_calendars';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { withKibana } from '../../../../../../../../src/plugins/kibana_react/public';
import { getDocLinks } from '../../../util/dependency_cache';
import { HelpMenu } from '../../../components/help_menu';
export class CalendarsListUI extends Component {
static propTypes = {
@ -104,6 +106,8 @@ export class CalendarsListUI extends Component {
const { canCreateCalendar, canDeleteCalendar } = this.props;
let destroyModal = '';
const helpLink = getDocLinks().links.ml.calendars;
if (this.state.isDestroyModalVisible) {
destroyModal = (
<EuiOverlayMask>
@ -168,6 +172,7 @@ export class CalendarsListUI extends Component {
{destroyModal}
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
}

View file

@ -13,6 +13,19 @@ import { CalendarsList } from './calendars_list';
jest.mock('../../../components/navigation_menu', () => ({
NavigationMenu: () => <div id="mockNavigationMenu" />,
}));
jest.mock('../../../components/help_menu', () => ({
HelpMenu: () => <div id="mockHelpMenu" />,
}));
jest.mock('../../../util/dependency_cache', () => ({
getDocLinks: () => ({
links: {
ml: { calendars: jest.fn() },
},
}),
}));
jest.mock('../../../capabilities/check_capabilities', () => ({
checkPermission: () => true,
}));

View file

@ -110,6 +110,9 @@ exports[`EditFilterList adds new items to filter list 1`] = `
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;
@ -225,6 +228,9 @@ exports[`EditFilterList renders after selecting an item and deleting it 1`] = `
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;
@ -335,6 +341,9 @@ exports[`EditFilterList renders after selecting an item and deleting it 2`] = `
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;
@ -429,6 +438,9 @@ exports[`EditFilterList renders the edit page for a new filter list and updates
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;
@ -523,6 +535,9 @@ exports[`EditFilterList renders the edit page for a new filter list and updates
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;
@ -634,6 +649,9 @@ exports[`EditFilterList renders the edit page for an existing filter list and up
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;
@ -745,6 +763,9 @@ exports[`EditFilterList renders the edit page for an existing filter list and up
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;
@ -856,5 +877,8 @@ exports[`EditFilterList updates the items per page 1`] = `
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;

View file

@ -35,6 +35,8 @@ import { NavigationMenu } from '../../../components/navigation_menu';
import { isValidFilterListId, saveFilterList } from './utils';
import { ml } from '../../../services/ml_api_service';
import { ML_PAGES } from '../../../../../common/constants/ml_url_generator';
import { getDocLinks } from '../../../util/dependency_cache';
import { HelpMenu } from '../../../components/help_menu';
const DEFAULT_ITEMS_PER_PAGE = 50;
@ -320,6 +322,8 @@ export class EditFilterListUI extends Component {
const totalItemCount = items !== undefined ? items.length : 0;
const helpLink = getDocLinks().links.ml.customRules;
return (
<Fragment>
<NavigationMenu tabId="settings" />
@ -393,6 +397,7 @@ export class EditFilterListUI extends Component {
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
}

View file

@ -8,6 +8,18 @@ jest.mock('../../../components/navigation_menu', () => ({
NavigationMenu: () => <div id="mockNavigationMenu" />,
}));
jest.mock('../../../components/help_menu', () => ({
HelpMenu: () => <div id="mockHelpMenu" />,
}));
jest.mock('../../../util/dependency_cache', () => ({
getDocLinks: () => ({
links: {
ml: { customRules: jest.fn() },
},
}),
}));
// Define the required mocks used for loading, saving and validating the filter list.
jest.mock('./utils', () => ({
isValidFilterListId: () => true,

View file

@ -43,5 +43,8 @@ exports[`Filter Lists renders a list of filters 1`] = `
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu
docLink={[MockFunction]}
/>
</Fragment>
`;

View file

@ -22,6 +22,9 @@ import { FilterListsHeader } from './header';
import { FilterListsTable } from './table';
import { ml } from '../../../services/ml_api_service';
import { getDocLinks } from '../../../util/dependency_cache';
import { HelpMenu } from '../../../components/help_menu';
export class FilterListsUI extends Component {
static displayName = 'FilterLists';
static propTypes = {
@ -85,6 +88,7 @@ export class FilterListsUI extends Component {
render() {
const { filterLists, selectedFilterLists } = this.state;
const { canCreateFilter, canDeleteFilter } = this.props;
const helpLink = getDocLinks().links.ml.customRules;
return (
<Fragment>
@ -111,6 +115,7 @@ export class FilterListsUI extends Component {
</EuiPageContent>
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
}

View file

@ -12,6 +12,19 @@ import { FilterLists } from './filter_lists';
jest.mock('../../../components/navigation_menu', () => ({
NavigationMenu: () => <div id="mockNavigationMenu" />,
}));
jest.mock('../../../components/help_menu', () => ({
HelpMenu: () => <div id="mockHelpMenu" />,
}));
jest.mock('../../../util/dependency_cache', () => ({
getDocLinks: () => ({
links: {
ml: { customRules: jest.fn() },
},
}),
}));
jest.mock('../../../capabilities/check_capabilities', () => ({
checkPermission: () => true,
}));

View file

@ -14,12 +14,27 @@ jest.mock('../components/navigation_menu', () => ({
NavigationMenu: () => <div id="mockNavigationMenu" />,
}));
jest.mock('../components/help_menu', () => ({
HelpMenu: () => <div id="mockHelpMenu" />,
}));
jest.mock('../contexts/kibana', () => ({
useNotifications: () => {
return {
toasts: { addDanger: jest.fn() },
};
},
useMlKibana: () => {
return {
services: {
docLinks: {
links: {
ml: { guide: jest.fn() },
},
},
},
};
},
}));
jest.mock('../contexts/kibana/use_create_url', () => ({

View file

@ -14,7 +14,14 @@ import { AnomalyDetectionSettings } from './anomaly_detection_settings';
import { NavigationMenu } from '../components/navigation_menu';
import { HelpMenu } from '../components/help_menu';
import { useMlKibana } from '../contexts/kibana';
export const Settings: FC = () => {
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.guide;
return (
<Fragment>
<NavigationMenu tabId="settings" />
@ -32,6 +39,7 @@ export const Settings: FC = () => {
<AnomalyDetectionSettings />
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</Fragment>
);
};

View file

@ -25,6 +25,9 @@ import { JobSelector } from '../components/job_selector';
import { NavigationMenu } from '../components/navigation_menu';
import { DatePickerWrapper } from '../components/navigation_menu/date_picker_wrapper';
import { HelpMenu } from '../components/help_menu';
import { useMlKibana } from '../contexts/kibana';
interface TimeSeriesExplorerPageProps {
dateFormatTz: string;
resizeRef?: any;
@ -35,6 +38,10 @@ export const TimeSeriesExplorerPage: FC<TimeSeriesExplorerPageProps> = ({
dateFormatTz,
resizeRef,
}) => {
const {
services: { docLinks },
} = useMlKibana();
const helpLink = docLinks.links.ml.anomalyDetection;
return (
<>
<NavigationMenu tabId="anomaly_detection" />
@ -78,6 +85,7 @@ export const TimeSeriesExplorerPage: FC<TimeSeriesExplorerPageProps> = ({
{children}
</EuiPageBody>
</EuiPage>
<HelpMenu docLink={helpLink} />
</div>
</>
);