mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Unified Observability] Status visualization improvements (#127894)
* Update style for status visualization boxes * Add content * Group boxes by hasData * Add links to doc-links service * Fix status visualization story * fix tests * fix doc link * fix translation keys * Update content for empty sections * Fix translation key * change button type * Update text Co-authored-by: Brandon Morelli <bmorelli25@gmail.com> * Update text Co-authored-by: Brandon Morelli <bmorelli25@gmail.com> * Update text Co-authored-by: Brandon Morelli <bmorelli25@gmail.com> * Update text Co-authored-by: Brandon Morelli <bmorelli25@gmail.com> * fix translations * Update button size Co-authored-by: Casper Hübertz <casper@formgeist.com> * Update size Co-authored-by: Casper Hübertz <casper@formgeist.com> * Remove custom margin Co-authored-by: Casper Hübertz <casper@formgeist.com> * change description size * change casting * Remove link opening in a new window Co-authored-by: Casper Hübertz <casper@formgeist.com> Co-authored-by: Brandon Morelli <bmorelli25@gmail.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Casper Hübertz <casper@formgeist.com>
This commit is contained in:
parent
3a4c6de7a5
commit
ac36edd0ab
12 changed files with 376 additions and 157 deletions
|
@ -45,6 +45,7 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
|
|||
droppedTransactionSpans: `${APM_DOCS}guide/${DOC_LINK_VERSION}/data-model-spans.html#data-model-dropped-spans`,
|
||||
upgrading: `${APM_DOCS}guide/${DOC_LINK_VERSION}/upgrade.html`,
|
||||
metaData: `${APM_DOCS}guide/${DOC_LINK_VERSION}/data-model-metadata.html`,
|
||||
overview: `${APM_DOCS}guide/${DOC_LINK_VERSION}/apm-overview.html`,
|
||||
tailSamplingPolicies: `${APM_DOCS}guide/${DOC_LINK_VERSION}/configure-tail-based-sampling.html`,
|
||||
},
|
||||
canvas: {
|
||||
|
@ -398,6 +399,11 @@ export const getDocLinks = ({ kibanaBranch }: GetDocLinkOptions): DocLinks => {
|
|||
monitorUptime: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/monitor-uptime.html`,
|
||||
tlsCertificate: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/tls-certificate-alert.html`,
|
||||
uptimeDurationAnomaly: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/duration-anomaly-alert.html`,
|
||||
monitorLogs: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/monitor-logs.html`,
|
||||
analyzeMetrics: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/analyze-metrics.html`,
|
||||
monitorUptimeSynthetics: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/monitor-uptime-synthetics.html`,
|
||||
userExperience: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/user-experience.html`,
|
||||
createAlerts: `${ELASTIC_WEBSITE_URL}guide/en/observability/${DOC_LINK_VERSION}/create-alerts.html`,
|
||||
},
|
||||
alerting: {
|
||||
guide: `${KIBANA_DOCS}create-and-manage-rules.html`,
|
||||
|
|
|
@ -31,6 +31,7 @@ export interface DocLinks {
|
|||
readonly droppedTransactionSpans: string;
|
||||
readonly upgrading: string;
|
||||
readonly metaData: string;
|
||||
readonly overview: string;
|
||||
readonly tailSamplingPolicies: string;
|
||||
};
|
||||
readonly canvas: {
|
||||
|
@ -290,6 +291,11 @@ export interface DocLinks {
|
|||
monitorUptime: string;
|
||||
tlsCertificate: string;
|
||||
uptimeDurationAnomaly: string;
|
||||
monitorLogs: string;
|
||||
analyzeMetrics: string;
|
||||
monitorUptimeSynthetics: string;
|
||||
userExperience: string;
|
||||
createAlerts: string;
|
||||
}>;
|
||||
readonly alerting: Record<string, string>;
|
||||
readonly maps: Readonly<{
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* 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 { HttpSetup, DocLinksStart } from 'kibana/public';
|
||||
import { ObservabilityFetchDataPlugins } from '../../../typings/fetch_overview_data';
|
||||
|
||||
export interface ObservabilityStatusContent {
|
||||
id: ObservabilityFetchDataPlugins | 'alert';
|
||||
title: string;
|
||||
description: string;
|
||||
addTitle: string;
|
||||
addLink: string;
|
||||
learnMoreLink: string;
|
||||
goToAppTitle: string;
|
||||
goToAppLink: string;
|
||||
}
|
||||
|
||||
export const getContent = (
|
||||
http: HttpSetup,
|
||||
docLinks: DocLinksStart
|
||||
): ObservabilityStatusContent[] => {
|
||||
return [
|
||||
{
|
||||
id: 'infra_logs',
|
||||
title: i18n.translate('xpack.observability.statusVisualization.logs.title', {
|
||||
defaultMessage: 'Logs',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.statusVisualization.logs.description', {
|
||||
defaultMessage:
|
||||
'Fast, easy, and scalable centralized log monitoring with out-of-the-box support for common data sources.',
|
||||
}),
|
||||
addTitle: i18n.translate('xpack.observability.statusVisualization.logs.link', {
|
||||
defaultMessage: 'Add integrations',
|
||||
}),
|
||||
addLink: http.basePath.prepend('/app/integrations/browse?q=logs'),
|
||||
learnMoreLink: docLinks.links.observability.monitorLogs,
|
||||
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.logs.goToAppTitle', {
|
||||
defaultMessage: 'Show log stream',
|
||||
}),
|
||||
goToAppLink: http.basePath.prepend('/app/logs/stream'),
|
||||
},
|
||||
{
|
||||
id: 'apm',
|
||||
title: i18n.translate('xpack.observability.statusVisualization.apm.title', {
|
||||
defaultMessage: 'APM',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.statusVisualization.apm.description', {
|
||||
defaultMessage:
|
||||
'Get deeper visibility into your applications with extensive support for popular languages, OpenTelemetry, and distributed tracing.',
|
||||
}),
|
||||
addTitle: i18n.translate('xpack.observability.statusVisualization.apm.link', {
|
||||
defaultMessage: 'Add data',
|
||||
}),
|
||||
addLink: http.basePath.prepend('/app/home#/tutorial/apm'),
|
||||
learnMoreLink: docLinks.links.apm.overview,
|
||||
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.apm.goToAppTitle', {
|
||||
defaultMessage: 'Show services inventory',
|
||||
}),
|
||||
goToAppLink: http.basePath.prepend('/app/apm/services'),
|
||||
},
|
||||
{
|
||||
id: 'infra_metrics',
|
||||
title: i18n.translate('xpack.observability.statusVisualization.metrics.title', {
|
||||
defaultMessage: 'Infrastructure',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.statusVisualization.metrics.description', {
|
||||
defaultMessage: 'Stream, visualize, and analyze your infrastructure metrics.',
|
||||
}),
|
||||
addTitle: i18n.translate('xpack.observability.statusVisualization.metrics.link', {
|
||||
defaultMessage: 'Add integrations',
|
||||
}),
|
||||
addLink: http.basePath.prepend('/app/integrations/browse?q=metrics'),
|
||||
learnMoreLink: docLinks.links.observability.analyzeMetrics,
|
||||
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.metrics.goToAppTitle', {
|
||||
defaultMessage: 'Show inventory',
|
||||
}),
|
||||
goToAppLink: http.basePath.prepend('/app/metrics/inventory'),
|
||||
},
|
||||
{
|
||||
id: 'synthetics',
|
||||
title: i18n.translate('xpack.observability.statusVisualization.uptime.title', {
|
||||
defaultMessage: 'Uptime',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.statusVisualization.uptime.description', {
|
||||
defaultMessage: 'Proactively monitor the availability and functionality of user journeys.',
|
||||
}),
|
||||
addTitle: i18n.translate('xpack.observability.statusVisualization.uptime.link', {
|
||||
defaultMessage: 'Add monitors',
|
||||
}),
|
||||
addLink: http.basePath.prepend('/app/home#/tutorial/uptimeMonitors'),
|
||||
learnMoreLink: docLinks.links.observability.monitorUptimeSynthetics,
|
||||
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.uptime.goToAppTitle', {
|
||||
defaultMessage: 'Show monitors ',
|
||||
}),
|
||||
goToAppLink: http.basePath.prepend('/app/uptime'),
|
||||
},
|
||||
{
|
||||
id: 'ux',
|
||||
title: i18n.translate('xpack.observability.statusVisualization.ux.title', {
|
||||
defaultMessage: 'User Experience',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.statusVisualization.ux.description', {
|
||||
defaultMessage:
|
||||
'Collect, measure, and analyze performance data that reflects real-world user experiences.',
|
||||
}),
|
||||
addTitle: i18n.translate('xpack.observability.statusVisualization.ux.link', {
|
||||
defaultMessage: 'Add data',
|
||||
}),
|
||||
addLink: http.basePath.prepend('/app/home#/tutorial/apm'),
|
||||
learnMoreLink: docLinks.links.observability.userExperience,
|
||||
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.ux.goToAppTitle', {
|
||||
defaultMessage: 'Show dashboard',
|
||||
}),
|
||||
goToAppLink: http.basePath.prepend('/app/ux'),
|
||||
},
|
||||
{
|
||||
id: 'alert',
|
||||
title: i18n.translate('xpack.observability.statusVisualization.alert.title', {
|
||||
defaultMessage: 'Alerting',
|
||||
}),
|
||||
description: i18n.translate('xpack.observability.statusVisualization.alert.description', {
|
||||
defaultMessage:
|
||||
'Detect complex conditions in Observability and trigger actions when those conditions are met.',
|
||||
}),
|
||||
addTitle: i18n.translate('xpack.observability.statusVisualization.alert.link', {
|
||||
defaultMessage: 'Create rules',
|
||||
}),
|
||||
addLink: http.basePath.prepend('/app/management/insightsAndAlerting/triggersActions/rules'),
|
||||
learnMoreLink: docLinks.links.observability.createAlerts,
|
||||
goToAppTitle: i18n.translate('xpack.observability.statusVisualization.alert.goToAppTitle', {
|
||||
defaultMessage: 'Show alerts',
|
||||
}),
|
||||
goToAppLink: http.basePath.prepend('/app/observability/alerts'),
|
||||
},
|
||||
];
|
||||
};
|
|
@ -8,25 +8,21 @@
|
|||
import React from 'react';
|
||||
import { useHasData } from '../../../hooks/use_has_data';
|
||||
import { ObservabilityStatusBoxes } from './observability_status_boxes';
|
||||
import { getEmptySections } from '../../../pages/overview/empty_section';
|
||||
import { getContent } from './content';
|
||||
import { useKibana } from '../../../../../../../src/plugins/kibana_react/public';
|
||||
import { ObservabilityAppServices } from '../../../application/types';
|
||||
|
||||
export function ObservabilityStatus() {
|
||||
const { http } = useKibana<ObservabilityAppServices>().services;
|
||||
const { http, docLinks } = useKibana<ObservabilityAppServices>().services;
|
||||
const { hasDataMap } = useHasData();
|
||||
|
||||
const appEmptySections = getEmptySections({ http });
|
||||
const content = getContent(http, docLinks);
|
||||
|
||||
const boxes = appEmptySections.map((app) => {
|
||||
const boxes = content.map((app) => {
|
||||
return {
|
||||
id: app.id,
|
||||
dataSourceName: app.title,
|
||||
...app,
|
||||
hasData: hasDataMap[app.id]?.hasData ?? false,
|
||||
description: app.description,
|
||||
modules: [],
|
||||
integrationLink: app.href ?? '',
|
||||
learnMoreLink: app.href ?? '',
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -16,82 +16,80 @@ export default {
|
|||
|
||||
const testBoxes = [
|
||||
{
|
||||
id: 'logs',
|
||||
dataSourceName: 'Logs',
|
||||
hasData: true,
|
||||
description: 'This is the description for logs',
|
||||
modules: [
|
||||
{ name: 'system', hasData: true },
|
||||
{ name: 'kubernetes', hasData: false },
|
||||
{ name: 'docker', hasData: true },
|
||||
],
|
||||
integrationLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
},
|
||||
{
|
||||
id: 'metrics',
|
||||
dataSourceName: 'Metrics',
|
||||
hasData: true,
|
||||
description: 'This is the description for metrics',
|
||||
modules: [
|
||||
{ name: 'system', hasData: true },
|
||||
{ name: 'kubernetes', hasData: true },
|
||||
{ name: 'docker', hasData: false },
|
||||
],
|
||||
integrationLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
id: 'infra_logs',
|
||||
title: 'Logs',
|
||||
description:
|
||||
'Fast, easy, and scalable, centralized log monitoring with out-of-the-box support for common data sources.',
|
||||
addTitle: 'Add integrations',
|
||||
addLink: '/app/integrations/browse?q=logs',
|
||||
learnMoreLink: 'http://lean-more-link-example.com',
|
||||
goToAppTitle: 'Show log stream',
|
||||
goToAppLink: '/app/logs/stream',
|
||||
hasData: false,
|
||||
modules: [],
|
||||
},
|
||||
{
|
||||
id: 'apm',
|
||||
dataSourceName: 'APM',
|
||||
hasData: true,
|
||||
description: 'This is the description for apm',
|
||||
modules: [
|
||||
{ name: 'system', hasData: true },
|
||||
{ name: 'kubernetes', hasData: true },
|
||||
{ name: 'docker', hasData: true },
|
||||
],
|
||||
integrationLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
title: 'APM',
|
||||
description:
|
||||
'Get deeper visibility into your applications with extensive support for popular languages, OpenTelemetry, and distributed tracing.',
|
||||
addTitle: 'Add data',
|
||||
addLink: '/app/home#/tutorial/apm',
|
||||
learnMoreLink: 'http://lean-more-link-example.com',
|
||||
goToAppTitle: 'Show services inventory',
|
||||
goToAppLink: '/app/apm/services',
|
||||
hasData: false,
|
||||
modules: [],
|
||||
},
|
||||
{
|
||||
id: 'uptime',
|
||||
dataSourceName: 'Uptime',
|
||||
id: 'infra_metrics',
|
||||
title: 'Infrastructure',
|
||||
description: 'Stream, visualize, and analyze your infrastructure metrics.',
|
||||
addTitle: 'Add integrations',
|
||||
addLink: '/app/integrations/browse?q=metrics',
|
||||
learnMoreLink: 'http://lean-more-link-example.com',
|
||||
goToAppTitle: 'Show inventory',
|
||||
goToAppLink: '/app/metrics/inventory',
|
||||
hasData: false,
|
||||
description: 'This is the description for uptime',
|
||||
modules: [
|
||||
{ name: 'system', hasData: true },
|
||||
{ name: 'kubernetes', hasData: true },
|
||||
{ name: 'docker', hasData: true },
|
||||
],
|
||||
integrationLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
modules: [],
|
||||
},
|
||||
{
|
||||
id: 'synthetics',
|
||||
title: 'Uptime',
|
||||
description: 'Proactively monitor the availability and functionality of user journeys.',
|
||||
addTitle: 'Add monitors',
|
||||
addLink: '/app/home#/tutorial/uptimeMonitors',
|
||||
learnMoreLink: 'http://lean-more-link-example.com',
|
||||
goToAppTitle: 'Show monitors ',
|
||||
goToAppLink: '/app/uptime',
|
||||
hasData: false,
|
||||
modules: [],
|
||||
},
|
||||
{
|
||||
id: 'ux',
|
||||
dataSourceName: 'User experience',
|
||||
hasData: false,
|
||||
description: 'This is the description for user experience',
|
||||
modules: [
|
||||
{ name: 'system', hasData: true },
|
||||
{ name: 'kubernetes', hasData: true },
|
||||
{ name: 'docker', hasData: true },
|
||||
],
|
||||
integrationLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
title: 'User Experience',
|
||||
description:
|
||||
'Collect, measure, and analyze performance data that reflects real-world user experiences.',
|
||||
addTitle: 'Add data',
|
||||
addLink: '/app/home#/tutorial/apm',
|
||||
learnMoreLink: 'http://lean-more-link-example.com',
|
||||
goToAppTitle: 'Show dashboard',
|
||||
goToAppLink: '/app/ux',
|
||||
hasData: true,
|
||||
modules: [],
|
||||
},
|
||||
{
|
||||
id: 'alerts',
|
||||
dataSourceName: 'Alerts and rules',
|
||||
id: 'alert',
|
||||
title: 'Alerting',
|
||||
description:
|
||||
'Detect complex conditions in Observability and trigger actions when those conditions are met.',
|
||||
addTitle: 'Create rules',
|
||||
addLink: '/app/management/insightsAndAlerting/triggersActions/rules',
|
||||
learnMoreLink: 'http://lean-more-link-example.com',
|
||||
goToAppTitle: 'Show alerts',
|
||||
goToAppLink: '/app/observability/alerts',
|
||||
hasData: true,
|
||||
description: 'This is the description for alerts and rules',
|
||||
modules: [
|
||||
{ name: 'system', hasData: true },
|
||||
{ name: 'kubernetes', hasData: true },
|
||||
{ name: 'docker', hasData: true },
|
||||
],
|
||||
integrationLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
modules: [],
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -15,12 +15,15 @@ describe('ObservabilityStatusBox', () => {
|
|||
beforeEach(() => {
|
||||
const props = {
|
||||
id: 'logs',
|
||||
dataSourceName: 'Logs',
|
||||
title: 'Logs',
|
||||
hasData: false,
|
||||
description: 'test description',
|
||||
modules: [],
|
||||
integrationLink: 'testIntegrationUrl.com',
|
||||
addTitle: 'logs add title',
|
||||
addLink: 'http://example.com',
|
||||
learnMoreLink: 'learnMoreUrl.com',
|
||||
goToAppTitle: 'go to app title',
|
||||
goToAppLink: 'go to app link',
|
||||
};
|
||||
|
||||
render(
|
||||
|
@ -35,8 +38,8 @@ describe('ObservabilityStatusBox', () => {
|
|||
});
|
||||
|
||||
it('should have a learn more button', () => {
|
||||
const learnMoreLink = screen.getByRole('link') as HTMLAnchorElement;
|
||||
expect(learnMoreLink.href).toContain('learnMoreUrl.com');
|
||||
const learnMoreLink = screen.getByText('Learn more') as HTMLElement;
|
||||
expect(learnMoreLink.closest('a')?.href).toContain('learnMoreUrl.com');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -44,7 +47,7 @@ describe('ObservabilityStatusBox', () => {
|
|||
beforeEach(() => {
|
||||
const props = {
|
||||
id: 'logs',
|
||||
dataSourceName: 'Logs',
|
||||
title: 'Logs',
|
||||
hasData: true,
|
||||
description: 'test description',
|
||||
modules: [
|
||||
|
@ -52,8 +55,11 @@ describe('ObservabilityStatusBox', () => {
|
|||
{ name: 'module2', hasData: false },
|
||||
{ name: 'module3', hasData: true },
|
||||
],
|
||||
integrationLink: 'addIntegrationUrl.com',
|
||||
learnMoreLink: 'learnMoreUrl.com',
|
||||
addTitle: 'logs add title',
|
||||
addLink: 'addIntegrationUrl.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
goToAppTitle: 'go to app title',
|
||||
goToAppLink: 'go to app link',
|
||||
};
|
||||
|
||||
render(
|
||||
|
@ -66,8 +72,8 @@ describe('ObservabilityStatusBox', () => {
|
|||
// it('should have a check icon', () => {});
|
||||
|
||||
it('should have the integration link', () => {
|
||||
const addIntegrationLink = screen.getByRole('link') as HTMLAnchorElement;
|
||||
expect(addIntegrationLink.href).toContain('addIntegrationUrl.com');
|
||||
const addIntegrationLink = screen.getByText('logs add title') as HTMLElement;
|
||||
expect(addIntegrationLink.closest('a')?.href).toContain('addIntegrationUrl.com');
|
||||
});
|
||||
|
||||
it('should have the list of modules', () => {
|
||||
|
|
|
@ -15,18 +15,22 @@ import {
|
|||
EuiPanel,
|
||||
EuiText,
|
||||
EuiTitle,
|
||||
EuiLink,
|
||||
} from '@elastic/eui';
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
||||
export interface ObservabilityStatusBoxProps {
|
||||
id: string;
|
||||
dataSourceName: string;
|
||||
title: string;
|
||||
hasData: boolean;
|
||||
description: string;
|
||||
modules: Array<{ name: string; hasData: boolean }>;
|
||||
integrationLink: string;
|
||||
addTitle: string;
|
||||
addLink: string;
|
||||
learnMoreLink: string;
|
||||
goToAppTitle: string;
|
||||
goToAppLink: string;
|
||||
}
|
||||
|
||||
export function ObservabilityStatusBox(props: ObservabilityStatusBoxProps) {
|
||||
|
@ -38,12 +42,15 @@ export function ObservabilityStatusBox(props: ObservabilityStatusBoxProps) {
|
|||
}
|
||||
|
||||
export function CompletedStatusBox({
|
||||
dataSourceName,
|
||||
title,
|
||||
modules,
|
||||
integrationLink,
|
||||
addLink,
|
||||
addTitle,
|
||||
goToAppTitle,
|
||||
goToAppLink,
|
||||
}: ObservabilityStatusBoxProps) {
|
||||
return (
|
||||
<EuiPanel color="subdued">
|
||||
<EuiPanel color="plain" hasBorder={true}>
|
||||
<EuiFlexGroup justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
|
@ -54,20 +61,26 @@ export function CompletedStatusBox({
|
|||
style={{ marginRight: 8 }}
|
||||
/>
|
||||
<EuiTitle size="xs" className="eui-displayInline eui-alignMiddle">
|
||||
<h2>{dataSourceName}</h2>
|
||||
<h2>{title}</h2>
|
||||
</EuiTitle>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButtonEmpty size="xs" iconType="plusInCircle" flush="right" href={integrationLink}>
|
||||
<FormattedMessage
|
||||
id="xpack.observability.status.addIntegrationLink"
|
||||
defaultMessage="Add"
|
||||
/>
|
||||
<EuiButtonEmpty size="s" iconType="plusInCircle" flush="right" href={addLink}>
|
||||
{addTitle}
|
||||
</EuiButtonEmpty>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<FormattedMessage
|
||||
id="xpack.observability.status.dataAvailable"
|
||||
defaultMessage="Data is available."
|
||||
/>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiFlexGroup alignItems="baseline" gutterSize="s" style={{ marginTop: 8 }} role="list">
|
||||
{modules.map((module) => (
|
||||
<EuiFlexItem role="listitem" key={module.name}>
|
||||
|
@ -81,52 +94,64 @@ export function CompletedStatusBox({
|
|||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export function EmptyStatusBox({
|
||||
dataSourceName,
|
||||
description,
|
||||
learnMoreLink,
|
||||
}: ObservabilityStatusBoxProps) {
|
||||
return (
|
||||
<EuiPanel color="subdued" style={{ marginBottom: 20 }}>
|
||||
<EuiFlexGroup justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiIcon
|
||||
type="dot"
|
||||
color="warning"
|
||||
className="eui-displayInline eui-alignMiddle"
|
||||
style={{ marginRight: 8 }}
|
||||
/>
|
||||
<EuiTitle size="xs" className="eui-displayInline eui-alignMiddle">
|
||||
<h2>{dataSourceName}</h2>
|
||||
</EuiTitle>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiIcon type="cross" color="text" />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="xs">{description}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiButton color="primary" size="s" href={learnMoreLink}>
|
||||
<FormattedMessage
|
||||
id="xpack.observability.status.learnMoreButton"
|
||||
defaultMessage="Learn more"
|
||||
/>
|
||||
<EuiButton color="primary" href={goToAppLink}>
|
||||
{goToAppTitle}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export function EmptyStatusBox({
|
||||
title,
|
||||
description,
|
||||
learnMoreLink,
|
||||
addTitle,
|
||||
addLink,
|
||||
}: ObservabilityStatusBoxProps) {
|
||||
return (
|
||||
<EuiPanel color="warning" hasBorder={true}>
|
||||
<EuiFlexGroup justifyContent="spaceBetween">
|
||||
<EuiFlexItem>
|
||||
<div>
|
||||
<EuiIcon
|
||||
type="minusInCircleFilled"
|
||||
color="warning"
|
||||
className="eui-displayInline eui-alignMiddle"
|
||||
style={{ marginRight: 8 }}
|
||||
/>
|
||||
<EuiTitle size="xs" className="eui-displayInline eui-alignMiddle">
|
||||
<h2>{title}</h2>
|
||||
</EuiTitle>
|
||||
</div>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiFlexGroup>
|
||||
<EuiFlexItem>
|
||||
<EuiText size="s">{description}</EuiText>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
|
||||
<EuiFlexGroup alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton color="primary" href={addLink} fill>
|
||||
{addTitle}
|
||||
</EuiButton>
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiLink color="primary" href={learnMoreLink} target="_blank">
|
||||
<FormattedMessage
|
||||
id="xpack.observability.status.learnMoreButton"
|
||||
defaultMessage="Learn more"
|
||||
/>
|
||||
</EuiLink>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</EuiPanel>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,31 +8,42 @@
|
|||
import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { ObservabilityStatusBoxes } from './observability_status_boxes';
|
||||
import { I18nProvider } from '@kbn/i18n-react';
|
||||
|
||||
describe('ObservabilityStatusBoxes', () => {
|
||||
it('should render all boxes passed as prop', () => {
|
||||
const boxes = [
|
||||
{
|
||||
id: 'logs',
|
||||
dataSourceName: 'Logs',
|
||||
title: 'Logs',
|
||||
hasData: true,
|
||||
description: 'This is the description for logs',
|
||||
modules: [],
|
||||
integrationLink: 'http://example.com',
|
||||
addTitle: 'logs add title',
|
||||
addLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
goToAppTitle: 'go to app title',
|
||||
goToAppLink: 'go to app link',
|
||||
},
|
||||
{
|
||||
id: 'metrics',
|
||||
dataSourceName: 'Metrics',
|
||||
title: 'Metrics',
|
||||
hasData: true,
|
||||
description: 'This is the description for metrics',
|
||||
modules: [],
|
||||
integrationLink: 'http://example.com',
|
||||
addTitle: 'metrics add title',
|
||||
addLink: 'http://example.com',
|
||||
learnMoreLink: 'http://example.com',
|
||||
goToAppTitle: 'go to app title',
|
||||
goToAppLink: 'go to app link',
|
||||
},
|
||||
];
|
||||
|
||||
render(<ObservabilityStatusBoxes boxes={boxes} />);
|
||||
render(
|
||||
<I18nProvider>
|
||||
<ObservabilityStatusBoxes boxes={boxes} />
|
||||
</I18nProvider>
|
||||
);
|
||||
|
||||
expect(screen.getByText('Logs')).toBeInTheDocument();
|
||||
expect(screen.getByText('Metrics')).toBeInTheDocument();
|
||||
|
|
|
@ -6,21 +6,56 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiSpacer } from '@elastic/eui';
|
||||
import { ObservabilityStatusBox, ObservabilityStatusBoxProps } from './observability_status_box';
|
||||
import { EuiTitle, EuiFlexGroup, EuiFlexItem, EuiHorizontalRule } from '@elastic/eui';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
import {
|
||||
CompletedStatusBox,
|
||||
EmptyStatusBox,
|
||||
ObservabilityStatusBoxProps,
|
||||
} from './observability_status_box';
|
||||
export interface ObservabilityStatusProps {
|
||||
boxes: ObservabilityStatusBoxProps[];
|
||||
}
|
||||
|
||||
export function ObservabilityStatusBoxes({ boxes }: ObservabilityStatusProps) {
|
||||
const hasDataBoxes = boxes.filter((box) => box.hasData);
|
||||
const noHasDataBoxes = boxes.filter((box) => !box.hasData);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{boxes.map((box) => (
|
||||
<>
|
||||
<ObservabilityStatusBox key={box.id} {...box} />
|
||||
<EuiSpacer />
|
||||
</>
|
||||
<EuiFlexGroup direction="column">
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs">
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.observability.status.recommendedSteps"
|
||||
defaultMessage="Recommended next steps"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
{noHasDataBoxes.map((box) => (
|
||||
<EuiFlexItem key={box.id}>
|
||||
<EmptyStatusBox {...box} />
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{noHasDataBoxes.length > 0 && <EuiHorizontalRule />}
|
||||
|
||||
<EuiFlexItem>
|
||||
<EuiTitle size="xs">
|
||||
<h2>
|
||||
<FormattedMessage
|
||||
id="xpack.observability.status.dataAvailableTitle"
|
||||
defaultMessage="Data available for"
|
||||
/>
|
||||
</h2>
|
||||
</EuiTitle>
|
||||
</EuiFlexItem>
|
||||
{hasDataBoxes.map((box) => (
|
||||
<EuiFlexItem key={box.id}>
|
||||
<CompletedStatusBox {...box} />
|
||||
</EuiFlexItem>
|
||||
))}
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ export const getEmptySections = ({ http }: { http: HttpSetup }): ISection[] => {
|
|||
icon: 'logoLogging',
|
||||
description: i18n.translate('xpack.observability.emptySection.apps.logs.description', {
|
||||
defaultMessage:
|
||||
'Centralize logs from any source. Search, tail, automate anomaly detection, and visualize trends so you can take action quicker.',
|
||||
'Fast, easy, and scalable centralized log monitoring with out-of-the-box support for common data sources.',
|
||||
}),
|
||||
linkTitle: i18n.translate('xpack.observability.emptySection.apps.logs.link', {
|
||||
defaultMessage: 'Install Filebeat',
|
||||
|
@ -34,7 +34,7 @@ export const getEmptySections = ({ http }: { http: HttpSetup }): ISection[] => {
|
|||
icon: 'logoObservability',
|
||||
description: i18n.translate('xpack.observability.emptySection.apps.apm.description', {
|
||||
defaultMessage:
|
||||
'Trace transactions through a distributed architecture and map your services’ interactions to easily spot performance bottlenecks.',
|
||||
'Get deeper visibility into your applications with extensive support for popular languages, OpenTelemetry, and distributed tracing.',
|
||||
}),
|
||||
linkTitle: i18n.translate('xpack.observability.emptySection.apps.apm.link', {
|
||||
defaultMessage: 'Install Agent',
|
||||
|
@ -48,8 +48,7 @@ export const getEmptySections = ({ http }: { http: HttpSetup }): ISection[] => {
|
|||
}),
|
||||
icon: 'logoMetrics',
|
||||
description: i18n.translate('xpack.observability.emptySection.apps.metrics.description', {
|
||||
defaultMessage:
|
||||
'Analyze metrics from your infrastructure, apps, and services. Discover trends, forecast behavior, get alerts on anomalies, and more.',
|
||||
defaultMessage: 'Stream, visualize, and analyze your infrastructure metrics.',
|
||||
}),
|
||||
linkTitle: i18n.translate('xpack.observability.emptySection.apps.metrics.link', {
|
||||
defaultMessage: 'Install Metricbeat',
|
||||
|
@ -63,8 +62,7 @@ export const getEmptySections = ({ http }: { http: HttpSetup }): ISection[] => {
|
|||
}),
|
||||
icon: 'logoUptime',
|
||||
description: i18n.translate('xpack.observability.emptySection.apps.uptime.description', {
|
||||
defaultMessage:
|
||||
'Proactively monitor the availability of your sites and services. Receive alerts and resolve issues faster to optimize your users’ experience.',
|
||||
defaultMessage: 'Proactively monitor the availability and functionality of user journeys.',
|
||||
}),
|
||||
linkTitle: i18n.translate('xpack.observability.emptySection.apps.uptime.link', {
|
||||
defaultMessage: 'Install Heartbeat',
|
||||
|
@ -79,7 +77,7 @@ export const getEmptySections = ({ http }: { http: HttpSetup }): ISection[] => {
|
|||
icon: 'logoObservability',
|
||||
description: i18n.translate('xpack.observability.emptySection.apps.ux.description', {
|
||||
defaultMessage:
|
||||
'Performance is a distribution. Measure the experiences of all visitors to your web application and understand how to improve the experience for everyone.',
|
||||
'Collect, measure, and analyze performance data that reflects real-world user experiences.',
|
||||
}),
|
||||
linkTitle: i18n.translate('xpack.observability.emptySection.apps.ux.link', {
|
||||
defaultMessage: 'Install RUM Agent',
|
||||
|
@ -94,7 +92,7 @@ export const getEmptySections = ({ http }: { http: HttpSetup }): ISection[] => {
|
|||
icon: 'watchesApp',
|
||||
description: i18n.translate('xpack.observability.emptySection.apps.alert.description', {
|
||||
defaultMessage:
|
||||
'Are 503 errors stacking up? Are services responding? Is CPU and RAM utilization jumping? See warnings as they happen—not as part of the post-mortem.',
|
||||
'Detect complex conditions within Observability and trigger actions when those conditions are met.',
|
||||
}),
|
||||
linkTitle: i18n.translate('xpack.observability.emptySection.apps.alert.link', {
|
||||
defaultMessage: 'Create rule',
|
||||
|
|
|
@ -20955,7 +20955,6 @@
|
|||
"xpack.observability.seriesEditor.edit": "系列を編集",
|
||||
"xpack.observability.seriesEditor.hide": "系列を非表示",
|
||||
"xpack.observability.seriesEditor.sampleDocuments": "新しいタブでサンプルドキュメントを表示",
|
||||
"xpack.observability.status.addIntegrationLink": "追加",
|
||||
"xpack.observability.status.learnMoreButton": "詳細",
|
||||
"xpack.observability.transactionRateLabel": "{value} tpm",
|
||||
"xpack.observability.urlFilter.wildcard": "ワイルドカード*{wildcard}*を使用",
|
||||
|
|
|
@ -20983,7 +20983,6 @@
|
|||
"xpack.observability.seriesEditor.edit": "编辑序列",
|
||||
"xpack.observability.seriesEditor.hide": "隐藏序列",
|
||||
"xpack.observability.seriesEditor.sampleDocuments": "在新选项卡中查看样例文档",
|
||||
"xpack.observability.status.addIntegrationLink": "添加",
|
||||
"xpack.observability.status.learnMoreButton": "了解详情",
|
||||
"xpack.observability.transactionRateLabel": "{value} tpm",
|
||||
"xpack.observability.urlFilter.wildcard": "使用通配符 *{wildcard}*",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue