mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[Obs-UX-Mgmt] Split Up SLO Details from Overview (#212826)
## Summary In an effort to make SLI charts more quickly visible on the SLO overview page, remove SLO details that do not give users valuable insight into key metrics and add them to a new tab. Retain some of the SLO details above the tabs like SLI value, tags, and description (see figma for the inspiration) https://www.figma.com/design/91R0OtRZHy5xvaE8dGStBo/SLO%2FSLI-assets?node-id=4601-59103&t=K1vI6qtXbb48XPgr-1 <img width="1474" alt="Screenshot 2025-02-28 at 4 53 05 PM" src="https://github.com/user-attachments/assets/3fdbe766-4047-45b5-a986-3a029c09bd1f" />  ## Release Notes SLO overview should give users a clear, immediate picture into key objective data. Previously, the user would have had to scroll past static data that describes the SLO definition before seeing valuable information about their SLIs. This static data has been moved to a separate tab, making charts more easily accessible. --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
65a41a6b96
commit
34fa3135a2
15 changed files with 203 additions and 137 deletions
|
@ -40274,19 +40274,15 @@
|
|||
"xpack.slo.sloDetails.overview.apmSource.transactionTypeLabel": "type de transaction : {value}",
|
||||
"xpack.slo.sloDetails.overview.budgetingMethodTitle": "Méthode de budgétisation",
|
||||
"xpack.slo.sloDetails.overview.calendarAlignedTimeWindow": "calendrier {duration} aligné",
|
||||
"xpack.slo.sloDetails.overview.descriptionTitle": "Description",
|
||||
"xpack.slo.sloDetails.overview.goodQueryTitle": "Bonne question",
|
||||
"xpack.slo.sloDetails.overview.indexTitle": "Modèle d'indexation",
|
||||
"xpack.slo.sloDetails.overview.indicatorTypeTitle": "Type d’indicateur",
|
||||
"xpack.slo.sloDetails.overview.observedValueSubtitle": "{value} (l'objectif est {objective})",
|
||||
"xpack.slo.sloDetails.overview.observedValueTitle": "Valeur observée",
|
||||
"xpack.slo.sloDetails.overview.overallQueryTitle": "Requête générale",
|
||||
"xpack.slo.sloDetails.overview.rollingTimeWindow": "{duration} en cours",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor": "Moniteur de Synthetics",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor.locationName": "Emplacement : {value}",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor.name": "Nom : {value}",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitorDetails": "Détails du moniteur Synthetics",
|
||||
"xpack.slo.sloDetails.overview.tagsTitle": "Balises",
|
||||
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetails": "{duration} sections, {target} cible",
|
||||
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetailsForTimesliceMetric": "{duration} sections",
|
||||
"xpack.slo.sloDetails.overview.timeWindowTitle": "Fenêtre temporelle",
|
||||
|
|
|
@ -40132,19 +40132,15 @@
|
|||
"xpack.slo.sloDetails.overview.apmSource.transactionTypeLabel": "transactionType: {value}",
|
||||
"xpack.slo.sloDetails.overview.budgetingMethodTitle": "バジェット計算方法",
|
||||
"xpack.slo.sloDetails.overview.calendarAlignedTimeWindow": "{duration}カレンダーが調整されました",
|
||||
"xpack.slo.sloDetails.overview.descriptionTitle": "説明",
|
||||
"xpack.slo.sloDetails.overview.goodQueryTitle": "正常系クエリー",
|
||||
"xpack.slo.sloDetails.overview.indexTitle": "インデックスパターン",
|
||||
"xpack.slo.sloDetails.overview.indicatorTypeTitle": "インジケータータイプ",
|
||||
"xpack.slo.sloDetails.overview.observedValueSubtitle": "{value}(目標は{objective}です)",
|
||||
"xpack.slo.sloDetails.overview.observedValueTitle": "観測された値",
|
||||
"xpack.slo.sloDetails.overview.overallQueryTitle": "全体的なクエリ",
|
||||
"xpack.slo.sloDetails.overview.rollingTimeWindow": "{duration}ローリング",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor": "Syntheticsモニター",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor.locationName": "場所:{value}",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor.name": "名前:{value}",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitorDetails": "Syntheticsモニター詳細",
|
||||
"xpack.slo.sloDetails.overview.tagsTitle": "タグ",
|
||||
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetails": "{duration}スライス、{target}目標",
|
||||
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetailsForTimesliceMetric": "{duration}スライス",
|
||||
"xpack.slo.sloDetails.overview.timeWindowTitle": "時間枠",
|
||||
|
|
|
@ -39556,19 +39556,15 @@
|
|||
"xpack.slo.sloDetails.overview.apmSource.transactionTypeLabel": "事务类型:{value}",
|
||||
"xpack.slo.sloDetails.overview.budgetingMethodTitle": "预算编制方法",
|
||||
"xpack.slo.sloDetails.overview.calendarAlignedTimeWindow": "{duration} 日历已对齐",
|
||||
"xpack.slo.sloDetails.overview.descriptionTitle": "描述",
|
||||
"xpack.slo.sloDetails.overview.goodQueryTitle": "良好查询",
|
||||
"xpack.slo.sloDetails.overview.indexTitle": "索引模式",
|
||||
"xpack.slo.sloDetails.overview.indicatorTypeTitle": "指标类型",
|
||||
"xpack.slo.sloDetails.overview.observedValueSubtitle": "{value}(目标为 {objective})",
|
||||
"xpack.slo.sloDetails.overview.observedValueTitle": "观察值",
|
||||
"xpack.slo.sloDetails.overview.overallQueryTitle": "总体查询",
|
||||
"xpack.slo.sloDetails.overview.rollingTimeWindow": "{duration} 滚动",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor": "Synthetics 监测",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor.locationName": "位置:{value}",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitor.name": "名称:{value}",
|
||||
"xpack.slo.sloDetails.overview.syntheticsMonitorDetails": "Synthetics 监测详情",
|
||||
"xpack.slo.sloDetails.overview.tagsTitle": "标签",
|
||||
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetails": "{duration} 切片,{target} 目标",
|
||||
"xpack.slo.sloDetails.overview.timeslicesBudgetingMethodDetailsForTimesliceMetric": "{duration} 切片",
|
||||
"xpack.slo.sloDetails.overview.timeWindowTitle": "时间窗口",
|
||||
|
|
|
@ -8,3 +8,4 @@
|
|||
export { SloStatusBadge } from './slo_status_badge';
|
||||
export { SloActiveAlertsBadge } from './slo_active_alerts_badge';
|
||||
export { SloStateBadge } from './slo_state_badge';
|
||||
export { SloValueBadge } from './slo_value_badge';
|
||||
|
|
|
@ -6,58 +6,72 @@
|
|||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { EuiBadge, EuiFlexItem, EuiToolTip } from '@elastic/eui';
|
||||
import { EuiBadge, EuiFlexItem, EuiSkeletonText, EuiToolTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { SLOWithSummaryResponse } from '@kbn/slo-schema';
|
||||
|
||||
export interface SloStatusProps {
|
||||
slo: SLOWithSummaryResponse;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export function SloStatusBadge({ slo }: SloStatusProps) {
|
||||
interface StatusHealth {
|
||||
displayText: string;
|
||||
badgeColor: string;
|
||||
}
|
||||
|
||||
type SLOStatus = 'HEALTHY' | 'DEGRADING' | 'VIOLATED' | 'NO_DATA';
|
||||
|
||||
export const displayStatus: Record<SLOStatus, StatusHealth> = {
|
||||
HEALTHY: {
|
||||
displayText: i18n.translate('xpack.slo.sloStatusBadge.healthy', {
|
||||
defaultMessage: 'Healthy',
|
||||
}),
|
||||
badgeColor: 'success',
|
||||
},
|
||||
|
||||
DEGRADING: {
|
||||
displayText: i18n.translate('xpack.slo.sloStatusBadge.degrading', {
|
||||
defaultMessage: 'Degrading',
|
||||
}),
|
||||
badgeColor: 'warning',
|
||||
},
|
||||
VIOLATED: {
|
||||
displayText: i18n.translate('xpack.slo.sloStatusBadge.violated', {
|
||||
defaultMessage: 'Violated',
|
||||
}),
|
||||
badgeColor: 'danger',
|
||||
},
|
||||
NO_DATA: {
|
||||
displayText: i18n.translate('xpack.slo.sloStatusBadge.noData', {
|
||||
defaultMessage: 'No Data',
|
||||
}),
|
||||
badgeColor: 'default',
|
||||
},
|
||||
};
|
||||
|
||||
export function SloStatusBadge({ slo, isLoading }: SloStatusProps) {
|
||||
if (isLoading || !slo) {
|
||||
return <EuiSkeletonText lines={2} data-test-subj="loadingTitle" />;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<EuiFlexItem grow={false}>
|
||||
{slo.summary.status === 'NO_DATA' && (
|
||||
{slo.summary.status === 'NO_DATA' ? (
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
content={i18n.translate('xpack.slo.sloStatusBadge.noDataTooltip', {
|
||||
defaultMessage: 'It may take some time before the data is aggregated and available.',
|
||||
})}
|
||||
>
|
||||
<EuiBadge color="default">
|
||||
{i18n.translate('xpack.slo.sloStatusBadge.noData', {
|
||||
defaultMessage: 'No data',
|
||||
})}
|
||||
<EuiBadge color={displayStatus[slo.summary.status].badgeColor}>
|
||||
{displayStatus[slo.summary.status]?.displayText}
|
||||
</EuiBadge>
|
||||
</EuiToolTip>
|
||||
)}
|
||||
{slo.summary.status === 'HEALTHY' && (
|
||||
<div>
|
||||
<EuiBadge color="success">
|
||||
{i18n.translate('xpack.slo.sloStatusBadge.healthy', {
|
||||
defaultMessage: 'Healthy',
|
||||
})}
|
||||
</EuiBadge>
|
||||
</div>
|
||||
)}
|
||||
{slo.summary.status === 'DEGRADING' && (
|
||||
<div>
|
||||
<EuiBadge color="warning">
|
||||
{i18n.translate('xpack.slo.sloStatusBadge.degrading', {
|
||||
defaultMessage: 'Degrading',
|
||||
})}
|
||||
</EuiBadge>
|
||||
</div>
|
||||
)}
|
||||
{slo.summary.status === 'VIOLATED' && (
|
||||
<div>
|
||||
<EuiBadge color="danger">
|
||||
{i18n.translate('xpack.slo.sloStatusBadge.violated', {
|
||||
defaultMessage: 'Violated',
|
||||
})}
|
||||
</EuiBadge>
|
||||
</div>
|
||||
) : (
|
||||
<EuiBadge color={displayStatus[slo.summary.status].badgeColor}>
|
||||
{displayStatus[slo.summary.status]?.displayText}
|
||||
</EuiBadge>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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 { EuiBadge, EuiFlexItem, EuiSkeletonText, EuiToolTip } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { SLOWithSummaryResponse } from '@kbn/slo-schema';
|
||||
import numeral from '@elastic/numeral';
|
||||
import { useKibana } from '../../../hooks/use_kibana';
|
||||
import { displayStatus } from './slo_status_badge';
|
||||
|
||||
export interface SloStatusProps {
|
||||
slo: SLOWithSummaryResponse;
|
||||
isLoading?: boolean;
|
||||
}
|
||||
|
||||
export function SloValueBadge({ slo, isLoading }: SloStatusProps) {
|
||||
const hasNoData = slo?.summary.status === 'NO_DATA';
|
||||
const { uiSettings } = useKibana().services;
|
||||
const percentFormat = uiSettings.get('format:percent:defaultPattern');
|
||||
|
||||
const badgeDisplayText = useMemo(() => {
|
||||
return i18n.translate('xpack.slo.sloStatusBadge.sloObjectiveValue', {
|
||||
defaultMessage: '{value} / {objective} (Objective)',
|
||||
values: {
|
||||
value: hasNoData ? '-' : numeral(slo.summary.sliValue).format(percentFormat),
|
||||
objective: numeral(slo.objective.target).format(percentFormat),
|
||||
},
|
||||
});
|
||||
}, [slo, percentFormat, hasNoData]);
|
||||
|
||||
if (isLoading || !slo) {
|
||||
return <EuiSkeletonText lines={2} data-test-subj="loadingTitle" />;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<EuiFlexItem grow={false}>
|
||||
{slo.summary.status === 'NO_DATA' ? (
|
||||
<EuiToolTip
|
||||
position="top"
|
||||
content={i18n.translate('xpack.slo.sloStatusBadge.noDataTooltip', {
|
||||
defaultMessage: 'It may take some time before the data is aggregated and available.',
|
||||
})}
|
||||
>
|
||||
<EuiBadge color={displayStatus[slo.summary.status].badgeColor}>
|
||||
{badgeDisplayText}
|
||||
</EuiBadge>
|
||||
</EuiToolTip>
|
||||
) : (
|
||||
<EuiBadge color={displayStatus[slo.summary.status].badgeColor}>
|
||||
{badgeDisplayText}
|
||||
</EuiBadge>
|
||||
)}
|
||||
</EuiFlexItem>
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -5,12 +5,19 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiFlexGroup, EuiFlexItem, EuiMarkdownFormat, EuiSkeletonText } from '@elastic/eui';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
EuiFlexGroup,
|
||||
EuiFlexItem,
|
||||
EuiMarkdownFormat,
|
||||
EuiSkeletonText,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { SLOWithSummaryResponse } from '@kbn/slo-schema';
|
||||
import moment from 'moment';
|
||||
import React from 'react';
|
||||
import { SloStateBadge, SloStatusBadge } from '../../../components/slo/slo_badges';
|
||||
import { TagsList } from '@kbn/observability-shared-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import moment from 'moment';
|
||||
import { SloStateBadge, SloStatusBadge, SloValueBadge } from '../../../components/slo/slo_badges';
|
||||
import { SloRemoteBadge } from '../../slos/components/badges/slo_remote_badge';
|
||||
import { SLOGroupings } from './groupings/slo_groupings';
|
||||
|
||||
|
@ -34,41 +41,36 @@ export function HeaderTitle({ isLoading, slo }: Props) {
|
|||
responsive={false}
|
||||
wrap={true}
|
||||
>
|
||||
<SloStatusBadge slo={slo} />
|
||||
<SloValueBadge slo={slo} isLoading={isLoading} />
|
||||
<SloStatusBadge slo={slo} isLoading={isLoading} />
|
||||
<SloStateBadge slo={slo} />
|
||||
<SloRemoteBadge slo={slo} />
|
||||
<EuiFlexGroup
|
||||
direction="row"
|
||||
gutterSize="m"
|
||||
alignItems="center"
|
||||
justifyContent="flexStart"
|
||||
responsive={false}
|
||||
wrap={true}
|
||||
>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiMarkdownFormat textSize="xs" color="subdued">
|
||||
{i18n.translate('xpack.slo.sloDetails.headerTitle.lastUpdatedLabel', {
|
||||
defaultMessage: '**Last updated by** {updatedBy} **on** {updatedAt}',
|
||||
values: {
|
||||
updatedBy: slo.updatedBy ?? NOT_AVAILABLE_LABEL,
|
||||
updatedAt: moment(slo.updatedAt).format('ll'),
|
||||
},
|
||||
})}
|
||||
</EuiMarkdownFormat>
|
||||
{!!slo?.tags?.length && (
|
||||
<EuiFlexItem grow={true}>
|
||||
<TagsList tags={slo.tags} />
|
||||
</EuiFlexItem>
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiMarkdownFormat textSize="xs" color="subdued">
|
||||
{i18n.translate('xpack.slo.sloDetails.headerTitle.createdLabel', {
|
||||
defaultMessage: '**Created by** {createdBy} **on** {createdAt}',
|
||||
values: {
|
||||
createdBy: slo.createdBy ?? NOT_AVAILABLE_LABEL,
|
||||
createdAt: moment(slo.createdAt).format('ll'),
|
||||
},
|
||||
})}
|
||||
</EuiMarkdownFormat>
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
)}
|
||||
</EuiFlexGroup>
|
||||
{slo.description && (
|
||||
<EuiFlexItem grow={true}>
|
||||
<EuiText className={'eui-textBreakWord'}>
|
||||
<EuiMarkdownFormat textSize="xs" color="subdued">
|
||||
{slo.description}
|
||||
</EuiMarkdownFormat>
|
||||
</EuiText>
|
||||
</EuiFlexItem>
|
||||
)}
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiMarkdownFormat textSize="xs" color="subdued">
|
||||
{i18n.translate('xpack.slo.sloDetails.headerTitle.lastUpdatedLabel', {
|
||||
defaultMessage: '**Last updated by** {updatedBy} **on** {updatedAt}',
|
||||
values: {
|
||||
updatedBy: slo.updatedBy ?? NOT_AVAILABLE_LABEL,
|
||||
updatedAt: moment(slo.updatedAt).format('ll'),
|
||||
},
|
||||
})}
|
||||
</EuiMarkdownFormat>
|
||||
</EuiFlexItem>
|
||||
<SLOGroupings slo={slo} />
|
||||
</EuiFlexGroup>
|
||||
);
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
import React from 'react';
|
||||
import { useKibana } from '../../../../hooks/use_kibana';
|
||||
import { convertSliApmParamsToApmAppDeeplinkUrl } from '../../../../utils/slo/convert_sli_apm_params_to_apm_app_deeplink_url';
|
||||
import { OverviewItem } from './overview_item';
|
||||
import { DefinitionItem } from './definition_item';
|
||||
|
||||
interface Props {
|
||||
slo: SLOWithSummaryResponse;
|
||||
|
@ -45,7 +45,7 @@ export function ApmIndicatorOverview({ slo }: Props) {
|
|||
} = indicator;
|
||||
|
||||
return (
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.apmSource', {
|
||||
defaultMessage: 'APM source',
|
||||
})}
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import { EuiFlexGrid, EuiPanel, EuiText, useIsWithinBreakpoints } from '@elastic/eui';
|
||||
import numeral from '@elastic/numeral';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { TagsList } from '@kbn/observability-shared-plugin/public';
|
||||
import {
|
||||
SLOWithSummaryResponse,
|
||||
occurrencesBudgetingMethodSchema,
|
||||
|
@ -26,18 +25,17 @@ import {
|
|||
} from '../../../../utils/slo/labels';
|
||||
import { ApmIndicatorOverview } from './apm_indicator_overview';
|
||||
import { DisplayQuery } from './display_query';
|
||||
import { OverviewItem } from './overview_item';
|
||||
import { DefinitionItem } from './definition_item';
|
||||
import { SyntheticsIndicatorOverview } from './synthetics_indicator_overview';
|
||||
|
||||
export interface Props {
|
||||
slo: SLOWithSummaryResponse;
|
||||
}
|
||||
|
||||
export function Overview({ slo }: Props) {
|
||||
export function Definition({ slo }: Props) {
|
||||
const isMobile = useIsWithinBreakpoints(['xs', 's']);
|
||||
const { uiSettings } = useKibana().services;
|
||||
const percentFormat = uiSettings.get('format:percent:defaultPattern');
|
||||
const hasNoData = slo.summary.status === 'NO_DATA';
|
||||
|
||||
let IndicatorOverview = null;
|
||||
switch (slo.indicator.type) {
|
||||
|
@ -50,37 +48,21 @@ export function Overview({ slo }: Props) {
|
|||
}
|
||||
|
||||
return (
|
||||
<EuiPanel paddingSize="none" color="transparent" data-test-subj="overview">
|
||||
<EuiPanel paddingSize="none" color="transparent" data-test-subj="definition">
|
||||
<EuiFlexGrid columns={isMobile ? 2 : 4} gutterSize="l" responsive={false}>
|
||||
<OverviewItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.observedValueTitle', {
|
||||
defaultMessage: 'Observed value',
|
||||
})}
|
||||
subtitle={
|
||||
<EuiText size="s">
|
||||
{i18n.translate('xpack.slo.sloDetails.overview.observedValueSubtitle', {
|
||||
defaultMessage: '{value} (objective is {objective})',
|
||||
values: {
|
||||
value: hasNoData ? '-' : numeral(slo.summary.sliValue).format(percentFormat),
|
||||
objective: numeral(slo.objective.target).format(percentFormat),
|
||||
},
|
||||
})}
|
||||
</EuiText>
|
||||
}
|
||||
/>
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.indicatorTypeTitle', {
|
||||
defaultMessage: 'Indicator type',
|
||||
})}
|
||||
subtitle={<EuiText size="s">{toIndicatorTypeLabel(slo.indicator.type)}</EuiText>}
|
||||
/>
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.timeWindowTitle', {
|
||||
defaultMessage: 'Time window',
|
||||
})}
|
||||
subtitle={toTimeWindowLabel(slo.timeWindow)}
|
||||
/>
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.budgetingMethodTitle', {
|
||||
defaultMessage: 'Budgeting method',
|
||||
})}
|
||||
|
@ -115,21 +97,10 @@ export function Overview({ slo }: Props) {
|
|||
)
|
||||
}
|
||||
/>
|
||||
<OverviewItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.descriptionTitle', {
|
||||
defaultMessage: 'Description',
|
||||
})}
|
||||
subtitle={<EuiText size="s">{!!slo.description ? slo.description : '-'}</EuiText>}
|
||||
/>
|
||||
<OverviewItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.tagsTitle', {
|
||||
defaultMessage: 'Tags',
|
||||
})}
|
||||
subtitle={<TagsList tags={slo.tags} />}
|
||||
/>
|
||||
|
||||
{IndicatorOverview}
|
||||
{'index' in slo.indicator.params && (
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.indexTitle', {
|
||||
defaultMessage: 'Index pattern',
|
||||
})}
|
||||
|
@ -137,7 +108,7 @@ export function Overview({ slo }: Props) {
|
|||
/>
|
||||
)}
|
||||
{'filter' in slo.indicator.params && (
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.overallQueryTitle', {
|
||||
defaultMessage: 'Overall query',
|
||||
})}
|
||||
|
@ -150,7 +121,7 @@ export function Overview({ slo }: Props) {
|
|||
/>
|
||||
)}
|
||||
{'good' in slo.indicator.params && querySchema.is(slo.indicator.params.good) && (
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.goodQueryTitle', {
|
||||
defaultMessage: 'Good query',
|
||||
})}
|
||||
|
@ -160,7 +131,7 @@ export function Overview({ slo }: Props) {
|
|||
/>
|
||||
)}
|
||||
{'total' in slo.indicator.params && querySchema.is(slo.indicator.params.total) && (
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.totalQueryTitle', {
|
||||
defaultMessage: 'Total query',
|
||||
})}
|
||||
|
@ -170,13 +141,13 @@ export function Overview({ slo }: Props) {
|
|||
/>
|
||||
)}
|
||||
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.settings.syncDelay', {
|
||||
defaultMessage: 'Sync delay',
|
||||
})}
|
||||
subtitle={slo.settings.syncDelay}
|
||||
/>
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={i18n.translate('xpack.slo.sloDetails.overview.settings.frequency', {
|
||||
defaultMessage: 'Frequency',
|
||||
})}
|
|
@ -13,7 +13,7 @@ export interface Props {
|
|||
subtitle: ReactNode;
|
||||
}
|
||||
|
||||
export function OverviewItem({ title, subtitle }: Props) {
|
||||
export function DefinitionItem({ title, subtitle }: Props) {
|
||||
return (
|
||||
<EuiFlexGroup direction="column" gutterSize="xs">
|
||||
<EuiFlexItem grow={false}>
|
|
@ -10,11 +10,11 @@ import { ComponentStory } from '@storybook/react';
|
|||
|
||||
import { KibanaReactStorybookDecorator } from '../../../../utils/kibana_react.storybook_decorator';
|
||||
import { buildSlo } from '../../../../data/slo/slo';
|
||||
import { Overview as Component, Props } from './overview';
|
||||
import { Definition as Component, Props } from './definition';
|
||||
|
||||
export default {
|
||||
component: Component,
|
||||
title: 'app/SLO/DetailsPage/Overview',
|
||||
title: 'app/SLO/DetailsPage/Definition',
|
||||
decorators: [KibanaReactStorybookDecorator],
|
||||
};
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ import {
|
|||
syntheticsMonitorLocationQueryLocatorID,
|
||||
} from '@kbn/observability-plugin/common';
|
||||
import { useKibana } from '../../../../hooks/use_kibana';
|
||||
import { OverviewItem } from './overview_item';
|
||||
import { DefinitionItem } from './definition_item';
|
||||
|
||||
interface Props {
|
||||
slo: SLOWithSummaryResponse;
|
||||
|
@ -41,14 +41,14 @@ export function SyntheticsIndicatorOverview({ slo }: Props) {
|
|||
|
||||
const onMonitorClick = () => monitorLocator?.navigate({ configId: monitorId, locationId });
|
||||
const onLocationClick = () => regionLocator?.navigate({ locationId: location });
|
||||
const showOverviewItem = name || location;
|
||||
const showDefinitionItem = name || location;
|
||||
|
||||
if (!showOverviewItem) {
|
||||
if (!showDefinitionItem) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<OverviewItem
|
||||
<DefinitionItem
|
||||
title={MONITOR_LABEL}
|
||||
subtitle={
|
||||
<EuiFlexGroup direction="row" alignItems="flexStart" gutterSize="s" responsive={false} wrap>
|
||||
|
|
|
@ -13,7 +13,7 @@ import { BurnRatePanel } from './burn_rate_panel/burn_rate_panel';
|
|||
import { EventsChartPanel } from './events_chart_panel/events_chart_panel';
|
||||
import { HistoricalDataCharts } from './historical_data_charts';
|
||||
import { SLODetailsHistory } from './history/slo_details_history';
|
||||
import { Overview } from './overview/overview';
|
||||
import { Definition } from './overview/definition';
|
||||
import { SloDetailsAlerts } from './slo_detail_alerts';
|
||||
import { SloHealthCallout } from './slo_health_callout';
|
||||
import { SloRemoteCallout } from './slo_remote_callout';
|
||||
|
@ -21,9 +21,14 @@ import { SloRemoteCallout } from './slo_remote_callout';
|
|||
export const TAB_ID_URL_PARAM = 'tabId';
|
||||
export const OVERVIEW_TAB_ID = 'overview';
|
||||
export const HISTORY_TAB_ID = 'history';
|
||||
export const DEFINITION_TAB_ID = 'definition';
|
||||
export const ALERTS_TAB_ID = 'alerts';
|
||||
|
||||
export type SloTabId = typeof OVERVIEW_TAB_ID | typeof ALERTS_TAB_ID | typeof HISTORY_TAB_ID;
|
||||
export type SloTabId =
|
||||
| typeof OVERVIEW_TAB_ID
|
||||
| typeof ALERTS_TAB_ID
|
||||
| typeof HISTORY_TAB_ID
|
||||
| typeof DEFINITION_TAB_ID;
|
||||
|
||||
export interface Props {
|
||||
slo: SLOWithSummaryResponse;
|
||||
|
@ -57,6 +62,10 @@ export function SloDetails({ slo, isAutoRefreshing, selectedTabId }: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
if (selectedTabId === DEFINITION_TAB_ID) {
|
||||
return <Definition slo={slo} />;
|
||||
}
|
||||
|
||||
if (selectedTabId === ALERTS_TAB_ID) {
|
||||
return <SloDetailsAlerts slo={slo} />;
|
||||
}
|
||||
|
@ -65,7 +74,6 @@ export function SloDetails({ slo, isAutoRefreshing, selectedTabId }: Props) {
|
|||
<EuiFlexGroup direction="column" gutterSize="xl">
|
||||
<SloRemoteCallout slo={slo} />
|
||||
<SloHealthCallout slo={slo} />
|
||||
<Overview slo={slo} />
|
||||
|
||||
<EuiFlexGroup direction="column" gutterSize="l">
|
||||
<BurnRatePanel slo={slo} isAutoRefreshing={isAutoRefreshing} />
|
||||
|
|
|
@ -15,6 +15,7 @@ import { useKibana } from '../../../hooks/use_kibana';
|
|||
import {
|
||||
ALERTS_TAB_ID,
|
||||
HISTORY_TAB_ID,
|
||||
DEFINITION_TAB_ID,
|
||||
OVERVIEW_TAB_ID,
|
||||
SloTabId,
|
||||
} from '../components/slo_details';
|
||||
|
@ -62,6 +63,28 @@ export const useSloDetailsTabs = ({
|
|||
: undefined,
|
||||
}),
|
||||
},
|
||||
{
|
||||
id: DEFINITION_TAB_ID,
|
||||
label: i18n.translate('xpack.slo.sloDetails.tab.definitionLabel', {
|
||||
defaultMessage: 'Definition',
|
||||
}),
|
||||
'data-test-subj': 'definitionTab',
|
||||
isSelected: selectedTabId === DEFINITION_TAB_ID,
|
||||
...(setSelectedTabId
|
||||
? {
|
||||
onClick: () => setSelectedTabId(DEFINITION_TAB_ID),
|
||||
}
|
||||
: {
|
||||
href: slo
|
||||
? `${basePath.get()}${paths.sloDetails(
|
||||
slo.id,
|
||||
slo.instanceId,
|
||||
slo.remote?.remoteName,
|
||||
DEFINITION_TAB_ID
|
||||
)}`
|
||||
: undefined,
|
||||
}),
|
||||
},
|
||||
...(slo?.timeWindow.type === 'rolling'
|
||||
? [
|
||||
{
|
||||
|
|
|
@ -229,7 +229,6 @@ describe('SLO Details Page', () => {
|
|||
render(<SloDetailsPage />);
|
||||
|
||||
expect(screen.queryByTestId('sloDetailsPage')).toBeTruthy();
|
||||
expect(screen.queryByTestId('overview')).toBeTruthy();
|
||||
expect(screen.queryByTestId('sliChartPanel')).toBeTruthy();
|
||||
expect(screen.queryByTestId('errorBudgetChartPanel')).toBeTruthy();
|
||||
expect(screen.queryAllByTestId('wideChartLoading').length).toBe(2);
|
||||
|
@ -244,7 +243,6 @@ describe('SLO Details Page', () => {
|
|||
render(<SloDetailsPage />);
|
||||
|
||||
expect(screen.queryByTestId('sloDetailsPage')).toBeTruthy();
|
||||
expect(screen.queryByTestId('overview')).toBeTruthy();
|
||||
expect(screen.queryByTestId('sliChartPanel')).toBeTruthy();
|
||||
expect(screen.queryByTestId('errorBudgetChartPanel')).toBeTruthy();
|
||||
expect(screen.queryByTestId('errorRateChart')).toBeTruthy();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue