[Unified Observability] Guided setup button on the overview page (#128172)

* Add guided setup button to overview page

* Update content for status vis flyout

* assure boxes order

* Fix types

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Ester Martí Vilaseca 2022-03-23 09:21:49 +01:00 committed by GitHub
parent 043c40b6d0
commit 77034b3f54
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 6 deletions

View file

@ -17,6 +17,7 @@ export interface ObservabilityStatusContent {
learnMoreLink: string;
goToAppTitle: string;
goToAppLink: string;
weight: number;
}
export const getContent = (
@ -42,6 +43,7 @@ export const getContent = (
defaultMessage: 'Show log stream',
}),
goToAppLink: http.basePath.prepend('/app/logs/stream'),
weight: 1,
},
{
id: 'apm',
@ -61,6 +63,7 @@ export const getContent = (
defaultMessage: 'Show services inventory',
}),
goToAppLink: http.basePath.prepend('/app/apm/services'),
weight: 3,
},
{
id: 'infra_metrics',
@ -79,6 +82,7 @@ export const getContent = (
defaultMessage: 'Show inventory',
}),
goToAppLink: http.basePath.prepend('/app/metrics/inventory'),
weight: 2,
},
{
id: 'synthetics',
@ -97,6 +101,7 @@ export const getContent = (
defaultMessage: 'Show monitors ',
}),
goToAppLink: http.basePath.prepend('/app/uptime'),
weight: 4,
},
{
id: 'ux',
@ -116,6 +121,7 @@ export const getContent = (
defaultMessage: 'Show dashboard',
}),
goToAppLink: http.basePath.prepend('/app/ux'),
weight: 5,
},
{
id: 'alert',
@ -135,6 +141,7 @@ export const getContent = (
defaultMessage: 'Show alerts',
}),
goToAppLink: http.basePath.prepend('/app/observability/alerts'),
weight: 6,
},
];
};

View file

@ -27,6 +27,7 @@ const testBoxes = [
goToAppLink: '/app/logs/stream',
hasData: false,
modules: [],
weight: 1,
},
{
id: 'apm',
@ -40,6 +41,7 @@ const testBoxes = [
goToAppLink: '/app/apm/services',
hasData: false,
modules: [],
weight: 2,
},
{
id: 'infra_metrics',
@ -52,6 +54,7 @@ const testBoxes = [
goToAppLink: '/app/metrics/inventory',
hasData: false,
modules: [],
weight: 3,
},
{
id: 'synthetics',
@ -64,6 +67,7 @@ const testBoxes = [
goToAppLink: '/app/uptime',
hasData: false,
modules: [],
weight: 4,
},
{
id: 'ux',
@ -77,6 +81,7 @@ const testBoxes = [
goToAppLink: '/app/ux',
hasData: true,
modules: [],
weight: 5,
},
{
id: 'alert',
@ -90,6 +95,7 @@ const testBoxes = [
goToAppLink: '/app/observability/alerts',
hasData: true,
modules: [],
weight: 6,
},
];

View file

@ -24,6 +24,7 @@ describe('ObservabilityStatusBox', () => {
learnMoreLink: 'learnMoreUrl.com',
goToAppTitle: 'go to app title',
goToAppLink: 'go to app link',
weight: 1,
};
render(
@ -60,6 +61,7 @@ describe('ObservabilityStatusBox', () => {
learnMoreLink: 'http://example.com',
goToAppTitle: 'go to app title',
goToAppLink: 'go to app link',
weight: 1,
};
render(

View file

@ -31,6 +31,7 @@ export interface ObservabilityStatusBoxProps {
learnMoreLink: string;
goToAppTitle: string;
goToAppLink: string;
weight: number;
}
export function ObservabilityStatusBox(props: ObservabilityStatusBoxProps) {

View file

@ -24,6 +24,7 @@ describe('ObservabilityStatusBoxes', () => {
learnMoreLink: 'http://example.com',
goToAppTitle: 'go to app title',
goToAppLink: 'go to app link',
weight: 2,
},
{
id: 'metrics',
@ -36,6 +37,7 @@ describe('ObservabilityStatusBoxes', () => {
learnMoreLink: 'http://example.com',
goToAppTitle: 'go to app title',
goToAppLink: 'go to app link',
weight: 1,
},
];
@ -48,4 +50,45 @@ describe('ObservabilityStatusBoxes', () => {
expect(screen.getByText('Logs')).toBeInTheDocument();
expect(screen.getByText('Metrics')).toBeInTheDocument();
});
it('should render elements by order', () => {
const boxes = [
{
id: 'logs',
title: 'Logs',
hasData: true,
description: 'This is the description for logs',
modules: [],
addTitle: 'logs add title',
addLink: 'http://example.com',
learnMoreLink: 'http://example.com',
goToAppTitle: 'go to app title',
goToAppLink: 'go to app link',
weight: 2,
},
{
id: 'metrics',
title: 'Metrics',
hasData: true,
description: 'This is the description for metrics',
modules: [],
addTitle: 'metrics add title',
addLink: 'http://example.com',
learnMoreLink: 'http://example.com',
goToAppTitle: 'go to app title',
goToAppLink: 'go to app link',
weight: 1,
},
];
render(
<I18nProvider>
<ObservabilityStatusBoxes boxes={boxes} />
</I18nProvider>
);
const content = screen.getAllByTestId(/box-*/);
expect(content[0]).toHaveTextContent('Metrics');
expect(content[1]).toHaveTextContent('Logs');
});
});

View file

@ -17,9 +17,13 @@ export interface ObservabilityStatusProps {
boxes: ObservabilityStatusBoxProps[];
}
const sortingFn = (a: ObservabilityStatusBoxProps, b: ObservabilityStatusBoxProps) => {
return a.weight - b.weight;
};
export function ObservabilityStatusBoxes({ boxes }: ObservabilityStatusProps) {
const hasDataBoxes = boxes.filter((box) => box.hasData);
const noHasDataBoxes = boxes.filter((box) => !box.hasData);
const hasDataBoxes = boxes.filter((box) => box.hasData).sort(sortingFn);
const noHasDataBoxes = boxes.filter((box) => !box.hasData).sort(sortingFn);
return (
<EuiFlexGroup direction="column">
@ -34,7 +38,7 @@ export function ObservabilityStatusBoxes({ boxes }: ObservabilityStatusProps) {
</EuiTitle>
</EuiFlexItem>
{noHasDataBoxes.map((box) => (
<EuiFlexItem key={box.id}>
<EuiFlexItem key={box.id} data-test-id={`box-${box.id}`}>
<EmptyStatusBox {...box} />
</EuiFlexItem>
))}
@ -52,7 +56,7 @@ export function ObservabilityStatusBoxes({ boxes }: ObservabilityStatusProps) {
</EuiTitle>
</EuiFlexItem>
{hasDataBoxes.map((box) => (
<EuiFlexItem key={box.id}>
<EuiFlexItem key={box.id} data-test-subj={`box-${box.id}`}>
<CompletedStatusBox {...box} />
</EuiFlexItem>
))}

View file

@ -5,9 +5,21 @@
* 2.0.
*/
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiHorizontalRule } from '@elastic/eui';
import {
EuiFlexGroup,
EuiFlexItem,
EuiSpacer,
EuiHorizontalRule,
EuiButton,
EuiFlyout,
EuiFlyoutHeader,
EuiTitle,
EuiFlyoutBody,
EuiText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useMemo, useRef, useCallback } from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import React, { useMemo, useRef, useCallback, useState } from 'react';
import { observabilityFeatureId } from '../../../common';
import { useKibana } from '../../../../../../src/plugins/kibana_react/public';
import { useTrackPageview } from '../..';
@ -33,6 +45,7 @@ import { ObservabilityAppServices } from '../../application/types';
import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions';
import { paths } from '../../config';
import { useDatePickerContext } from '../../hooks/use_date_picker_context';
import { ObservabilityStatus } from '../../components/app/observability_status';
interface Props {
routeParams: RouteParams<'/overview'>;
}
@ -53,6 +66,7 @@ export function OverviewPage({ routeParams }: Props) {
}),
},
]);
const [isFlyoutVisible, setIsFlyoutVisible] = useState(false);
const indexNames = useAlertIndexNames();
const { cases, docLinks, http } = useKibana<ObservabilityAppServices>().services;
@ -110,6 +124,12 @@ export function OverviewPage({ routeParams }: Props) {
? {
pageTitle: overviewPageTitle,
rightSideItems: [
<EuiButton color="text" iconType="wrench" onClick={() => setIsFlyoutVisible(true)}>
<FormattedMessage
id="xpack.observability.overview.guidedSetupButton"
defaultMessage="Guided setup"
/>
</EuiButton>,
<DatePicker
rangeFrom={relativeStart}
rangeTo={relativeEnd}
@ -177,6 +197,37 @@ export function OverviewPage({ routeParams }: Props) {
</EuiFlexGroup>
</>
)}
{isFlyoutVisible && (
<EuiFlyout
size="s"
ownFocus
onClose={() => setIsFlyoutVisible(false)}
aria-labelledby="statusVisualizationFlyoutTitle"
>
<EuiFlyoutHeader hasBorder>
<EuiTitle size="m">
<h2 id="statusVisualizationFlyoutTitle">
<FormattedMessage
id="xpack.observability.overview.statusVisualizationFlyoutTitle"
defaultMessage="Guided setup"
/>
</h2>
</EuiTitle>
<EuiSpacer size="s" />
<EuiText size="s">
<p>
<FormattedMessage
id="xpack.observability.overview.statusVisualizationFlyoutDescription"
defaultMessage="Track your progress towards adding observability integrations and features."
/>
</p>
</EuiText>
</EuiFlyoutHeader>
<EuiFlyoutBody>
<ObservabilityStatus />
</EuiFlyoutBody>
</EuiFlyout>
)}
</ObservabilityPageTemplate>
);
}