Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Obs-UX-Mgmt] Split Up SLO Details from Overview #212826

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -40289,19 +40289,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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40147,19 +40147,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": "時間枠",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39571,19 +39571,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": "时间窗口",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
Original file line number Diff line number Diff line change
@@ -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: 'Observed SLI: {value} / {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>
</>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -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}>
)}
</EuiFlexGroup>
{slo.description && (
<EuiFlexItem grow={true}>
<EuiText className={'eui-textBreakWord'}>
<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'),
},
})}
{slo.description}
</EuiMarkdownFormat>
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexGroup>
</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>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -45,7 +45,7 @@ export function ApmIndicatorOverview({ slo }: Props) {
} = indicator;

return (
<OverviewItem
<DefinitionItem
title={i18n.translate('xpack.slo.sloDetails.overview.apmSource', {
defaultMessage: 'APM source',
})}
Expand Down
Loading