mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Synthetics] Some ui code clean up (#149821)
This commit is contained in:
parent
be498a5c58
commit
a489d221dd
22 changed files with 270 additions and 566 deletions
|
@ -1,34 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
// app.test.js
|
||||
import React from 'react';
|
||||
import 'jest-styled-components';
|
||||
import { render } from '../../../utils/testing/rtl_helpers';
|
||||
import { SyntheticsPageTemplateComponent } from './synthetics_page_template';
|
||||
import { OVERVIEW_ROUTE } from '../../../../../../common/constants';
|
||||
|
||||
describe('SyntheticsPageTemplateComponent', () => {
|
||||
describe('styling', () => {
|
||||
// In this test we use snapshots because we're asserting on generated
|
||||
// styles. Writing assertions manually here could make this test really
|
||||
// convoluted, and it require us to manually update styling strings
|
||||
// according to `styled-components` generator, which is counter-productive.
|
||||
// In general, however, we avoid snaphshot tests.
|
||||
|
||||
it('does not apply header centering on bigger resolutions', () => {
|
||||
const { container } = render(<SyntheticsPageTemplateComponent path={OVERVIEW_ROUTE} />);
|
||||
expect(container.firstChild).toBeDefined();
|
||||
});
|
||||
|
||||
it('applies the header centering on mobile', () => {
|
||||
window.innerWidth = 600;
|
||||
const { container } = render(<SyntheticsPageTemplateComponent path={OVERVIEW_ROUTE} />);
|
||||
expect(container.firstChild).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import { EuiPageHeaderProps, EuiPageTemplateProps } from '@elastic/eui';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useInspectorContext } from '@kbn/observability-plugin/public';
|
||||
import { useSyntheticsDataView } from '../../../contexts';
|
||||
import { ClientPluginsStart } from '../../../../../plugin';
|
||||
import { EmptyStateLoading } from '../../monitors_page/overview/empty_state/empty_state_loading';
|
||||
import { EmptyStateError } from '../../monitors_page/overview/empty_state/empty_state_error';
|
||||
|
||||
interface Props {
|
||||
path: string;
|
||||
pageHeader?: EuiPageHeaderProps;
|
||||
}
|
||||
|
||||
export const SyntheticsPageTemplateComponent: React.FC<Props & EuiPageTemplateProps> = ({
|
||||
path,
|
||||
pageHeader,
|
||||
children,
|
||||
...pageTemplateProps
|
||||
}) => {
|
||||
const {
|
||||
services: { observability },
|
||||
} = useKibana<ClientPluginsStart>();
|
||||
|
||||
const PageTemplateComponent = observability.navigation.PageTemplate;
|
||||
|
||||
const { loading, error, hasData } = useSyntheticsDataView();
|
||||
const { inspectorAdapters } = useInspectorContext();
|
||||
|
||||
useEffect(() => {
|
||||
inspectorAdapters.requests.reset();
|
||||
}, [inspectorAdapters.requests]);
|
||||
|
||||
if (error) {
|
||||
return <EmptyStateError errors={[error]} />;
|
||||
}
|
||||
|
||||
const showLoading = loading && !hasData;
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageTemplateComponent
|
||||
pageHeader={pageHeader}
|
||||
data-test-subj={'synthetics-page-template'}
|
||||
isPageDataLoaded={loading === false}
|
||||
{...pageTemplateProps}
|
||||
>
|
||||
{showLoading && <EmptyStateLoading />}
|
||||
<div style={{ visibility: showLoading ? 'hidden' : 'initial' }}>{children}</div>
|
||||
</PageTemplateComponent>
|
||||
</>
|
||||
);
|
||||
};
|
|
@ -12,6 +12,7 @@ import moment from 'moment';
|
|||
import { AllSeries, createExploratoryViewUrl } from '@kbn/observability-plugin/public';
|
||||
import { euiStyled } from '@kbn/kibana-react-plugin/common';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { SYNTHETICS_INDEX_PATTERN } from '../../../../../../common/constants';
|
||||
import { JourneyStep } from '../../../../../../common/runtime_types';
|
||||
import { useSyntheticsStartPlugins } from '../../../contexts';
|
||||
|
||||
|
@ -78,7 +79,7 @@ export function StepFieldTrend({
|
|||
axisTitlesVisibility={{ x: false, yLeft: false, yRight: false }}
|
||||
legendIsVisible={false}
|
||||
dataTypesIndexPatterns={{
|
||||
synthetics: 'synthetics-*',
|
||||
synthetics: SYNTHETICS_INDEX_PATTERN,
|
||||
}}
|
||||
withActions={false}
|
||||
/>
|
||||
|
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { useHistory, useRouteMatch } from 'react-router-dom';
|
||||
import { EuiIcon, EuiPageHeaderProps } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { MonitorDetailsPageTitle } from './monitor_details_page_title';
|
||||
import { EditMonitorLink } from '../common/links/edit_monitor';
|
||||
import { RunTestManually } from './run_test_manually';
|
||||
import { MonitorDetailsLastRun } from './monitor_details_last_run';
|
||||
import { MonitorDetailsStatus } from './monitor_details_status';
|
||||
import { MonitorDetailsLocation } from './monitor_details_location';
|
||||
import { MonitorErrors } from './monitor_errors/monitor_errors';
|
||||
import { MonitorHistory } from './monitor_history/monitor_history';
|
||||
import { MonitorSummary } from './monitor_summary/monitor_summary';
|
||||
import { MonitorDetailsPage } from './monitor_details_page';
|
||||
import {
|
||||
MONITOR_ERRORS_ROUTE,
|
||||
MONITOR_HISTORY_ROUTE,
|
||||
MONITOR_ROUTE,
|
||||
OVERVIEW_ROUTE,
|
||||
} from '../../../../../common/constants';
|
||||
import { RouteProps } from '../../routes';
|
||||
|
||||
export const getMonitorDetailsRoute = (
|
||||
history: ReturnType<typeof useHistory>,
|
||||
syntheticsPath: string,
|
||||
baseTitle: string
|
||||
): RouteProps[] => {
|
||||
return [
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorDetails.title', {
|
||||
defaultMessage: 'Synthetics Monitor Details | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITOR_ROUTE,
|
||||
component: () => (
|
||||
<MonitorDetailsPage>
|
||||
<MonitorSummary />
|
||||
</MonitorDetailsPage>
|
||||
),
|
||||
dataTestSubj: 'syntheticsMonitorDetailsPage',
|
||||
pageHeader: getMonitorSummaryHeader(history, syntheticsPath, 'overview'),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorHistory.title', {
|
||||
defaultMessage: 'Synthetics Monitor History | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITOR_HISTORY_ROUTE,
|
||||
component: () => (
|
||||
<MonitorDetailsPage>
|
||||
<MonitorHistory />
|
||||
</MonitorDetailsPage>
|
||||
),
|
||||
dataTestSubj: 'syntheticsMonitorHistoryPage',
|
||||
pageHeader: getMonitorSummaryHeader(history, syntheticsPath, 'history'),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorErrors.title', {
|
||||
defaultMessage: 'Synthetics Monitor Errors | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITOR_ERRORS_ROUTE,
|
||||
component: () => (
|
||||
<MonitorDetailsPage>
|
||||
<MonitorErrors />
|
||||
</MonitorDetailsPage>
|
||||
),
|
||||
dataTestSubj: 'syntheticsMonitorHistoryPage',
|
||||
pageHeader: getMonitorSummaryHeader(history, syntheticsPath, 'errors'),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const getMonitorSummaryHeader = (
|
||||
history: ReturnType<typeof useHistory>,
|
||||
syntheticsPath: string,
|
||||
selectedTab: 'overview' | 'history' | 'errors'
|
||||
): EuiPageHeaderProps => {
|
||||
// Not a component, but it doesn't matter. Hooks are just functions
|
||||
const match = useRouteMatch<{ monitorId: string }>(MONITOR_ROUTE); // eslint-disable-line react-hooks/rules-of-hooks
|
||||
|
||||
if (!match) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const search = history.location.search;
|
||||
const monitorId = match.params.monitorId;
|
||||
|
||||
return {
|
||||
pageTitle: <MonitorDetailsPageTitle />,
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: (
|
||||
<>
|
||||
<EuiIcon size="s" type="arrowLeft" />{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorSummaryRoute.monitorBreadcrumb"
|
||||
defaultMessage="Monitors"
|
||||
/>
|
||||
</>
|
||||
),
|
||||
color: 'primary',
|
||||
'aria-current': false,
|
||||
href: `${syntheticsPath}${OVERVIEW_ROUTE}`,
|
||||
},
|
||||
],
|
||||
rightSideItems: [
|
||||
<EditMonitorLink />,
|
||||
<RunTestManually />,
|
||||
<MonitorDetailsLastRun />,
|
||||
<MonitorDetailsStatus />,
|
||||
<MonitorDetailsLocation />,
|
||||
],
|
||||
tabs: [
|
||||
{
|
||||
label: i18n.translate('xpack.synthetics.monitorOverviewTab.title', {
|
||||
defaultMessage: 'Overview',
|
||||
}),
|
||||
isSelected: selectedTab === 'overview',
|
||||
href: `${syntheticsPath}${MONITOR_ROUTE.replace(':monitorId?', monitorId)}${search}`,
|
||||
'data-test-subj': 'syntheticsMonitorOverviewTab',
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.synthetics.monitorHistoryTab.title', {
|
||||
defaultMessage: 'History',
|
||||
}),
|
||||
isSelected: selectedTab === 'history',
|
||||
href: `${syntheticsPath}${MONITOR_HISTORY_ROUTE.replace(':monitorId', monitorId)}${search}`,
|
||||
'data-test-subj': 'syntheticsMonitorHistoryTab',
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.synthetics.monitorErrorsTab.title', {
|
||||
defaultMessage: 'Errors',
|
||||
}),
|
||||
prepend: <EuiIcon type="alert" color="danger" />,
|
||||
isSelected: selectedTab === 'errors',
|
||||
href: `${syntheticsPath}${MONITOR_ERRORS_ROUTE.replace(':monitorId', monitorId)}${search}`,
|
||||
'data-test-subj': 'syntheticsMonitorErrorsTab',
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { Fragment } from 'react';
|
||||
import { EuiEmptyPrompt, EuiLoadingSpinner, EuiSpacer, EuiTitle } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export const EmptyStateLoading = () => (
|
||||
<EuiEmptyPrompt
|
||||
body={
|
||||
<Fragment>
|
||||
<EuiLoadingSpinner size="xl" />
|
||||
<EuiSpacer />
|
||||
<EuiTitle size="l">
|
||||
<h2>
|
||||
{i18n.translate('xpack.synthetics.emptyState.loadingMessage', {
|
||||
defaultMessage: 'Loading…',
|
||||
})}
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
);
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useContext, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { getIndexStatus, selectIndexState } from '../../../../state';
|
||||
import { SyntheticsRefreshContext } from '../../../../contexts';
|
||||
// import { getDynamicSettings } from '../../../state/actions/dynamic_settings';
|
||||
|
||||
export const useHasData = () => {
|
||||
const { loading, error, data } = useSelector(selectIndexState);
|
||||
const { lastRefresh } = useContext(SyntheticsRefreshContext);
|
||||
|
||||
// const { settings } = useSelector(selectDynamicSettings); // TODO: Add state for dynamicSettings
|
||||
const settings = { heartbeatIndices: 'synthetics-*' };
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getIndexStatus());
|
||||
}, [dispatch, lastRefresh]);
|
||||
|
||||
/* useEffect(() => {
|
||||
dispatch(getDynamicSettings());
|
||||
}, [dispatch]);*/
|
||||
|
||||
return {
|
||||
data,
|
||||
error,
|
||||
loading,
|
||||
settings,
|
||||
};
|
||||
};
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import React from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
import { OverviewPage } from './overview/overview_page';
|
||||
import { MonitorsPageHeader } from './management/page_header/monitors_page_header';
|
||||
import { CreateMonitorButton } from './create_monitor_button';
|
||||
import { MonitorsPageWithServiceAllowed } from './monitors_page';
|
||||
import { RouteProps } from '../../routes';
|
||||
import { MONITORS_ROUTE, OVERVIEW_ROUTE } from '../../../../../common/constants';
|
||||
|
||||
export const getMonitorsRoute = (
|
||||
history: ReturnType<typeof useHistory>,
|
||||
syntheticsPath: string,
|
||||
baseTitle: string
|
||||
): RouteProps[] => {
|
||||
return [
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.overviewRoute.title', {
|
||||
defaultMessage: 'Synthetics Overview | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: OVERVIEW_ROUTE,
|
||||
component: OverviewPage,
|
||||
dataTestSubj: 'syntheticsOverviewPage',
|
||||
pageHeader: {
|
||||
pageTitle: <MonitorsPageHeader />,
|
||||
rightSideItems: [<CreateMonitorButton />],
|
||||
tabs: getMonitorsTabs(syntheticsPath, 'overview'),
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorManagementRoute.title', {
|
||||
defaultMessage: 'Monitor Management | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITORS_ROUTE,
|
||||
component: MonitorsPageWithServiceAllowed,
|
||||
dataTestSubj: 'syntheticsMonitorManagementPage',
|
||||
pageHeader: {
|
||||
pageTitle: <MonitorsPageHeader />,
|
||||
rightSideItems: [<CreateMonitorButton />],
|
||||
tabs: getMonitorsTabs(syntheticsPath, 'management'),
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const getMonitorsTabs = (syntheticsPath: string, selected: 'overview' | 'management') => {
|
||||
return [
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorManagement.overviewTab.title"
|
||||
defaultMessage="Overview"
|
||||
/>
|
||||
),
|
||||
href: `${syntheticsPath}${OVERVIEW_ROUTE}`,
|
||||
isSelected: selected === 'overview',
|
||||
'data-test-subj': 'syntheticsMonitorOverviewTab',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorManagement.monitorsTab.title"
|
||||
defaultMessage="Management"
|
||||
/>
|
||||
),
|
||||
href: `${syntheticsPath}${MONITORS_ROUTE}`,
|
||||
isSelected: selected === 'management',
|
||||
'data-test-subj': 'syntheticsMonitorManagementTab',
|
||||
},
|
||||
];
|
||||
};
|
|
@ -12,16 +12,11 @@ import {
|
|||
BROWSER_TRACE_TYPE,
|
||||
useStepWaterfallMetrics,
|
||||
} from './use_step_waterfall_metrics';
|
||||
import * as reduxHooks from 'react-redux';
|
||||
import * as searchHooks from '@kbn/observability-plugin/public/hooks/use_es_search';
|
||||
import { SYNTHETICS_INDEX_PATTERN } from '../../../../../../common/constants';
|
||||
|
||||
describe('useStepWaterfallMetrics', () => {
|
||||
jest
|
||||
.spyOn(reduxHooks, 'useSelector')
|
||||
.mockReturnValue({ settings: { heartbeatIndices: 'heartbeat-*' } });
|
||||
|
||||
it('returns result as expected', () => {
|
||||
// @ts-ignore
|
||||
const searchHook = jest.spyOn(searchHooks, 'useEsSearch').mockReturnValue({
|
||||
loading: false,
|
||||
data: {
|
||||
|
@ -85,7 +80,7 @@ describe('useStepWaterfallMetrics', () => {
|
|||
},
|
||||
size: 1000,
|
||||
},
|
||||
index: 'synthetics-*',
|
||||
index: SYNTHETICS_INDEX_PATTERN,
|
||||
},
|
||||
['44D-444FFF-444-FFF-3333', true],
|
||||
{ name: 'getWaterfallStepMetrics' }
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { createEsParams, useEsSearch } from '@kbn/observability-plugin/public';
|
||||
import { SYNTHETICS_INDEX_PATTERN } from '../../../../../../common/constants';
|
||||
import { MarkerItems } from './waterfall/context/waterfall_context';
|
||||
|
||||
export interface Props {
|
||||
|
@ -22,7 +23,7 @@ export const useStepWaterfallMetrics = ({ checkGroup, hasNavigationRequest, step
|
|||
const { data, loading } = useEsSearch(
|
||||
hasNavigationRequest
|
||||
? createEsParams({
|
||||
index: 'synthetics-*',
|
||||
index: SYNTHETICS_INDEX_PATTERN,
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
|
|
|
@ -9,4 +9,3 @@ export * from './synthetics_refresh_context';
|
|||
export * from './synthetics_settings_context';
|
||||
export * from './synthetics_theme_context';
|
||||
export * from './synthetics_startup_plugins_context';
|
||||
export * from './synthetics_data_view_context';
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import React, { createContext, useContext, useEffect, useMemo } from 'react';
|
||||
import { useFetcher } from '@kbn/observability-plugin/public';
|
||||
import { DataViewsPublicPluginStart, DataView } from '@kbn/data-views-plugin/public';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { IHttpSerializedFetchError } from '../state/utils/http_error';
|
||||
import { getIndexStatus, selectIndexState } from '../state';
|
||||
|
||||
export const SyntheticsDataViewContext = createContext(
|
||||
{} as {
|
||||
dataView?: DataView;
|
||||
loading?: boolean;
|
||||
indices?: string;
|
||||
error?: IHttpSerializedFetchError | null;
|
||||
hasData?: boolean;
|
||||
}
|
||||
);
|
||||
|
||||
export const SyntheticsDataViewContextProvider: React.FC<{
|
||||
dataViews: DataViewsPublicPluginStart;
|
||||
}> = ({ children, dataViews }) => {
|
||||
const { loading: hasDataLoading, error, data: indexStatus } = useSelector(selectIndexState);
|
||||
|
||||
const heartbeatIndices = indexStatus?.indices || '';
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const hasData = Boolean(indexStatus?.indexExists);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getIndexStatus());
|
||||
}, [dispatch]);
|
||||
|
||||
const { data, loading } = useFetcher<Promise<DataView | undefined>>(async () => {
|
||||
if (heartbeatIndices && indexStatus?.indexExists) {
|
||||
// this only creates an dateView in memory, not as saved object
|
||||
return dataViews.create({ title: heartbeatIndices });
|
||||
}
|
||||
}, [heartbeatIndices, indexStatus?.indexExists]);
|
||||
|
||||
const isLoading = loading || hasDataLoading;
|
||||
|
||||
const value = useMemo(() => {
|
||||
return { dataView: data, indices: heartbeatIndices, isLoading, error, hasData };
|
||||
}, [data, heartbeatIndices, isLoading, error, hasData]);
|
||||
|
||||
return <SyntheticsDataViewContext.Provider value={value} children={children} />;
|
||||
};
|
||||
|
||||
export const useSyntheticsDataView = () => useContext(SyntheticsDataViewContext);
|
|
@ -7,8 +7,8 @@
|
|||
|
||||
import { EuiThemeComputed } from '@elastic/eui/src/services/theme/types';
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import { EuiIcon, EuiLink, EuiPageHeaderProps, useEuiTheme } from '@elastic/eui';
|
||||
import { Route, Switch, useHistory, useRouteMatch } from 'react-router-dom';
|
||||
import { EuiLink, useEuiTheme } from '@elastic/eui';
|
||||
import { Route, Switch, useHistory } from 'react-router-dom';
|
||||
import { OutPortal } from 'react-reverse-portal';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -16,21 +16,16 @@ import { APP_WRAPPER_CLASS } from '@kbn/core/public';
|
|||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useInspectorContext } from '@kbn/observability-plugin/public';
|
||||
import type { LazyObservabilityPageTemplateProps } from '@kbn/observability-plugin/public';
|
||||
import { EditMonitorLink } from './components/common/links/edit_monitor';
|
||||
import { MonitorDetailsLocation } from './components/monitor_details/monitor_details_location';
|
||||
import { ClientPluginsStart } from '../../plugin';
|
||||
import { getMonitorsRoute } from './components/monitors_page/route_config';
|
||||
import { getMonitorDetailsRoute } from './components/monitor_details/route_config';
|
||||
import { getStepDetailsRoute } from './components/step_details_page/route_config';
|
||||
import { getTestRunDetailsRoute } from './components/test_run_details/route_config';
|
||||
import { getSettingsRouteConfig } from './components/settings/route_config';
|
||||
import { TestRunDetails } from './components/test_run_details/test_run_details';
|
||||
import { MonitorAddPageWithServiceAllowed } from './components/monitor_add_edit/monitor_add_page';
|
||||
import { MonitorEditPageWithServiceAllowed } from './components/monitor_add_edit/monitor_edit_page';
|
||||
import { MonitorDetailsPageTitle } from './components/monitor_details/monitor_details_page_title';
|
||||
import { MonitorDetailsPage } from './components/monitor_details/monitor_details_page';
|
||||
import { GettingStartedPage } from './components/getting_started/getting_started_page';
|
||||
import { MonitorsPageHeader } from './components/monitors_page/management/page_header/monitors_page_header';
|
||||
import { CreateMonitorButton } from './components/monitors_page/create_monitor_button';
|
||||
import { OverviewPage } from './components/monitors_page/overview/overview_page';
|
||||
import { SyntheticsPageTemplateComponent } from './components/common/pages/synthetics_page_template';
|
||||
import { NotFoundPage } from './components/common/pages/not_found';
|
||||
import {
|
||||
MonitorTypePortalNode,
|
||||
|
@ -38,24 +33,12 @@ import {
|
|||
} from './components/monitor_add_edit/portals';
|
||||
import {
|
||||
GETTING_STARTED_ROUTE,
|
||||
MONITORS_ROUTE,
|
||||
MONITOR_ADD_ROUTE,
|
||||
MONITOR_EDIT_ROUTE,
|
||||
MONITOR_ERRORS_ROUTE,
|
||||
MONITOR_HISTORY_ROUTE,
|
||||
MONITOR_ROUTE,
|
||||
OVERVIEW_ROUTE,
|
||||
TEST_RUN_DETAILS_ROUTE,
|
||||
} from '../../../common/constants';
|
||||
import { PLUGIN } from '../../../common/constants/plugin';
|
||||
import { MonitorsPageWithServiceAllowed } from './components/monitors_page/monitors_page';
|
||||
import { apiService } from '../../utils/api_service';
|
||||
import { RunTestManually } from './components/monitor_details/run_test_manually';
|
||||
import { MonitorDetailsStatus } from './components/monitor_details/monitor_details_status';
|
||||
import { MonitorDetailsLastRun } from './components/monitor_details/monitor_details_last_run';
|
||||
import { MonitorSummary } from './components/monitor_details/monitor_summary/monitor_summary';
|
||||
import { MonitorHistory } from './components/monitor_details/monitor_history/monitor_history';
|
||||
import { MonitorErrors } from './components/monitor_details/monitor_errors/monitor_errors';
|
||||
import { getErrorDetailsRouteConfig } from './components/error_details/route_config';
|
||||
|
||||
export type RouteProps = LazyObservabilityPageTemplateProps & {
|
||||
|
@ -86,6 +69,8 @@ const getRoutes = (
|
|||
getErrorDetailsRouteConfig(history, syntheticsPath, baseTitle),
|
||||
getTestRunDetailsRoute(history, syntheticsPath, baseTitle),
|
||||
getStepDetailsRoute(history, syntheticsPath, baseTitle),
|
||||
...getMonitorDetailsRoute(history, syntheticsPath, baseTitle),
|
||||
...getMonitorsRoute(history, syntheticsPath, baseTitle),
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.gettingStartedRoute.title', {
|
||||
defaultMessage: 'Synthetics Getting Started | {baseTitle}',
|
||||
|
@ -99,118 +84,6 @@ const getRoutes = (
|
|||
paddingSize: 'none',
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorDetails.title', {
|
||||
defaultMessage: 'Synthetics Monitor Details | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITOR_ROUTE,
|
||||
component: () => (
|
||||
<MonitorDetailsPage>
|
||||
<MonitorSummary />
|
||||
</MonitorDetailsPage>
|
||||
),
|
||||
dataTestSubj: 'syntheticsMonitorDetailsPage',
|
||||
pageHeader: getMonitorSummaryHeader(history, syntheticsPath, 'overview'),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorHistory.title', {
|
||||
defaultMessage: 'Synthetics Monitor History | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITOR_HISTORY_ROUTE,
|
||||
component: () => (
|
||||
<MonitorDetailsPage>
|
||||
<MonitorHistory />
|
||||
</MonitorDetailsPage>
|
||||
),
|
||||
dataTestSubj: 'syntheticsMonitorHistoryPage',
|
||||
pageHeader: getMonitorSummaryHeader(history, syntheticsPath, 'history'),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorErrors.title', {
|
||||
defaultMessage: 'Synthetics Monitor Errors | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITOR_ERRORS_ROUTE,
|
||||
component: () => (
|
||||
<MonitorDetailsPage>
|
||||
<MonitorErrors />
|
||||
</MonitorDetailsPage>
|
||||
),
|
||||
dataTestSubj: 'syntheticsMonitorHistoryPage',
|
||||
pageHeader: getMonitorSummaryHeader(history, syntheticsPath, 'errors'),
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.overviewRoute.title', {
|
||||
defaultMessage: 'Synthetics Overview | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: OVERVIEW_ROUTE,
|
||||
component: OverviewPage,
|
||||
dataTestSubj: 'syntheticsOverviewPage',
|
||||
pageHeader: {
|
||||
pageTitle: <MonitorsPageHeader />,
|
||||
rightSideItems: [<CreateMonitorButton />],
|
||||
tabs: [
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorManagement.overviewTab.title"
|
||||
defaultMessage="Overview"
|
||||
/>
|
||||
),
|
||||
isSelected: true,
|
||||
'data-test-subj': 'syntheticsMonitorOverviewTab',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorManagement.monitorsTab.title"
|
||||
defaultMessage="Management"
|
||||
/>
|
||||
),
|
||||
href: `${syntheticsPath}${MONITORS_ROUTE}`,
|
||||
'data-test-subj': 'syntheticsMonitorManagementTab',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.monitorManagementRoute.title', {
|
||||
defaultMessage: 'Monitor Management | {baseTitle}',
|
||||
values: { baseTitle },
|
||||
}),
|
||||
path: MONITORS_ROUTE,
|
||||
component: MonitorsPageWithServiceAllowed,
|
||||
dataTestSubj: 'syntheticsMonitorManagementPage',
|
||||
pageHeader: {
|
||||
pageTitle: <MonitorsPageHeader />,
|
||||
rightSideItems: [<CreateMonitorButton />],
|
||||
tabs: [
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorManagement.overviewTab.title"
|
||||
defaultMessage="Overview"
|
||||
/>
|
||||
),
|
||||
href: `${syntheticsPath}${OVERVIEW_ROUTE}`,
|
||||
'data-test-subj': 'syntheticsMonitorOverviewTab',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorManagement.monitorsTab.title"
|
||||
defaultMessage="Management"
|
||||
/>
|
||||
),
|
||||
isSelected: true,
|
||||
'data-test-subj': 'syntheticsMonitorManagementTab',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
title: i18n.translate('xpack.synthetics.createMonitorRoute.title', {
|
||||
defaultMessage: 'Create Monitor | {baseTitle}',
|
||||
|
@ -289,76 +162,6 @@ const getRoutes = (
|
|||
];
|
||||
};
|
||||
|
||||
const getMonitorSummaryHeader = (
|
||||
history: ReturnType<typeof useHistory>,
|
||||
syntheticsPath: string,
|
||||
selectedTab: 'overview' | 'history' | 'errors'
|
||||
): EuiPageHeaderProps => {
|
||||
// Not a component, but it doesn't matter. Hooks are just functions
|
||||
const match = useRouteMatch<{ monitorId: string }>(MONITOR_ROUTE); // eslint-disable-line react-hooks/rules-of-hooks
|
||||
|
||||
if (!match) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const search = history.location.search;
|
||||
const monitorId = match.params.monitorId;
|
||||
|
||||
return {
|
||||
pageTitle: <MonitorDetailsPageTitle />,
|
||||
breadcrumbs: [
|
||||
{
|
||||
text: (
|
||||
<>
|
||||
<EuiIcon size="s" type="arrowLeft" />{' '}
|
||||
<FormattedMessage
|
||||
id="xpack.synthetics.monitorSummaryRoute.monitorBreadcrumb"
|
||||
defaultMessage="Monitors"
|
||||
/>
|
||||
</>
|
||||
),
|
||||
color: 'primary',
|
||||
'aria-current': false,
|
||||
href: `${syntheticsPath}${OVERVIEW_ROUTE}`,
|
||||
},
|
||||
],
|
||||
rightSideItems: [
|
||||
<EditMonitorLink />,
|
||||
<RunTestManually />,
|
||||
<MonitorDetailsLastRun />,
|
||||
<MonitorDetailsStatus />,
|
||||
<MonitorDetailsLocation />,
|
||||
],
|
||||
tabs: [
|
||||
{
|
||||
label: i18n.translate('xpack.synthetics.monitorOverviewTab.title', {
|
||||
defaultMessage: 'Overview',
|
||||
}),
|
||||
isSelected: selectedTab === 'overview',
|
||||
href: `${syntheticsPath}${MONITOR_ROUTE.replace(':monitorId?', monitorId)}${search}`,
|
||||
'data-test-subj': 'syntheticsMonitorOverviewTab',
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.synthetics.monitorHistoryTab.title', {
|
||||
defaultMessage: 'History',
|
||||
}),
|
||||
isSelected: selectedTab === 'history',
|
||||
href: `${syntheticsPath}${MONITOR_HISTORY_ROUTE.replace(':monitorId', monitorId)}${search}`,
|
||||
'data-test-subj': 'syntheticsMonitorHistoryTab',
|
||||
},
|
||||
{
|
||||
label: i18n.translate('xpack.synthetics.monitorErrorsTab.title', {
|
||||
defaultMessage: 'Errors',
|
||||
}),
|
||||
prepend: <EuiIcon type="alert" color="danger" />,
|
||||
isSelected: selectedTab === 'errors',
|
||||
href: `${syntheticsPath}${MONITOR_ERRORS_ROUTE.replace(':monitorId', monitorId)}${search}`,
|
||||
'data-test-subj': 'syntheticsMonitorErrorsTab',
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
const RouteInit: React.FC<Pick<RouteProps, 'path' | 'title'>> = ({ path, title }) => {
|
||||
useEffect(() => {
|
||||
document.title = title;
|
||||
|
@ -367,15 +170,17 @@ const RouteInit: React.FC<Pick<RouteProps, 'path' | 'title'>> = ({ path, title }
|
|||
};
|
||||
|
||||
export const PageRouter: FC = () => {
|
||||
const { services } = useKibana();
|
||||
const { application, observability } = useKibana<ClientPluginsStart>().services;
|
||||
const { addInspectorRequest } = useInspectorContext();
|
||||
const { euiTheme } = useEuiTheme();
|
||||
const history = useHistory();
|
||||
|
||||
const routes = getRoutes(
|
||||
euiTheme,
|
||||
history,
|
||||
services.application!.getUrlForApp(PLUGIN.SYNTHETICS_PLUGIN_ID)
|
||||
application.getUrlForApp(PLUGIN.SYNTHETICS_PLUGIN_ID)
|
||||
);
|
||||
const PageTemplateComponent = observability.navigation.PageTemplate;
|
||||
|
||||
apiService.addInspectorRequest = addInspectorRequest;
|
||||
|
||||
|
@ -393,13 +198,14 @@ export const PageRouter: FC = () => {
|
|||
<Route path={path} key={dataTestSubj} exact={true}>
|
||||
<div className={APP_WRAPPER_CLASS} data-test-subj={dataTestSubj}>
|
||||
<RouteInit title={title} path={path} />
|
||||
<SyntheticsPageTemplateComponent
|
||||
path={path}
|
||||
<PageTemplateComponent
|
||||
pageHeader={pageHeader}
|
||||
data-test-subj={'synthetics-page-template'}
|
||||
isPageDataLoaded={true}
|
||||
{...pageTemplateProps}
|
||||
>
|
||||
<RouteComponent />
|
||||
</SyntheticsPageTemplateComponent>
|
||||
</PageTemplateComponent>
|
||||
</div>
|
||||
</Route>
|
||||
)
|
||||
|
|
|
@ -11,7 +11,6 @@ export type { SyntheticsAppState as AppState } from './root_reducer';
|
|||
export type { IHttpSerializedFetchError } from './utils/http_error';
|
||||
|
||||
export * from './ui';
|
||||
export * from './index_status';
|
||||
export * from './synthetics_enablement';
|
||||
export * from './service_locations';
|
||||
export * from './monitor_list';
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { createAction } from '@reduxjs/toolkit';
|
||||
import { StatesIndexStatus } from '../../../../../common/runtime_types';
|
||||
import { IHttpSerializedFetchError } from '../utils/http_error';
|
||||
|
||||
export const getIndexStatus = createAction<void>('[INDEX STATUS] GET');
|
||||
export const getIndexStatusSuccess = createAction<StatesIndexStatus>('[INDEX STATUS] GET SUCCESS');
|
||||
export const getIndexStatusFail =
|
||||
createAction<IHttpSerializedFetchError>('[INDEX STATUS] GET FAIL');
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { API_URLS } from '../../../../../common/constants';
|
||||
import { StatesIndexStatus, StatesIndexStatusType } from '../../../../../common/runtime_types';
|
||||
import { apiService } from '../../../../utils/api_service';
|
||||
|
||||
export const fetchIndexStatus = async (): Promise<StatesIndexStatus> => {
|
||||
return await apiService.get(API_URLS.INDEX_STATUS, undefined, StatesIndexStatusType);
|
||||
};
|
|
@ -1,18 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { takeLeading } from 'redux-saga/effects';
|
||||
import { getIndexStatus, getIndexStatusSuccess, getIndexStatusFail } from './actions';
|
||||
import { fetchEffectFactory } from '../utils/fetch_effect';
|
||||
import { fetchIndexStatus } from './api';
|
||||
|
||||
export function* fetchIndexStatusEffect() {
|
||||
yield takeLeading(
|
||||
getIndexStatus,
|
||||
fetchEffectFactory(fetchIndexStatus, getIndexStatusSuccess, getIndexStatusFail)
|
||||
);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { createReducer } from '@reduxjs/toolkit';
|
||||
import { IHttpSerializedFetchError } from '../utils/http_error';
|
||||
import { StatesIndexStatus } from '../../../../../common/runtime_types';
|
||||
|
||||
import { getIndexStatus, getIndexStatusSuccess, getIndexStatusFail } from './actions';
|
||||
|
||||
export interface IndexStatusState {
|
||||
data: StatesIndexStatus | null;
|
||||
loading: boolean;
|
||||
error: IHttpSerializedFetchError | null;
|
||||
}
|
||||
|
||||
const initialState: IndexStatusState = {
|
||||
data: null,
|
||||
loading: false,
|
||||
error: null,
|
||||
};
|
||||
|
||||
export const indexStatusReducer = createReducer(initialState, (builder) => {
|
||||
builder
|
||||
.addCase(getIndexStatus, (state) => {
|
||||
state.loading = true;
|
||||
})
|
||||
.addCase(getIndexStatusSuccess, (state, action) => {
|
||||
state.data = action.payload;
|
||||
state.loading = false;
|
||||
})
|
||||
.addCase(getIndexStatusFail, (state, action) => {
|
||||
state.error = action.payload;
|
||||
state.loading = false;
|
||||
});
|
||||
});
|
||||
|
||||
export * from './actions';
|
||||
export * from './effects';
|
||||
export * from './selectors';
|
|
@ -1,12 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { createSelector } from 'reselect';
|
||||
import type { SyntheticsAppState } from '../root_reducer';
|
||||
|
||||
const getState = (appState: SyntheticsAppState) => appState.indexStatus;
|
||||
export const selectIndexState = createSelector(getState, (state) => state);
|
|
@ -18,7 +18,6 @@ import { syncGlobalParamsEffect } from './settings';
|
|||
import { fetchAgentPoliciesEffect } from './private_locations';
|
||||
import { fetchNetworkEventsEffect } from './network_events/effects';
|
||||
import { fetchSyntheticsMonitorEffect } from './monitor_details';
|
||||
import { fetchIndexStatusEffect } from './index_status';
|
||||
import { fetchSyntheticsEnablementEffect } from './synthetics_enablement';
|
||||
import {
|
||||
enableMonitorAlertEffect,
|
||||
|
@ -32,7 +31,6 @@ import { fetchPingStatusesEffect } from './ping_status';
|
|||
|
||||
export const rootEffect = function* root(): Generator {
|
||||
yield all([
|
||||
fork(fetchIndexStatusEffect),
|
||||
fork(fetchSyntheticsEnablementEffect),
|
||||
fork(upsertMonitorEffect),
|
||||
fork(fetchServiceLocationsEffect),
|
||||
|
|
|
@ -21,7 +21,6 @@ import { agentPoliciesReducer, AgentPoliciesState } from './private_locations';
|
|||
import { networkEventsReducer, NetworkEventsState } from './network_events';
|
||||
import { monitorDetailsReducer, MonitorDetailsState } from './monitor_details';
|
||||
import { uiReducer, UiState } from './ui';
|
||||
import { indexStatusReducer, IndexStatusState } from './index_status';
|
||||
import { syntheticsEnablementReducer, SyntheticsEnablementState } from './synthetics_enablement';
|
||||
import { monitorListReducer, MonitorListState } from './monitor_list';
|
||||
import { serviceLocationsReducer, ServiceLocationsState } from './service_locations';
|
||||
|
@ -35,7 +34,6 @@ export interface SyntheticsAppState {
|
|||
pingStatus: PingStatusState;
|
||||
elasticsearch: QueriesState;
|
||||
monitorList: MonitorListState;
|
||||
indexStatus: IndexStatusState;
|
||||
overview: MonitorOverviewState;
|
||||
networkEvents: NetworkEventsState;
|
||||
agentPolicies: AgentPoliciesState;
|
||||
|
@ -53,7 +51,6 @@ export const rootReducer = combineReducers<SyntheticsAppState>({
|
|||
settings: settingsReducer,
|
||||
pingStatus: pingStatusReducer,
|
||||
monitorList: monitorListReducer,
|
||||
indexStatus: indexStatusReducer,
|
||||
overview: monitorOverviewReducer,
|
||||
networkEvents: networkEventsReducer,
|
||||
elasticsearch: elasticsearchReducer,
|
||||
|
|
|
@ -17,7 +17,7 @@ import {
|
|||
} from '@kbn/kibana-react-plugin/public';
|
||||
import { EuiThemeProvider } from '@kbn/kibana-react-plugin/common';
|
||||
import { InspectorContextProvider } from '@kbn/observability-plugin/public';
|
||||
import { SyntheticsAppProps, SyntheticsDataViewContextProvider } from './contexts';
|
||||
import { SyntheticsAppProps } from './contexts';
|
||||
|
||||
import {
|
||||
SyntheticsRefreshContextProvider,
|
||||
|
@ -100,24 +100,22 @@ const Application = (props: SyntheticsAppProps) => {
|
|||
<EuiThemeProvider darkMode={darkMode}>
|
||||
<SyntheticsRefreshContextProvider>
|
||||
<SyntheticsSettingsContextProvider {...props}>
|
||||
<SyntheticsDataViewContextProvider dataViews={startPlugins.dataViews}>
|
||||
<SyntheticsThemeContextProvider darkMode={darkMode}>
|
||||
<SyntheticsStartupPluginsContextProvider {...startPlugins}>
|
||||
<div className={APP_WRAPPER_CLASS} data-test-subj="syntheticsApp">
|
||||
<RedirectAppLinks
|
||||
className={APP_WRAPPER_CLASS}
|
||||
application={core.application}
|
||||
>
|
||||
<InspectorContextProvider>
|
||||
<PageRouter />
|
||||
<ActionMenu appMountParameters={appMountParameters} />
|
||||
<TestNowModeFlyoutContainer />
|
||||
</InspectorContextProvider>
|
||||
</RedirectAppLinks>
|
||||
</div>
|
||||
</SyntheticsStartupPluginsContextProvider>
|
||||
</SyntheticsThemeContextProvider>
|
||||
</SyntheticsDataViewContextProvider>
|
||||
<SyntheticsThemeContextProvider darkMode={darkMode}>
|
||||
<SyntheticsStartupPluginsContextProvider {...startPlugins}>
|
||||
<div className={APP_WRAPPER_CLASS} data-test-subj="syntheticsApp">
|
||||
<RedirectAppLinks
|
||||
className={APP_WRAPPER_CLASS}
|
||||
application={core.application}
|
||||
>
|
||||
<InspectorContextProvider>
|
||||
<PageRouter />
|
||||
<ActionMenu appMountParameters={appMountParameters} />
|
||||
<TestNowModeFlyoutContainer />
|
||||
</InspectorContextProvider>
|
||||
</RedirectAppLinks>
|
||||
</div>
|
||||
</SyntheticsStartupPluginsContextProvider>
|
||||
</SyntheticsThemeContextProvider>
|
||||
</SyntheticsSettingsContextProvider>
|
||||
</SyntheticsRefreshContextProvider>
|
||||
</EuiThemeProvider>
|
||||
|
|
|
@ -30,11 +30,6 @@ export const mockState: SyntheticsAppState = {
|
|||
searchText: '',
|
||||
monitorId: '',
|
||||
},
|
||||
indexStatus: {
|
||||
data: null,
|
||||
error: null,
|
||||
loading: false,
|
||||
},
|
||||
serviceLocations: {
|
||||
throttling: DEFAULT_THROTTLING,
|
||||
locations: [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue