mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Uptime] Update no data available state (#112403)
* wip * update component * update paths * fix i18n * fix tests * revert uneeded
This commit is contained in:
parent
b2bc5a592d
commit
322c5e26f0
14 changed files with 151 additions and 380 deletions
|
@ -26137,13 +26137,7 @@
|
|||
"xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.label": "TLS設定",
|
||||
"xpack.uptime.durationChart.emptyPrompt.description": "このモニターは選択された時間範囲で一度も{emphasizedText}していません。",
|
||||
"xpack.uptime.durationChart.emptyPrompt.title": "利用可能な期間データがありません",
|
||||
"xpack.uptime.emptyState.configureHeartbeatIndexSettings": "Heartbeatがすでに設定されている場合は、データがElasticsearchに送信されていることを確認してから、Heartbeat構成に合わせてインデックスパターン設定を更新します。",
|
||||
"xpack.uptime.emptyState.configureHeartbeatToGetStartedMessage": "サービスの監視を開始するには、Heartbeatを設定します。",
|
||||
"xpack.uptime.emptyState.loadingMessage": "読み込み中…",
|
||||
"xpack.uptime.emptyState.noDataMessage": "インデックス{indexName}にはアップタイムデータが見つかりません",
|
||||
"xpack.uptime.emptyState.noIndexTitle": "パターン{indexName}のインデックスが見つかりません",
|
||||
"xpack.uptime.emptyState.updateIndexPattern": "インデックスパターン設定を更新",
|
||||
"xpack.uptime.emptyState.viewSetupInstructions": "セットアップの手順を表示",
|
||||
"xpack.uptime.emptyStateError.notAuthorized": "アップタイムデータの表示が承認されていません。システム管理者にお問い合わせください。",
|
||||
"xpack.uptime.emptyStateError.notFoundPage": "ページが見つかりません",
|
||||
"xpack.uptime.emptyStateError.title": "エラー",
|
||||
|
|
|
@ -26572,13 +26572,7 @@
|
|||
"xpack.uptime.createPackagePolicy.stepConfigure.tlsSettings.label": "TLS 设置",
|
||||
"xpack.uptime.durationChart.emptyPrompt.description": "在选定时间范围内此监测从未{emphasizedText}。",
|
||||
"xpack.uptime.durationChart.emptyPrompt.title": "没有持续时间数据",
|
||||
"xpack.uptime.emptyState.configureHeartbeatIndexSettings": "如果已设置 Heartbeat,请确认其正向 Elasticsearch 发送数据,然后更新索引模式设置以匹配 Heartbeat 配置。",
|
||||
"xpack.uptime.emptyState.configureHeartbeatToGetStartedMessage": "设置 Heartbeat 以开始监测您的服务。",
|
||||
"xpack.uptime.emptyState.loadingMessage": "正在加载……",
|
||||
"xpack.uptime.emptyState.noDataMessage": "在索引 {indexName} 中找不到运行时间数据",
|
||||
"xpack.uptime.emptyState.noIndexTitle": "找不到模式 {indexName} 的索引",
|
||||
"xpack.uptime.emptyState.updateIndexPattern": "更新索引模式设置",
|
||||
"xpack.uptime.emptyState.viewSetupInstructions": "查看设置说明",
|
||||
"xpack.uptime.emptyStateError.notAuthorized": "您无权查看 Uptime 数据,请联系系统管理员。",
|
||||
"xpack.uptime.emptyStateError.notFoundPage": "未找到页面",
|
||||
"xpack.uptime.emptyStateError.title": "错误",
|
||||
|
|
64
x-pack/plugins/uptime/public/apps/uptime_page_template.tsx
Normal file
64
x-pack/plugins/uptime/public/apps/uptime_page_template.tsx
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* 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, { useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { EuiPageHeaderProps } from '@elastic/eui';
|
||||
import { OVERVIEW_ROUTE } from '../../common/constants';
|
||||
import { useKibana } from '../../../../../src/plugins/kibana_react/public';
|
||||
import { ClientPluginsStart } from './plugin';
|
||||
import { useNoDataConfig } from './use_no_data_config';
|
||||
import { EmptyStateLoading } from '../components/overview/empty_state/empty_state_loading';
|
||||
import { EmptyStateError } from '../components/overview/empty_state/empty_state_error';
|
||||
import { useHasData } from '../components/overview/empty_state/use_has_data';
|
||||
|
||||
interface Props {
|
||||
path: string;
|
||||
pageHeader?: EuiPageHeaderProps;
|
||||
}
|
||||
|
||||
export const UptimePageTemplateComponent: React.FC<Props> = ({ path, pageHeader, children }) => {
|
||||
const {
|
||||
services: { observability },
|
||||
} = useKibana<ClientPluginsStart>();
|
||||
|
||||
const PageTemplateComponent = observability.navigation.PageTemplate;
|
||||
|
||||
const StyledPageTemplateComponent = useMemo(() => {
|
||||
return styled(PageTemplateComponent)`
|
||||
.euiPageHeaderContent > .euiFlexGroup {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
`;
|
||||
}, [PageTemplateComponent]);
|
||||
|
||||
const noDataConfig = useNoDataConfig();
|
||||
|
||||
const { loading, error } = useHasData();
|
||||
|
||||
if (error) {
|
||||
return <EmptyStateError errors={[error]} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div data-test-subj={noDataConfig ? 'data-missing' : undefined} />
|
||||
<StyledPageTemplateComponent
|
||||
pageHeader={pageHeader}
|
||||
noDataConfig={path === OVERVIEW_ROUTE && !loading ? noDataConfig : undefined}
|
||||
>
|
||||
{loading && path === OVERVIEW_ROUTE && <EmptyStateLoading />}
|
||||
<div
|
||||
style={{ visibility: loading && path === OVERVIEW_ROUTE ? 'hidden' : 'initial' }}
|
||||
data-test-subj={noDataConfig ? 'data-missing' : undefined}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</StyledPageTemplateComponent>
|
||||
</>
|
||||
);
|
||||
};
|
46
x-pack/plugins/uptime/public/apps/use_no_data_config.ts
Normal file
46
x-pack/plugins/uptime/public/apps/use_no_data_config.ts
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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 { useContext } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { KibanaPageTemplateProps, useKibana } from '../../../../../src/plugins/kibana_react/public';
|
||||
import { UptimeSettingsContext } from '../contexts';
|
||||
import { ClientPluginsStart } from './plugin';
|
||||
import { indexStatusSelector } from '../state/selectors';
|
||||
|
||||
export function useNoDataConfig(): KibanaPageTemplateProps['noDataConfig'] {
|
||||
const { basePath } = useContext(UptimeSettingsContext);
|
||||
|
||||
const {
|
||||
services: { docLinks },
|
||||
} = useKibana<ClientPluginsStart>();
|
||||
|
||||
const { data } = useSelector(indexStatusSelector);
|
||||
|
||||
// Returns no data config when there is no historical data
|
||||
if (data && !data.indexExists) {
|
||||
return {
|
||||
solution: i18n.translate('xpack.uptime.noDataConfig.solutionName', {
|
||||
defaultMessage: 'Observability',
|
||||
}),
|
||||
actions: {
|
||||
beats: {
|
||||
title: i18n.translate('xpack.uptime.noDataConfig.beatsCard.title', {
|
||||
defaultMessage: 'Add monitors with Heartbeat',
|
||||
}),
|
||||
description: i18n.translate('xpack.uptime.noDataConfig.beatsCard.description', {
|
||||
defaultMessage:
|
||||
'Proactively monitor the availability of your sites and services. Receive alerts and resolve issues faster to optimize your users experience.',
|
||||
}),
|
||||
href: basePath + `/app/home#/tutorial/uptimeMonitors`,
|
||||
},
|
||||
},
|
||||
docsLink: docLinks!.links.observability.guide,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,26 +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 from 'react';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { render } from '../../../lib/helper/rtl_helpers';
|
||||
import { DataOrIndexMissing } from './data_or_index_missing';
|
||||
|
||||
describe('DataOrIndexMissing component', () => {
|
||||
it('renders headingMessage', () => {
|
||||
const headingMessage = (
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.emptyState.noIndexTitle"
|
||||
defaultMessage="Uptime index {indexName} not found"
|
||||
values={{ indexName: <em>heartbeat-*</em> }}
|
||||
/>
|
||||
);
|
||||
render(<DataOrIndexMissing headingMessage={headingMessage} />);
|
||||
expect(screen.getByText(/heartbeat-*/)).toBeInTheDocument();
|
||||
});
|
||||
});
|
|
@ -1,87 +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 {
|
||||
EuiFlexGroup,
|
||||
EuiEmptyPrompt,
|
||||
EuiFlexItem,
|
||||
EuiSpacer,
|
||||
EuiPanel,
|
||||
EuiTitle,
|
||||
EuiButton,
|
||||
} from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import React, { useContext } from 'react';
|
||||
import { UptimeSettingsContext } from '../../../contexts';
|
||||
import { DynamicSettings } from '../../../../common/runtime_types';
|
||||
|
||||
interface DataMissingProps {
|
||||
headingMessage: JSX.Element;
|
||||
settings?: DynamicSettings;
|
||||
}
|
||||
|
||||
export const DataOrIndexMissing = ({ headingMessage, settings }: DataMissingProps) => {
|
||||
const { basePath } = useContext(UptimeSettingsContext);
|
||||
return (
|
||||
<EuiFlexGroup justifyContent="center" data-test-subj="data-missing">
|
||||
<EuiFlexItem grow={false} style={{ flexBasis: 700 }}>
|
||||
<EuiSpacer size="m" />
|
||||
<EuiPanel hasBorder>
|
||||
<EuiEmptyPrompt
|
||||
iconType="logoUptime"
|
||||
title={
|
||||
<EuiTitle size="l">
|
||||
<h3>{headingMessage}</h3>
|
||||
</EuiTitle>
|
||||
}
|
||||
body={
|
||||
<>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.emptyState.configureHeartbeatToGetStartedMessage"
|
||||
defaultMessage="Set up Heartbeat to start monitoring your services."
|
||||
/>
|
||||
</p>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.emptyState.configureHeartbeatIndexSettings"
|
||||
defaultMessage="If Heartbeat is already set up, confirm it's sending data to Elasticsearch,
|
||||
then update the index pattern settings to match the Heartbeat config."
|
||||
/>
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
actions={
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiButton
|
||||
fill
|
||||
color="primary"
|
||||
href={`${basePath}/app/home#/tutorial/uptimeMonitors`}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.emptyState.viewSetupInstructions"
|
||||
defaultMessage="View setup instructions"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem>
|
||||
<EuiButton color="primary" href={`${basePath}/app/uptime/settings`}>
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.emptyState.updateIndexPattern"
|
||||
defaultMessage="Update index pattern settings"
|
||||
/>
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
}
|
||||
/>
|
||||
</EuiPanel>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
};
|
|
@ -1,99 +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 from 'react';
|
||||
import { screen } from '@testing-library/react';
|
||||
import { EmptyStateComponent } from './empty_state';
|
||||
import { StatesIndexStatus } from '../../../../common/runtime_types';
|
||||
import { HttpFetchError, IHttpFetchError } from 'src/core/public';
|
||||
import { render } from '../../../lib/helper/rtl_helpers';
|
||||
|
||||
describe('EmptyState component', () => {
|
||||
let statesIndexStatus: StatesIndexStatus;
|
||||
|
||||
beforeEach(() => {
|
||||
statesIndexStatus = {
|
||||
indexExists: true,
|
||||
docCount: 1,
|
||||
indices: 'heartbeat-*,synthetics-*',
|
||||
};
|
||||
});
|
||||
|
||||
it('renders child components when count is truthy', () => {
|
||||
render(
|
||||
<EmptyStateComponent statesIndexStatus={statesIndexStatus} loading={false}>
|
||||
<div>Foo</div>
|
||||
<div>Bar</div>
|
||||
<div>Baz</div>
|
||||
</EmptyStateComponent>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Foo')).toBeInTheDocument();
|
||||
expect(screen.getByText('Bar')).toBeInTheDocument();
|
||||
expect(screen.getByText('Baz')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it(`doesn't render child components when count is falsy`, () => {
|
||||
render(
|
||||
<EmptyStateComponent statesIndexStatus={null} loading={false}>
|
||||
<div>Should not be rendered</div>
|
||||
</EmptyStateComponent>
|
||||
);
|
||||
expect(screen.queryByText('Should not be rendered')).toBeNull();
|
||||
});
|
||||
|
||||
it(`renders error message when an error occurs`, () => {
|
||||
const errors: IHttpFetchError[] = [
|
||||
new HttpFetchError('There was an error fetching your data.', 'error', {} as any, {} as any, {
|
||||
body: { message: 'There was an error fetching your data.' },
|
||||
}),
|
||||
];
|
||||
render(
|
||||
<EmptyStateComponent statesIndexStatus={null} errors={errors} loading={false}>
|
||||
<div>Should not appear...</div>
|
||||
</EmptyStateComponent>
|
||||
);
|
||||
expect(screen.queryByText('Should not appear...')).toBeNull();
|
||||
});
|
||||
|
||||
it('renders loading state if no errors or doc count', () => {
|
||||
render(
|
||||
<EmptyStateComponent loading={true} statesIndexStatus={null}>
|
||||
<div>Should appear even while loading...</div>
|
||||
</EmptyStateComponent>
|
||||
);
|
||||
expect(screen.queryByText('Should appear even while loading...')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not render empty state with appropriate base path and no docs', () => {
|
||||
statesIndexStatus = {
|
||||
docCount: 0,
|
||||
indexExists: true,
|
||||
indices: 'heartbeat-*,synthetics-*',
|
||||
};
|
||||
const text = 'If this is in the snapshot the test should fail';
|
||||
render(
|
||||
<EmptyStateComponent statesIndexStatus={statesIndexStatus} loading={false}>
|
||||
<div>{text}</div>
|
||||
</EmptyStateComponent>
|
||||
);
|
||||
expect(screen.queryByText(text)).toBeNull();
|
||||
});
|
||||
|
||||
it('notifies when index does not exist', () => {
|
||||
statesIndexStatus.indexExists = false;
|
||||
|
||||
const text = 'This text should not render';
|
||||
|
||||
render(
|
||||
<EmptyStateComponent statesIndexStatus={statesIndexStatus} loading={false}>
|
||||
<div>{text}</div>
|
||||
</EmptyStateComponent>
|
||||
);
|
||||
expect(screen.queryByText(text)).toBeNull();
|
||||
});
|
||||
});
|
|
@ -1,73 +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 { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { IHttpFetchError } from 'src/core/public';
|
||||
import { EmptyStateError } from './empty_state_error';
|
||||
import { EmptyStateLoading } from './empty_state_loading';
|
||||
import { DataOrIndexMissing } from './data_or_index_missing';
|
||||
import { DynamicSettings, StatesIndexStatus } from '../../../../common/runtime_types';
|
||||
|
||||
interface EmptyStateProps {
|
||||
children: JSX.Element[] | JSX.Element;
|
||||
statesIndexStatus: StatesIndexStatus | null;
|
||||
loading: boolean;
|
||||
errors?: IHttpFetchError[];
|
||||
settings?: DynamicSettings;
|
||||
}
|
||||
|
||||
export const EmptyStateComponent = ({
|
||||
children,
|
||||
statesIndexStatus,
|
||||
loading,
|
||||
errors,
|
||||
settings,
|
||||
}: EmptyStateProps) => {
|
||||
if (errors?.length) {
|
||||
return <EmptyStateError errors={errors} />;
|
||||
}
|
||||
const { indexExists, docCount } = statesIndexStatus ?? {};
|
||||
|
||||
const isLoading = loading && (!indexExists || docCount === 0 || !statesIndexStatus);
|
||||
|
||||
const noIndicesMessage = (
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.emptyState.noIndexTitle"
|
||||
defaultMessage="No indices found for the pattern {indexName}"
|
||||
values={{ indexName: <em>{settings?.heartbeatIndices}</em> }}
|
||||
/>
|
||||
);
|
||||
|
||||
const noUptimeDataMessage = (
|
||||
<FormattedMessage
|
||||
id="xpack.uptime.emptyState.noDataMessage"
|
||||
defaultMessage="No uptime data found in index {indexName}"
|
||||
values={{ indexName: <em>{settings?.heartbeatIndices}</em> }}
|
||||
/>
|
||||
);
|
||||
|
||||
if (!indexExists && !isLoading) {
|
||||
return <DataOrIndexMissing settings={settings} headingMessage={noIndicesMessage} />;
|
||||
} else if (indexExists && docCount === 0 && !isLoading) {
|
||||
return <DataOrIndexMissing settings={settings} headingMessage={noUptimeDataMessage} />;
|
||||
}
|
||||
/**
|
||||
* We choose to render the children any time the count > 0, even if
|
||||
* the component is loading. If we render the loading state for this component,
|
||||
* it will blow away the state of child components and trigger an ugly
|
||||
* jittery UX any time the components refresh. This way we'll keep the stale
|
||||
* state displayed during the fetching process.
|
||||
*/
|
||||
return (
|
||||
<Fragment>
|
||||
{isLoading && <EmptyStateLoading />}
|
||||
<div style={{ visibility: isLoading ? 'hidden' : 'initial' }}>{children}</div>
|
||||
</Fragment>
|
||||
);
|
||||
// }
|
||||
};
|
|
@ -1,54 +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, { useContext, useEffect } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { indexStatusAction } from '../../../state/actions';
|
||||
import { indexStatusSelector, selectDynamicSettings } from '../../../state/selectors';
|
||||
import { EmptyStateComponent } from './index';
|
||||
import { UptimeRefreshContext } from '../../../contexts';
|
||||
import { getDynamicSettings } from '../../../state/actions/dynamic_settings';
|
||||
|
||||
export const EmptyState: React.FC = ({ children }) => {
|
||||
const { data, loading, error } = useSelector(indexStatusSelector);
|
||||
const { lastRefresh } = useContext(UptimeRefreshContext);
|
||||
|
||||
const { settings } = useSelector(selectDynamicSettings);
|
||||
|
||||
const heartbeatIndices = settings?.heartbeatIndices || '';
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const noDataInfo = !data || data?.docCount === 0 || data?.indexExists === false;
|
||||
|
||||
useEffect(() => {
|
||||
if (noDataInfo) {
|
||||
// only call when we haven't fetched it already
|
||||
dispatch(indexStatusAction.get());
|
||||
}
|
||||
}, [dispatch, lastRefresh, noDataInfo]);
|
||||
|
||||
useEffect(() => {
|
||||
// using separate side effect, we want to call index status,
|
||||
// every statue indices setting changes
|
||||
dispatch(indexStatusAction.get());
|
||||
}, [dispatch, heartbeatIndices]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getDynamicSettings());
|
||||
}, [dispatch]);
|
||||
|
||||
return (
|
||||
<EmptyStateComponent
|
||||
statesIndexStatus={data}
|
||||
loading={loading}
|
||||
errors={error ? [error] : undefined}
|
||||
children={children as React.ReactElement}
|
||||
settings={settings}
|
||||
/>
|
||||
);
|
||||
};
|
|
@ -1,9 +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.
|
||||
*/
|
||||
|
||||
export { EmptyStateComponent } from './empty_state';
|
||||
export { EmptyState } from './empty_state_container';
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 { indexStatusAction } from '../../../state/actions';
|
||||
import { indexStatusSelector, selectDynamicSettings } from '../../../state/selectors';
|
||||
import { UptimeRefreshContext } from '../../../contexts';
|
||||
import { getDynamicSettings } from '../../../state/actions/dynamic_settings';
|
||||
|
||||
export const useHasData = () => {
|
||||
const { loading, error } = useSelector(indexStatusSelector);
|
||||
const { lastRefresh } = useContext(UptimeRefreshContext);
|
||||
|
||||
const { settings } = useSelector(selectDynamicSettings);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(indexStatusAction.get());
|
||||
}, [dispatch, lastRefresh]);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(getDynamicSettings());
|
||||
}, [dispatch]);
|
||||
|
||||
return {
|
||||
error,
|
||||
loading,
|
||||
settings,
|
||||
};
|
||||
};
|
|
@ -6,6 +6,5 @@
|
|||
*/
|
||||
|
||||
export * from './monitor_list';
|
||||
export * from './empty_state';
|
||||
export * from './alerts';
|
||||
export * from './snapshot';
|
||||
|
|
|
@ -12,7 +12,6 @@ import styled from 'styled-components';
|
|||
import { useBreadcrumbs } from '../hooks/use_breadcrumbs';
|
||||
import { useTrackPageview } from '../../../observability/public';
|
||||
import { MonitorList } from '../components/overview/monitor_list/monitor_list_container';
|
||||
import { EmptyState } from '../components/overview';
|
||||
import { StatusPanel } from '../components/overview/status_panel';
|
||||
import { QueryBar } from '../components/overview/query_bar/query_bar';
|
||||
import { MONITORING_OVERVIEW_LABEL } from '../routes';
|
||||
|
@ -37,7 +36,7 @@ export const OverviewPageComponent = () => {
|
|||
useBreadcrumbs([{ text: MONITORING_OVERVIEW_LABEL }]); // No extra breadcrumbs on overview
|
||||
|
||||
return (
|
||||
<EmptyState>
|
||||
<>
|
||||
<EuiFlexGroup gutterSize="xs" wrap responsive={false}>
|
||||
<QueryBar />
|
||||
<EuiFlexItemStyled grow={true}>
|
||||
|
@ -48,6 +47,6 @@ export const OverviewPageComponent = () => {
|
|||
<StatusPanel />
|
||||
<EuiSpacer size="s" />
|
||||
<MonitorList />
|
||||
</EmptyState>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
import React, { FC, useEffect } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { Route, Switch } from 'react-router-dom';
|
||||
import { FormattedMessage } from '@kbn/i18n/react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
@ -27,10 +26,8 @@ import {
|
|||
SyntheticsCheckStepsPageHeader,
|
||||
SyntheticsCheckStepsPageRightSideItem,
|
||||
} from './pages/synthetics/synthetics_checks';
|
||||
import { ClientPluginsStart } from './apps/plugin';
|
||||
import { MonitorPageTitle, MonitorPageTitleContent } from './components/monitor/monitor_title';
|
||||
import { UptimeDatePicker } from './components/common/uptime_date_picker';
|
||||
import { useKibana } from '../../../../src/plugins/kibana_react/public';
|
||||
import { CertRefreshBtn } from './components/certificates/cert_refresh_btn';
|
||||
import { CertificateTitle } from './components/certificates/certificate_title';
|
||||
import { SyntheticsCallout } from './components/overview/synthetics_callout';
|
||||
|
@ -40,6 +37,7 @@ import {
|
|||
StepDetailPageHeader,
|
||||
StepDetailPageRightSideItem,
|
||||
} from './pages/synthetics/step_detail_page';
|
||||
import { UptimePageTemplateComponent } from './apps/uptime_page_template';
|
||||
|
||||
interface RouteProps {
|
||||
path: string;
|
||||
|
@ -159,17 +157,6 @@ const RouteInit: React.FC<Pick<RouteProps, 'path' | 'title' | 'telemetryId'>> =
|
|||
};
|
||||
|
||||
export const PageRouter: FC = () => {
|
||||
const {
|
||||
services: { observability },
|
||||
} = useKibana<ClientPluginsStart>();
|
||||
const PageTemplateComponent = observability.navigation.PageTemplate;
|
||||
|
||||
const StyledPageTemplateComponent = styled(PageTemplateComponent)`
|
||||
.euiPageHeaderContent > .euiFlexGroup {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
`;
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
{Routes.map(
|
||||
|
@ -178,9 +165,9 @@ export const PageRouter: FC = () => {
|
|||
<div className={APP_WRAPPER_CLASS} data-test-subj={dataTestSubj}>
|
||||
<SyntheticsCallout />
|
||||
<RouteInit title={title} path={path} telemetryId={telemetryId} />
|
||||
<StyledPageTemplateComponent pageHeader={pageHeader}>
|
||||
<UptimePageTemplateComponent path={path} pageHeader={pageHeader}>
|
||||
<RouteComponent />
|
||||
</StyledPageTemplateComponent>
|
||||
</UptimePageTemplateComponent>
|
||||
</div>
|
||||
</Route>
|
||||
)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue